still_dreaming_1
still_dreaming_1

Reputation: 9155

How to check a returned bit mask value?

I am calling this function from C#: GetKeyboardStatus()

Looking at the documentation it says that it returns a bit mask value. The goal of my code is to determine if the device has a physical keyboard with alphanumeric characters. I have successfully called this function and the return value is 15. However since I don't understand bit masks, I don't know how to compare it to the 0x0008 value, which according to the documentation "Indicates whether or not the keyboard hardware has alphanumeric keys.". I am not tagging this as a Windows Mobile or Compact Framework question because I think all you will need to understand to answer my question is bit masks and C# and I am hoping the answer will expand my understanding of how to work with a bit mask (not required though). Here is my code. I think the only part that is wrong is the return statement:

        public static bool HasAlphaNumericKeys {
            get {
                const uint KBDI_KEYBOARD_ALPHA_NUM = 0x0008;
                uint returnValue = GetKeyboardStatus();
                return returnValue == KBDI_KEYBOARD_ALPHA_NUM;
            }
        }

        [DllImport("coredll")]
        private static extern uint GetKeyboardStatus();

Thanks for trying to help but I have discovered that this is not a reliable way to determine if there is a physical keyboard with alphanumeric keys. I tried 2 devices, one with a keyboard and one without and the GetKeyboardStatus function returned 15 for both of them, so I can't even test the explanation of bit masks in the answers.

Upvotes: 0

Views: 6341

Answers (4)

Eddy
Eddy

Reputation: 5370

The bitwise operations get a lot easier to understand if you actually write them on a piece of paper as binary values

You 15 (decimal) is in binary 1111 (2^3 + 2^2 + 2^1 + 2^0) = (8+4+2+1)
The 8 (decimal) is in binary 1000 (2^3 + 0 + 0 + 0) = (8+0+0+0)

A logical and means that for each bit if both value are a 1 then the result is a 1 otherwise a 0

    In our case the (Y means both are 1 and N means one or both have a 0):
    1111
    1000
    ----
    YNNN

    Or in it's binary result
    1000  

So for the record: The result of the logical AND operation is a number and not true/false. Since you want the result to have all the bits from KBDI_KEYBOARD_ALPHA_NUM set I would prefer to check like this

if ((returnValue & KBDI_KEYBOARD_ALPHA_NUM) == KBDI_KEYBOARD_ALPHA_NUM) { /* YES */ }

I would compare the result with != 0 only if I want any of the bits in KBDI_KEYBOARD_ALPHA_NUM to be set. Since in this case there is only 1 bit involved both will work the same. But to illustrate the difference:

const uint NEED_ALL_THESE_BITS = 0x0009;   // Binary: 1001
uint result = 3; // Binary: 0011;
((result & NEED_ALL_THESE_BITS) != 0) --> True
((result & NEED_ALL_THESE_BITS) == NEED_ALL_THESE_BITS) --> False

Comparing to != 0 when you want all bits to be set doesn't make your code self-explanatory

Upvotes: 2

sll
sll

Reputation: 62544

Basically you need to check whether fourth bit is set, so just use bitwise AND operation:

bool IsAbc(int key)
{
  return 0 != (0x08 & key);
}

Upvotes: 0

bbogovich
bbogovich

Reputation: 341

I believe bitwise operators are what you want, specifically bitwise-AND (&). Bitwise AND looks at each bit of the two operands and returns '1' if both bits are '1', and '0' otherwise. So if you AND a bitmask with a specific flag value, and get a non-zero result, you know that the bitmask contains the flag.

return (returnValue & KBDI_KEYBOARD_ALPHA_NUM) != 0;

Upvotes: 1

markgz
markgz

Reputation: 6266

Try

return (returnValue & KBDI_KEYBOARD_ALPHA_NUM) != 0;

This returns true if bit 3 of returnValue is set, regardless of the values of any of the other bits in returnValue.

Upvotes: 1

Related Questions