Windows.Forms.MouseButtons中的奇数枚举值

时间:2013-06-10 20:48:39

标签: c# winforms enums

我在System.Windows.Forms命名空间中找到了这个gem(IMO)。我正在努力弄清楚为什么会这样设置。

[Flags]
public enum MouseButtons
{
    None = 0,
    Left = 1048576,
    Right = 2097152,
    Middle = 4194304,
    XButton1 = 8388608,
    XButton2 = 16777216,
}

有人可以解释为什么它使用这些值(2^202^24的力量)而不是:

public enum MouseButtons
{
    None = 0,
    Left = 1,      // 2^0
    Right = 2,     // 2^1
    Middle = 4,    // 2^2
    XButton1 = 8,  // 2^3
    XButton2 = 16, // 2^4
}

第一个值是二进制的100000000000000000000,剩下20位的空间!为什么我们需要这样的空间,为什么会这样保存?

2 个答案:

答案 0 :(得分:4)

Winforms中使用的枚举值确实倾向于匹配winapi中的相应位,但对于鼠标按钮来说根本不是这样。解释这个需要一个非常疯狂的猜测。

我确实有一个,你在不依赖Windows消息的情况下检索鼠标按钮状态的方式很奇怪。您调用GetAsyncKeyState(),将VK_LBUTTON传递给VK_XBUTTON2。假虚拟键实际上代表鼠标键而不是键盘键。很久以前就发生了 way 让我猜测为什么他们这样做而不是提供正确的GetMouseButtonState()winapi函数。

Keys枚举也具有这些值,如Keys.LButton等。 Key的另一个特别之处在于它还可以编码修饰键的状态。例如Keys.Control和Keys.ControlKey。和Keys.Shift vs Keys.ShiftKey,等等。第一个表示密钥的状态,第二个表示实际密钥。这允许像keydata ==(Keys.Control | Keys.F)这样的友好代码检查是否按下了Ctrl + F.

这些MouseButtons枚举值的重要性在于它们符合Keys枚举值以指示鼠标按钮的状态。将20位可用于编码密钥的位。

听起来不错,不是吗?唯一的打嗝是它永远不会在Winforms对象模型中以这种方式组合。但也可以在您自己的代码中定义也使用鼠标状态的快捷方式。

答案 1 :(得分:1)

我的猜测是它与底层Windows API如何将鼠标信息传递给.NET有关。

Windows打包单击了哪些鼠标按钮以及指针在信息块中的位置(想想旧的MOUSE_EVENT结构)。 .NET中的枚举是以高效的方式设置的,因此它们可能与基础Windows消息的排列方式非常吻合。

因此,.NET不是获取较低级别的消息而是必须将其转换为一组新的值,而是仅针对它感兴趣的低级消息中的位 - 没有转换,没有数学,只是效率