FindDragTarget 不检测禁用的控件
FindDragTarget does not detect disabled controls
创建一个 Delphi VCL 表单应用程序并在表单上放置 2 TButton
和一个 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.
现在单击 Button1 将鼠标指针更改为 crHelp
。
然后再次单击 Button1,它会正确显示名称 "Button1"。
现在再次单击 Button1 将鼠标指针再次更改为 crHelp
。
然后点击禁用的Button2: 你可以看到现在FindDragTarget
没有检测到禁用的控件,虽然参数AllowDisabled
设置为True
.
那么如何通过单击鼠标来检测禁用的控件?
Delphi 10.1.2
"problem"(这实际上是设计使然)是FindDragTarget
函数不检查禁用子Windowed控件。
function FindDragTarget(const Pos: TPoint; AllowDisabled: Boolean): TControl;
var
Window: TWinControl;
Control: TControl;
begin
...
Control := Window.ControlAtPos(Window.ScreenToClient(Pos), AllowDisabled);
...
end;
请注意,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;
创建一个 Delphi VCL 表单应用程序并在表单上放置 2 TButton
和一个 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.
现在单击 Button1 将鼠标指针更改为 crHelp
。
然后再次单击 Button1,它会正确显示名称 "Button1"。
现在再次单击 Button1 将鼠标指针再次更改为 crHelp
。
然后点击禁用的Button2: 你可以看到现在FindDragTarget
没有检测到禁用的控件,虽然参数AllowDisabled
设置为True
.
那么如何通过单击鼠标来检测禁用的控件?
Delphi 10.1.2
"problem"(这实际上是设计使然)是FindDragTarget
函数不检查禁用子Windowed控件。
function FindDragTarget(const Pos: TPoint; AllowDisabled: Boolean): TControl;
var
Window: TWinControl;
Control: TControl;
begin
...
Control := Window.ControlAtPos(Window.ScreenToClient(Pos), AllowDisabled);
...
end;
请注意,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;