首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 操作系统 > windows >

windows消息处理(强烈推荐,珍藏)

2012-08-30 
windows消息处理(强烈推荐,收藏)由于看了一下,比较好理解,暂时先放到这里,待有空再翻译。只是在每节后大致

windows消息处理(强烈推荐,收藏)

由于看了一下,比较好理解,暂时先放到这里,待有空再翻译。只是在每节后大致介绍一下讲的内容。

感觉写的比较全,无论从消息的原理还是从MFC操作上来说,值得一看,我也在此做个收藏。

(一)

说明:以下首先对消息进行介绍,然后在消息处理中,使用类向导创建消息循环,这个操作是在vc6.0(或者之下版本)操作的。

Introduction

Perhaps one of the most important means of communication in windows is Messages. The traditional program starts at yourmain() 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 aWM_LBUTTONDOWN message, and it draws the pressed-button. When you let go of the mouse button it receives aWM_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 inWM_CHAR andWM_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 forWM_SIZE is usually calledOnSize.

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, theWM_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 theWM_CTLCOLOR messages expect you to return anHBRUSH.

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 theCWinApp 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:

CWnd *pCalc;BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)afx_msg LRESULT OnMessage(WPARAM wParam, LPARAM lParam);

where OnMessage is the name of your handler function. TheON_MESSAGE macro takes 2 parameters: The address of the handler, and the message it should handle. For example: The following statement MapsWM_GETTEXTLENGTH toOnGetTextLength():

ON_MESSAGE (WM_GETTEXTLENGTH, OnGetTextLength)

OnGetTextLength is prototyped as

afx_msg LRESULT OnGetTextLength(WPARAM wParam, LPARAM lParam);
 
说明:以上部分还是接第一部分的类向导,通过ctrl+w快捷键进入,选择之后,vc6会自动把上文标注的三步骤放到相应的位置,下边自定义的消息(在类向导中没有的消息,自己定义的消息),则可以参考上文的三步骤,在和它们对应的位置添加,注意这个需要定义一个消息宏(下面红色标注),WM_APP现在应该为WM_USER,自定义消息只需要在WM_USER之上加上一个数字,因为一般WM_USER之前的消息,是系统消息(ctrl+w中看到的鼠标点击消息、键盘消息】重绘消息等)。
User-defined messages

Sometimes, you will need to communicate between 2 windows in your application or between 2 windows from different applications. An easy way to do this is by using User-defined messages. The name "User-defined" can be confusing at first; you define a User-defined message and not the user of your program. I have stated in Part 1 that messages are identified by numbers, and that Windows predefines standard messages. The way of using predefined messages is to simply use a number. To make sure that you don't conflict with the system defined messages you should use a number in the range of WM_APP through 0xBFFF:

MSG msg; LRESULT CALLBACK WindowProc(     HWND hwnd, LRESULT CALLBACK WndProc (HWND hwnd, UINT uMsg,                       WPARAM wParam, LPARAM lParam) {     #include <windows.h>HWND hWndCalc;WORD xPos = LOWORD(lParam);  SendMessage(hWndTarget, WM_MOUSEMOVE, fFlags, MAKELPARAM(x,y));
Dialogs

Handling a message in a dialog is very similar to handling a message in a normal window. Windows have Window Procedures, Dialogs have Dialog Procedures. One major difference is that you don't specify a window class for a dialog. When you create a dialog using one of the CreateDialog... functions or theDialogBox... functions, you pass a Dialog Procedure as one of the parameters. A Dialog Procedure is prototyped as:

BOOL CALLBACK DialogProc(    HWND hwndDlg,   
WNDPROC g_OldEdit;

The second step is to create a new Window Procedure for the edit control:

 
LRESULT CALLBACK NewEditProc (HWND hwnd, UINT message,                              WPARAM wParam, LPARAM lParam){          TCHAR chCharCode; 
hwnd hWndEdit = GetDlgItem(hDlg, IDC_EDIT1);<BR>

Using MFC relieves you from having to call the old Message Handlers, since MFC will take care of it for you.
The second step is to add Message Handlers to your new class. If you handle a message and you want the control's message handler to get a shot at it, you should call the base class member function the corresponds with the message. this is the subclassedWM_CHAR handler:

In a non-dialog parent you should add a member variable instance of your control to it, and call one of the twoCWnd Subclassing functions:CWnd::SubclassWindow or CWnd::SubclassDlgItem. Both routines attach aCWnd object to an existing WindowsHWND.SubclassWindow takes theHWND directly, andSubclassDlgItem is a helper that takes a control ID and the parent window (usually a dialog).SubclassDlgItemis designed for attaching C++ objects to dialog controls created from a dialog template.

Further Reading

For a more in depth treatment of MFC subclassing see Chris Maunder's article: "Create your own controls - the art of subclassing".

Reflected Messages - MFC 4.0+

When you subclass a control, besides handling the message it receives, in MFC you can also handle the notifications it sends to it's parent window. This technique is called Message Reflecting. Windows controls often send notifications to their parents, for example, a Button will send a WM_COMMAND message telling it's parent it has been clicked. Usually it is the parent's job to handle these messages, but MFC will also allow you to handle them in the control itself. In ClassWizard these messages appear with an "=" sign before them, indicating they are Reflected Messages. You handle them just like any other message. The macros for these messages are similar to the regular messages, but have_REFLECT added to the end of the macro. For example,ON_NOTIFY() becomesON_NOTIFY_REFLECT().

 

热点排行
Bad Request.