当前位置:  开发笔记 > 编程语言 > 正文

使用RegisterHotKey api调用时,为什么它接受1,2,4和8作为修饰符?

如何解决《使用RegisterHotKeyapi调用时,为什么它接受1,2,4和8作为修饰符?》经验,为你挑选了1个好方法。

我参考这篇文章;

http://www.pinvoke.net/default.aspx/user32/RegisterHotKey.html

    #region fields
    public static int MOD_ALT = 0x1;
    public static int MOD_CONTROL = 0x2;
    public static int MOD_SHIFT = 0x4;
    public static int MOD_WIN = 0x8;
    public static int WM_HOTKEY = 0x312;
    #endregion

    [DllImport("user32.dll")]
    private static extern bool RegisterHotKey(IntPtr hWnd, int id, int fsModifiers, int vlc);

    [DllImport("user32.dll")]
    private static extern bool UnregisterHotKey(IntPtr hWnd, int id);

    private static int keyId;
    public static void RegisterHotKey(Form f, Keys key)
    {
        int modifiers = 0;

        if ((key & Keys.Alt) == Keys.Alt)
            modifiers = modifiers | WindowsShell.MOD_ALT;

        if ((key & Keys.Control) == Keys.Control)
            modifiers = modifiers | WindowsShell.MOD_CONTROL;

        if ((key & Keys.Shift) == Keys.Shift)
            modifiers = modifiers | WindowsShell.MOD_SHIFT;

        Keys k = key & ~Keys.Control & ~Keys.Shift & ~Keys.Alt;

        Func ff = delegate()
            {
                keyId = f.GetHashCode(); // this should be a key unique ID, modify this if you want more than one hotkey
                RegisterHotKey((IntPtr)f.Handle, keyId, modifiers, (int)k);
            };

        f.Invoke(ff); // this should be checked if we really need it (InvokeRequired), but it's faster this way
    }

我的问题是,如何RegisterHotKeyAPI知道1,2,4,8是Windows键?因为ctrl,shift和menu(alt)的键代码会为键提供完全不同的值?RegisterHotKey在它正在检查的函数中究竟发生了什么:

if ((key & Keys.Control) == Keys.Control)
                modifiers = modifiers | WindowsShell.MOD_CONTROL;

它在这做什么?

Keys k = key & ~Keys.Control & ~Keys.Shift & ~Keys.Alt;

Daniel LeChe.. 5

MOD_ALT,MOD_CONTROL等,与关联密钥的密钥代码没有任何关系.

您将看到enum用于表示一组标志的类型.这是一种表示状态组合的状态的特别紧凑的方式(如同时按下修改键,文件访问权限等)

enum以这种方式使用s时,枚举类型的变量的每个位可用于指示设置了特定的"标志".

// Note that powers of 2 are used; each value has only a single bit set
public static int MOD_ALT = 0x1;     // If bit 0 is set, Alt is pressed
public static int MOD_CONTROL = 0x2; // If bit 1 is set, Ctrl is pressed
public static int MOD_SHIFT = 0x4;   // If bit 2 is set, Shift is pressed 
public static int MOD_WIN = 0x8;     // If bit 3 is set, Win is pressed

// If we wanted to represent a combination of keys:
int altAndControl = MOD_ALT | MOD_CONTROL; // == 3
int controlAndShift = MOD_CONTROL | MOD_SHIFT; // == 6

这有两个好处:

API不必为每个修饰键采用单独的布尔参数

可以扩展API以包含其他修饰键而无需更改界面

按位&s和|s可用于确定在值中设置哪些标志,以及在值中设置或取消设置标志.

您询问的代码就是这样做的:

if ((key & Keys.Control) == Keys.Control) 
   modifiers = modifiers | WindowsShell.MOD_CONTROL

正在说"如果密钥Control设置了位,则将控制位设置为modifiers"

Keys k = key & ~Keys.Control & ~Keys.Shift & ~Keys.Alt;

是说" k被分配keyControl,Shift并且Alt标志清除了"

我不确定为什么pinvoke的贡献者选择使用常量; 您可以轻松使用适当的枚举:

[Flags]
public enum Modifiers
{
   None = 0,
   Alt = 1,
   Control = 2,
   // ...
}

我对类似问题的回答有关于标志如何工作的更多细节,以及更多示例.



1> Daniel LeChe..:

MOD_ALT,MOD_CONTROL等,与关联密钥的密钥代码没有任何关系.

您将看到enum用于表示一组标志的类型.这是一种表示状态组合的状态的特别紧凑的方式(如同时按下修改键,文件访问权限等)

enum以这种方式使用s时,枚举类型的变量的每个位可用于指示设置了特定的"标志".

// Note that powers of 2 are used; each value has only a single bit set
public static int MOD_ALT = 0x1;     // If bit 0 is set, Alt is pressed
public static int MOD_CONTROL = 0x2; // If bit 1 is set, Ctrl is pressed
public static int MOD_SHIFT = 0x4;   // If bit 2 is set, Shift is pressed 
public static int MOD_WIN = 0x8;     // If bit 3 is set, Win is pressed

// If we wanted to represent a combination of keys:
int altAndControl = MOD_ALT | MOD_CONTROL; // == 3
int controlAndShift = MOD_CONTROL | MOD_SHIFT; // == 6

这有两个好处:

API不必为每个修饰键采用单独的布尔参数

可以扩展API以包含其他修饰键而无需更改界面

按位&s和|s可用于确定在值中设置哪些标志,以及在值中设置或取消设置标志.

您询问的代码就是这样做的:

if ((key & Keys.Control) == Keys.Control) 
   modifiers = modifiers | WindowsShell.MOD_CONTROL

正在说"如果密钥Control设置了位,则将控制位设置为modifiers"

Keys k = key & ~Keys.Control & ~Keys.Shift & ~Keys.Alt;

是说" k被分配keyControl,Shift并且Alt标志清除了"

我不确定为什么pinvoke的贡献者选择使用常量; 您可以轻松使用适当的枚举:

[Flags]
public enum Modifiers
{
   None = 0,
   Alt = 1,
   Control = 2,
   // ...
}

我对类似问题的回答有关于标志如何工作的更多细节,以及更多示例.

推荐阅读
135369一生真爱_890
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有