Win32编程之资源文件(三)
一、菜单资源的使用
1.菜单的分类
- 窗口的顶层菜单
- 弹出式菜单
- 系统菜单
HMENU类型表示菜单,ID表示菜单项
2、菜单资源的使用
(1).注册窗口类时设置菜单
(2).创建窗口传参设置菜单
(3).在主窗口WM_CREATE消息中利用SetMenu函数设置菜单
加载菜单资源
HMENU LoadMenu( HINSTANCE hInstance, LPCTSTR lpMenuName );
示例代码:
#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
示例代码:
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);
}
二、图标资源的使用
添加资源:注意图标的大小,一个图标文件中,可以有多个不同大小的图标
加载函数:
HICON LoadIcon( HINSTANCE hInstance, LPCTSTR lpIconName ); 成功返回HICON句柄
示例代码:
#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,是当前鼠标的热点
加载资源:
HCURSOR LoadCursor( HINSTANCE hInstance, LPCTSTR lpCursorName ); hInstance可以为NULL,获取系统默认的Cursor
设置资源:在注册窗口时,设置光标
示例代码:
//入口函数
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设置光标:
HCURSOR SetCursor( HCURSOR hCursor ); WN_SETCURSOR: 消息参数;wPARAM:当前使用的光标句柄, IPARAM:LOWORD 当前区域的代码,HTCLIENT(客户区域)/HTCAPTION(标题栏区域)...;HIWORD:当前鼠标消息ID
示例代码:
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);
}
四、字符串资源
添加字符串资源:添加字符串表,在表中增减字符串
字符串资源的使用:
int LoadString( HINSTANCE hInstance, UINT uID,//字符串ID LPTSTR lpBuffer,//存放字符串BUFF int nBUfferMax //字符串BUFF长度 ); 成功返回字符串长度,失败0
示例资源:
//入口函数
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.使用加速键表:
加载加速键表: HACCEL LoadAccelerators( HINSTANCE hInstance, LPCTSTR lpTableName );返回加速键句柄 翻译加速键: int TranslateAccelerator( HWND hWnd, //处理消息的窗口句柄 HACCEL hAccTable, //加速键句柄 LPMSG lpMsg //消息 );如果是加速键,返回非0

在WM_COMMAND中相应消息中,消息参数: wPARAM:HIWORD为1表示加速键,为0表示菜单 lParam:为0
示例代码:
#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;
}

浙公网安备 33010602011771号