Dal's Programming Course - Lesson 09

Accelerators

What is an "accelerator"? Under Windows, an accelerator is a special command that is invoked by a keystroke. That is, a particular keystroke "accelerates" control over your program. Typically, menu commands are all assigned a one or more keystrokes that accomplish the same function as selecting the menu item with a mouse click.

Windows has a built-in system for providing and managing Accelerators. First, you can create an Accelerator table, which holds the information for assigning a given keystroke to a menu command. Second, Window provides functions that will search the table, and if a keystroke-command combination is found, Windows will issue a WM_COMMAND message in place of the original message.

Materials for this Lesson: Download.
Homework

Item

Time

Description

1 5 Mins Start by creating an Accelerator resource. Name it IDR_MAIN_ACCELERATORS. Put two Accelerators in it: "F6" and "F7". Associate "F6" with ID_RED, and "F7" with ID_BLUE.
2 10 Mins Read about the following Windows functions:
  • TranslateAccelerator()
  • LoadAccelerator()
  • 3 20 Mins To use the Accelerators that you just created, you will have to call TranslateAccelerator(). TranslateAccelerator() will need access to all messages, just in case any of the incoming messages contain keystrokes that need to be translated into WM_COMMAND messages. Of course, before you call TranslateAccelerator() you will need to have a handle to an accelerator table, which is obtained by calling LoadAccelerator(). Where in your program do you think all this should be done? Try coding up a solution now.
    4 10 Mins If you got it all working before this point, congratulations. However, here are some hints if you need more help: Put all the new code in MainApp.cpp. Call LoadAccelerator() before your main message loop to get a handle to an accelerator table. LoadAccelerator() will need access to the resource symbol "IDR_MAIN_ACCELERATORS", so include "resource.h" in MainApp.cpp. Call TranslateAccelerator() in your message loop before TranslateMessage() and DispatchMessage(). If TranslateAccelerator() is successful, then you don't need to call TranslateMessage() and DispatchMessage() because TranslateAccelerator() already dispatched the message. So your loop will need some additional logic.
    5 20 Mins Test your program. You should be able to press F6 and F7 and change the color of the background in your windows. F6 and F7 should work on which ever window has the focus, and these keys should work for both windows. If this isn't what is happening, then revisit your call to TranslateAccelerator(). How are you getting the correct window handle for the first argument? Also, make sure that GetMessage() is retrieving all the messages to your application, and not just messages for a specific window. Final hint: the window that a message belongs to is one of the members of the message structure.
    6 5 Mins After everything works, you should revisit your menu resource, and edit it so that the accelerator keys are named in the menu itself. That is, change "Red Background" to "Red Background F6". Do the similar thing for blue. Note that you can put tabs in the menu caption with the "\t" sequence, such as "Red Background\tF6".