Click here to Skip to main content
Click here to Skip to main content

Windows Message Handling - Part 1

, 7 Jun 2000
Rate this:
Please Sign up or sign in to vote.
An introduction to basic Windows messages such as WM_SIZE and WM_CLOSE, and how to add your own handlers

Introduction

Perhaps one of the most important means of communication in windows is Messages. The traditional program starts at your main() function, moves down line-by-line in your code, and eventually exits. The Windows concept is different. The way you program in windows is by responding to events. These events are called messages.

Messages can signal many events, caused by the user, the operating system, or another program. An event could be caused by a mousemove, a key-press, or by your window getting resized. There are 2 kinds of messages: a window message, or a thread message. Since Threads are an advanced issue, I'll refer only to window messages.

Window Messages:

In general, a message must be sent to a window. All the messages sent to you are stored in a Message Queue, a place in the memory which stores message which are transferred between applications.

Message Loop:

the way you retrieve messages from the Message Queue is by creating a Message Loop. A Message Loop is a loop that checks for messages in the Message Queue. once a message is received, the Message Loop dispatches the message by calling a Message Handler, a function designed to help the Message Loop at processing the message.

The Message Loop will end when a WM_QUIT message is received, signaling the application to end. This message could be sent because the user selected Exit from your File menu, clicked on the close button (the X small button in the upper right corner of your window), or pressed Alt+F4. Windows has default Message Handlers for almost all the messages, giving your window the default window behavior. In fact, all the standard controls are simply windows with Message handlers. Take a Button for example. When it gets a WM_PAINT message it will draw the button. When you Left-click the button, it gets a WM_LBUTTONDOWN message, and it draws the pressed-button. When you let go of the mouse button it receives a WM_LBUTTONUP message, and respectively draws the button.

Windows defines many different message types (which are stored as UINTs). They usually begin with the letters "WM" and an underscore, as in WM_CHAR and WM_SIZE. The names of the message are usually a good indicator of what they represent. WM_SIZE for sizing messages, WM_CHAR for character entry messages and so on. The naming convention in MFC for message handler functions is to take away the "WM_" and replace it with "On", so the message handler for WM_SIZE is usually called OnSize.

A message comes with 2 parameters that give you more information about the event. Each parameter is a 32-bit value: lParam and wParam. For example: WM_MOUSEMOVE will give you the mouse coordinates in one paramter, and in the other some flags indicating the state of the ALT, Shift, CTRL and mouse buttons.

A Message may also return a value which allows you to send data back to the the sending program. For example, the WM_QUERYENDSESSION message sent by windows before the computer is shutdown, expects you to return a Boolean value. If your application can terminate conveniently, it should return TRUE; otherwise, it should return FALSE. Other message such as the WM_CTLCOLOR messages expect you to return an HBRUSH.

Note: In the rest of the tutorial I will focus on MFC for simplicity reasons. All the information above applies to both SDK programs, and MFC programs.

Message Handlers:

Fortunately, MFC will give all the code needed for the message loop, One of the CWinApp member functions called by WinMain—Run—provides the message loop that pumps messages to the application's window. The only thing you need to do so you can receive messages is to create Message Handlers, and inform MFC of them. So, how do you create a Message Handler? Once you have an MFC C++ class that encapsulates a window, you can easily use ClassWizard to create Message Handlers.

Using ClassWizard to create Message Handlers:

Press Ctrl + W to start the ClassWizard, or right click the Add button and select ClassWizard from the context menu. Open ClassWizard, select Message Maps tab. In Class name select the name of your C++ class. on Object IDs select either the ID of a menu item (for messages caused by the user interacting with a menu), the ID of a control (for messages caused by the user interacting with a control), or the first option to handle messages other messages. Choose the message from the Messages list, WM_SIZE for example, and Click on Add Function. Click OK, then click Edit Code. ClassWizard will write a new empty function (OnSize for example) with the proper prototype in the class header. The code generated should look similar to this:

void CAboutWindow::OnSize(UINT nType, int cx, int cy)
{
	CDialog::OnSize(nType, cx, cy);
	// TODO: Add your message handler code here

	// Here is where you can resize controls in your window, change
	// the size of a bitmap in it, or do what ever you can think of.
}

That's it, now you can handle messages. If you want to handle a message and then let the default message handler handle the message, you should call the base class member function that corresponds with the message. Take the following WM_CLOSE Message Handler as an example:

void CAboutWindow::OnClose()
{
	//The User or another program is trying to close our window...
	//If you don't add code to close the window, your window will never close
}

