I found this gem (IMO) in System.Windows.Forms
namespace. I'm struggling to figure out why is it set like this.
[Flags]
public enum MouseButtons
{
None = 0,
Left = 1048576,
Right = 2097152,
Middle = 4194304,
XButton1 = 8388608,
XButton2 = 16777216,
}
Can somebody explain why it uses these values (power of 2^20
to 2^24
) instead of this:
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
}
The first value is 100000000000000000000
in binary, which leaves space for another 20 bits! Why do we need such space and why is it preserved like this?
Enum values used in Winforms do tend to match corresponding bits in the winapi but that's not the case at all for mouse buttons. Explaining this one requires a pretty wild guess.
I do have one, the way you retrieve the state of the mouse buttons without relying on a Windows message is very strange. You call GetAsyncKeyState(), passing VK_LBUTTON through VK_XBUTTON2. Fake virtual keys that actually represent mouse keys and not keyboard keys. This happened way too long ago for me to guess why they did it this way instead of providing a proper GetMouseButtonState() winapi function.
The Keys enumeration has those values as well, like Keys.LButton etcetera. Something else that's special about Keys is that it can also encode the state of a modifier key. There are for example Keys.Control and Keys.ControlKey. And Keys.Shift vs Keys.ShiftKey, etcetera. The first one indicates the state of the key, the second one indicates the actual key. Which permits friendly code like keydata == (Keys.Control | Keys.F) to check if Ctrl+F was pressed.
The significance of these MouseButtons enum values is then that they fit in a Keys enum value to indicate the state of the mouse buttons. Leaving 20 bits available for the bits that encode the key.
Sounds good, doesn't it? The only hiccup is that it is never combined that way within the Winforms object model. But could be in your own code to define a shortcut that also uses the mouse state.
My guess is that it has to do with how the underlying Windows API is passing mouse information to .NET.
Windows packages up which mouse buttons are clicked as well as pointer position in a block of information (think of the old MOUSE_EVENT structure). The enums in .NET are setup the way they are to be efficient, so they probably line up nicely with how the underlying Windows message.
So, instead of getting the lower-level message and having to convert it into a new set of values, .NET just targets the bits in the lower-level message that it is interested in - no conversion, no math, just efficiency.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With