Win32编程之资源文件(三)

一、菜单资源的使用

1.菜单的分类

  • 窗口的顶层菜单
  • 弹出式菜单
  • 系统菜单

HMENU类型表示菜单,ID表示菜单项

2、菜单资源的使用

 (1).注册窗口类时设置菜单

 (2).创建窗口传参设置菜单

 (3).在主窗口WM_CREATE消息中利用SetMenu函数设置菜单

 加载菜单资源 

1
2
3
4
HMENU LoadMenu(
      HINSTANCE hInstance,
      LPCTSTR lpMenuName
);

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#include <Windows.h>
#include <stdio.h>
#include "resource.h"
 
HINSTANCE g_hIns = NULL;
 
//窗口处理函数(自定义,处理消息)
LRESULT CALLBACK WindProc(HWND hWnd, UINT msgID, WPARAM wParam, LPARAM lParam) {
    switch (msgID) {
    case WM_CREATE: {
        HMENU hMenu = LoadMenu(g_hIns, (LPCWSTR)IDR_MENU1);
        SetMenu(hWnd, hMenu);
        break;
    }
    default:
        break;
    }
 
    return DefWindowProc(hWnd, msgID, wParam, lParam);
}
 
//入口函数
int CALLBACK WinMain(HINSTANCE hIns, HINSTANCE hPreIns, LPSTR lpCmdLine, int nCmdShow) {
    g_hIns = hIns;
     
    //设计窗口类
    WNDCLASS wc = { 0 };
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    wc.hCursor = NULL;
    wc.hIcon = NULL;
    wc.hInstance = hIns;
    wc.lpfnWndProc = WindProc;
    wc.lpszClassName = TEXT("Main");
    //1.注册窗口类时设置菜单
    //wc.lpszMenuName = (LPCWSTR)IDR_MENU1;
    wc.lpszMenuName = NULL;
    wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
 
    //2.创建窗口传参设置菜单
    //HMENU hMenu = LoadMenu(hIns, (LPCWSTR)IDR_MENU1);
     
    //注册窗口类
    RegisterClass(&wc);//将以上所有赋值全部写入操作系统
 
    //在内存中创建窗口
    //HWND hWnd = CreateWindowEx(0, wc.lpszClassName, TEXT("Window"), WS_OVERLAPPEDWINDOW, 100, 100, 500, 500, NULL, hMenu, hIns, NULL);
    HWND hWnd = CreateWindowEx(0, wc.lpszClassName, TEXT("Window"), WS_OVERLAPPEDWINDOW, 100, 100, 500, 500, NULL, NULL, hIns, NULL);
 
    //显示窗口
    ShowWindow(hWnd, SW_SHOW);
    UpdateWindow(hWnd);
 
    //消息循环
    MSG nMsg = { 0 };
    while (true) {
        if ((PeekMessage(&nMsg, NULL, 0, 0, PM_NOREMOVE))) {
            //有消息
            if (GetMessage(&nMsg, NULL, 0, 0)) {
                TranslateMessage(&nMsg);
                DispatchMessage(&nMsg);
            }
            else {
                break;
            }
        }
    }
 
    return 0;
}

3、菜单命令消息处理

菜单消息:WM_COMMAND

附带参数信息:

  wPARAM:HIWORD:对于菜单为0,LOWORD:菜单项的ID

  lPARAM:对于菜单为0

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
void onCommand(HWND hWnd, WPARAM wParam) {
    switch (LOWORD(wParam)) {
    case ID_NEW:
        MessageBox(hWnd, TEXT("新建被点击"), TEXT("提示"), MB_OK);
        break;
    case ID_EXIT:
        MessageBox(hWnd, TEXT("退出被点击"), TEXT("提示"), MB_OK);
        break;
    case ID_ABOUT:
        MessageBox(hWnd, TEXT("关于被点击"), TEXT("提示"), MB_OK);
        break;
    default:
        break;
    }
}
 
//窗口处理函数(自定义,处理消息)
LRESULT CALLBACK WindProc(HWND hWnd, UINT msgID, WPARAM wParam, LPARAM lParam) {
    switch (msgID) {
    case WM_CREATE: {
        HMENU hMenu = LoadMenu(g_hIns, (LPCWSTR)IDR_MENU1);
        SetMenu(hWnd, hMenu);
        break;
    }
    case WM_COMMAND: {
        onCommand(hWnd, wParam);
        break;
    }
    default:
        break;
    }
 
    return DefWindowProc(hWnd, msgID, wParam, lParam);
}

二、图标资源的使用

添加资源:注意图标的大小,一个图标文件中,可以有多个不同大小的图标

加载函数:

1
2
3
4
5
HICON LoadIcon(
      HINSTANCE hInstance,
      LPCTSTR lpIconName
);
成功返回HICON句柄

 示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include <Windows.h>
#include "resource.h"
 
 
//窗口处理函数(自定义,处理消息)
LRESULT CALLBACK WindProc(HWND hWnd, UINT msgID, WPARAM wParam, LPARAM lParam) {
    return DefWindowProc(hWnd, msgID, wParam, lParam);
}
 
