Control basic condition
Control itself + CMainFrame + View
All control messages are forwarded to CMainFrame for processing
Begin_msg_map (Ciecschart)//chain_msg_map (ccomcontrol<ciecschart>) message_handler (MSG_SELECTION_CHANGED, MessageHandler) Chain_msg_map (_base) {MSG msg = {hWnd, umsg, WParam, LParam};if (! CMainFrame::P retranslatemessage (&msg)) {Chain_msg_map (CMainFrame)}}default_reflection_handler () End_msg_map ( )
and look at the part that handles the accelerator key.
<pre name= "code" class= "CPP" >
STDMETHOD (TranslateAccelerator) (lpmsg pMsg) {/*haccel haccel;haccel = atlloadaccelerators (Makeintresource (IDR_ Iecschart)), if (wm_keyfirst<=pmsg->message && pmsg->message <= wm_keylast) {if (Haccel &&: : TranslateAccelerator (m_hwnd,haccel,pmsg)) return TRUE; */return CMainFrame::P retranslatemessage (PMSG)? S_ok:s_false;}
BOOL CMainFrame::P retranslatemessage (msg* pMsg) {/*if (Pmsg->wparam = vk_delete) {if (M_haccel! = NULL &&:: TranslateAccelerator (M_hwnd, M_haccel, PMSG)) return TRUE; */if (_base::P retranslatemessage (PMSG)) return true;if (Mapview.pretranslatemessage (PMSG)) return true;//allow Typical message Processingreturn FALSE;}
After the actual test, the Vk_delete message can be received in the CMainFrame::P Retranslatemessage, but the converted command message is not received.
Look at one more function:
TranslateAcceleratorTranslateAccelerator, function function: Translationaccelerator keystable. The function handles the menu command in theaccelerator keys. This function translates a wm_keydown or wm_syskeydown message into a WM_COMMAND or wm_syscommand message (if a givenaccelerator keysThe entry for the key is in the table, and then the WM_COMMAND or Wm_syscommand message is sent directly to the appropriate window process.
Combining the above analysis should be a failure to turn the message into command.
Conversion requires a conversion table, in fact, is defined in the Resource Accelerator key table, can be processed in the following ways:
Haccel haccel;haccel = atlloadaccelerators (Makeintresource (Idr_iecschart)); if (wm_keyfirst<=pmsg->message && pmsg->message <= wm_keylast) {if (Haccel &&:: TranslateAccelerator (M_HWND,HACCEL,PMSG)) return TRUE;}
But in ATL/WTL-based applications, we all know that there is no need for such explicit loading, so what is the difference?
Let's take a look at a function in atlframe.h
HWND CreateEx (HWND hwndparent = NULL, atl::_u_rect RECT = null, DWORD dwstyle = 0, dword dwexstyle = 0, lpvoid lpcreatepar AM = NULL) {Const int cchname = 256; TCHAR szwindowname[cchname];szwindowname[0] = 0; #ifndef _win32_wce::loadstring (Modulehelper::getresourceinstance () , T::getwndclassinfo (). M_ucommonresourceid, Szwindowname, cchname); HMENU HMENU =:: LoadMenu (Modulehelper::getresourceinstance (), Makeintresource (T::getwndclassinfo (). m_ Ucommonresourceid)); #else//CE specific::loadstring (Modulehelper::getresourceinstance (), T::getwndclassinfo (). m_ Ucommonresourceid, Szwindowname, cchname);//This all needs to is NULL for Windows ce.//Frame Window menus has to go onto the commandbar.//use createsimplececommandbarhmenu hMenu = NULL; #endif//_win32_wcet* PT = static_cast<t*> (th IS); HWND hwnd = Pt->create (hwndparent, rect, Szwindowname, Dwstyle, dwExStyle, HMenu, Lpcreateparam); if (hWnd! = NULL) M_hac CEL =:: Loadaccelerators (Modulehelper::getresourceinstance (), Makeintresource (T:: GetWndClassInfo (). M_ucommonresourceid)); return hWnd;}
Notice the last call to Loadaccelerators, so why is it not called in the control?
This is actually called by the application of the method, and then CMainFrame OnCreate is called when the window has been created, but not in the same way in the application, that is, in the control CreateEx not called, that is, M_haccel is actually empty, Then of course the translateaccelerator can't turn.
Solution Solutions
After the analysis is clear, actually is to call the Atlloadaccelerators, the m_haccel initializes the line, of course, the most appropriate place is the OnCreate function:
LRESULT cmainframe::oncreate (UINT/*umsg*/, WPARAM/*wparam*/, LPARAM/*lparam*/, bool&/*bhandled*/) {if (m_hwnd! = NULL) {//m_haccel =:: Loadaccelerators (Modulehelper::getresourceinstance (), Makeintresource (:: GetWndClassInfo (). m_ Ucommonresourceid)); m_haccel = Atlloadaccelerators (Makeintresource (Idr_iecschart));} M_hwndclient = mapview.create (*this, NULL, NULL, WS_CHILD | Ws_visible, Ws_ex_staticedge); PostMessage (msg_postcreate); return 0;}
Other Matters
After the conversion, is the original message discarded?
After testing, the original message was not discarded, that is, in CMainFrame::P Retranslatemessage can receive two messages: one is the original Vk_delete message, the other is the converted Command
Using accelerator keys (atlloadaccelerators) in ATL-based controls