Home > database >  WM_SIZE: How to correctly parse lParam?
WM_SIZE: How to correctly parse lParam?

Time:01-06

This question is incredibly specific. When I read other C/C posts on SO.com, they are so severe about signed vs unsigned integral values.

The Win32 WM_SIZE message is defined as: https://learn.microsoft.com/en-us/windows/win32/winmsg/wm-size

LPARAM lParam

lParam

The low-order word of lParam specifies the new width of the client area.

The high-order word of lParam specifies the new height of the client area.

My platform is: 64-bit Win 10

This page: https://learn.microsoft.com/en-us/windows/win32/winprog/windows-data-types

... says: typedef LONG_PTR LPARAM -> typedef __int64 LONG_PTR

Type is signed long long (essentially: <stdint.h> -> int64_t)

I (wrongly?) assume to "split" LPARAM into two parts:

WORD LOWORD(DWORD dwValue)

^^^ Ref: https://learn.microsoft.com/en-us/previous-versions/windows/desktop/legacy/ms632659(v=vs.85)

WORD HIWORD(DWORD dwValue)

^^^ https://learn.microsoft.com/en-us/previous-versions/windows/desktop/legacy/ms632657(v=vs.85)

But WORD is defined as A 16-bit unsigned integer here: https://learn.microsoft.com/en-us/windows/win32/winprog/windows-data-types

This seems to incorrectly mix signed and unsigned integral types. In my view, this is dreaded "UB" (undefined behaviour), but obviously millions of Win32 programs use this technique correctly.

What do I misunderstand?

Finally, please edit this question if better tags can be added, or the title/content can be improved(!).

CodePudding user response:

The C standard, at least since C99, has to say this:

6.3.1.3 Signed and unsigned integers

When a value with integer type is converted to another integer type ... if the value can be represented by the new type, it is unchanged.

Otherwise, if the new type is unsigned, the value is converted by repeatedly adding or subtracting one more than the maximum value that can be represented in the new type until the value is in the range of the new type.

Therefore the casting of signed to unsigned is well-defined, and produces the same value modulo MAX_VALUE 1. The exact meaning, as far as bits go, depends on the representation of integer values. On two's complement machines, this description simply leaves the bits (that fit) unchanged, and ignores the higher order bits if the new type is smaller.


None of it really matters though, because WINAPI is a very specific platform that's meant to be compiled with a very concrete compiler (MSVC). Therefore, if Microsoft intends you to use LOWORD and HIWORD, and "millions of programs" use them, you can be sure that these will work for their intended purpose on Windows, no matter if the ISO standard guarantees that or not.

  • Related