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

C# 当使用RegisterHotKey api调用时,为什么它接受1、2、4和8作为修饰符?,c#,enums,pinvoke,flags,C#,Enums,Pinvoke,Flags,我提到这个职位 我的问题是,RegisterHotKeyapi如何知道1、2、4、8都是windows键?因为ctrl、shift和menu(alt)的键代码返回的键值完全不同?在RegisterHotKey函数中,它检查的是什么: if ((key & Keys.Control) == Keys.Control) modifiers = modifiers | WindowsShell.MOD_CONTROL; 它在这里干什么 Keys k = ke

我提到这个职位

我的问题是,
RegisterHotKey
api如何知道
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;

MOD_ALT
MOD_CONTROL
等与相关键的键代码没有任何关系

您将看到一个
enum
类型,用于表示一组数据。这是一种非常简洁的表示状态的方法,表示事物的组合(如同时按下修改键、文件访问权限等)

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

这有两个好处:

  • API不必为每个修改器键接受单个布尔参数
  • API可以扩展为包含附加的修改器键,而无需更改接口
按位
&
s和
|
s可用于确定在值中设置哪些标志,以及设置或取消设置值中的标志

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

if ((key & Keys.Control) == Keys.Control) 
   modifiers = modifiers | WindowsShell.MOD_CONTROL
表示“如果键设置了
控制
位,则在
修改器中设置控制位

表示“
k
已分配
Shift
Alt
标志已清除”

我不知道pinvoke的贡献者为什么选择使用常量;您可以同样轻松地使用适当的枚举:

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

提供了有关标志如何工作的更多详细信息和更多示例。

如果您想了解有关RegisterHotKey API的更多信息,请查看以下内容:


另外,下载平台SDK以查看WinUser.h中MOD_ALT、MOD_CONTROL等的定义值。

1、2、4、8用于表示单个位。1是将启用的最低有效位。添加2将打开第二个最低有效位等。因此,您可以彼此独立地设置多个标志

1 = 0001
2 = 0010
4 = 0100
8 = 1000

因此,如果您想将2和4表示的变量设置为true,您可以使用0110=6。

这是否也适用于相同的方式?[Flags()]公共枚举键修饰符{None=0,Alt=1,Control=2,Shift=4,Windows=8}最让我困惑的部分是修饰符参数。fsModifiers如何知道0x2==CTRL键?那是内部函数吗。从dll api?是的,这是api内部的。它是否只包含1、2、4、8的键?介于3、5、6和7之间的其他键是什么?如果我想特别使用L档或右档怎么办?MSDN表示:VK_LSHIFT(0xA0)=左换档键和VK_RSHIFT(0xA1)=右换档键;所有可能的标志都有信息吗?@Mike:记住,每个键都映射到一个位。(1、2、4、8都有一个位集)3有两个位集,表示同时按下ALT和CTRL(3==ALT | CTRL)
Keys k = key & ~Keys.Control & ~Keys.Shift & ~Keys.Alt;
[Flags]
public enum Modifiers
{
   None = 0,
   Alt = 1,
   Control = 2,
   // ...
}
1 = 0001
2 = 0010
4 = 0100
8 = 1000