- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我遇到了 WM_NCHITTEST
的奇怪行为消息。
总而言之,一旦我将鼠标悬停在目标(即:Hooked)控件上并保持鼠标静止(或空闲),我就会收到 无休止地百位 WM_NCHITTEST
每秒消息。无论我是否对 WndProc
进行子类化都会发生这种情况该控件的 WindowProc()
, 或者如果我 覆盖 WndProc
子类中的方法(为了简单起见,我在下面的代码中子类化)。
据我从在线 Win32 API 文档和其他来源中找到的信息,我怀疑此消息是否以这种频率触发,但我可能是错的。或者可能有一个我完全错过的明显解释,或者我不知道的 API 发生了一些变化。无论如何,我真的很想知道它是什么,或者正在发生什么。
我已经在两个不同的系统上测试了相同的代码(下面的示例),结果相同,尽管两个系统都在相同的 Delphi/OS 版本和配置中。我尝试在 IDE 之外运行应用程序(因此没有调试 Hook ),在调试和发布配置(后者没有调试信息)中,针对 32 位和 64 位,我总是得到相同的结果。
我正在 Win10 Pro 64 位版本 20H2(我相信是最新的 Windows 版本)下使用 Delphi XE7 Enterprise 进行开发。
这是一个非常简单的程序来重现我所经历的:TForm
与 TPanel
, TCheckBox
, 和 TLabel
.面板是勾选复选框时被钩住的控件,标签显示的是多少WM_NCHITTEST
消息由 WndProc()
接收方法:
unit Unit5;
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
TForm5 = class(TForm)
CheckBox1: TCheckBox;
Label1: TLabel;
Panel1: TPanel;
procedure FormDestroy(Sender: TObject);
procedure CheckBox1Click(Sender: TObject);
private
FHookedCtrl: TControl;
FHookedCtrlWndProc: TWndMethod;
FMessageCount: Integer;
procedure SetHookedCtrl(const Value: TControl);
public
procedure ControlWndProc(var Message: TMessage);
property HookedCtrl: TControl read FHookedCtrl write SetHookedCtrl;
end;
var
Form5: TForm5;
implementation
{$R *.dfm}
{ TForm5 }
procedure TForm5.CheckBox1Click(Sender: TObject);
begin
//checkbox activates or deactivates the hook
if CheckBox1.Checked then
//hook the panel's WndProc by subclassing
HookedCtrl := Panel1
//release the hook on WndProc
else HookedCtrl := nil;
end;
procedure TForm5.ControlWndProc(var Message: TMessage);
begin
case Message.Msg of
WM_NCHITTEST:
begin
//show how many messages received with the label's caption
Inc(FMessageCount);
Label1.Caption := FormatFloat('##,##0 messages', FMessageCount);
end;
end;
//not really handling the messsage, just counting.
FHookedCtrlWndProc(Message);
end;
procedure TForm5.FormDestroy(Sender: TObject);
begin
//make sure to clear the hook if assigned
HookedCtrl := nil;
end;
procedure TForm5.SetHookedCtrl(const Value: TControl);
begin
if (Value <> FHookedCtrl) then
begin
if Assigned(FHookedCtrl) then
begin
//release the hook
FHookedCtrl.WindowProc := FHookedCtrlWndProc;
FHookedCtrlWndProc := nil;
FMessageCount := 0;
end;
FHookedCtrl := Value;
if Assigned(FHookedCtrl) then
begin
//hook the panel (i.e. Value)
FHookedCtrlWndProc := FHookedCtrl.WindowProc;
FHookedCtrl.WindowProc := ControlWndProc;
end;
end;
end;
end.
重现:运行应用程序,选中 CheckBox,将鼠标悬停在面板上并让它保持空闲(静止)。就我而言,我收到了 100 个
WM_NCHITTEST
每秒消息,它永远不会停止。这应该发生吗?
最佳答案
我用过 Microsoft Spy++工具来查看会发生什么以及何时发生。
它是 WM_NCHITTEST 处理程序中的以下行
Label1.Caption := FormatFloat('##,##0 messages', FMessageCount);
这导致了这个问题。当您删除它时,所有这些
WM_NCHITTEST
都没有了。消息。要查看消息数量,请使用
TTimer
以 1 秒的间隔并在标签中显示消息计数。你会看到你得到一个
WM_NCHITTEST
每次计时器触发时(如果您有一个空的 OnTimer 处理程序,您仍然会收到一条消息),当然还有鼠标移动时。
unit Unit5;
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
TForm5 = class(TForm)
Label1: TLabel;
CheckBox1: TCheckBox;
Panel1: TPanel;
Timer1: TTimer;
procedure FormDestroy(Sender: TObject);
procedure CheckBox1Click(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
private
FHookedCtrl: TControl;
FHookedCtrlWndProc: TWndMethod;
FMessageCount: Integer;
procedure SetHookedCtrl(const Value: TControl);
public
procedure ControlWndProc(var Message: TMessage);
property HookedCtrl: TControl read FHookedCtrl write SetHookedCtrl;
end;
var
Form5: TForm5;
implementation
{$R *.dfm}
{ TForm5 }
procedure TForm5.CheckBox1Click(Sender: TObject);
begin
//checkbox activates or deactivates the hook
if CheckBox1.Checked then
//hook the panel's WndProc by subclassing
HookedCtrl := Panel1
else
//release the hook on WndProc
HookedCtrl := nil;
end;
procedure TForm5.ControlWndProc(var Message: TMessage);
begin
case Message.Msg of
WM_NCHITTEST:
//Count how many messages received
Inc(FMessageCount);
end;
//not really handling the messsage, just counting.
FHookedCtrlWndProc(Message);
end;
procedure TForm5.FormDestroy(Sender: TObject);
begin
//make sure to clear the hook if assigned
HookedCtrl := nil;
end;
procedure TForm5.SetHookedCtrl(const Value: TControl);
begin
if (Value <> FHookedCtrl) then begin
if Assigned(FHookedCtrl) then begin
//release the hook
FHookedCtrl.WindowProc := FHookedCtrlWndProc;
FHookedCtrlWndProc := nil;
FMessageCount := 0;
end;
FHookedCtrl := Value;
if Assigned(FHookedCtrl) then begin
//hook the panel (i.e. Value)
FHookedCtrlWndProc := FHookedCtrl.WindowProc;
FHookedCtrl.WindowProc := ControlWndProc;
end;
end;
end;
procedure TForm5.Timer1Timer(Sender: TObject);
begin
// Show how many message received
Label1.Caption := FormatFloat('##,##0 messages', FMessageCount);
end;
end.
关于delphi - WM_NCHITTEST 是否应该由 Win10 以每秒 100 次的频率永久生成,即使鼠标处于空闲状态?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66501361/
我想要一个按钮,单击该按钮会在指定时间后刷新当前页面。 我目前有: setTimeout(function reload(){ location = '' },1000) Relo
我有一个场景,我需要每秒向服务器发送数据(非常少的字节)。这个细节很重要,所以我也需要对其进行加密。 深入研究后,我认为我们可以使用 HTTP 协议(protocol),但在这种情况下,HTTP he
我在即将进行的测试的学习指南中得到了这个问题。我不明白如何解决这个问题。今天是我的考试,我希望能得到一些帮助。 如果 CPU 每条指令发出一个内存请求并且计算机以 200 MIPS 运行,大约需要多少
我正在编写一个程序来确定每秒可以运行多少个 NOP,但我得到的数字似乎非常小。 int main() { struct timeval tvStart, tvDiff, tvEnd;
我想实现每秒 5-1 百万次远程函数调用。假设我们有一台开始计算的 Central 计算机,还有一台执行计算的 Worker 计算机。实际配置中会有很多Worker计算机。 假设我们的任务是计算一个[
下面的代码向最后一个 div 添加了一个类: $(".mydivs:last").addClass('added'); 这适用于页面加载,但 div 在动画中,因此顺序会改变。有没有办法让代码每秒运行
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 这个问题似乎不是关于 a specific programming problem, a softwa
我刚刚在 HBase 中创建了一个表并用数据填充了它。从 7 个区域服务器看来,数据已写入区域服务器 6 和 7。 但我不明白为什么服务器 6 和 7 的每秒请求数为零? 最佳答案 读取请求计数 和写
我正在开发一个聊天应用程序,需要您的帮助。如果有人在线,我将信息存储在数据库中。现在我有一个功能,可以显示您的好友列表以及聊天伙伴是否在线。问题是:如果有人上网,我想经常检查。到目前为止,我有一个每秒
我正在编写一个快速而肮脏的脚本来检测服务器停机时间。我有一台服务器和两个远程客户端,它们每秒对服务器执行一次 ping 操作以查看它是否已启动。 如果您最多可以每分钟运行一次 cron,我该如何设置任
有什么方法可以让 Graphite 绘制图表请求吗? 当你从 nginx_status 检索 nginx 请求时,你正在向 Graphite 发送一个绝对值,所以我在想是否有任何方法可以获取每秒的速率
我正在构建一个 Android 应用程序,它将加速度计和陀螺仪数据记录到文本文件中。在大多数教程中,他们使用的方法涉及创建两个文本文件,并每秒打开和关闭它们 50 次。即: private stati
嘿,我目前在我的 mysql 上有超过 300+ qps。在相当繁重的 PHP 网站上大约有 12000 UIP 一天/没有 cron。我知道在没有看到该网站的情况下很难判断是否可以,但您是否认为这完
我希望每秒钟使用我的鼠标移动功能旋转矩形我做错了什么?我怎样才能做我的变换,以便高度和旋转每隔一个元素改变一次?我用 if ( i % 2 == 0){} 试了一下 function modifyRe
有没有办法配置具有恒定负载的性能测试用例(例如,每秒 3 个新请求,持续 1 分钟)? 其他负载测试库具有此功能来设置请求率(例如 Artillery.io、Vegeta)。 k6 有设置VUs 的方
(只是想提一下,这是我的第一个问题,如果我做错了什么,我深表歉意)。我正在制作一个解析 CSV 文件并将其保存为列表的 Python 程序。但是,该程序需要用户输入他们希望将数据发送到服务器的速度。我
如何使用 python 将毫秒转换为帧数?我知道视频的帧速率(每帧 25 秒) 2683480 2684448 最佳答案 我最终决定手动执行此操作,因为我仍然没有弄清楚 ffmpeg 函数等 25fp
我有一个动态表,它按从主要编号到次要编号的降序排列。我想用 jQuery 在前 2 行放置红色背景,在接下来的行放置橙色背景,在接下来的 2 行放置黄色背景,在接下来的 3 行放置绿色背景。 表结构:
构建 Rails 应用程序 (ruby 2.4.0p0/Rails 5.1.4) 并使用我的 Macbook air (MacOS High Sierra 10.13.2) 在本地进行测试,但我一直遇
这个问题已经有答案了: NSTimer not firing when runloop is blocked (2 个回答) 已关闭 9 年前。 我使用 NSTimer,它每秒触发一次并更新一个标签,
我是一名优秀的程序员,十分优秀!