Original URL: http://blog.csdn.net/hyhnoproblem/article/details/6182646
This example explains the delivery process for a generic window message by adding a Wm_lbuttonclick message handler function to the view of a single document program. Based on vs 2005
[CPP]View Plaincopy
- Begin_message_map (CMyView, CView)
- ON_WM_LBUTTONDBLCLK ()
- End_message_map ()
- ON_WM_LBUTTONDBLCLK macro Expansion
- #define ON_WM_LBUTTONDBLCLK ()/
- {wm_lbuttondblclk, 0, 0, 0, AFXSIG_VWP,/
- (afx_pmsg) (AFX_PMSGW)/
- (static_cast< void (afx_msg_call CWnd::*) (UINT, CPoint) > (&thisclass:: ONLBUTTONDBLCLK))},
As you can see from the code above, the type label for the Wm_lbuttonclick message is AFXSIG_VWP and there is an enumeration type Afxsig in Afxmsg_.h, and the message label is used primarily to differentiate the type of the message handler function. The value of AFXSIG_VWP is defined in this type:
[CPP]View Plaincopy
- Enum Afxsig
- {
- //...
- AFXSIG_VWP = afxsig_v_w_p
- //...
- }
In AfxWndProc, the handle in the message is mapped to a window class pointer, which points to cmyview. AfxWndProc Call Afxcallwndproc,afxcallwndproc call Cwnd::windowproc,cwnd::windowproc call Cwnd::onwndmsg,cwnd::o Nwndmsg completes the processing of the message.
[CPP]View Plaincopy
- Wincore.cpp 1746
- BOOL cwnd::onwndmsg (UINT message, WPARAM WPARAM, LPARAM LPARAM, lresult* pResult)
- {
- // ...
- //Getmessagemap is a virtual function because the current pointer is pointing to CMyView, so the CMyView message map is taken
- const afx_msgmap* pmessagemap; pmessagemap = Getmessagemap ();
- UINT ihash; ihash = (LoWord ((dword_ptr) pmessagemap) ^ message) & (IHASHMAX-1);
- Winmsglock.lock (Crit_winmsgcache);
- //Global message hash cache, lookup cache
- Afx_msg_cache* Pmsgcache; Pmsgcache = &_afxMsgCache[iHash];
- Const afx_msgmap_entry* Lpentry;
- if (message = = Pmsgcache->nmsg && Pmessagemap = = Pmsgcache->pmessagemap)
- {
- //Cache hit
- Lpentry = pmsgcache->lpentry;
- Winmsglock.unlock ();
- if (lpentry = = NULL)
- return FALSE;
- //cache hit, and it needs to be handled
- if (Message < 0xc000)
- Goto Ldispatch; //System messages?
- Else
- Goto ldispatchregistered; //Registered message?
- }
- Else
- {
- //Not in the cache, look for it
- pmsgcache->nmsg = message;
- Pmsgcache->pmessagemap = Pmessagemap;
- For (/* Pmessagemap already init ' ed */; Pmessagemap->pfngetbasemap! = NULL;
- Pmessagemap = (*pmessagemap->pfngetbasemap) ())
- {
- //Note:catch common but fatal mistake!!
- //Begin_message_map (Cmywnd, Cmywnd)
- ASSERT (Pmessagemap! = (*pmessagemap->pfngetbasemap));
- if (Message < 0xc000)
- {
- //Constant window message
- if (lpentry = Afxfindmessageentry (pmessagemap->lpentries,
- Message, 0, 0))! = NULL)
- {
- Pmsgcache->lpentry = Lpentry;
- Winmsglock.unlock ();
- Goto Ldispatch;
- }
- }
- Else
- {
- //Registered Windows message
- Lpentry = pmessagemap->lpentries;
- While ((Lpentry = Afxfindmessageentry (lpentry, 0xc000, 0, 0)) = NULL)
- {
- uint* Pnid = (uint*) (LPENTRY->NSIG);
- ASSERT (*pnid >= 0xc000 | | *pnid = = 0);
- //Must be successfully registered
- if (*pnid = = message)
- {
- Pmsgcache->lpentry = Lpentry;
- Winmsglock.unlock ();
- Goto ldispatchregistered;
- }
- lpentry++; //Keep looking past this one
- }
- }
- }
- Pmsgcache->lpentry = NULL;
- Winmsglock.unlock ();
- return FALSE;
- }
- // ...
- Ldispatch:
- MMF.PFN = lpentry->pfn;
- switch (LPENTRY->NSIG)
- {
- //...
- Case afxsig_v_u_p: //Message label
- {
- CPoint Point (LParam);
- (this->*mmf.pfn_v_u_p) (static_cast<uint> (WParam), point);
- }
- Break ;
- //...
- }
- //...
- Ldispatchregistered: //For registered Windows messages
- ASSERT (Message >= 0xc000);
- ASSERT (sizeof (MMF) = = sizeof (MMF.PFN));
- MMF.PFN = lpentry->pfn;
- LResult = (this->*mmf.pfn_l_w_l) (WParam, LParam);
- }
- Message-handling function type Enumeration
- Union messagemapfunctions
- {
- Afx_pmsg PFN; //generic member function pointer
- // ...
- LRESULT (afx_msg_call CWnd::* pfn_l_w_l) (WPARAM, LPARAM);
- };
"Go" Windows message Delivery Process: General window message Delivery (Wm_lbuttonclick)