33.2.4 Sending a Message

You can use the SendMessage function to send a message directly to a window procedure. SendMessage calls a window procedure and waits for that procedure to process the message and return a result.

A message can be sent to any window in the system; all that is required is a window handle. Windows uses the handle to determine which window procedure should receive the message.

A window procedure can cause a message deadlock situation if it yields control while processing a message that was sent by another thread (see Section 0.1.7, “Message Deadlocks”). You should call the InSendMessage function before processing a message that may have been sent from another thread. If InSendMessage returns TRUE, you should call ReplyMessage before calling the function that yields control, as shown in the following example:

case WM_USER+5:

if (InSendMessage())

ReplyMessage(TRUE);

DialogBox(hInst, "MyDialogBox", hwndMain, (DLGPROC)MyDlgProc);

break;

Windows includes a number of messages that you send to controls in a dialog box. You use these control messages to set the appearance, behavior, and content of controls, or to retrieve information about controls. For example, you can send the CB_ADDSTRING message to a combo box to add a string to the combo box, or the BM_SETCHECK message to set the check state of a check box or radio button.

You use the SendDlgItemMessage function to send a message to a control, specifying the identifier of the control and the handle of the dialog window that contains the control. The following example, taken from a dialog-box procedure, copies a string from a combo box's entry field into its list box. The example uses SendDlgItemMessage to send a CB_ADDSTRING message to the combo box.

HWND hwndCombo;

int cTxtLen;

PSTR pszMem;

switch (uMsg) {

case WM_COMMAND:

switch (LOWORD(wParam)) {

case IDD_ADDCBITEM:

/*

* Get the handle of the combo box and the

* length of the string in the edit control of

* the combo box.

*/

hwndCombo = GetDlgItem(hwndDlg, IDD_COMBO);

cTxtLen = GetWindowTextLength(hwndCombo);

/*

* Allocate memory for the string and copy

* the string into the memory.

*/

pszMem = (PSTR) VirtualAlloc((LPVOID) NULL,

(DWORD) (cTxtLen + 1), MEM_COMMIT,

PAGE_READWRITE);

GetWindowText(hwndCombo, pszMem, cTxtLen + 1);

/*

* Add the string to the list box of the

* combo box and remove the string from the

* edit control of the combo box.

*/

if (*pszMem != NULL) {

SendDlgItemMessage(hwndDlg, IDD_COMBO,

CB_ADDSTRING, 0,

(DWORD) ((LPSTR) pszMem));

SetWindowText(hwndCombo, (LPSTR) NULL);

}

/* Free the memory and return. */

VirtualFree(pszMem, 0, MEM_RELEASE);

return TRUE;

.

. /* Process other dialog-box commands. */

.

}

.

. /* Process other dialog-box messages. */

.

}