Reputation: 6061
Create a Delphi VCL Forms Application and put 2 TButton
and a TApplicationEvents
on the form:
Then insert these event-handlers:
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.
Now click on Button1 to change the mouse pointer to crHelp
.
Then click again on Button1 which correctly shows the name "Button1".
Now click again on Button1 to change the mouse pointer again to crHelp
.
Then click on the disabled Button2: You can see that now FindDragTarget
has not detected the disabled control although the argument AllowDisabled
is set to True
.
So how can I detect a disabled control with a mouse-click?
Delphi 10.1.2
Upvotes: 2
Views: 394
Reputation: 21252
The "problem" (this is actually by design) is that the FindDragTarget
function does not check for disabled child Windowed Controls.
function FindDragTarget(const Pos: TPoint; AllowDisabled: Boolean): TControl;
var
Window: TWinControl;
Control: TControl;
begin
...
Control := Window.ControlAtPos(Window.ScreenToClient(Pos), AllowDisabled);
...
end;
Note that Window.ControlAtPos
only passes AllowDisabled
argument but NOT the AllowWinControls
(which is False
by default).
FindDragTarget
will only find child TGraphicControl
descendant controls (which use their parent Handle).
You can use this function instead:
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;
Upvotes: 5