星期二, 四月 24, 2007

The Route of Command Processing

After you have pressed a Button in Windows, how does Windows System process the events, I think, is an amazing part when you learn to code under MFC.

Firstly, you should know three important functions. CWnd::WindowProc, CWnd::OnWndMsg, and CWnd::DefWindowProc. When your Windows system starts, the crucial shell process, explorer.exe, is always running to capture every little change of your computer. When a button is clicked, Windows always sends a WM_COMMAND message to Parent Windows. And CWnd::OnWndMsg function is to define the type of received message. CWnd::WindowProc can process all received message. CWnd::WindowProc calls CWnd::OnWndMsg, and decide whether call CWnd::DefWindowProc depending on the return value of CWnd::OnWndMsg.

LRESULT CWnd:: WinodwProc ( UNIT message, WPARM wParam, LPARAM lParam)
{
LRESULT lResult = 0;
If ( !OnWndMsg (message, wParam, lParam, &lResult))
lResult = DefWindowProc(message, wParam, lParam);
return lResult;
}

Two parameters, wParam and lParam should be noticed. Parameter wParam contains two values, which the lower one is the ID resource of menu, control, and shortcut, and the higher one express the message information (BN_CLICKED expresses a button is clicked). Parameter lParam indicates the window handler of the controller.


When the message is WM_COMMAND, CWnd::OnCommand function is called and its return value is sent to CWnd::WindowProc.

CWnd::OnCommand checks the validity of the message, such as whether the return value is 0, whether the controller has been disabled. After checkout, CWnd::OnCommand sends a message to the controller. Finally, CWnd::OnCommand calls CDialog::OnCmdMsg, and CDialog::OnCmdMsg will call CCmdTarget::OnCmdMsg.

CCmdTarget is a base class of MFC. When a message is sent to a Dialog, a default route appears: firstly the message is sent to Dialog, and then to Dialog window. Finally, it is sent to an application object.

Finally, how to combine the controller and the processing function is a main point to concern. When you open the source file of your Dialog, for example, dlgcore.cpp, and search for BEGIN_MESSAGE_MAP, the following code appears:

BEGIN_MESSAGE_MAP (CDialog, CWnd)
//{{AFX_MSG_MAP(CDialog)
ON_COMMAND(IDOK, OnOK)
ON_COMMAND(IDCANCEL, OnCancel)
ON_MESSAGE(WM_COMMANDHELP, OnCommandHelp)
ON_MESSAGE(WM_HELPHITTEST, OnHelpHitTest)
ON_MESSAGE(WM_INITDIALOG, HandleInitDialog)
ON_MESSAGE(WM_SETFONT, HandleSetFont)
ON_WM_PAINT()
//}} AFX_MSG_MAP
END_MESSAGE_MAP

This is the table of message mapping. You can find the processing function and the ID resource are combined by this way. A virtual function GetMessageMap, which is defined in extended Macro _messageEntries, is used to find a proper function entry from upper table.

This is the basic process of message cycling in MFC.



没有评论: