13

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

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

有人可以解释为什么它使用这些值( to 的力量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 位留出了空间!为什么我们需要这样的空间,为什么要这样保存?

4

2 回答 2

4

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

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

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

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

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

于 2013-06-10T21:48:20.377 回答
1

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

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

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

于 2013-06-10T22:01:40.663 回答