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

Windows Message Handling - Part 1

By , 7 Jun 2000
 

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

About the Author

Daniel Kopitchinski
Web Developer
Israel Israel
Member
No Biography provided

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralMy vote of 5memberiampradeepsharma17 Dec '12 - 17:04 
good article
GeneralMy vote of 5memberShilpa from Mysore8 Aug '12 - 23:19 
good for beginners
QuestionFinememberrajesh.vbnet23 May '12 - 18:33 
Good class for a beginer....
GeneralMy vote of 4memberMember 777106013 Apr '11 - 22:09 
This article is very useful and for beginners.
Questionwho will create message loop and message queue?membervasu_sri17 Oct '10 - 21:34 
in win32, where will keep the all messages are generated by the window? and how do know this message is belongs to this window? and who will maintain the message queue? what happand in background? what is the code in c++? what are the methods are fallows in background?
Regards,
Srinivas

GeneralMy vote of 5memberdefiantgti14 Oct '10 - 14:13 
OMG u r God like !!
GeneralGreat for beginners!memberNickolay Karnaukhov19 Jun '09 - 1:03 
Thanks!
 
------------------------------------------------------------
Want to be happy - do what you like!

QuestionDisable system bell sound when a key is pressed on dialog?membersunil_963114 Nov '07 - 21:36 
Hi,
 
In MFC Dialogs, when a key is pressed, I am capturing the keydown event in message_maps (WM_KEYDOWN) and calling a relevant procedure void OnKeyDown(nChar, nRepCnt, nFlags).   But after executing the OnKeyDown event I could hear a beep sound.   Is there any way to disable the beep sound when a key is pressed?
 
Thanks in advance.
AnswerRe: Disable system bell sound when a key is pressed on dialog?memberwr1274 Mar '09 - 22:28 
I have the exact problem.... Anyone ?
QuestionHow to get Dialog handlememberGofur Halmuratov26 Dec '06 - 5:40 
Hello, i am new c++ programmer, i have 2 dialogs in my solution(Visual studio). and i want to change second dialogs, data by being in first dialog, how can i do that? could someone help me?
 

thanksSmile | :) Smile | :) Smile | :)
 
it is never late to learn!!!
Generalclosing dialog when escape key pressedmemberKhathar26 Dec '05 - 5:31 
hi friends..!
 
i need to know that how to disble access of escape and enter key events in mfc dialog based application.
GeneralRe: closing dialog when escape key pressedmemberzetasolid2 Jan '06 - 4:55 
You can diable it by handler the OnCancel event!!!!
 

GeneralRe: closing dialog when escape key pressedmembervikhuanmaytinh8 Jan '06 - 22:10 
To disable closing dialog when escape. You do as following.
///////////////////////////////////////////////
BOOL DialogName::PreTranslateMessage(MSG* pMsg)
{
// TODO: Add your specialized code here and/or call the base class
if(pMsg->message==WM_KEYDOWN)
{
if(pMsg->wParam==VK_RETURN || pMsg->wParam==VK_ESCAPE)
pMsg->wParam=NULL ;
}
return CDialog::PreTranslateMessage(pMsg);
}
///////////////////////////////////////////////
 
TXK
GeneralRe: closing dialog when escape key pressedmembersaddam.ua21 Jun '06 - 6:06 
Thanks a lot for your hint!
 
BR -
Saddam
GeneralRe: closing dialog when escape key pressedmemberasi1103 Oct '07 - 20:59 
I am using this code but its not working i have also declared a ON_WM_KEYDOWN() message map?
QuestionCan someone clarify this for me?memberszakaryan16 May '05 - 6:12 
I walked through the dialog application, with out must problem until I compiled it and got the following error statement. I have search the error database but none of the suggested solutions made a difference. Any ideas as to what I am doing wrong.
 
C:\Program Files\Microsoft Visual Studio\MyProjects\dialog1\dialog1Dlg.cpp(192) : error C2039: 'AddString' : is not a member of 'CString'
c:\program files\microsoft visual studio\vc98\mfc\include\afx.h(368) : see declaration of 'CString'
 



AnswerRe: Can someone clarify this for me?memberRaj241116 Aug '06 - 18:56 
I think this error in itself is very much describing. CString doesnt have function called Addstring. For this operation, the + operator is overloaded in CString. Also you can do it using Format function.
 
