我发现了一个与光标位置相关的非常奇怪的 Delphi IDE 行为。
创建一个示例项目:
unit Unit2;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls, Vcl.StdCtrls;
type
TForm2 = class(TForm)
ListBox1: TListBox;
Panel1: TPanel;
procedure Panel1MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
procedure Panel1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure Panel1MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
private
FStartLog : boolean;
public
{ Public declarations }
end;
var
Form2: TForm2;
implementation
{$R *.dfm}
procedure TForm2.Panel1MouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
FStartLog := True;
end;
procedure TForm2.Panel1MouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
if FStartLog then ListBox1.Items.Add(Format('X = %d; Y = %d', [X, Y]))
end;
procedure TForm2.Panel1MouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
FStartLog := False;
end;
end.
我们有一个简单的表单,其中包含一个用于记录的 ListBox 和一个面板。当我们单击面板上的鼠标按钮时,我们会收到鼠标消息,直到按钮被释放。
当鼠标离开面板窗体时会发生奇怪的事情。当我们在后台使用 Delphi IDE 运行应用程序并单击鼠标右键并向右移动时,我们会看到以下内容:
X = 218; Y = 228
X = 237; Y = 228
X = 257; Y = 227
X = 313; Y = 226
X = 315; Y = 226
X = 333; Y = 225
X = 334; Y = 225
X = 353; Y = 224
X = 379; Y = 224
X = 380; Y = 224
X = 381; Y = 224
X = -288; Y = 61
X = -288; Y = 61
X = -287; Y = 61
当我们离开Form时,X
和坐标是不同的。Y
好的,也许它与屏幕和客户端坐标之间的对话有关。因此,最小化 IDE,我们会在后台看到桌面并执行相同的操作。
X = 222; Y = 144
X = 229; Y = 144
X = 230; Y = 144
X = 231; Y = 144
X = 232; Y = 144
X = 233; Y = 144
X = 234; Y = 144
X = 273; Y = 144
X = 314; Y = 147
X = 317; Y = 147
X = 345; Y = 148
X = 347; Y = 148
X = 373; Y = 148
X = 375; Y = 148
X = 377; Y = 149
我们看到我们得到了正确的坐标。
请注意,在所有情况下,应用程序都在 Delphi IDE 下运行,但在 Delphi 之外运行不会改变任何事情。当应用程序窗口显示在 Delphi IDE 上时,会发生此行为。所以,我认为这是 Delphi IDE 创建的一些鼠标钩子中的一个错误。
我正在用 XE7 和 10.4 检查这个问题。
我对么?
另外,经过调查,我发现与高 Dpi 功能相关的错误,如果顶部窗口正确使用高 Dpi 和底部窗口在高 DPI 上显示缩放。因此,WM_NCHITTEST 首先转到底部窗口(我们可以将光标悬停在它上面),然后它们根据缩放转换坐标,并且在捕获鼠标的窗口收到消息后,坐标仍保持缩放。在 Windows 7 上测试。