//入口函数
int CALLBACK WinMain(HINSTANCE hIns, HINSTANCE hPreIns, LPSTR lpCmdLine, int nCmdShow) {
    //设计窗口类
    WNDCLASS wc = { 0 };
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    wc.hCursor = NULL;
    wc.hIcon = LoadIcon(hIns, (LPCWSTR)IDI_ICON1);
    wc.hInstance = hIns;
    wc.lpfnWndProc = WindProc;
    wc.lpszClassName = TEXT("Main");
    wc.lpszMenuName = NULL;
    wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
 
    //2.创建窗口传参设置菜单
    //HMENU hMenu = LoadMenu(hIns, (LPCWSTR)IDR_MENU1);
 
    //注册窗口类
    RegisterClass(&wc);//将以上所有赋值全部写入操作系统
 
    HWND hWnd = CreateWindowEx(0, wc.lpszClassName, TEXT("Window"), WS_OVERLAPPEDWINDOW, 100, 100, 500, 500, NULL, NULL, hIns, NULL);
 
    //显示窗口
    ShowWindow(hWnd, SW_SHOW);
    UpdateWindow(hWnd);
 
    //消息循环
    MSG nMsg = { 0 };
    while (true) {
        if ((PeekMessage(&nMsg, NULL, 0, 0, PM_NOREMOVE))) {
            //有消息
            if (GetMessage(&nMsg, NULL, 0, 0)) {
                TranslateMessage(&nMsg);
                DispatchMessage(&nMsg);
            }
            else {
                break;
            }
        }
    }
 
    return 0;
}

三、光标资源 

添加光标资源:光标的大小默认是32x32像素,每个光标都有HotSpot,是当前鼠标的热点

加载资源:

1
2
3
4
5
HCURSOR LoadCursor(
        HINSTANCE hInstance,
        LPCTSTR lpCursorName
);
hInstance可以为NULL,获取系统默认的Cursor

设置资源:在注册窗口时,设置光标

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
//入口函数
int CALLBACK WinMain(HINSTANCE hIns, HINSTANCE hPreIns, LPSTR lpCmdLine, int nCmdShow) {
    //设计窗口类
    WNDCLASS wc = { 0 };
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    wc.hCursor = LoadCursor(hIns, (LPCWSTR)IDC_CURSOR1);
    wc.hIcon = LoadIcon(hIns, (LPCWSTR)IDI_ICON1);
    wc.hInstance = hIns;
    wc.lpfnWndProc = WindProc;
    wc.lpszClassName = TEXT("Main");
    wc.lpszMenuName = NULL;
    wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
 
    //2.创建窗口传参设置菜单
    //HMENU hMenu = LoadMenu(hIns, (LPCWSTR)IDR_MENU1);
 
    //注册窗口类
    RegisterClass(&wc);//将以上所有赋值全部写入操作系统
 
    HWND hWnd = CreateWindowEx(0, wc.lpszClassName, TEXT("Window"), WS_OVERLAPPEDWINDOW, 100, 100, 500, 500, NULL, NULL, hIns, NULL);
 
    //显示窗口
    ShowWindow(hWnd, SW_SHOW);
    UpdateWindow(hWnd);
 
    //消息循环
    MSG nMsg = { 0 };
    while (true) {
        if ((PeekMessage(&nMsg, NULL, 0, 0, PM_NOREMOVE))) {
            //有消息
            if (GetMessage(&nMsg, NULL, 0, 0)) {
                TranslateMessage(&nMsg);
                DispatchMessage(&nMsg);
            }
            else {
                break;
            }
        }
    }
 
    return 0;
}

使用SetCursor设置光标:

1
2
3
4
5
6
7
HCURSOR SetCursor(
        HCURSOR hCursor
);
 
WN_SETCURSOR:
    消息参数;wPARAM:当前使用的光标句柄,
             IPARAM:LOWORD 当前区域的代码,HTCLIENT(客户区域)/HTCAPTION(标题栏区域)...;HIWORD:当前鼠标消息ID

 示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
LRESULT CALLBACK WindProc(HWND hWnd, UINT msgID, WPARAM wParam, LPARAM lParam) {
    switch (msgID) {
    case WM_SETCURSOR: {
        HCURSOR hCur = LoadCursor(g_hIns, (LPCWSTR)IDC_CURSOR2);
        if (LOWORD(lParam) == HTCLIENT) {
            //鼠标如果在窗口的客户区活动
            SetCursor(hCur);
            return 0;
        }
    }
    default:
        break;
    }
     
    return DefWindowProc(hWnd, msgID, wParam, lParam);
}

四、字符串资源 

添加字符串资源:添加字符串表,在表中增减字符串

字符串资源的使用:

1
2
3
4
5
6
7
int LoadString(
    HINSTANCE hInstance,
    UINT uID,//字符串ID
    LPTSTR lpBuffer,//存放字符串BUFF
    int nBUfferMax //字符串BUFF长度
);
成功返回字符串长度,失败0