-Regards
QuestionHow to refresh the explorer in my own program?membergly17 Jan '05 - 16:11 
In my program, i got the handle of an explorer window,and i wannna refresh it in my program.Any ideas?Thank you!
Questionmessage with console app ?memberdharani3 Sep '04 - 2:29 
Hi all /auther
How can I send a message in a console app ? I am not using a dialog based or view based application but a console app so I am not able to pass the HWND .
I am trying to get a call back at LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
but its not working as i dont ha HWND to pass to ...
Any ideas ?
regds
Dharani babu s

AnswerRe: message with console app ?member.:floyd:.15 Jan '05 - 17:21 
PostThreadMessage[^]
 
.f
GeneralSending a message to a TabCtrlmemberDavid Fleming9 Nov '03 - 17:21 
I need to simulate clicking a tab on a tab control. And that has to trigger the code in OnSelChange. My understanding is that I need to send TCN_SELCHANGE to that tab control to do that. Unfortunately, I can't seem to make it work.
 
Here's a partial code listing:

void CDialogList::OnInitialUpdate()
{
CFormView::OnInitialUpdate();

//Various setup code in here
...
 
////Select the tab to display first
m_tabLists.SetCurSel(1); //This does NOT call OnSelchange
ChangeTabListsDisplay(); //This is a work-around
//m_tabLists.SendMessage(TCN_SELCHANGE, 0, 0);
//SendDlgItemMessage(IDC_TAB_LISTS, TCN_SELCHANGE, 0, 0);
}
 
void CDialogList::OnSelchangeTabLists(NMHDR* pNMHDR, LRESULT* pResult)
{
ChangeTabListsDisplay(); //This is a work-around
*pResult = 0;
}
 

 
Neither the SendMessage line nor the SendDlgItemMessage line works. The CDialogList::OnSelchangeTabLists function only gets called when I actually click on a tab with the mouse.
 
I want to be able to programmatically call the function so that I can set the active tab (and change the display accordingly, which is what the OnSelchange code is for) based on other activities in the program.
 
How do I do it? What am I missing here?
 
Thanks.
GeneralRe: Sending a message to a TabCtrlmemberAravind Kumar K15 Nov '06 - 19:48 
Use the below logic to invoke it programmatically
 
NMHDR Msg;
Msg.code = TCN_SELCHANGE;
Msg.idFrom = IDC_MainTab;
Msg.hwndFrom = m_CtrlTab_MainTAB.m_hWnd;
if(NULL != m_CtrlTab_MainTAB.m_hWnd) {
m_CtrlTab_MainTAB.SetCurSel(i_eTabDialog);
SendMessage(WM_NOTIFY,TCN_SELCHANGE,(LPARAM)&Msg);
}
 
Aravind.
GeneralThe window still didn't closememberPika7 Sep '03 - 14:13 
I wonder why as i did put CWnd::OnClose(); but nothing happened.
 
God loves us.
GeneralCatch hover message of botton controlmemberhoangphi21116 Dec '02 - 21:55 
I had difficulties that. I have a botton on a dialog, and I have to play an audio file whenever my mouse hovering.
 
Please give me suggestions.
thanks,
GeneralRe: Catch hover message of botton controlmemberDavide Pizzolato16 Dec '02 - 22:42 
see owner-draw buttons:
http://www.codeproject.com/buttonctrl/cbuttonst.asp
http://www.codeproject.com/buttonctrl/mfc2ocx.asp

GeneralQuery about message typememberoRion23 Sep '02 - 12:28 
That's a helpful article you got here. I am trying to sendmessage back from my class. Does the message type only restricted to WM_XXXX type? Can I do a On_MyAppUpdate type of message back to CView Class?
 
Confused | :confused:
GeneralGood tutorial for beginnerseditorBrian Delahunty30 Aug '02 - 7:45 
Nice tutorial for beginners easy to follow.
 
Regards,
Brian Dela Smile | :)
GeneralGood! It's simple but useful.memberlihboy29 Jul '02 - 15:14 
I think I have learned some from your article!It's easy to catch on.Thanks!
GeneralNice TutorialsmemberBrad Harper14 Mar '02 - 11:13 
This Site has some of the best tutorials I have seen...
Keep up the good work...
 
Brad HarperCool | :cool:
GeneralI really love thismembermaoxingliang28 Jan '02 - 1:20 
I'm a college student in china hunan province and major in GIS. i think codeproject.com is my best finding in this
month ,and i will e-mail to my classmate to shareing the
pefect WebSite,
 
