FindDragTarget不检测禁用的控件

use*_*348 2 delphi delphi-10.1-berlin

创建Delphi VCL Forms应用程序并在表单上放置2 TButton和a TApplicationEvents:

在此输入图像描述

然后插入这些事件处理程序:

unit Unit2;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.AppEvnts;

type
  TForm2 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    ApplicationEvents1: TApplicationEvents;
    procedure ApplicationEvents1Message(var Msg: tagMSG; var Handled: Boolean);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form2: TForm2;

implementation

{$R *.dfm}

procedure TForm2.Button1Click(Sender: TObject);
begin
  Screen.Cursor := crHelp;
end;

procedure TForm2.ApplicationEvents1Message(var Msg: tagMSG; var Handled: Boolean);
var
  Target: TControl;
  Point: TPoint;
begin
  if Msg.Message = WM_LBUTTONDOWN then
  begin
    if Screen.Cursor = crHelp then
    begin
      Screen.Cursor := crDefault;
      Handled := True;
      GetCursorPos(Point);
      Target := FindDragTarget(Point, True);
      if Assigned(Target) then
        ShowMessage(Target.Name)
      else
        ShowMessage(IntToStr(Point.X) + ', ' + IntToStr(Point.Y));
    end;
  end;
end;

end.
Run Code Online (Sandbox Code Playgroud)

现在单击Button1将鼠标指针更改为crHelp.

然后再次单击Button1,正确显示名称"Button1".

现在再次单击Button1再次将鼠标指针更改为crHelp.

然后单击禁用的Button2:FindDragTarget虽然参数AllowDisabled设置为,但您可以看到现在没有检测到禁用的控件True.

那么如何通过鼠标单击检测禁用的控件?

Delphi 10.1.2

kob*_*bik 5

"问题"(实际上是设计)是该FindDragTarget函数不检查禁用的子窗口控件.

function FindDragTarget(const Pos: TPoint; AllowDisabled: Boolean): TControl;
var
  Window: TWinControl;
  Control: TControl;
begin
  ...
  Control := Window.ControlAtPos(Window.ScreenToClient(Pos), AllowDisabled);
  ...
end;
Run Code Online (Sandbox Code Playgroud)

请注意,Window.ControlAtPos只传递AllowDisabled参数但不传递AllowWinControls(False默认情况下).

FindDragTarget只会找到子TGraphicControl后代控件(使用其父句柄).

您可以使用此功能:

function FindDragTargetEx(const Pos: TPoint; AllowDisabled: Boolean; AllowWinControls: Boolean): TControl;
var
  Window: TWinControl;
  Control: TControl;
begin
  Result := nil;
  Window := FindVCLWindow(Pos);
  if Window <> nil then
  begin
    Result := Window;
    Control := Window.ControlAtPos(Window.ScreenToClient(Pos), AllowDisabled, AllowWinControls);
    if Control <> nil then Result := Control;
  end;
end;
Run Code Online (Sandbox Code Playgroud)