Using HIWORD and LOWORD in Win32 API. How does the system work?

Salavat 121 Reputation points
2021-06-08T11:33:40.193+00:00

Hello!
While studying the API, I ran into the problem of understanding what the upper and lower words are.
Below is an example of a window procedure. Two buttons are created in the WM_CREATE message (both handles are declared in a header file not shown). Further, in the WM_COMMAND message I catch the button presses. I looked at this example on one forum, but I just can't figure out at what stage the button descriptor is assigned to the lParam parameter and what happens when the left mouse button is pressed. When I turn on the debug mode, when the mouse button is pressed, the lParam parameter has already been assigned a handle to one of the buttons on the working surface. If I click on the Exit menu button (see the switch (LOWORD (wParam)) part of the code), it turns out that the wParam parameter has already been assigned the ID_FILE_EXIT number in the resources, defined through "define". When I looked at what HIWORD and LOWORD are practically everywhere "magic words" pop up :) that these are the upper and lower words. That is, if there is a number 0x3256abcd, then HIWORD is 3256, and LOWORD is abcd, but this does not explain how to catch certain responses of ready-made functions and macros from the Win32 API. Is there a general rule of what kind of code construction needs to be written to catch the pressing of a certain button, selecting text from a multiple list, changing the style of a drop-down menu, etc.

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
   switch (msg)
   {
   case WM_CREATE:
   {
       ...
       fbHwnd = CreateWindow(L"BUTTON", L"Next", WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, 150, 200, 70, 50, hwnd, NULL, (HINSTANCE)GetWindowLongPtr(hwnd, GWLP_HINSTANCE), NULL);
       sbHwnd = CreateWindow(L"BUTTON", L"Exit", WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON, 222, 272, 70, 50, hwnd, NULL,(HINSTANCE)GetWindowLongPtr(hwnd, GWLP_HINSTANCE), NULL);
       ...
    }
    break;
    case WM_COMMAND:
    {
        if (lParam == (int)fbHwnd)
        {
               if (HIWORD(wParam) == BN_CLICKED)
                  {
                     MessageBox(hwnd, L"First button", L"Warning", MB_OK);  
                  }
         }
         else if (lParam == (int)sbHwnd)
         {
               if (HIWORD(wParam) == BN_CLICKED)
                  {
                     MessageBox(hwnd, L"Second button", L"Warning", MB_OK);   
                  }
          }
          break;
          switch (LOWORD(wParam))
          {
           ...
          case ID_FILE_EXIT:
          {
                PostMessageW(hwnd, WM_CLOSE, 0, 0);
          }
          break;
          ...
          }
     }
     break;
     }
}
Windows API - Win32
Windows API - Win32
A core set of Windows application programming interfaces (APIs) for desktop and server applications. Previously known as Win32 API.
2,422 questions
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. RLWA32 40,286 Reputation points
    2021-06-08T12:25:48.787+00:00

    Is there a general rule of what kind of code construction needs to be written to catch the pressing of a certain button, selecting text from a multiple list, changing the style of a drop-down menu, etc.

    The general rules that you are referring to would be documentation for the messages and notifications that the various controls in the Windows API use. Its a large topic but the documentation is here - window-controls

    As an example, the behavior of button controls is documented here - buttons

    Carefully read the documentation for BN_CLICKED, WM_COMMAND and CreateWindow. In particular, carefully review the table in the Remarks section of the CreateWindow documentation. Compare these details with the posted code.

    With respect to the posted code -

    1. CreateWindow does not assign control identifiers to the two buttons created in the WM_CREATE handler. This identifier is passed as the hMenu parameter.
    2. CreateWindow returns a window handle (an HWND). It should not be cast to an int.
    3. The switch statement in which the ID_FILE_EXIT menu command is handled appears to be outside of the WM_COMMAND handler.

    Finally, handling messages in a window procedure can be simplified by using "message crackers". These are macros that will split out the relevant parts of window messages and make it easier to handle them. They are located in the windowsx.h header.

    1 person found this answer helpful.