在 C#/Windows 窗体中检测应用程序启动时的 Shift 键

发布于 2024-07-24 09:43:45 字数 136 浏览 4 评论 0原文

有没有办法让标准 Windows 窗体应用程序检测在应用程序启动时是否按住 Shift 键 - 而不使用 Windows 挂钩?

理想情况下,如果在运行 EXE 文件时按住 Shift 键,工作流程会从正常情况改变。

Is there a way to get a standard Windows Forms application to detect if the Shift key is being held down on application startup - without using Windows hooks?

I ideally would like the workflow to change from normal if the shift key is held down when the EXE file is run.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

早茶月光 2024-07-31 09:43:45

ModifierKeys 属性看起来很理想:

private void Form1_Load(object sender, EventArgs e)
{
    if ( (ModifierKeys & Keys.Shift) != 0)
    {
      MessageBox.Show("Shift is pressed");
    }
}

The ModifierKeys property looks ideal:

private void Form1_Load(object sender, EventArgs e)
{
    if ( (ModifierKeys & Keys.Shift) != 0)
    {
      MessageBox.Show("Shift is pressed");
    }
}
溺ぐ爱和你が 2024-07-31 09:43:45

我意识到这已经非常古老了,但看到人们为此苦苦挣扎,我有点困扰。 ModifierKeys 是一个位字段,因此依靠 .ToString() 或 == 来查看是否按下 Shift 键充其量是不可靠的,并且不是位字段的正确使用:

public enum ModifierKeys
{
    /// <summary>No modifiers are pressed.</summary>
    None = 0,

    /// <summary>The ALT key.</summary>
    Alt = 1,

    /// <summary>The CTRL key.</summary>
    Control = 2,

    /// <summary>The SHIFT key.</summary>
    Shift = 4,

    /// <summary>The Windows logo key.</summary>
    // Windows = 8, No longer leaked
}

没有或 Alt、可能会按下 Control 或 Shift 键,因此检查应该是:

if ((ModifierKeys & Keys.Shift) != 0)
{
    MessageBox.Show("Shift is pressed");
}

一旦我获得这样做的权利,我就会对 Dan 的答案进行投票:-) .Net 4+ 也包含 HasFlag() 方法,但我是习惯了按位运算所以没用过。 有关按位运算、标志、真值表和其他花絮的更多信息,请参阅:

http://geekswithblogs.net/BlackRabbitCoder/archive/2010/07/22/c-fundamentals-combining-enum-values-with-bit-flags .aspx

您在源代码中看到的内容更加有趣:

/// <devdoc>
///     Retrieves the current state of the modifier keys. This will check the
///     current state of the shift, control, and alt keys.
/// </devdoc>
public static Keys ModifierKeys {
    get {
        Keys modifiers = 0;
        // SECURITYNOTE : only let state of Shift-Control-Alt out...
        //
        if (UnsafeNativeMethods.GetKeyState((int)Keys.ShiftKey) < 0) modifiers |= Keys.Shift;
        if (UnsafeNativeMethods.GetKeyState((int)Keys.ControlKey) < 0) modifiers |= Keys.Control;
        if (UnsafeNativeMethods.GetKeyState((int)Keys.Menu) < 0) modifiers |= Keys.Alt;
        return modifiers;
    }
}

此实现仅发出 Shift、Control 和 Alt 的状态。 不包括 Windows 的按键状态。

如果您想在创建表单或控件之前检测按键状态,也许在 Main() 方法中,您可能会发疯。

也许您想要这样做:

if (VirtualKeyState.VK_SHIFT.IsKeyPressed())
{
    Debugger.Launch();
}

创建一个简单的扩展方法:

public static class KeyAssist
{
    public const int KEY_PRESSED = 0x8000;

    public static bool IsKeyPressed(this VirtualKeyState key) => Convert.ToBoolean(Native.GetKeyState(key) & KEY_PRESSED);
}

导入:

[DllImport("user32.dll")]
public static extern short GetKeyState(VirtualKeyState virtualKeyState);

创建以下枚举(或者如果您愿意的话,创建一些子部分)(来自 PInvoke):

public enum VirtualKeyState
{

