Click here to Skip to main content
15,867,756 members
Articles / Desktop Programming / MFC

Windows Message Handling - Part 1

Rate me:
Please Sign up or sign in to vote.
4.72/5 (68 votes)
7 Jun 2000 728.6K   306   41
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 two 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 messages 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 parameter, 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 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 WinMainRun—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:

C++
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:

C++
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:

C++
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:

C++
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 its 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".

C++
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

History

  • 8th June, 2000: Initial version

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.


Written By
Web Developer
Israel Israel
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralMy vote of 5 Pin
iampradeepsharma17-Dec-12 17:04
iampradeepsharma17-Dec-12 17:04 
GeneralMy vote of 5 Pin
sowbhagya sanjeev8-Aug-12 23:19
sowbhagya sanjeev8-Aug-12 23:19 
QuestionFine Pin
rajesh.vbnet23-May-12 18:33
rajesh.vbnet23-May-12 18:33 
GeneralMy vote of 4 Pin
Member 777106013-Apr-11 22:09
Member 777106013-Apr-11 22:09 
Questionwho will create message loop and message queue? Pin
vasu_sri17-Oct-10 21:34
vasu_sri17-Oct-10 21:34 
GeneralMy vote of 5 Pin
defiantgti14-Oct-10 14:13
defiantgti14-Oct-10 14:13 
GeneralGreat for beginners! Pin
Nickolay Karnaukhov19-Jun-09 1:03
Nickolay Karnaukhov19-Jun-09 1:03 
QuestionDisable system bell sound when a key is pressed on dialog? Pin
sunil_963114-Nov-07 21:36
sunil_963114-Nov-07 21:36 
AnswerRe: Disable system bell sound when a key is pressed on dialog? Pin
wr1274-Mar-09 22:28
wr1274-Mar-09 22:28 
QuestionHow to get Dialog handle Pin
Gofur Halmurat26-Dec-06 5:40
Gofur Halmurat26-Dec-06 5:40 
Generalclosing dialog when escape key pressed Pin
Khathar26-Dec-05 5:31
Khathar26-Dec-05 5:31 
GeneralRe: closing dialog when escape key pressed Pin
zetasolid2-Jan-06 4:55
zetasolid2-Jan-06 4:55 
GeneralRe: closing dialog when escape key pressed Pin
vikhuanmaytinh8-Jan-06 22:10
vikhuanmaytinh8-Jan-06 22:10 
GeneralRe: closing dialog when escape key pressed Pin
saddam.ua21-Jun-06 6:06
saddam.ua21-Jun-06 6:06 
GeneralRe: closing dialog when escape key pressed Pin
asi1103-Oct-07 20:59
asi1103-Oct-07 20:59 
QuestionCan someone clarify this for me? Pin
Member 195600516-May-05 6:12
Member 195600516-May-05 6:12 
AnswerRe: Can someone clarify this for me? Pin
Raj241116-Aug-06 18:56
Raj241116-Aug-06 18:56 
QuestionHow to refresh the explorer in my own program? Pin
gly17-Jan-05 16:11
gly17-Jan-05 16:11 
Questionmessage with console app ? Pin
dharani3-Sep-04 2:29
dharani3-Sep-04 2:29 
AnswerRe: message with console app ? Pin
.:floyd:.15-Jan-05 17:21
.:floyd:.15-Jan-05 17:21 
GeneralSending a message to a TabCtrl Pin
David Fleming9-Nov-03 17:21
David Fleming9-Nov-03 17:21 
GeneralRe: Sending a message to a TabCtrl Pin
Aravind Kumar K15-Nov-06 19:48
Aravind Kumar K15-Nov-06 19:48 
GeneralThe window still didn't close Pin
Pika7-Sep-03 14:13
Pika7-Sep-03 14:13 
GeneralCatch hover message of botton control Pin
phidotnet16-Dec-02 21:55
phidotnet16-Dec-02 21:55 
GeneralRe: Catch hover message of botton control Pin
Davide Pizzolato16-Dec-02 22:42
Davide Pizzolato16-Dec-02 22:42 

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

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