Delphi FormKeyDown ALT键卡住
我有一个表单,有两个复选框,一个用于按住CTRL键,一个用于按住ALT键。 这两个复选框都被禁用,因此窗体的KeyDown事件可以正常工作。 还有一个TTimer,如果按下ALT/CTRL键,它每10毫秒同步一次 我的计时器: 我的按键关闭事件: 我的密钥更新事件: 这在使用CTRL键时不会出现任何问题。 但是ALT键有时会卡住,甚至根本不出现。 当我只按ALT键而不按任何其他组合键时会发生这种情况Delphi FormKeyDown ALT键卡住,delphi,winapi,delphi-7,vcl,keylogger,Delphi,Winapi,Delphi 7,Vcl,Keylogger,我有一个表单,有两个复选框,一个用于按住CTRL键,一个用于按住ALT键。 这两个复选框都被禁用,因此窗体的KeyDown事件可以正常工作。 还有一个TTimer,如果按下ALT/CTRL键,它每10毫秒同步一次 我的计时器: 我的按键关闭事件: 我的密钥更新事件: 这在使用CTRL键时不会出现任何问题。 但是ALT键有时会卡住,甚至根本不出现。 当我只按ALT键而不按任何其他组合键时会发生这种情况 这是为什么?我该如何解决这个问题?如果您打算以这种方式运行计时器,那么您不妨打个电话 只需去掉O
这是为什么?我该如何解决这个问题?如果您打算以这种方式运行计时器,那么您不妨打个电话 只需去掉OnKeyDown和OnKeyUp事件处理程序。当系统已经启动时,您试图跟踪钥匙是向上还是向下是毫无意义的
你的计时器间隔很短。无论如何,系统不会频繁地触发它们。如果我没记错的话,计时器的分辨率通常在50毫秒左右。如果你打算用这种方式运行计时器,那么你最好打个电话 只需去掉OnKeyDown和OnKeyUp事件处理程序。当系统已经启动时,您试图跟踪钥匙是向上还是向下是毫无意义的
你的计时器间隔很短。无论如何,系统不会频繁地触发它们。如果我没记错的话,计时器的分辨率通常在50ms左右。如果你想了解微软的内部方式,请阅读微软的文档,KeyUp就是这样 您可以看到,释放Alt键是系统事件,在WM_KeyUp中是不可能的。
添加对WM_SYSCOMMAND、WM_SYSKEYUP和WM_SYSKEYDOWN的监控。当您想了解其内部方式时,请阅读microsoft文档,KeyUp就是这样 您可以看到,释放Alt键是系统事件,在WM_KeyUp中是不可能的。
添加对WM_SYSCOMMAND、WM_SYSKEYUP和WM_SYSKEYDOWN的监控。这很有效。但如果它打开两次,它实际上会阻止相同的进程@BenjaminWeiss不,不是这样的。这是正确的方法。这可以工作,但即使窗口未处于活动状态也可以工作。是否应添加if Self.Active[…]?或者有更好的方法吗?这很有效!您所需要做的就是按原样使用代码。系统会跟踪每个键是向上还是向下。GetAsyncKeyState提供对该信息的访问。关于为什么会这样,我认为这是因为在按下Alt键后,表单不再处于活动状态。主动控制为菜单,由主菜单或系统菜单中的sole-Alt激活。这也涉及到你的最后一个问题,我希望在菜单打开后,你的窗体不再是活动控件,但你可以尝试并测试它。这是有效的。但如果它打开两次,它实际上会阻止相同的进程@BenjaminWeiss不,不是这样的。这是正确的方法。这可以工作,但即使窗口未处于活动状态也可以工作。是否应添加if Self.Active[…]?或者有更好的方法吗?这很有效!您所需要做的就是按原样使用代码。系统会跟踪每个键是向上还是向下。GetAsyncKeyState提供对该信息的访问。关于为什么会这样,我认为这是因为在按下Alt键后,表单不再处于活动状态。主动控制为菜单,由主菜单或系统菜单中的sole-Alt激活。这也涉及到你的最后一个问题,我希望菜单打开后,你的表单不再是主动控制,但是您可以尝试测试它。当您将KeyPreview设置为True时,WM_SYSKEYDOWN和WM_SYSKEYUP会激发提交到表单的OnKeyDown和OnKeyUp事件。但可能不是WM_SYSCOMMAND@Arioch'我不确定WM_SYSCOMMAND与ALT键是向上还是向下的问题有何关系。如果TS想检查ALT键是否正确发布,那么WM_SYSCOMMAND将很有帮助。但无论如何,如果topic starter不再坚持跟踪向上/向下的消息,并且同意使用AsyncGetState,那么这可能并不重要。然而,一开始他反对AsyncGetState,我想展示另一种方法。当您将KeyPreview设置为True时,WM_SYSKEYDOWN和WM_SYSKEYUP会触发表单中的OnKeyDown和OnKeyUp事件。但可能不是WM_SYSCOMMAND@Arioch我不确定WM_SYSCOMMAND与ALT键是向上还是向下。如果TS想检查Alt键是否已释放,则WM_SYSCOMMAND将非常有用。但无论如何,如果topic starter不再坚持跟踪向上/向下的消息,并且同意使用AsyncGetState,那么这可能并不重要。然而,最初他反对AsyncGetState,我想展示另一种方法。
procedure TForm1.Timer1Timer(Sender: TObject);
begin
CheckBox1.Checked := ALTDOWN; // ALTDOWN IS GLOBAL
CheckBox2.Checked := CTRLDOWN; // CTRLDOWN IS GLOBAL
end;
procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
if Key = VK_MENU then begin
ALTDOWN := TRUE;
exit;
end;
if Key = VK_CONTROL then begin
CTRLDOWN := TRUE;
exit;
end;
end;
procedure TForm1.FormKeyUp(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
if Key = VK_MENU then begin
ALTDOWN := FALSE;
exit;
end;
if Key = VK_CONTROL then begin
CTRLDOWN := FALSE;
exit;
end;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
begin
CheckBox1.Checked := GetAsyncKeyState(VK_MENU)<0;
CheckBox2.Checked := GetAsyncKeyState(VK_CONTROL)<0;
end;