Windows 为什么是表格';在MouseMove事件中从点调用WindowFromPoint时,系统按钮是否高亮显示?
在TWinControl的MouseMove事件中调用WindowFromPoint会在传递给WindowFromPoint的点处引发MouseOver事件。这是VCL错误吗?有人知道是否有解决办法吗 以下是演示代码:Windows 为什么是表格';在MouseMove事件中从点调用WindowFromPoint时,系统按钮是否高亮显示?,windows,delphi,delphi-xe2,Windows,Delphi,Delphi Xe2,在TWinControl的MouseMove事件中调用WindowFromPoint会在传递给WindowFromPoint的点处引发MouseOver事件。这是VCL错误吗?有人知道是否有解决办法吗 以下是演示代码: unit Unit7; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Contr
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:
我正在Windows 7 Pro 64位上使用Delphi XE2。我也可以用Delphi 7来复制。< P>我用最简单的C++应用程序测试了这一点,观察到了同样的行为,这不是VCL错误(正如戴维在评论中提到的)。顺便说一句,它与鼠标移动无关,只要你调用
WindowFromPoint
传递标题按钮的坐标,这种特性就会出现。它只发生在属于调用函数的线程的窗口上
因此,对于解决方法,可以从线程调用WindowFromPoint
。下面是一个简单的示例,在代码等待它完成时,它实际上不是一个后台线程:
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
测试bug显示的条件(操作系统、主题…)并使代码有条件以避免不必要的开销是有意义的。WindowFromPoint是Windows API。所以这似乎不是VCL的问题。@TLama-实际上,表单可以是任何大小,但光标必须在系统按钮正下方小于等于40像素。这篇来自Raymond Chen的文章可能与此相关:Hi Sertac。那很有效,非常感谢。你知道如何完全关闭高亮显示吗?我问这个问题的原因是,在TchromeTab中,我处理自己的选项卡拖放。拖动选项卡时,当光标位于系统按钮上方时,系统按钮仍高亮显示。Chrome确实表现出这种行为,所以我想一定有办法暂时禁用高光效果。也许这应该是一个新问题?@norge-不客气。我现在想不出什么,我要测试的第一件事是尝试处理WM_NCHITTEST,但是对于DWM来说,处理它可能会有一些不同。
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