我在System.Windows.Forms
命名空间中找到了这个gem(IMO)。我正在努力弄清楚为什么会这样设置。
[Flags]
public enum MouseButtons
{
None = 0,
Left = 1048576,
Right = 2097152,
Middle = 4194304,
XButton1 = 8388608,
XButton2 = 16777216,
}
有人可以解释为什么它使用这些值(2^20
到2^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位的空间!为什么我们需要这样的空间,为什么会这样保存?
答案 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不是获取较低级别的消息而是必须将其转换为一组新的值,而是仅针对它感兴趣的低级消息中的位 - 没有转换,没有数学,只是效率