Broad Network


Control Messages

Windows Predefined Controls – Part 2

Volume - Windows User Interface

Forward: In this part of the series, we look at control messages.

By: Chrysanthus Date Published: 29 Aug 2012

Introduction

This is part 2 of my series, Windows Predefined Controls. In order to understand this part of the series, you most have read the previous part (tutorial) of the series. In this part of the series, we look at control messages.

Note: If you cannot see the code or if you think anything is missing (broken link, image absent), just contact me at forchatrans@yahoo.com. That is, contact me for the slightest problem you have about what you are reading.

LOWORD and HIWORD
Consider the following binary (base 2) number:

    10100011010100110110110001010010

There are 32 bits (binary digits) here. The first 16 bits form what is called the LOWORD (for Low Word). The next 16 bits form what is called the HIWORD (for High Word). Know that 8 bits form a byte; 16 bits form a half word; 32 bits form a word; 64 bits form a double word.

So far as messages are concerned, it is possible for the 32 bits to have one meaning. Alternatively, the first 16 bits (LOWORD) of the 32 bits can have a meaning different from the meaning of the next 16 bits (HIWORD).

A Message
When thinking of a message, imagine what (parameters) goes into a window’s procedure. The parameters of a window’s procedure are, (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam). hwnd is the handle of the window that uses the window procedure. The actual message consists of three parts, which are uMsg, wParam and lParam. uMsg is the real message and in many cases wParam and/or lParam are data for the real message. So, in general, a message consists of the three parts, uMsg, wParam and lParam. wParam and lParam are each an integer expressed as a binary number in 32 bits. uMsg is also an int.

Sending a Message to a Control
A control is a child window. A child window is still a window. So you can send window messages to a control. A predefined control such as the Edit control has a predefined class (the system EDIT class) and a predefined procedure. In your application, you do not have to type anything for the predefined class and the predefined procedure. The predefined procedure of the control processes the window messages sent to the control, without you knowing.

An example of a window message to send to a window (e.g. an Edit control) is WM_SETTEXT. WM_SETTEXT is an identifier (name) of a constant value. So far as the above three message parameters are concerned, WM_SETTEXT is for uMsg. We are still to consider the wParam and lParam arguments (parameters) associated with WM_SETTEXT. The WM_SETTEXT message sets (displays) the text for a window. The actual text is indicated in the lParam parameter (see later).

The SendMessage Function
The SendMessage Function can be used to send a message to a window or control. The syntax is:

LRESULT WINAPI SendMessage(
  __in  HWND hWnd,
  __in  UINT Msg,
  __in  WPARAM wParam,
  __in  LPARAM lParam
);

hWnd is the handle of the window (or control). Msg is the message, e.g. WM_SETTEXT. wParam and lParam are for the data of the message. The return value is the returned value of the message and not of the SendMessage function. The message cannot move itself, so the function moves it to the window or control. When the message returns a value, it is the function that brings the returned value back, as an LRESULT type.

Sending WM_SETTEXT to an Edit Control
Here, we consider a sending message example. The WM_SETTEXT message is used to send text to a control or window so that the control or window displays it. For the WM_SETTEXT message, the wParam parameter is not used; so it is set to NULL in the SendMessage function. The lParam parameter for the WM_SETTEXT message is a pointer to a null-terminated ( ) string that has the text of interest. The return value of the WM_SETTEXT is TRUE if the message is set (displayed). For an Edit control, if there is not enough space for the text to be set, then the return value of the WM_SETTEXT message would be FALSE. This would happen if the width of your edit control were very small (everything being equal).

So after creating an edit control with the handle say, hwndEdit1, you can send the text, “Some txt” to it as follows:

    const char *str = "Some txt";    //C++ statement
    SendMessage(hwndEdit1, WM_SETTEXT, NULL, (LPARAM)str);

Now a pointer (str) to a constant null-terminated string and the LPARAM type are similar; but they are not exactly the same type. That is why, in the SendMessage function str is cast (converted) to LPARAM by the presence of the parentheses around LPARAM.

We shall try this. Go to the winedit.cpp file. Change the text (4 statements) for creating the edit control to:

    HWND hwndEdit1;
    hwndEdit1 = CreateWindowEx(0, "EDIT", NULL, WS_CHILD, 100, 100, 150, 15, hwndMain, (HMENU)1, hinstance, NULL);
    ShowWindow(hwndEdit1, SW_SHOW);
    UpdateWindow(hwndEdit1);

    const char *str = "Some txt";    //C++ statement
    SendMessage(hwndEdit1, WM_SETTEXT, NULL, (LPARAM)str);

Save the resulting file as editmsg.cpp. Compile it at the command prompt window as follows:

    g++ editmsg.cpp -mwindows -o editmsg.exe

Go to the MinGW directory and double click the editmsg.exe icon to see the text, "Some txt" in the edit control.

If you are not sure whether a message will be set (edit control width may not be long enough), then you would have to place the SendMessage function in an if-construct; to know if the return value is true so that you can proceed with other statements.

When the SendMessage function sends a message, the procedure of the class of the control processes the message for us. This procedure is provided by the (operating) system and it is not available to us.

Notifications from Controls
We have seen how to send messages to a control, which is a window (a child window). Now when a user acts on a control, for example, clicks the control or type something in the control, that is an event. The procedure of the control is not available to us. It is the procedure of the parent window that is available to us. When such an event occurs, the control will send a message of the event to the procedure of the parent window. Such messages are called Notification Messages. These notifications indicate the actions the user wants (the event).

We can process the notifications in the parent window procedure. If we have the call to the DefWindowProc default window class procedure, then many of these messages will be processed for us (i.e. we would not need any coding to process the notifications). However, we shall also need to process (code) some of these messages in the parent window class procedure (see later).

Note: The notification messages will have to pass through the system message queue and the WHILE message loop before it reaches the parent window procedure.

Most notifications are sent to the parent window procedure as either a WM_COMMAND or a WM_NOTIFY message.

The WM_COMMAND Message
A notification can be sent from a control to the parent window procedure using the WM_COMMAND Message. The value of the uMsg parameter for the WM_COMMAND Message is, WM_COMMAND. WM_COMMAND is an identifier for a constant integer value. It works with the wParam and lParam parameters. For a control, the low word (LOWORD) of the wParam parameter is the Control Identifier (unique integer), while the high word (HIWORD) of the wParam parameter is the control-defined notification code (the notification itself - see later). Also, for a control, the lParam parameter is the handle to the control window (for example, hwndEdit1 in the code above).

The WM_NOTIFY Message
A notification can also be sent from a control to the parent window procedure using the WM_NOTIFY Message. The value of the uMsg parameter for the WM_NOTIFY message is, WM_NOTIFY. The wParam parameter is the identifier (integer) for the control that is sending the message (notification). lParam is a pointer to a struct called, NMHDR (or its variant). This structure contains the notification code (see later) and additional message information.  

The NMHDR struct
The description of the NMHDR struct is:

typedef struct tagNMHDR {
  HWND     hwndFrom;
  UINT_PTR idFrom;
  UINT     code;
} NMHDR;

hwndFrom is the handle of the control sending the message. idFrom is the identifier (integer) of the control sending the message. Here, handle and identifier are referring to the same control, but they are of different data types and are used in different ways. code is the actual notification (code).

I know you have many questions at this point. Let us leave that for the other parts of the series. So, we end here and continue in the next part.

Chrys

Related Courses

C++ Course
Relational Database and Sybase
Windows User Interface
Computer Programmer – A Jack of all Trade – Poem
NEXT

Comments

Become the Writer's Fan
Send the Writer a Message