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

本文关键字:枚举 Forms MouseButtons Windows | 更新日期: 2023-09-27 18:17:51

我在System.Windows.Forms命名空间中发现了这个宝石(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位留出了空间!为什么我们需要这样的空间,为什么它被保存成这样?

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

在Winforms中使用的枚举值确实倾向于匹配winapi中相应的位,但对于鼠标按钮则完全不是这样。要解释这一点需要一个相当大胆的猜测。

我确实有一个,你检索鼠标按钮的状态而不依赖于Windows消息的方式是非常奇怪的。你调用GetAsyncKeyState(),通过VK_XBUTTON2传递VK_LBUTTON。伪造的虚拟键实际上代表鼠标键而不是键盘键。这发生在方式很久以前,我猜不出为什么他们这样做,而不是提供一个适当的GetMouseButtonState() winapi函数。

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

这些MouseButtons枚举值的意义在于它们适合于Keys枚举值,以指示鼠标按钮的状态。为编码密钥的位保留20位。

听起来不错,不是吗?唯一的问题是,它从来没有在Winforms对象模型中以这种方式组合。但是可以在您自己的代码中定义一个快捷方式,该快捷方式也使用鼠标状态。

我猜这与底层Windows API如何将鼠标信息传递给。net有关。

Windows打包了鼠标按钮被点击以及指针在信息块中的位置(想想旧的MOUSE_EVENT结构)。. net中的枚举被设置为高效的方式,因此它们可能与底层Windows消息的方式很好地对齐。

因此,与获取低级消息并将其转换为一组新的值不同,. net只针对低级消息中它感兴趣的位——没有转换,没有数学,只有效率。