    VK_LBUTTON = 0x01,
    VK_RBUTTON = 0x02,
    VK_CANCEL = 0x03,
    VK_MBUTTON = 0x04,
    VK_XBUTTON1 = 0x05,
    VK_XBUTTON2 = 0x06,
    VK_BACK = 0x08,
    VK_TAB = 0x09,
    VK_CLEAR = 0x0C,
    VK_RETURN = 0x0D,
    VK_SHIFT = 0x10,
    VK_CONTROL = 0x11,
    VK_MENU = 0x12,
    VK_PAUSE = 0x13,
    VK_CAPITAL = 0x14,
    VK_KANA = 0x15,
    VK_HANGEUL = 0x15,           
    VK_HANGUL = 0x15,
    VK_JUNJA = 0x17,
    VK_FINAL = 0x18,
    VK_HANJA = 0x19,
    VK_KANJI = 0x19,
    VK_ESCAPE = 0x1B,
    VK_CONVERT = 0x1C,
    VK_NONCONVERT = 0x1D,
    VK_ACCEPT = 0x1E,
    VK_MODECHANGE = 0x1F,
    VK_SPACE = 0x20,
    VK_PRIOR = 0x21,
    VK_NEXT = 0x22,
    VK_END = 0x23,
    VK_HOME = 0x24,
    VK_LEFT = 0x25,
    VK_UP = 0x26,
    VK_RIGHT = 0x27,
    VK_DOWN = 0x28,
    VK_SELECT = 0x29,
    VK_PRINT = 0x2A,
    VK_EXECUTE = 0x2B,
    VK_SNAPSHOT = 0x2C,
    VK_INSERT = 0x2D,
    VK_DELETE = 0x2E,
    VK_HELP = 0x2F,
    VK_LWIN = 0x5B,
    VK_RWIN = 0x5C,
    VK_APPS = 0x5D,
    VK_SLEEP = 0x5F,
    VK_NUMPAD0 = 0x60,
    VK_NUMPAD1 = 0x61,
    VK_NUMPAD2 = 0x62,
    VK_NUMPAD3 = 0x63,
    VK_NUMPAD4 = 0x64,
    VK_NUMPAD5 = 0x65,
    VK_NUMPAD6 = 0x66,
    VK_NUMPAD7 = 0x67,
    VK_NUMPAD8 = 0x68,
    VK_NUMPAD9 = 0x69,
    VK_MULTIPLY = 0x6A,
    VK_ADD = 0x6B,
    VK_SEPARATOR = 0x6C,
    VK_SUBTRACT = 0x6D,
    VK_DECIMAL = 0x6E,
    VK_DIVIDE = 0x6F,
    VK_F1 = 0x70,
    VK_F2 = 0x71,
    VK_F3 = 0x72,
    VK_F4 = 0x73,
    VK_F5 = 0x74,
    VK_F6 = 0x75,
    VK_F7 = 0x76,
    VK_F8 = 0x77,
    VK_F9 = 0x78,
    VK_F10 = 0x79,
    VK_F11 = 0x7A,
    VK_F12 = 0x7B,
    VK_F13 = 0x7C,
    VK_F14 = 0x7D,
    VK_F15 = 0x7E,
    VK_F16 = 0x7F,
    VK_F17 = 0x80,
    VK_F18 = 0x81,
    VK_F19 = 0x82,
    VK_F20 = 0x83,
    VK_F21 = 0x84,
    VK_F22 = 0x85,
    VK_F23 = 0x86,
    VK_F24 = 0x87,
    VK_NUMLOCK = 0x90,
    VK_SCROLL = 0x91,
    VK_OEM_NEC_EQUAL = 0x92,        
    VK_OEM_FJ_JISHO = 0x92,     
    VK_OEM_FJ_MASSHOU = 0x93,          
    VK_OEM_FJ_TOUROKU = 0x94,      
    VK_OEM_FJ_LOYA = 0x95,      
    VK_OEM_FJ_ROYA = 0x96,      
    VK_LSHIFT = 0xA0,
    VK_RSHIFT = 0xA1,
    VK_LCONTROL = 0xA2,
    VK_RCONTROL = 0xA3,
    VK_LMENU = 0xA4,
    VK_RMENU = 0xA5,
    VK_BROWSER_BACK = 0xA6,
    VK_BROWSER_FORWARD = 0xA7,
    VK_BROWSER_REFRESH = 0xA8,
    VK_BROWSER_STOP = 0xA9,
    VK_BROWSER_SEARCH = 0xAA,
    VK_BROWSER_FAVORITES = 0xAB,
    VK_BROWSER_HOME = 0xAC,
    VK_VOLUME_MUTE = 0xAD,
    VK_VOLUME_DOWN = 0xAE,
    VK_VOLUME_UP = 0xAF,
    VK_MEDIA_NEXT_TRACK = 0xB0,
    VK_MEDIA_PREV_TRACK = 0xB1,
    VK_MEDIA_STOP = 0xB2,
    VK_MEDIA_PLAY_PAUSE = 0xB3,
    VK_LAUNCH_MAIL = 0xB4,
    VK_LAUNCH_MEDIA_SELECT = 0xB5,
    VK_LAUNCH_APP1 = 0xB6,
    VK_LAUNCH_APP2 = 0xB7,
    VK_OEM_1 = 0xBA,      
    VK_OEM_PLUS = 0xBB,      
    VK_OEM_COMMA = 0xBC,      
    VK_OEM_MINUS = 0xBD,      
    VK_OEM_PERIOD = 0xBE,      
    VK_OEM_2 = 0xBF,      
    VK_OEM_3 = 0xC0,      
    VK_OEM_4 = 0xDB,      
    VK_OEM_5 = 0xDC,      
    VK_OEM_6 = 0xDD,      
    VK_OEM_7 = 0xDE,      
    VK_OEM_8 = 0xDF,
    VK_OEM_AX = 0xE1,         
    VK_OEM_102 = 0xE2,          
    VK_ICO_HELP = 0xE3,       
    VK_ICO_00 = 0xE4,       
    VK_PROCESSKEY = 0xE5,
    VK_ICO_CLEAR = 0xE6,
    VK_PACKET = 0xE7,
    VK_OEM_RESET = 0xE9,
    VK_OEM_JUMP = 0xEA,
    VK_OEM_PA1 = 0xEB,
    VK_OEM_PA2 = 0xEC,
    VK_OEM_PA3 = 0xED,
    VK_OEM_WSCTRL = 0xEE,
    VK_OEM_CUSEL = 0xEF,
    VK_OEM_ATTN = 0xF0,
    VK_OEM_FINISH = 0xF1,
    VK_OEM_COPY = 0xF2,
    VK_OEM_AUTO = 0xF3,
    VK_OEM_ENLW = 0xF4,
    VK_OEM_BACKTAB = 0xF5,
    VK_ATTN = 0xF6,
    VK_CRSEL = 0xF7,
    VK_EXSEL = 0xF8,
    VK_EREOF = 0xF9,
    VK_PLAY = 0xFA,
    VK_ZOOM = 0xFB,
    VK_NONAME = 0xFC,
    VK_PA1 = 0xFD,
    VK_OEM_CLEAR = 0xFE
}

