Resources in the windows menu programming applications ----

Application resources in Windows programming

Resources

Accelerator, bitmaps, cursors, dialog boxes, menus, strings, tools

1. Create a menu

Menu consists of the following components:
(1) Main Window menu bar
(2) pull-down menu box
(3) hot key menu item identifier
(4) identifying the menu item accelerator key
(5) separate line menu item

1) Custom Menu

menuID MENU [,载入特性选项]
{
    菜单项列表
}

menulD: menulD a menu resource name, to identify the specific menu, the application loads the specified resource name menu by menu, which can be a string or an integer between 1 to 6535 any.
MENU key: to identify with the nature of the resource.
Loading Characteristics Option: to identify the menu has the load characteristics

DISCARDABLE
当不再需要菜单时可丢弃
FIXED
将菜单保存在内存中的固定位置
LOADONCALL
需要时加载菜单
MOVEABLE
底单在内存中可移动
PRELOAI
立即加载菜单

Menu item: Menu items are part of the menu. Applications using the keyword MENUITEM and POPUP menu items defined in the resource description file.

①POPUP statement
POPUP statement defines the pop-up menu in the form of:
POPUP "菜单项名" [,选项];
The programmer can also join symbol in the menu item name "&" to define hot keys for the menu item. Pop-defined, for example
in the form of the "Edit" menu item as follows:
POPUP"编辑(&E)";
This menu item using the Alt十Ekey as the hot key.
POPUP defined popup menu item may further comprise a submenu.

②MENUITEM statement
MENUITEM statement defines a menu item in the form of:
MENUITEM "菜单项名" 菜单项标识(ID)[,选项]

Menu item ID is identification, including identification of the selected menu in the word parameter wParam WM_COMMAND message. Identifier must be unique for each menu item, identification values ​​are usually defined in the header file.

Build windows desktop applications, the menu item identifier defined in Resource.h, as in VS2019:

#define    IDM_NEW          10
#define    IDM_OPEN         11
#define    IDM_CLOSE        12
#define    IDM_SAVE     13
#define    IDM_SAVEAS       14
#define    IDM_EXIT         15
...

Then in the resource file 项目名.rcin the Edit menu style, as can directly open the .rc file, add graphical menu option, you can use Notepad to open the .rc file, add something like the following:

IDC_RESOURCESTUDY MENU
BEGIN
    POPUP "文件(&F)"
    BEGIN
        MENUITEM "打开文件...",                     ID_32771
        MENUITEM "关闭文件...",                     ID_32773
        MENUITEM SEPARATOR
        MENUITEM "创建统计计算菜单项(&P)\t Ctrl+P",      IDM_ADDMENU
        MENUITEM "删除统计计算菜单项(&D)\t Ctrl+D",      IDM_DELMENU
        MENUITEM SEPARATOR
        MENUITEM "退出(&X)",                      IDM_EXIT
    END
    POPUP "帮助(&H)"
    BEGIN
        MENUITEM "关于(&A) ...",                  IDM_ABOUT
    END
END

2, load the menu resource

Load the menu in the window class

WNDCLASS  wndclass;
… 
wndclass.lpszMenuName=lpszMenuName;

When you create a window to load menu

HWND hwnd;HMENU hmenu;
        …
hmenu=LoadMenu(hlnstance, "My_menu");
    hwnd=CreateWindow(  …,hmenu, …); 

Dynamic loading menu

hmenu2=LoadMenu(hlnstance, "Menu2");
SetMenu(hwnd,hmenu2);
…

3, the operation menu items

1) prohibit or activate the menu item

When you create an application menu, the options menu item is set in the resource description file to specify the menu item
initially disabled or enabled, or call the function EnableMenuItem change its initial state. The prototype of this function is:
BOOL EnableMenultem(HMENU hmenu, UINT wIDEnableItem, UINT dwEnable)

Wherein: wIDEnableItem is prohibited or activated menu item identifier, in accordance with the value dwEnable possible values ​​for the menu item ID may also be the location for the menu item in the menu; dwEnable operation menu item identifier

dwEnable参数的操作标识:
MF_BYCOMMAND        表明以ID值标识菜单项
MF_BYPOSITION       表明以位置标识菜单项
MF_DISABLED         禁止菜单项
MF_ENABLED          激活菜单项
MF_GRAYED           禁止菜单项并使其变灰显示

For example, block pop-up menu "File" in the "open" form of the following items:
EnableMenuItem(hmenu, IDM_OPEN, MF_BYCOMMAND | MF_DISABLED) ;

2) Set or uncheck the mark

Displays a check mark next to the menu, such as "√"

DWORD CheckMenuItem(
    HMENU hmenu,
    UNIT wIDCheckItem,  //wIDCheckItem为设置或取消选中标志的菜单项标识
    UNIT dwCheck    //dwCheck为操作标识,MF_CHECKED 添加选中标志;MF_UNCHECKED 删除选中标志
)

