Reputation: 9155
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
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
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
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
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