示例资源:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
//入口函数
int CALLBACK WinMain(HINSTANCE hIns, HINSTANCE hPreIns, LPSTR lpCmdLine, int nCmdShow) {
    g_hIns = hIns;
     
    //设计窗口类
    WNDCLASS wc = { 0 };
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    wc.hCursor = LoadCursor(hIns, (LPCWSTR)IDC_CURSOR1);
    wc.hIcon = LoadIcon(hIns, (LPCWSTR)IDI_ICON1);
    wc.hInstance = hIns;
    wc.lpfnWndProc = WindProc;
    wc.lpszClassName = TEXT("Main");
    wc.lpszMenuName = NULL;
    wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
 
    //2.创建窗口传参设置菜单
    //HMENU hMenu = LoadMenu(hIns, (LPCWSTR)IDR_MENU1);
 
    //注册窗口类
    RegisterClass(&wc);//将以上所有赋值全部写入操作系统
 
    WCHAR szTitle[256] = { 0 };
    LoadString(hIns, IDS_WND, szTitle, 256);
     
    HWND hWnd = CreateWindowEx(0, wc.lpszClassName, szTitle, WS_OVERLAPPEDWINDOW, 100, 100, 500, 500, NULL, NULL, hIns, NULL);
 
    //显示窗口
    ShowWindow(hWnd, SW_SHOW);
    UpdateWindow(hWnd);
 
    //消息循环
    MSG nMsg = { 0 };
    while (true) {
        if ((PeekMessage(&nMsg, NULL, 0, 0, PM_NOREMOVE))) {
            //有消息
            if (GetMessage(&nMsg, NULL, 0, 0)) {
                TranslateMessage(&nMsg);
                DispatchMessage(&nMsg);
            }
            else {
                break;
            }
        }
    }
 
    return 0;
}

五、加速键资源

1.资源添加加速键表,增加命令ID对应的加速键 

2.使用加速键表:

1
2
3
4
5
6
7
8
9
10
11
12
加载加速键表:
HACCEL LoadAccelerators(
    HINSTANCE hInstance,
    LPCTSTR lpTableName
);返回加速键句柄
 
翻译加速键:
int TranslateAccelerator(
    HWND hWnd, //处理消息的窗口句柄
    HACCEL hAccTable, //加速键句柄
    LPMSG lpMsg //消息
);如果是加速键,返回非0

1
2
3
在WM_COMMAND中相应消息中,消息参数:
    wPARAM:HIWORD为1表示加速键,为0表示菜单
    lParam:为0 

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#include <Windows.h>
#include "resource.h"
 
HINSTANCE g_hIns = NULL;
 
LRESULT CALLBACK WindProc(HWND hWnd, UINT msgID, WPARAM wParam, LPARAM lParam) {
    switch (msgID) {
    case WM_COMMAND: {
        if (LOWORD(wParam) == ID_NEW) {
            if (HIWORD(wParam) == 0) {
                MessageBox(hWnd, TEXT("新建菜单被点击"), TEXT("提示"), MB_OK);
            }
            else if (HIWORD(wParam) == 1) {
                MessageBox(hWnd, TEXT("CTRL+M被点击"), TEXT("提示"), MB_OK);
            }          
        }
        break;
    }
    default:
        break;
    }
     
    return DefWindowProc(hWnd, msgID, wParam, lParam);
}
 
//入口函数
int CALLBACK WinMain(HINSTANCE hIns, HINSTANCE hPreIns, LPSTR lpCmdLine, int nCmdShow) {
    g_hIns = hIns;
     
    //设计窗口类
    WNDCLASS wc = { 0 };
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
    wc.hCursor = LoadCursor(hIns, (LPCWSTR)IDC_CURSOR1);
    wc.hIcon = LoadIcon(hIns, (LPCWSTR)IDI_ICON1);
    wc.hInstance = hIns;
    wc.lpfnWndProc = WindProc;
    wc.lpszClassName = TEXT("Main");
    wc.lpszMenuName = (LPCWSTR)IDR_MENU1;
    wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
 
    //注册窗口类
    RegisterClass(&wc);//将以上所有赋值全部写入操作系统
 
    WCHAR szTitle[256] = { 0 };
    LoadString(hIns, IDS_WND, szTitle, 256);
     
    HWND hWnd = CreateWindowEx(0, wc.lpszClassName, szTitle, WS_OVERLAPPEDWINDOW, 100, 100, 500, 500, NULL, NULL, hIns, NULL);
 
    //显示窗口
    ShowWindow(hWnd, SW_SHOW);
    UpdateWindow(hWnd);
 
    HACCEL hAccel = LoadAccelerators(hIns, (LPCWSTR)IDR_ACCELERATOR1);
     
    //消息循环
    MSG nMsg = { 0 };
    while (true) {
        if ((PeekMessage(&nMsg, NULL, 0, 0, PM_NOREMOVE))) {
            //有消息
            if (GetMessage(&nMsg, NULL, 0, 0)) {
                if (!TranslateAccelerator(hWnd, hAccel, &nMsg)) {
                    //非加速键才需要翻译和派发
                    TranslateMessage(&nMsg);
                    DispatchMessage(&nMsg);
                }
            }
            else {
                break;
            }
        }
    }
 
    return 0;
}

 

 
posted @   TechNomad  阅读(119)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示