3) add a menu item

Programmers may be increased by the application menu items dynamically in two forms:
(1) increase at the end of the menu item of the menu
application may call a function in the menu items increase AppendMenu tail menu, the function prototype is:

BOOL AppendMenu(
    HMENU hmenu,
    UINT dwFlags,
    //新加入的菜单项类型标识或其他信息
    UINT dwIDNewItem,// 新加入菜单项的标识
    LPCTSTR lpNewItem // 新加入的菜单项内容,取决于dwFlags参数
)

For example at the end of the pop-up menu "File" in the form of an increase in "on" are as follows:
AppendMenu(hmenu, MF_ENABLED, IDM_ABOUT, "关于(&A)");

(2) insert menu item in the menu
application may call a function InsertMenu insert a new menu item in the menu, the function prototype is:

BOOL InsertMenu
(
HMENU hmenu,
//菜单句柄
UINT wPosition,
//指定新菜单项插入的位置
UINT dwFlag,
//新加入的菜单项的信息及对wPosition的解释
UINT dwIDNweItem,
//新加入的菜单项的标识
LPCTSTR lpNewItem
//新插入的菜单项的内容
)

For example, in the pop-up menu "File" and "Exit" (which is identified as IDM_EXIT) before adding the new item menu item "Print" (which is identified as IDM_ PRINT) statement as follows:
InsertMenu (hmenu, IDM_EXIT, MF_BYCOMMAND |MF_ENABLED, IDM_PRINT,"打印(&P)");

4) delete menu items

Applications can call the function DeleteMenu delete menu items, the prototype of the function is:

BOOL DeleteMenu
(
HMENU hmenu,
UINT wPosition,
//指定要删除的菜单项的位置
UINT dwFlag
//对wPosition的解释
)

For wPosition, which is interpreted by the parameter dwFlag meaning, if dwFlag is MF_BYCOMMAND, the parameter values for the menu item ID; if dwFlag is MF_BIYPOSITION, the parameter for the location of the menu item number.
For example, remove the pop-up "File" menu in the "Save As" in the form of entry is as follows:
DeleteMenu(hmenu, IDM_SAVEAS, MF_BYCOMMAND)
It is noteworthy that, if the menu item containing the pop-up menu, then remove the pop-up menu when the menu item is also deleted.

5) modify menu items

Applications can call the function ModifyMenu modify a menu item, the function prototype is:

BOOL ModifyMenu(
    HMENU hmenu,
    UINT wPosition,             //指定需修改的菜单项位置
    UINT dwFlag,
    UINT dw IDNweItem,          //-般为修改后菜单项的标识
    LPCTSTR lpNewItem           //-般为修改后的菜单项名
)

For wPosition, if dwFlag is MF_BYCOMMAND, the parameter values for the menu item ID; if dwFlag is MF_BYPOSITION, the parameter for the location of the menu item number.

Such as modifying the pop-up menu "File" in the "Open" item to "load" the statement items are as follows
ModifyMenu(hmenu, IDM_OPEN, MF_BYCOMMAND, IDM_LOAD,"加载(&L)");

4, dynamically created menus

Dynamically created menus can save more system resources dynamically create a menu in two steps in the application:
(1) call to create an empty CreateMenu pop-up menus, function prototype CreateMenu follows:
HMENU CreateMenu(void)
(2) call in AppendMenu or InsertMenu the menu to the menu item.
For example, to create a dynamic pop-up menu in the application's Window menu "Edit" is as follows:

HMENU hmenu, hPopupmenu;        //主窗口菜单句柄和新创建的菜单句柄
AppendMenu(lmenu, MF_POPUP ,(UINT)hmenuPopup, "编辑(&E)");    //将弹出式菜单“编辑”加人到菜单中

5, an example

// resource_study.cpp : 定义应用程序的入口点。
//

#include "framework.h"
#include "resource_study.h"
#include "windows.h"                      

#define MAX_LOADSTRING 100

// 全局变量:
HMENU hmenu, haddmenu; //定义菜单句柄
HINSTANCE hInst;                                // 当前实例
WCHAR szTitle[MAX_LOADSTRING];                  // 标题栏文本
WCHAR szWindowClass[MAX_LOADSTRING];            // 主窗口类名

// 此代码模块中包含的函数的前向声明:
ATOM                MyRegisterClass(HINSTANCE hInstance);
BOOL                InitInstance(HINSTANCE, int);
LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK    About(HWND, UINT, WPARAM, LPARAM);

