菜单分类
窗口的顶层菜单
弹出式菜单
系统菜单
HMENU类型表示菜单,ID表示菜单项。
资源相关
资源脚本文件:*.rc文件
编译器: RC.EXE
CL.EXE
.c/.cpp ------ .obj| -------- > .obj| LINK.EXE
RC.EXE | -----------------> .exe
.rc ---------------------------->.res|
菜单资源的使用
添加菜单资源
加载菜单资源
1> 注册窗口类时设置菜单
2>创建窗口传参设置菜单
3>在主窗口WM_CREATE消息中利用SetMenu函数设置菜单
加载菜单资源
HMENU LoadMenu(
HINSTANCE hInstance, //handle to module
LPCTSTR IpMenuName // menu name or rersource identifier
);
#include <windows.h>
#include "resource.h" //添加
HINSTANCE g_hInstance = 0;
void OnCreate(HWND hWnd) {
HMENU hMenu = LoadMenu(g_hInstance, (char*)IDR_MENU1);
SetMenu(hWnd, hMenu);
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT msgID, WPARAM wParam, LPARAM IParam)
{
switch (msgID) {
case WM_CREATE:
OnCreate(hWnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
}
return DefWindowProc(hWnd, msgID, wParam, IParam);
}
int CALLBACK WinMain(HINSTANCE hIns, HINSTANCE hPreIns, LPSTR lpCmdLine, int nCmdShow) {
g_hInstance = 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 = WndProc;
wc.lpszClassName = "Main";
wc.lpszMenuName = NULL;//(char*)IDR_MENU1; //设置菜单
wc.style = CS_HREDRAW | CS_VREDRAW;
RegisterClass(&wc); //将以上所有赋值全部写入操作系统中
//在内存创建窗口
//HMENU hMenu = LoadMenu(hIns, (char*)IDR_MENU1);
HWND hWnd = CreateWindowEx(0, "Main", "window", WS_OVERLAPPEDWINDOW, 100, 100, 500, 500, NULL, NULL
, hIns
, NULL); //倒数第三个(菜单句柄 )
//显示窗口
ShowWindow(hWnd, SW_SHOW);
UpdateWindow(hWnd);
//消息循环
MSG nMsg = { 0 };
while (GetMessage(&nMsg, NULL, 0, 0)) { //抓消息
TranslateMessage(&nMsg);//翻译消息
DispatchMessage(&nMsg);//派发消息:将消息交给窗口处理函数来处理。
}
return 0;
}
//需要在任务管理器中退出线程!
命令消息处理(WM_COMMAND)处理
附带信息:
wPARAM:
HIWORD - 对于菜单为0
LOWORD - 菜单项的ID
IPARAM - 对于菜单为0
#include <windows.h>
#include "resource.h" //添加
HINSTANCE g_hInstance = 0;
void OnCreate(HWND hWnd) {
HMENU hMenu = LoadMenu(g_hInstance, (char*)IDR_MENU1);
SetMenu(hWnd, hMenu);
}
void OnCommand(HWND hWnd, WPARAM wParam) {
switch (LOWORD(wParam))
{
case ID_NEW:
MessageBox(hWnd, "新建被点击", "Infor",MB_OK);
break;
case ID_EXIT:
MessageBox(hWnd, "退出被点击", "Infor", MB_OK);
break;
case ID_ABOUT:
MessageBox(hWnd, "关于被点击", "Infor", MB_OK);
break;
}
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT msgID, WPARAM wParam, LPARAM IParam)
{
switch (msgID) {
case WM_COMMAND:
OnCommand(hWnd, wParam);
break;
case WM_CREATE:
OnCreate(hWnd);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
}
return DefWindowProc(hWnd, msgID, wParam, IParam);
}
int CALLBACK WinMain(HINSTANCE hIns, HINSTANCE hPreIns, LPSTR lpCmdLine, int nCmdShow) {
g_hInstance = 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 = WndProc;
wc.lpszClassName = "Main";
wc.lpszMenuName = NULL;//(char*)IDR_MENU1; //设置菜单
wc.style = CS_HREDRAW | CS_VREDRAW;
RegisterClass(&wc); //将以上所有赋值全部写入操作系统中
//在内存创建窗口
//HMENU hMenu = LoadMenu(hIns, (char*)IDR_MENU1);
HWND hWnd = CreateWindowEx(0, "Main", "window", WS_OVERLAPPEDWINDOW, 100, 100, 500, 500, NULL, NULL
, hIns
, NULL); //倒数第三个(菜单句柄 )
//显示窗口
ShowWindow(hWnd, SW_SHOW);
UpdateWindow(hWnd);
//消息循环
MSG nMsg = { 0 };
while (GetMessage(&nMsg, NULL, 0, 0)) { //抓消息
TranslateMessage(&nMsg);//翻译消息
DispatchMessage(&nMsg);//派发消息:将消息交给窗口处理函数来处理。
}
return 0;
}
//需要在任务管理器中退出线程!
图标资源
添加资源
注意i图标的大小,一个图标文件中,可以有多个不同大小的图标。
加载
HICON LoadIcon(
HINSTANCE hInstance,
LPCTSTR IpIconName
);成功返回HICON句柄
设置
注册窗口类
#include <windows.h>
#include "resource.h"
LRESULT CALLBACK WndProc(HWND hWnd, UINT msgID, WPARAM wParam, LPARAM IParam)
{
switch (msgID) {
case WM_DESTROY:
PostQuitMessage(0);
break;
}
return DefWindowProc(hWnd, msgID, wParam, IParam);
}
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,(char*)IDI_ICON1); //写在这里!
wc.hInstance = hIns;
wc.lpfnWndProc = WndProc;
wc.lpszClassName = "Main";
wc.lpszMenuName = NULL;
wc.style = CS_HREDRAW | CS_VREDRAW;
RegisterClass(&wc); //将以上所有赋值全部写入操作系统中
//在内存创建窗口
HWND hWnd = CreateWindowEx(0, "Main", "window", WS_OVERLAPPEDWINDOW, 100, 100, 500, 500, NULL, NULL
, hIns
, NULL);
//显示窗口
ShowWindow(hWnd, SW_SHOW);
UpdateWindow(hWnd);
//消息循环
MSG nMsg = { 0 };
while (GetMessage(&nMsg, NULL, 0, 0)) { //抓消息
TranslateMessage(&nMsg);//翻译消息
DispatchMessage(&nMsg);//派发消息:将消息交给窗口处理函数来处理。
}
return 0;
}
//需要在任务管理器中退出线程!
光标资源
添加光标的资源
光标的大小默认是32X32像素,每个光标有HotSpot,是当前鼠标的热点
加载资源
HCURSOR LoadCursor(
HINSTANCE hInstance,
LPCTSTR IpCursorName
);hInstance - 可以为NULL,获取系统默认的Cursor
设置资源
在注册窗口时,设置光标
使用SetCursor设置光标
HCURSOR SetCursor(
HCURSOR hCursor //handle to cursor
);
WM_SETCURSOR 消息参数
wPARAM - 当前使用的光标句柄
IPARAM - LOWORD 当前区域的代码 (Hit - Test code)
HTCLIENT / HTCAPTION…
HIWORD - 当前鼠标消息ID
#include <windows.h>
#include "resource.h"
HINSTANCE g_hInstance = 0;
LRESULT CALLBACK WndProc(HWND hWnd, UINT msgID, WPARAM wParam, LPARAM IParam)
{
switch (msgID) {
case WM_SETCURSOR:
{
HCURSOR hCur = LoadCursor(g_hInstance, (char*)IDC_CURSOR2);
if (LOWORD(IParam) == HTCLIENT) {
SetCursor(hCur);
return 0;
}
else
{
}
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
}
return DefWindowProc(hWnd, msgID, wParam, IParam);
}
int CALLBACK WinMain(HINSTANCE hIns, HINSTANCE hPreIns, LPSTR lpCmdLine, int nCmdShow) {
g_hInstance = hIns;
WNDCLASS wc = { 0 };
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wc.hCursor = LoadCursor(hIns,(char*)IDC_CURSOR1);
wc.hIcon = LoadIcon(hIns,(char*)IDI_ICON1); //写在这里!
wc.hInstance = hIns;
wc.lpfnWndProc = WndProc;
wc.lpszClassName = "Main";
wc.lpszMenuName = NULL;
wc.style = CS_HREDRAW | CS_VREDRAW;
RegisterClass(&wc); //将以上所有赋值全部写入操作系统中
//在内存创建窗口
HWND hWnd = CreateWindowEx(0, "Main", "window", WS_OVERLAPPEDWINDOW, 100, 100, 500, 500, NULL, NULL
, hIns
, NULL);
//显示窗口
ShowWindow(hWnd, SW_SHOW);
UpdateWindow(hWnd);
//消息循环
MSG nMsg = { 0 };
while (GetMessage(&nMsg, NULL, 0, 0)) { //抓消息
TranslateMessage(&nMsg);//翻译消息
DispatchMessage(&nMsg);//派发消息:将消息交给窗口处理函数来处理。
}
return 0;
}
//需要在任务管理器中退出线程!