Sunteți pe pagina 1din 4

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 WinMainRunprovides 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:
Collapse | Copy Code

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:
Collapse | Copy Code

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:
Collapse | Copy Code

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:
Collapse | Copy Code

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, Lets 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".
Collapse | Copy Code

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. }

S-ar putea să vă placă și