If you want windows to get a shot at the message, you should call the base class member function OnClose:

void CAboutWindow::OnClose()
{
	MessageBox(_T("Closing the window!"))
	//Call the Base class member function, which will close the window.
	CWnd::OnClose()
}

You could use this behavior to screen-out events. For example, a program that prompts the user if he is sure that he wants to close the window:

void CAboutWindow::OnClose()
{
	int Ret = MessageBox(_T("Are you sure you want to close the window?"),
	                     _T("Close Window?"), MB_YESNO);
	if(Ret == IDYES){
		// The User is sure, close the window by calling the base class
		// member
		CWnd::OnClose()
	}
	else{
		// The user pressed no, screen out the message by not calling
		// the base class member

		//Do nothing
	}
}

Sending Messages:

Besides receiving messages, you will often find your self sending messages. You might want to send messages to communicate between to windows in your program, or to communicate between different programs. In order to send a message you need a pointer to a c++ window class. This can be retrieved using various functions, including CWnd::FindWindow, GetDlgItem(), GetParent(), and more. The CWnd class has a SendMessage() member function which allows you to send messages to it's window. For example, Let’s say you have a CWnd pointer to the Calculator, and you want to close it. What you should do is send a WM_CLOSE message, which will notify the Calculator that it should close. You can use the following code. In order to get a pointer to Calculator, I use the static CWnd::FindWindow() function and pass the title of the window, which in our case is "Calculator".

CWnd *pCalc;
//Get a pointer to the "Calculator" Window
pCalc = CWnd::FindWindow(NULL, _T("Calculator));
if(pCalc == NULL){
	//Couldn't find Calculator
}
else{
	pCalc->SendMessage(WM_CLOSE);
	//Presto! The Calculator should close.
}

More to come

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

Daniel Kopitchinski
Web Developer
Israel Israel
No Biography provided

Comments and Discussions

 
GeneralMy vote of 5 Pinmemberiampradeepsharma17-Dec-12 17:04 
GeneralMy vote of 5 PinmemberShilpa from Mysore8-Aug-12 23:19 
QuestionFine Pinmemberrajesh.vbnet23-May-12 18:33 
GeneralMy vote of 4 PinmemberMember 777106013-Apr-11 22:09 
This article is very useful and for beginners.
Questionwho will create message loop and message queue? Pinmembervasu_sri17-Oct-10 21:34 
GeneralMy vote of 5 Pinmemberdefiantgti14-Oct-10 14:13 
GeneralGreat for beginners! PinmemberNickolay Karnaukhov19-Jun-09 1:03 
QuestionDisable system bell sound when a key is pressed on dialog? Pinmembersunil_963114-Nov-07 21:36 
AnswerRe: Disable system bell sound when a key is pressed on dialog? Pinmemberwr1274-Mar-09 22:28 
QuestionHow to get Dialog handle PinmemberGofur Halmuratov26-Dec-06 5:40 
Generalclosing dialog when escape key pressed PinmemberKhathar26-Dec-05 5:31 
GeneralRe: closing dialog when escape key pressed Pinmemberzetasolid2-Jan-06 4:55 
GeneralRe: closing dialog when escape key pressed Pinmembervikhuanmaytinh8-Jan-06 22:10 
GeneralRe: closing dialog when escape key pressed Pinmembersaddam.ua21-Jun-06 6:06 
GeneralRe: closing dialog when escape key pressed Pinmemberasi1103-Oct-07 20:59 
QuestionCan someone clarify this for me? Pinmemberszakaryan16-May-05 6:12 
AnswerRe: Can someone clarify this for me? PinmemberRaj241116-Aug-06 18:56 
QuestionHow to refresh the explorer in my own program? Pinmembergly17-Jan-05 16:11 
Questionmessage with console app ? Pinmemberdharani3-Sep-04 2:29 
AnswerRe: message with console app ? Pinmember.:floyd:.15-Jan-05 17:21 
GeneralSending a message to a TabCtrl PinmemberDavid Fleming9-Nov-03 17:21 
GeneralRe: Sending a message to a TabCtrl PinmemberAravind Kumar K15-Nov-06 19:48 
GeneralThe window still didn't close PinmemberPika7-Sep-03 14:13 
GeneralCatch hover message of botton control Pinmemberhoangphi21116-Dec-02 21:55 
GeneralRe: Catch hover message of botton control PinmemberDavide Pizzolato16-Dec-02 22:42 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web02 | 2.8.141015.1 | Last Updated 8 Jun 2000
Article Copyright 2000 by Daniel Kopitchinski
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid