Using accelerator keys (atlloadaccelerators) in ATL-based controls

Source: Internet
Author: User

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

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.