Home Delphi FindVCLWindow returning nil
Reply: 1

Delphi FindVCLWindow returning nil

Chris Hubbard
Chris Hubbard Published in 2017-09-11 06:05:44Z

My application uses mouse wheel scrolling in a number of places.

Thus I’ve written a mouse wheel handler, and this handler works out where the mouse is located before calling the appropriate object method.

On most PCs this works fine, but I have one laptop here where it does not. Despite the handler receiving the correct mouse co-ordinates from Windows, calls to FindVCLWindow are returning nil. This is however only happening when I use the laptop’s internal touch pad. External USB mice work fine.

I’ve updated the laptop’s touch pad driver to the latest available from the manufacturer's web site, but to no avail.

How else can I fix this?

Here’s the code:

unit Mouse_Wheel_Testing;


  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls, ExtCtrls, Grids;

  TForm1 = class(TForm)
    Panel1: TPanel;
    StringGrid1: TStringGrid;
    Mouse_Coordinates: TEdit;
    Control_Name: TEdit;
    Button1: TButton;
    procedure MouseWheelHandler(var Message: TMessage); override;
    { Private declarations }
    { Public declarations }

  Form1: TForm1;


{$R *.DFM}

procedure TForm1.MouseWheelHandler(var Message: TMessage);
  Target_Control: TWinControl;
  with TWMMouseWheel(Message) do
    Mouse_Coordinates.Text := IntToStr(XPos) + ', ' + IntToStr(YPos);
    Target_Control := FindVCLWindow(Point(XPos, YPos));
    if Target_Control <> nil then
      Control_Name.Text := Target_Control.Name
      Control_Name.Text := 'nil';

Chris Hubbard
Chris Hubbard Reply to 2017-09-13 02:23:36Z

The reason why FindVCLWindow was returning nil was that WindowFromPoint was returning an incorrect handle. This in turn was the result of a setting in the laptop relating to the behavior of its touch pad when in scrolling mode. This option needed to be set correctly for the correct handle to be returned.

Since my application cannot rely on the user having their laptop set correctly, I have now written a new FindComponent function which is based upon ChildWindowFromPointEx. The following function now resides within the mouse wheel handler:

function Find_Control: TWinControl;
  Parent: HWND;
  Child: HWND;
  Position: TPoint;
begin { Find_Control }
  Result := nil;
  Parent := Self.Handle;
  with TWMMouseWheel(Message) do
    Position := ScreenToClient(Point(XPos, YPos));
  Child := ChildWindowFromPointEx(Parent, Position, CWP_SKIPINVISIBLE);
  while (Child <> 0) and (Child <> Parent) do
    Result := FindControl(Child);
    Position := Point(Position.X - Result.Left, Position.Y - Result.Top);
    Parent := Child;
    Child := ChildWindowFromPointEx(Parent, Position, CWP_SKIPINVISIBLE);
  end; { while (Child <> 0) and (Child <> Parent) }
end; { Find_Control }
You need to login account before you can post.

About| Privacy statement| Terms of Service| Advertising| Contact us| Help| Sitemap|
Processed in 0.309361 second(s) , Gzip On .

© 2016 Powered by cudou.com design MATCHINFO