C# 如何在Windows窗体中的热键控件中捕获PrintScreen?

C# 如何在Windows窗体中的热键控件中捕获PrintScreen?,c#,winforms,winapi,user-interface,C#,Winforms,Winapi,User Interface,我正在开发一个屏幕捕获程序,我想允许用户设置自定义热键 我已尝试在自定义控件中使用Windowsmsctls\u hotkey32控件类,使用的是CreateParams。但是,它不接受PrintScr作为键,因为我的程序的性质,这是不可接受的 我尝试创建一个自定义控件,该控件扩展了System.Windows.Forms.TextBox并覆盖ProcessCmdKey,以捕获键盘输入。但是,PrintScreen键从不调用该函数,涉及该键的组合也不包括该函数(例如,按Ctrl+PrintScr

我正在开发一个屏幕捕获程序,我想允许用户设置自定义热键

我已尝试在自定义控件中使用Windows
msctls\u hotkey32
控件类,使用的是
CreateParams
。但是,它不接受PrintScr作为键,因为我的程序的性质,这是不可接受的

我尝试创建一个自定义控件,该控件扩展了
System.Windows.Forms.TextBox
并覆盖
ProcessCmdKey
,以捕获键盘输入。但是,PrintScreen键从不调用该函数,涉及该键的组合也不包括该函数(例如,按Ctrl+PrintScr只会给我
ControlKey,Control

经过一些研究,我发现只有一个
WM_KEYUP
消息被发送到PrintScreen,但是对于热键控件,只有key down事件是可以接受的,因为您需要能够输入组合键

是否有一种变通方法可以让我捕获包括PrintScreen的按键组合? 如果没有,我如何设计我的用户界面来允许这样的组合键,而不只是使用一个巨大的下拉列表?

试试看

protected override bool ProcessKeyEventArgs(ref Message msg) {
if (((Keys)(int)msg.WParam) == Keys.PrintScreen) {
  ScreenCapture(Environment.GetFolderPath(Environment.SpecialFolder.Desktop));
  }
  return base.ProcessKeyEventArgs(ref msg);
}
更多信息

Upd:


我将首先捕获
WM_KEYDOWN
消息并检查
虚拟键代码

protected override void WndProc(ref Message m)
{

    if (m.Msg == 0x0100) //WM_KEYDOWN
    {
        if ((int)m.WParam == 0x2C) //VK_SNAPSHOT
        {
            //...
        }
    }

    base.WndProc(ref m);
}
但就像你和我一样,它不起作用。这是因为我的
PrintScr
键盘(可能也是你的)使用的是
Insert
键。所以,改变

(int)m.WParam == 0x2C //VK_SNAPSHOT


解决了这个问题

这也只能在WM_KEYUP上显示PrintScreen,而不是在WM_KEYDOWN上显示PrintScreen,因此我无法确定键的组合。在这种情况下,您应该使用受保护的override bool ProcessCmdKey(ref Message msg,Keys keyData){if(keyData==(Keys.Control | Keys.PrintScr)){//do PrintScreen}return base.ProcessCmdKey(ref msg,keyData);}这里描述一下我已经在使用ProcessCmdKey了,但是它不起作用,正如我在question@horsedrowner究竟为什么要使用
ProcessCmdKey
?它适用于带有
上下文菜单的控件
!您是否尝试过@AlexFilatov和@user3311691中的代码来捕捉
PrintScreen
键?链接中的代码表明您没有尝试任何操作。Windows已经为PrintScreen按钮使用了热键。窃取它需要使用一个特殊的id,IDHOT\u SNAPDESKTOP(-2)和IDHOT\u SNAPWINDOW(-1)。我不知道这在现代Windows版本上的效果如何,我认为需要UAC提升。教热键控制新技巧是一个长期的尝试,只需自己动手。这也是我尝试做的-扩展一个文本框并覆盖ProcessCmdKey以获得键盘输入,但它不会被PrintScrWell调用,当然,鸡和蛋的问题:)要查看键,首先必须注册热键。当您的文本框具有焦点时,暂时执行此操作不应该是一个挂断。在屏幕捕获程序中,当用户按下
PrintScr
时,键盘焦点将位于其他窗口中。你必须使用键盘钩子(谷歌搜索),这种方法应该可以避免从窗口中捕获
PrintScr
的问题。@AndrewLambert我已经在实际的屏幕捕获功能中使用了它,虽然我想我可以在设置窗体中重复使用它,并在收到热键回调时手动设置具有焦点的控件。。。这并不理想,但我认为这是一种方法。如果我在WndProc中打印按键代码,然后按PrintScr,我只会收到一条WM_KEYUP消息,而不会收到WM_KEYDOWN消息,即使是不同的按键
(int)m.WParam == 0x2C //VK_SNAPSHOT
(int)m.WParam == 0x2D //VK_INSERT