maoxingliang a student major in
GIS tech.
GeneralRe: I really love thismemberTheWay2 Nov '02 - 5:12 
Yeah,me too!I am studying in SCUT and thanks for the codeproject providing so helpful material.
GeneralRe: I really love thismemberTheWay2 Nov '02 - 5:19 
Which school are you studying in ?
General3 suggestions.memberAnonymous24 Feb '01 - 20:30 
Very good discussion for newbie.
 
Three suggestions,
 
(1) the article focus on how message was handled. But doesnt address how message was created. ie.
 
1. The user clicks a mouse button.
 
2. The mouse driver puts an item into the system input queue.
 
3. A system thread, which handles user input, retrieves this item and, using
coordinates recorded by the driver, determines to which window this message
should be posted. Mouse messages are always sent to the window under the
cursor (unless another window has captured mouse input).
 
Given the window handle the system detemines the thread to which this window
belongs and posts WM_LBUTTONDOWN and WM_LBUTTONUP messages to the
message queue of this thread. Note, the message is posted to only one message
queue since the system knowns to which thread the window belongs.
 
4. Button window procedure receives WM_LBUTTONUP message and sends
WM_COMMAND/BN_CLICKED notification to the parent window.
 
5. Then the rest of the story...
 
//////////////////////////
(2) Quote:
 
"MFC uses a technique called Message Maps. A Message Map is a table that associates messages with functions. When you receive a message, MFC will go through your Message Map and search for a corresponding Message Handler. I have showed in Part 1 how you add a Message Handler to the Message Map by using ClassWizard, but what really happens code-wise? "
 
What do you mean "MFC will go through the message map"? Do you mean the application object, derived from MFC CWinApp, will search the message at "runtime" for appropriate handler?
 
//////////////////////////
(3) Why not draw a flowchart? A good diagram is better than a thousand words.
Wink | ;)
 
Please let me know if there's an improved version available.
Questionhow to make the "close" button in title bar dim?memberJerry An20 Dec '00 - 21:11 
i know when push this button,the window will receive a WM_CLOSE message,
if i do nothing in my own handler of WM_CLOSE,then this button will not
work,but i think it will be better if we can make this button dim.
 
do u have any trick? thanx in advance!
AnswerRe: how to make the "close" button in title bar dim?membermoliate5 Nov '01 - 1:30 
Perhaps you can use this.
 

CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu)
pSysMenu->EnableMenuItem(SC_CLOSE, MF_GRAYED);

 

GeneralRe: how to make the "close" button in title bar dim?memberziemeq12 Jul '05 - 22:23 
i try this, and
 
(2097) : error C2660: 'GetSystemMenu' : function does not take 1 parameters
 

thx.
GeneralRe: how to make the "close" button in title bar dim?membermoliate13 Jul '05 - 7:32 
It seems like I assumed a member function of the MFC CWnd class in the comment above. If you are using Win32 API you need to provide the HWND parameter yourself.
 
Syntax:
HMENU GetSystemMenu(HWND hWnd, BOOL bRevert);
 
Regards/
# moliate
 

 


The corners of my eyes catch hasty, bloodless motion -
a mouse?
Well, certainly a peripheral of some kind.

Neil Gaiman - Cold Colours


GeneralVery well put !sussMayuresh S Kadu31 Oct '00 - 2:38 
I have been teaching VC++ for about 3 yrs now and am professional developer for same in Pune. I wish to complement u in the lucidity u have maintained in explaining the topic.
 
i had recommend the same to my class and believe me - they share my opinion !
 
keep up the good work !

General!!Superb!!sussT.S. Prasad14 Jun '00 - 20:16 
Dear Experts,
Thanks for A-1 grade lessons. I have a suggestion. Instead of posting two or three articles for beginners in the same newsletter, will it not be better to cover one article for beginners (such as message handling by Windows), one article revealing secrets of, say, Document-View, one on more advanced (such as OLEs/COM). Of course it need not be that only one author writes all the articles. The articles/lessons can e continued in the next issue of the newsletter
GeneralPerfect!sussJonathan Gabai9 Jun '00 - 21:47 
I started as an SDK programmer and I always wondered how MFC message Handling realy works. I was porting some code to MFC but I was stuck When It came to subclassing. This article realy helped m
GeneralExcelent set of articles!sussJames Pinn9 Jun '00 - 20:42 
Exactly what I needed

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

Permalink | Advertise | Privacy | Mobile
Web01 | 2.6.130516.1 | Last Updated 8 Jun 2000
Article Copyright 2000 by Daniel Kopitchinski
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid