Reputation: 55
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;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ExtCtrls, Grids;
type
TForm1 = class(TForm)
Panel1: TPanel;
StringGrid1: TStringGrid;
Mouse_Coordinates: TEdit;
Control_Name: TEdit;
Button1: TButton;
procedure MouseWheelHandler(var Message: TMessage); override;
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.MouseWheelHandler(var Message: TMessage);
var
Target_Control: TWinControl;
begin
with TWMMouseWheel(Message) do
begin
Mouse_Coordinates.Text := IntToStr(XPos) + ', ' + IntToStr(YPos);
Target_Control := FindVCLWindow(Point(XPos, YPos));
if Target_Control <> nil then
Control_Name.Text := Target_Control.Name
else
Control_Name.Text := 'nil';
end;
end;
end.
Upvotes: 0
Views: 530
Reputation: 55
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;
var
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
begin
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 }
Upvotes: 1