The signed/unsigned behaviour and handling was the first thing I was wondering about when I saw you made a class for this, Matti. I was wondering if you took that into account... (since the WriteDWORD function can accept signed values too, yet you make it possible to define stuff like UINT, etc)... but I didn't checked your code yet to see for myself if you took that into account (lazy
)... Anyways, since you brought it up...
quote:
Originally posted by Matti
While I was playing with these signed/unsigned types, I saw that the code member from NMHDR was defined as a UINT, but could also take signed values (e.g. LVN_COLUMNCLICK = -108) so to get around this, I defined code as an INT instead. Anyone has a valid explanation for this behavior? Source: NMHDR on MSDN
A signed value can always be represented as an unsigned value and vice versa. So if you assign -108 to an UINT (=4 bytes in memory), you actually assign the unsigned value: 0xFFFFFF94 or 4294967188 in memory.
And -108 is just easier to remember and to recognize in code than 4294967188, that's all. Actually -108 (LVN_COLUMNCLICK ) comes from the calculation LVN_FIRST-8, and LVN_FIRST is defined as 0xFFFFFF9C (or -100 when you interpret is as a signed INT).
Thus,
code should actually be defined as UINT though, not as an INT! So, instead of that 'workaround' by defining it as a wrong type, your function should convert the given signed value to an unsigned value, which is actually automatically already done by WriteDWORD anyways. That is: it simply writes the given number as-is to memory, which is already enough... (after of course AND'ing it with 0xFFFFFFFF to avoid overflow errors).
But to read the UINT value again, you must do some calculation yourself though. ReadDWORD() will otherwise return -108 (in the above example). But since it is defined as UINT it should return 4294967188 instead. So, what you should do is check the return value and if <0 you need to add 0x100000000 to the returned value.
In short (taking INT/UINT as example):
- To write a value you don't need to do anything (accept AND'ing with 0xFFFFFFFF of course). It doesn't matter if the number is pos or neg or if the type is signed or not...
- But to properly return an unsigned value, you do need to check if the returned value isn't negative, if so, you add 0xFFFFFFFF+1 to it)
--
PS: Another thing you could come across which would be very related to this is that quite a lot of functions in Windows actually compare your assigned value with an OR function to a mask which represents the meaningfull bits. So, it could well be that a -108 value (to take the same number as above) is simply interpreted as 4 in case the mask with meaningfull bits is 0xF. So, in that case -108, -236, 292, 1104936484, -4294966732, etc all have the same function since the least significant digit is always 0x4.
In the other way around: there are also some types used in Windows which are defined as a signed type, but in fact only unsigned (positive) values are defined. That is: only some positive values have a meaning. This is in most cases by design. And in those cases, in later Windows versions, you'll see that some other values are added and sometimes they are indeed negative values. So, it is not because the type is signed and only positive values are defined now, that in a later Windows version some new (negative) values aren't added anymore.
I hope I make some sense here, it's already late and I didn't slept much last nights either...