MFC Windows 程序设计->键盘加速键
来源:互联网 发布:php key 编辑:程序博客网 时间:2024/05/01 04:39
As you design your application's menus, you have the option of using keyboard accelerators to assign shortcut keys to any or all of the menu items. An accelerator produces a WM_COMMAND message just as making a menu selection does. Adding keyboard accelerators to your application is simplicity itself. You create an accelerator table resource—a special resource that correlates menu item IDs to keys or combinations of keys—and load the resource into your program with a function call. If the application's main window is a frame window, Windows and the framework do the rest, automatically trapping presses of accelerator keys and notifying your application with WM_COMMAND messages.
An accelerator table resource is defined by an ACCELERATORS block in an RC file. Here is the general format:
ResourceID ACCELERATORSBEGIN END
ResourceID is the accelerator table's resource ID. The statements between BEGIN and END identify the accelerator keys and the corresponding menu item IDs. The MFC AppWizard generates accelerator tables using the following format:
IDR_MAINFRAME ACCELERATORS PRELOAD MOVEABLEBEGIN "N", ID_FILE_NEW, VIRTKEY,CONTROL "O", ID_FILE_OPEN, VIRTKEY,CONTROL "S", ID_FILE_SAVE, VIRTKEY,CONTROL "Z", ID_EDIT_UNDO, VIRTKEY,CONTROL "X", ID_EDIT_CUT, VIRTKEY,CONTROL "C", ID_EDIT_COPY, VIRTKEY,CONTROL "V", ID_EDIT_PASTE, VIRTKEY,CONTROL VK_BACK, ID_EDIT_UNDO, VIRTKEY,ALT VK_DELETE, ID_EDIT_CUT, VIRTKEY,SHIFT VK_INSERT, ID_EDIT_COPY, VIRTKEY,CONTROL VK_INSERT, ID_EDIT_PASTE, VIRTKEY,SHIFTEND
In this example, IDR_MAINFRAME is the accelerator table's resource ID. PRELOAD and MOVEABLE are load options that, like the equivalent keywords in MENU statements, have no effect in the Win32 environment. Each line in the table defines one accelerator. The first entry in each line defines the accelerator key, and the second identifies the corresponding menu item. The VIRTKEY keyword tells the resource compiler that the first entry is a virtual key code, and the keyword following it—CONTROL, ALT, or SHIFT—identifies an optional modifier key. In this example, Ctrl-N is an accelerator for File-New, Ctrl-O is an accelerator for File-Open, and so on. The Edit menu's Undo, Cut, Copy, and Paste functions each have two accelerators defined: Ctrl-Z and Alt-Backspace for Undo, Ctrl-X and Shift-Del for Cut, Ctrl-C and Ctrl-Ins for Copy, and Ctrl-V and Shift-Ins for Paste.
Like menus, keyboard accelerators must be loaded and attached to a window before they'll do anything. For a frame window, LoadAccelTable does the loading and attaching in one step:
LoadFrame also does the job nicely. In fact, the same function call that loads the menu also loads the accelerator table if the two resources share the same ID:
For accelerators to work, the message loop must include a call to the API function ::TranslateAccelerator, as shown here:
MFC's CFrameWnd class handles this part for you. Specifically, it overrides the virtual PreTranslateMessage function that it inherits from CWnd and calls ::TranslateAccelerator if it sees an accelerator table has been loaded—that is, if the frame window's m_hAccelTable data member contains a non-NULL accelerator table handle. Not surprisingly, LoadAccelTable loads an accelerator resource and copies the handle to m_hAccelTable. LoadFrame does the same by calling LoadAccelTable.
Accelerators must be handled differently when loaded for nonframe windows that lack the accelerator support in CFrameWnd. Suppose you derive a custom window class from CWnd and want to use accelerators, too. Here's how you'd go about it:
- Add an m_hAccelTable data member (type HACCEL) to the derived class.
- Early in your application's lifetime, use the API function ::LoadAccelerators to load the accelerator table. Copy the handle returned by ::LoadAccelerators to m_hAccelTable.
- In the window class, override PreTranslateMessage and call ::TranslateAccelerator with the handle stored in m_hAccelTable. Use the value returned by ::TranslateAccelerator as the return value for PreTranslateMessage so that the message won't be translated and dispatched if ::TranslateAccelerator has dispatched it already.
Here's how it looks in code:
With this framework in place, a CWnd-type window will use accelerators just as a frame window does. Note that accelerators loaded with ::LoadAccelerators (or LoadAccelTable) don't need to be deleted before termination because Windows deletes them automatically.
Using accelerators to provide shortcuts for commonly used menu commands is preferable to processing keystroke messages manually for two reasons. The first is that accelerators simplify the programming logic. Why write WM_KEYDOWN and WM_CHAR handlers if you don't have to? The second is that if your application's window contains child windows and a child window has the input focus, keyboard messages will go to the child window instead of the main window. (Child windows are discussed in Chapter 7.) As you learned in Chapter 3, keyboard messages always go to the window with the input focus. But when an accelerator is pressed, Windows makes sure the resulting WM_COMMAND message goes to the main window even if one of its children has the input focus.
Accelerators are so useful for trapping keystrokes that they're sometimes used apart from menus. If you want to be notified any time the Ctrl-Shift-F12 combination is pressed, for example, simply create an accelerator for that key combination with a statement like this one:
VK_F12, ID_CTRL_SHIFT_F12, VIRTKEY, CONTROL, SHIFT
Then map the accelerator to a class member function by adding an
ON_COMMAND (ID_CTRL_SHIFT_F12, OnCtrlShiftF12)
entry to the message map. Presses of Ctrl-Shift-F12 will thereafter activate OnCtrlShiftF12, even if no menu item is assigned the ID ID_CTRL_SHIFT_F12.
- MFC Windows 程序设计->键盘加速键
- MFC Windows 程序设计 第三章 鼠标与键盘
- MFC Windows程序设计学习笔记--鼠标和键盘
- Windows程序设计 键盘
- 《Windows程序设计》之键盘
- Windows程序设计---键盘
- Windows程序设计-键盘
- 10.3 键盘加速键
- 《MFC Windows 程序设计》
- mfc windows 程序设计
- MFC Windows 程序设计(1)
- MFC Windows 程序设计(2)
- MFC Windows 程序设计(3)
- MFC Windows 程序设计(4)
- MFC Windows 程序设计(5)
- MFC Windows 程序设计(6)
- MFC Windows 程序设计(7)
- MFC Windows程序设计读书笔记
- 2011-04-02
- 安装vim 以及Vim介绍比较
- windows消息处理过程---消息pump
- Android学习笔记(二一):有趣的widget-日期和时间
- oralce函数大全
- MFC Windows 程序设计->键盘加速键
- gtk 的第一个实例
- eclispe 流行插件
- 2011微软实习生计划启动
- java基础知识记录--集合 (摘自张孝祥整理java面试题)
- VC6.0 如果重新获取函数原形提示?
- Only 64-bit build environments are supported beyond froyo/2.2
- printk的几个优先级
- printk的几个优先级