3

I'm using the following .NET 4.5.2 code:

if (this.ContainsFocus && keyData == (Keys.Tab|Keys.Shift))
{ ... }

Why is the expression true when ContainsFocus (bool = true) and keyData (System.Windows.Forms.Keys) is Keys.O | Keys.Shift?

As you can see the breakpoint is hit:

breakpointscreenshot

with this values:

watchscreenshot

A workaround for this bug (?!) is:

if (this.ContainsFocus && (int)keyData == (int)(Keys.Tab|Keys.Shift))
{ ... }
CrazyTea
  • 297
  • 1
  • 3
  • 13
  • which control event do you use? – Fredou Aug 05 '15 at 14:40
  • 6
    [Keys](https://msdn.microsoft.com/en-us/library/system.windows.forms.keys(v=vs.110).aspx): "Do not use the values in this enumeration for combined bitwise operations. The values in the enumeration are not mutually exclusive." – Damien_The_Unbeliever Aug 05 '15 at 14:40
  • @Damien_The_Unbeliever Ignoring the line near the top: `This enumeration has a FlagsAttribute attribute that allows a bitwise combination of its member values.` lol probably an auto-doc fail from having the `FlagsAttribute` applied. – Adam Houldsworth Aug 05 '15 at 14:45
  • @AdamHouldsworth - yes, I do find the application of the `FlagsAttribute` to that enumeration... troublesome. – Damien_The_Unbeliever Aug 05 '15 at 14:46

2 Answers2

4

No, HasFlag does not have a bug. Unfortunately, the .NET FlagsAttribute is all or nothing and System.Windows.Forms.Keys is defined in such a way that only Keys.Modifiers may be used as flags.

From https://msdn.microsoft.com/en-us/library/system.windows.forms.keys%28v=vs.110%29.aspx

The Keys class contains constants for processing keyboard input. The members of the Keys enumeration consist of a key code and a set of modifiers combined into a single integer value. In the Win32 application programming interface (API) a key value has two halves, with the high-order bits containing the key code (which is the same as a Windows virtual key code), and the low-order bits representing key modifiers such as the SHIFT, CONTROL, and ALT keys.

As a result, you can check any of the modifiers (Keys.Shift, Keys.Alt, Keys.Control) with HasFlag, but nothing else.

jmc
  • 383
  • 1
  • 6
1

This is not a bug of HasFlag, it is how it work.
Suppose we have the following values:

var a = (Keys.Tab | Keys.Shift);
var b = (Keys.O | Keys.Shift);

Now we analyze the bits of these values (when we cast them to integers):

a: 10000000001000001
b: 10000000001001111

If we call a.HasFlag(b) we get false because not every 1-bit from b is a 1 in a too. But if we call b.HasFlag(a) we get true because every 1-bit of a is set in b too.

That's why you need to compare the values with a==b or with a.HasFlag(b) && b.HasFlag(a). Then it will work properly.

Koopakiller
  • 2,838
  • 3
  • 32
  • 47