Agregar aceleradores (atajos) en MFC - ¿CÓMO?

Encontré este enlace: http://support.microsoft.com/kb/222829

But I can't understand that much.

Ok, I understood I need to add this to my header file:

HACCEL  m_hAccelTable;

y luego esto:

m_hAccelTable = LoadAccelerators(AfxGetInstanceHandle(), MAKEINTRESOURCE(IDR_ACCELERATOR1));

to my main .cpp

Pero, ¿adónde va esto?

BOOL CAboutDlg::PreTranslateMessage(MSG* pMsg) {
   if (m_hAccelTable) {
      if (::TranslateAccelerator(m_hWnd, m_hAccelTable, pMsg)) {
         return(TRUE);
      }
   }
   return CDialog::PreTranslateMessage(pMsg);

}

I need around 6 shortcuts (CTRL + U to load something, CTRL + O to load smth else), I can't understand how this works, need a little bit of help

preguntado el 22 de mayo de 12 a las 13:05

2 Respuestas

Now, MSDN article is misleading. It shows how to add accelerators to About box and only About box will be able to handle accelerator that is in this case equivalent of pressing the button with IDC_BUTTON1 ID.

You need to do something very different allowing all objects in your application to get a chance to handle this message. This is done for you in MDI/SDI apps.

Once you create accelerator table in the resource, you have to add accelerators: Key combination paired Accelerator key combination, when used generates command message with appropriate ID. Once you are done adding, you have to create command message handlers for each of the ID. When accelerator is used the handler is invoked and you can add the code you need. Now do this: Declare HACCEL type variable to your app class. In the InitInstance call LoadAccelerators. Use wizard to insert PreTranslateMessage override in your application class. Add following:

      if (m_hAccelTable) 
      {
                if (::TranslateAccelerator(*m_pMainWnd, m_hAccelTable, pMsg)) 
                {
                          return(TRUE);
                }
      }

This will allow the main dialog to handle accelerators. Note *m_pMainWnd. It is your dialog handle (automatically casted). Now you can add handlers for any accelerator to the dialog or to the application class. You can also route command messages to any window in your application using OnCmdMsg.

My advice for the future. When you decide to make your app a dialog based, consider creating SDI application with CFormView derived class. You can change frame style to not allow resizing and it will look like dialog based but. . . You will have ability to use a toolbar a menu for free and most importantly you will have all accelerator and command routing for free.

contestado el 22 de mayo de 12 a las 23:05

The page you referenced describes adding an accelerator table to a dialog based applicaion.

Are you creating a dialog based application or just a normal MFC frame based application with a menu bar?

If you are doing the former then as the page you referenced suggest you need to override the PreTranslateMessage dialog box method.

If you are doing the later then you only need to call the CFrameWnd::LoadAccelTable función.

contestado el 22 de mayo de 12 a las 17:05

You do not need to add anything to MDI/SDI app created by the wizard. Framework handles all intricasies accelerator and command handling/routing. The MSDN sample does not specify what kind of application is it. It shows how to add accelerators to the About box, instead showing some other sample that would make more sense. - JuanCz

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.