无论如何,这仅供参考,因此没有太多猜测在。

HTH,

科尔比

I realize this is super old, but it bothered me a little bit to see people struggling with this. ModifierKeys is a bit field, so relying on .ToString() or == to see if the Shift key is pressed is, at best, unreliable and isn't the correct use of a bit field:

public enum ModifierKeys
{
    /// <summary>No modifiers are pressed.</summary>
    None = 0,

    /// <summary>The ALT key.</summary>
    Alt = 1,

    /// <summary>The CTRL key.</summary>
    Control = 2,

    /// <summary>The SHIFT key.</summary>
    Shift = 4,

    /// <summary>The Windows logo key.</summary>
    // Windows = 8, No longer leaked
}

Either none or any combination of Alt, Control, or Shift may be pressed, so the check should be:

if ((ModifierKeys & Keys.Shift) != 0)
{
    MessageBox.Show("Shift is pressed");
}

I will up-vote Dan's answer as soon as I earn the right to do so :-) .Net 4+ includes the HasFlag() method as well, but I am accustomed to bitwise operations so I haven't used it. For more information on bitwise operations, flags, (with) truth tables, and other tidbits see:

http://geekswithblogs.net/BlackRabbitCoder/archive/2010/07/22/c-fundamentals-combining-enum-values-with-bit-flags.aspx

What you see in the source is even more intriguing:

/// <devdoc>
///     Retrieves the current state of the modifier keys. This will check the
///     current state of the shift, control, and alt keys.
/// </devdoc>
public static Keys ModifierKeys {
    get {
        Keys modifiers = 0;
        // SECURITYNOTE : only let state of Shift-Control-Alt out...
        //
        if (UnsafeNativeMethods.GetKeyState((int)Keys.ShiftKey) < 0) modifiers |= Keys.Shift;
        if (UnsafeNativeMethods.GetKeyState((int)Keys.ControlKey) < 0) modifiers |= Keys.Control;
        if (UnsafeNativeMethods.GetKeyState((int)Keys.Menu) < 0) modifiers |= Keys.Alt;
        return modifiers;
    }
}

This implementation ONLY emits the state of Shift, Control, and Alt. The Windows' key state is not included.

If you want to detect the key state BEFORE a form or control is created, maybe in the Main() method, you can go crazy.

