Click here to Skip to main content
15,886,258 members
Articles / Desktop Programming / MFC

Implement Accelerators in a Dialog-Based Application

Rate me:
Please Sign up or sign in to vote.
5.00/5 (1 vote)
4 Jul 2012CPOL2 min read 18.5K   7  
Getting accelerators to work in a dialog box.

One of the options you have when creating an MFC application is to make your application dialog-based. This is one of the options in the MFC Wizards.

Dialog-based applications are simply applications where the main window is a dialog box. Applications that need to display a bunch of controls in the main window are considerably easier to implement as dialog-based applications.

In addition, you can also add a menu to your dialog box, which can complete a sophisticated dialog-based application. A menu can be added by simple choosing the menu resource ID in the Properties window for the dialog box. But if your menu has accelerators (hotkeys), you’ll notice that they don’t work. In this article, I’ll describe getting accelerators to work in a dialog box.

The discussion below assumes you have created a dialog box with a menu, that you’ve also created an accelerator resource with hotkeys for one or more commands in your dialog box menu, and that you’ve defined handlers for those commands.

In your main application class (not the dialog box class), define the following member variable:

C++
HACCEL m_hAccelTable;
Listing 1: Add variable to main application class.

Next, initialize this variable in your main application class’s InitInstance() method. You may want to initialize it after the basic MFC initialization code, but be sure to initialize it before the main dialog box is displayed. Again, this is in your main application class and not in your dialog box class.

C++
BOOL CMyApp::InitInstance()
{
 // ...

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

 // ...
}
Listing 2: Initialize variable in InitInstance().

Note that this code assumes the ID of your accelerator is IDR_ACCELERATOR1. You’ll need to change it if you are using a different resource ID.

Next, override ProcessMessageFilter in your main application class. Again, this is in your main application class and not in your dialog box class.

C++
BOOL CMyApp::ProcessMessageFilter(int code, LPMSG lpMsg)
{
 if (code >= 0 && m_pMainWnd && m_hAccelTable)
   {
   if (::TranslateAccelerator(m_pMainWnd->m_hWnd, m_hAccelTable, lpMsg))
      return TRUE;
  }
  return CWinApp::ProcessMessageFilter(code, lpMsg);
}
Listing 3: Override ProcessMessageFilter().

And that’s all there is to it. Assuming you have the menu and accelerator resources implemented and associated with your dialog box, and you have handlers for the commands, the accelerators should now work.

I’m not sure why this change is even necessary and couldn’t easily find out. At first glance, it sure seems like this trivial amount of code should be implemented in the base MFC classes. But this approach is simple, and should work for any dialog box in your application (that includes a menu and accelerator resource).

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



Comments and Discussions

 
-- There are no messages in this forum --