Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi FormKeyDown ALT键卡住_Delphi_Winapi_Delphi 7_Vcl_Keylogger - Fatal编程技术网

Delphi FormKeyDown 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

我有一个表单,有两个复选框,一个用于按住CTRL键,一个用于按住ALT键。 这两个复选框都被禁用,因此窗体的KeyDown事件可以正常工作。 还有一个TTimer,如果按下ALT/CTRL键,它每10毫秒同步一次

我的计时器:

我的按键关闭事件:

我的密钥更新事件:

这在使用CTRL键时不会出现任何问题。 但是ALT键有时会卡住,甚至根本不出现。 当我只按ALT键而不按任何其他组合键时会发生这种情况


这是为什么?我该如何解决这个问题?

如果您打算以这种方式运行计时器,那么您不妨打个电话

只需去掉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;