转至繁体中文版     | 网站首页 | 图文教程 | 资源下载 | 站长博客 | 图片素材 | 武汉seo | 武汉网站优化 | 
最新公告:     敏韬网|教学资源学习资料永久免费分享站!  [mintao  2008年9月2日]        
您现在的位置: 学习笔记 >> 图文教程 >> 软件开发 >> VB.NET程序 >> 正文
Menu Basics         ★★★★

Menu Basics

作者:闵涛 文章来源:闵涛的学习笔记 点击数:2636 更新时间:2009/4/23 18:58:10
lleted.

Just how useful is MFC''''s command-update mechanism? Later in this chapter, we''''ll develop a sample program that uses two identical Color menus—one that''''s invoked from a top-level menu and another that''''s invoked from a right-click context menu. The same command and update handler will serve both menus, and no matter how a color is selected, both menus will be updated to match—with one line of code no less. It''''s hard to imagine how updating menu items could be any easier.

Keyboard Accelerators

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 ACCELERATORS
BEGIN
  
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 MOVEABLE
BEGIN
    "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,SHIFT
END

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:

LoadAccelTable (MAKEINTRESOURCE (IDR_MAINFRAME));

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:

LoadFrame (IDR_MAINFRAME, WS_OVERLAPPEDWINDOW, NULL, NULL);

For accelerators to work, the message loop must include a call to the API function ::TranslateAccelerator, as shown here:

while (GetMessage (&msg, NULL, 0, 0)) {
    if (!TranslateAccelerator (hwnd, hAccel, &msg)) {
        TranslateMessage (&msg);
        DispatchMessage (&msg);
    }
}

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:

  1. Add an m_hAccelTable data member (type HACCEL) to the derived class.

  2. 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.

  3. 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:

// In CMainWindow''''s constructor
m_hAccelTable = ::LoadAccelerators (AfxGetInstanceHandle (),
    MAKEINTRESOURCE (IDR_ACCELERATORS));

// PreTranslateMessage override
BOOL CMainWindow::PreTranslateMessage (MSG* pMsg)
{
    if (CWnd::PreTranslateMessage (pMsg))
        return TRUE;
    return ((m_hAccelTable != NULL) &&
        ::TranslateAccelerator (m_hWnd, m_hAccelTable, pMsg));
}

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.

上一页  [1] [2] [3] [4] 


[常用软件][设计]Flashation Menu Builder 菜单软件教学  [Delphi程序]Create a menu item into the Delphi menu
[VB.NET程序]WAP Basics  [VB.NET程序]Event-Handling Basics
[VB.NET程序]Internet Basics  [Web开发]利用JavaScript和CSS制作浮动menu
[MySql]linux下的c 编程------控制台下的menu  
教程录入:mintao    责任编辑:mintao 
  • 上一篇教程:

  • 下一篇教程:
  • 【字体: 】【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
      注:本站部分文章源于互联网,版权归原作者所有!如有侵权,请原作者与本站联系,本站将立即删除! 本站文章除特别注明外均可转载,但需注明出处! [MinTao学以致用网]
      网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!)

    同类栏目
    · C语言系列  · VB.NET程序
    · JAVA开发  · Delphi程序
    · 脚本语言
    更多内容
    热门推荐 更多内容
  • 没有教程
  • 赞助链接
    更多内容
    闵涛博文 更多关于武汉SEO的内容
    500 - 内部服务器错误。

    500 - 内部服务器错误。

    您查找的资源存在问题,因而无法显示。

    | 设为首页 |加入收藏 | 联系站长 | 友情链接 | 版权申明 | 广告服务
    MinTao学以致用网

    Copyright @ 2007-2012 敏韬网(敏而好学,文韬武略--MinTao.Net)(学习笔记) Inc All Rights Reserved.
    闵涛 投放广告、内容合作请Q我! E_mail:admin@mintao.net(欢迎提供学习资源)

    站长:MinTao ICP备案号:鄂ICP备11006601号-18

    闵涛站盟:医药大全-武穴网A打造BCD……
    咸宁网络警察报警平台