int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
                     _In_opt_ HINSTANCE hPrevInstance,
                     _In_ LPWSTR    lpCmdLine,
                     _In_ int       nCmdShow)
{
    UNREFERENCED_PARAMETER(hPrevInstance);
    UNREFERENCED_PARAMETER(lpCmdLine);

    // TODO: 在此处放置代码。

    // 初始化全局字符串
    LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
    LoadStringW(hInstance, IDC_RESOURCESTUDY, szWindowClass, MAX_LOADSTRING);
    MyRegisterClass(hInstance);

    // 执行应用程序初始化:
    if (!InitInstance (hInstance, nCmdShow))
    {
        return FALSE;
    }

    HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_RESOURCESTUDY));

    MSG msg;

    // 主消息循环:
    while (GetMessage(&msg, nullptr, 0, 0))
    {
        if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }

    return (int) msg.wParam;
}



//
//  函数: MyRegisterClass()
//
//  目标: 注册窗口类。
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
    WNDCLASSEXW wcex;

    wcex.cbSize = sizeof(WNDCLASSEX);

    wcex.style          = CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc    = WndProc;
    wcex.cbClsExtra     = 0;
    wcex.cbWndExtra     = 0;
    wcex.hInstance      = hInstance;
    wcex.hIcon          = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_RESOURCESTUDY));
    wcex.hCursor        = LoadCursor(nullptr, IDC_ARROW);
    wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1);
    wcex.lpszMenuName   = MAKEINTRESOURCEW(IDC_RESOURCESTUDY);
    wcex.lpszClassName  = szWindowClass;
    wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

    return RegisterClassExW(&wcex);
}

//
//   函数: InitInstance(HINSTANCE, int)
//
//   目标: 保存实例句柄并创建主窗口
//
//   注释:
//
//        在此函数中,我们在全局变量中保存实例句柄并
//        创建和显示主程序窗口。
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
   hInst = hInstance; // 将实例句柄存储在全局变量中

   HWND hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr);

   if (!hWnd)
   {
      return FALSE;
   }

   ShowWindow(hWnd, nCmdShow);
   UpdateWindow(hWnd);

   return TRUE;
}

//
//  函数: WndProc(HWND, UINT, WPARAM, LPARAM)
//
//  目标: 处理主窗口的消息。
//
//  WM_COMMAND  - 处理应用程序菜单
//  WM_PAINT    - 绘制主窗口
//  WM_DESTROY  - 发送退出消息并返回
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_COMMAND:
        {
            int wmId = LOWORD(wParam);
            // 分析菜单选择:
            switch (wmId)
            {
            case IDM_ADDMENU:       //在主菜单中添加弹出式菜单
                hmenu = GetMenu(hWnd);      //获取主菜单句柄
                haddmenu = CreateMenu();        //动态创建菜单
                //在创建的菜单中增加菜单项
                AppendMenu(haddmenu, MF_ENABLED, IDM_qiuhe, L"求和");
                AppendMenu(haddmenu, MF_ENABLED, IDM_fangcha, L"方差");
                AppendMenu(haddmenu, MF_ENABLED, IDM_pinjunzhi, L"平均值");
                AppendMenu(haddmenu, MF_ENABLED, IDM_junfanggen, L"均方根");
                //将创建的弹出式菜单插入主菜单中
                InsertMenu(hmenu, 2, MF_POPUP | MF_BYPOSITION,
                    (UINT)haddmenu, L"统计计算(&C)");
                //相应改变菜单中有关绘图统计计算菜单项的属性
                EnableMenuItem(hmenu, IDM_ADDMENU, MF_GRAYED);
                EnableMenuItem(hmenu, IDM_DELMENU, MF_ENABLED);
                DrawMenuBar(hWnd);      //重新显示窗口菜单
                break;
            case IDM_DELMENU:
                DeleteMenu(hmenu, 2, MF_BYPOSITION);    //删除统计计算菜单项
                //相应改变“文件”菜单中有关统计计算菜单项的属性
                EnableMenuItem(hmenu, IDM_ADDMENU, MF_ENABLED);
                EnableMenuItem(hmenu, IDM_DELMENU, MF_GRAYED);
                DrawMenuBar(hWnd);          //重新显示窗口菜单
                break;
            
            case IDM_ABOUT:
                DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
                break;
            case IDM_EXIT:
                DestroyWindow(hWnd);
                break;
            default:
                return DefWindowProc(hWnd, message, wParam, lParam);
            }
        }
        break;
    case WM_PAINT:
        {
            PAINTSTRUCT ps;
            HDC hdc = BeginPaint(hWnd, &ps);
            // TODO: 在此处添加使用 hdc 的任何绘图代码...
            EndPaint(hWnd, &ps);
        }
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

// “关于”框的消息处理程序。
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
    UNREFERENCED_PARAMETER(lParam);
    switch (message)
    {
    case WM_INITDIALOG:
        return (INT_PTR)TRUE;

    case WM_COMMAND:
        if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
        {
            EndDialog(hDlg, LOWORD(wParam));
            return (INT_PTR)TRUE;
        }
        break;
    }
    return (INT_PTR)FALSE;
}

Guess you like

Origin www.cnblogs.com/zw1sh/p/12509932.html