Maybe you want to to this:

if (VirtualKeyState.VK_SHIFT.IsKeyPressed())
{
    Debugger.Launch();
}

Create a simple extension method:

public static class KeyAssist
{
    public const int KEY_PRESSED = 0x8000;

    public static bool IsKeyPressed(this VirtualKeyState key) => Convert.ToBoolean(Native.GetKeyState(key) & KEY_PRESSED);
}

Import:

[DllImport("user32.dll")]
public static extern short GetKeyState(VirtualKeyState virtualKeyState);

Create the following enum (or some sub-section if you please) (from PInvoke):

public enum VirtualKeyState
{

    VK_LBUTTON = 0x01,
    VK_RBUTTON = 0x02,
    VK_CANCEL = 0x03,
    VK_MBUTTON = 0x04,
    VK_XBUTTON1 = 0x05,
    VK_XBUTTON2 = 0x06,
    VK_BACK = 0x08,
    VK_TAB = 0x09,
    VK_CLEAR = 0x0C,
    VK_RETURN = 0x0D,
    VK_SHIFT = 0x10,
    VK_CONTROL = 0x11,
    VK_MENU = 0x12,
    VK_PAUSE = 0x13,
    VK_CAPITAL = 0x14,
    VK_KANA = 0x15,
    VK_HANGEUL = 0x15,           
    VK_HANGUL = 0x15,
    VK_JUNJA = 0x17,
    VK_FINAL = 0x18,
    VK_HANJA = 0x19,
    VK_KANJI = 0x19,
    VK_ESCAPE = 0x1B,
    VK_CONVERT = 0x1C,
    VK_NONCONVERT = 0x1D,
    VK_ACCEPT = 0x1E,
    VK_MODECHANGE = 0x1F,
    VK_SPACE = 0x20,
    VK_PRIOR = 0x21,
    VK_NEXT = 0x22,
    VK_END = 0x23,
    VK_HOME = 0x24,
    VK_LEFT = 0x25,
    VK_UP = 0x26,
    VK_RIGHT = 0x27,
    VK_DOWN = 0x28,
    VK_SELECT = 0x29,
    VK_PRINT = 0x2A,
    VK_EXECUTE = 0x2B,
    VK_SNAPSHOT = 0x2C,
    VK_INSERT = 0x2D,
    VK_DELETE = 0x2E,
    VK_HELP = 0x2F,
    VK_LWIN = 0x5B,
    VK_RWIN = 0x5C,
    VK_APPS = 0x5D,
    VK_SLEEP = 0x5F,
    VK_NUMPAD0 = 0x60,
    VK_NUMPAD1 = 0x61,
    VK_NUMPAD2 = 0x62,
    VK_NUMPAD3 = 0x63,
    VK_NUMPAD4 = 0x64,
    VK_NUMPAD5 = 0x65,
    VK_NUMPAD6 = 0x66,
    VK_NUMPAD7 = 0x67,
    VK_NUMPAD8 = 0x68,
    VK_NUMPAD9 = 0x69,
    VK_MULTIPLY = 0x6A,
    VK_ADD = 0x6B,
    VK_SEPARATOR = 0x6C,
    VK_SUBTRACT = 0x6D,
    VK_DECIMAL = 0x6E,
    VK_DIVIDE = 0x6F,
    VK_F1 = 0x70,
    VK_F2 = 0x71,
    VK_F3 = 0x72,
    VK_F4 = 0x73,
    VK_F5 = 0x74,
    VK_F6 = 0x75,
    VK_F7 = 0x76,
    VK_F8 = 0x77,
    VK_F9 = 0x78,
    VK_F10 = 0x79,
    VK_F11 = 0x7A,
    VK_F12 = 0x7B,
    VK_F13 = 0x7C,
    VK_F14 = 0x7D,
    VK_F15 = 0x7E,
    VK_F16 = 0x7F,
    VK_F17 = 0x80,
    VK_F18 = 0x81,
    VK_F19 = 0x82,
    VK_F20 = 0x83,
    VK_F21 = 0x84,
    VK_F22 = 0x85,
    VK_F23 = 0x86,
    VK_F24 = 0x87,
    VK_NUMLOCK = 0x90,
    VK_SCROLL = 0x91,
    VK_OEM_NEC_EQUAL = 0x92,        
    VK_OEM_FJ_JISHO = 0x92,     
    VK_OEM_FJ_MASSHOU = 0x93,          
    VK_OEM_FJ_TOUROKU = 0x94,      
    VK_OEM_FJ_LOYA = 0x95,      
    VK_OEM_FJ_ROYA = 0x96,      
    VK_LSHIFT = 0xA0,
    VK_RSHIFT = 0xA1,
    VK_LCONTROL = 0xA2,
    VK_RCONTROL = 0xA3,
    VK_LMENU = 0xA4,
    VK_RMENU = 0xA5,
    VK_BROWSER_BACK = 0xA6,
    VK_BROWSER_FORWARD = 0xA7,
    VK_BROWSER_REFRESH = 0xA8,
    VK_BROWSER_STOP = 0xA9,
    VK_BROWSER_SEARCH = 0xAA,
    VK_BROWSER_FAVORITES = 0xAB,
    VK_BROWSER_HOME = 0xAC,
    VK_VOLUME_MUTE = 0xAD,
    VK_VOLUME_DOWN = 0xAE,
    VK_VOLUME_UP = 0xAF,
    VK_MEDIA_NEXT_TRACK = 0xB0,
    VK_MEDIA_PREV_TRACK = 0xB1,
    VK_MEDIA_STOP = 0xB2,
    VK_MEDIA_PLAY_PAUSE = 0xB3,
    VK_LAUNCH_MAIL = 0xB4,
    VK_LAUNCH_MEDIA_SELECT = 0xB5,
    VK_LAUNCH_APP1 = 0xB6,
    VK_LAUNCH_APP2 = 0xB7,
    VK_OEM_1 = 0xBA,      
    VK_OEM_PLUS = 0xBB,      
    VK_OEM_COMMA = 0xBC,      
    VK_OEM_MINUS = 0xBD,      
    VK_OEM_PERIOD = 0xBE,      
    VK_OEM_2 = 0xBF,      
    VK_OEM_3 = 0xC0,      
    VK_OEM_4 = 0xDB,      
    VK_OEM_5 = 0xDC,      
    VK_OEM_6 = 0xDD,      
    VK_OEM_7 = 0xDE,      
    VK_OEM_8 = 0xDF,
    VK_OEM_AX = 0xE1,         
    VK_OEM_102 = 0xE2,          
    VK_ICO_HELP = 0xE3,       
    VK_ICO_00 = 0xE4,       
    VK_PROCESSKEY = 0xE5,
    VK_ICO_CLEAR = 0xE6,
    VK_PACKET = 0xE7,
    VK_OEM_RESET = 0xE9,
    VK_OEM_JUMP = 0xEA,
    VK_OEM_PA1 = 0xEB,
    VK_OEM_PA2 = 0xEC,
    VK_OEM_PA3 = 0xED,
    VK_OEM_WSCTRL = 0xEE,
    VK_OEM_CUSEL = 0xEF,
    VK_OEM_ATTN = 0xF0,
    VK_OEM_FINISH = 0xF1,
    VK_OEM_COPY = 0xF2,
    VK_OEM_AUTO = 0xF3,
    VK_OEM_ENLW = 0xF4,
    VK_OEM_BACKTAB = 0xF5,
    VK_ATTN = 0xF6,
    VK_CRSEL = 0xF7,
    VK_EXSEL = 0xF8,
    VK_EREOF = 0xF9,
    VK_PLAY = 0xFA,
    VK_ZOOM = 0xFB,
    VK_NONAME = 0xFC,
    VK_PA1 = 0xFD,
    VK_OEM_CLEAR = 0xFE
}

Anyway, this is just for reference so there isn't so much guessing going on.

HTH,

Colby

书间行客 2024-07-31 09:43:45

检查 Control.ModifierKeys ...

    [STAThread]
    static void Main(string[] args)
    {
        if (Control.ModifierKeys == Keys.ShiftKey)
        {
            // Do something special
        }
    }

Check Control.ModifierKeys ...

    [STAThread]
    static void Main(string[] args)
    {
        if (Control.ModifierKeys == Keys.ShiftKey)
        {
            // Do something special
        }
    }
岁月染过的梦 2024-07-31 09:43:45

我知道这篇文章相当旧,但我遇到了这个问题并通过修改 Jamie 的代码来修复它:

[STAThread]
static void Main(string[] args)
{
    if (Control.ModifierKeys.ToString() == "Shift")
    {
        // Do something special
    }
}

I know this post is rather old but I ran into this issue and fixed it by modifying Jamie's code:

[STAThread]
static void Main(string[] args)
{
    if (Control.ModifierKeys.ToString() == "Shift")
    {
        // Do something special
    }
}
落花随流水 2024-07-31 09:43:45

Here is an article about reading the key states (and mouse) directly.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文