Why are form system buttons highlighted when WindowFromPoint is called in the MouseMove event?

A WindowFromPoint call in the MouseMove event for TWinControl raises the MouseOver event at the point passed to WindowFromPoint. Is this a VCL error? Does anyone know if there is a workaround?

enter image description here

Here is a demo code:

unit Unit7; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls; type TForm7 = class(TForm) Button1: TButton; procedure Button1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); private { Private declarations } public { Public declarations } end; var Form7: TForm7; implementation {$R *.dfm} procedure TForm7.Button1MouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer); begin WindowFromPoint(Point(Mouse.CursorPos.X, Mouse.CursorPos.Y - 40)); end; end. 

DFM:

 object Form7: TForm7 Left = 0 Top = 0 Caption = 'Form7' ClientHeight = 40 ClientWidth = 116 Color = clBtnFace Font.Charset = DEFAULT_CHARSET Font.Color = clWindowText Font.Height = -11 Font.Name = 'Tahoma' Font.Style = [] OldCreateOrder = False PixelsPerInch = 96 TextHeight = 13 object Button1: TButton Left = 24 Top = 7 Width = 75 Height = 25 Caption = 'Button1' TabOrder = 0 OnMouseMove = Button1MouseMove end end 

I am using Delphi XE2 on Windows 7 Pro 64bit. I can also play using Delphi 7.

+4
source share
1 answer

I tested this with the simplest C ++ application and observed the same behavior, this is not a VCL error (as David mentioned in the comments). This is not related to the BTW mouse movement, any time you call WindowFromPoint , passing the coordinates of the title button, a special feature arises. And this only happens in windows belonging to the thread that calls the function call.

So, for a workaround, you can call WindowFromPoint from the stream. The simple example below is not really a background thread, since the code is waiting for it to complete:

 type TGetWndThread = class(TThread) private FPoint: TPoint; protected procedure Execute; override; constructor Create(AOwner: TComponent; Point: TPoint); end; constructor TGetWndThread.Create(AOwner: TComponent; Point: TPoint); begin FPoint := Point; inherited Create; end; procedure TGetWndThread.Execute; begin ReturnValue := WindowFromPoint(FPoint); end; .. var Wnd: HWND; Thr: TGetWndThread; begin Thr := TGetWndThread.Create(nil, Point(Mouse.CursorPos.X, Mouse.CursorPos.Y - 40)); Wnd := Thr.WaitFor; Thr.Free; .. // use Wnd 


It would be advisable to test the conditions that display the error (OS, themes ..), and make the code conditional in order to avoid unnecessary costs if this is not necessary.

+4
source

All Articles