资源操作
如何添加资源:
我们无法直接定位到资源,并使用函数操作他们,和窗口一样,一般情况我们都是需要得到资源的句柄。
LodaXXX:XXX是资源类型
例如:LoadIcon载入图标、LoadCursor载入光标,LoadMenu载入菜单。。。
图标资源:
LoadIcon
光标资源:
LoadCursor
SetCursor();
实现图标资源添加
#include<Windows.h>
#include<CommCtrl.h>
#include"resource1.h"
void print(LPCWSTR format, ...)
{
WCHAR outBuff[1024] = { 0 };
va_list args;
va_start(args, format);
wvsprintfW(outBuff, format, args);
va_end(args);
OutputDebugStringW(outBuff);
}
BOOL CALLBACK EnumChildProc(
_In_ HWND hwnd,
_In_ LPARAM lParam
)
{
WCHAR buff[100]{ 0 };
GetWindowTextW(hwnd, buff, 100);
print(L"窗口名称:%ls\n", buff);
return TRUE;
}
LRESULT CALLBACK WindowProc(
_In_ HWND hwnd,
_In_ UINT uMsg,
_In_ WPARAM wParam,//低两位存储控件ID
_In_ LPARAM lParam//存储控件句柄
)
{
static HINSTANCE hInstance = GetModuleHandle(NULL);//获取当前程序的实例句柄
switch (uMsg)
{
case WM_CREATE:
//添加控件
CreateWindowW(WC_BUTTON, L"移动按钮", WS_CHILD | WS_VISIBLE, 10, 10, 120, 40, hwnd, (HMENU)0x100, hInstance, 0);
CreateWindowW(WC_BUTTON, L"设置菜单", WS_CHILD | WS_VISIBLE, 10, 60, 120, 40, hwnd, (HMENU)0x101, hInstance, 0);
CreateWindowW(WC_EDIT, L"文本框内容", WS_CHILD | WS_BORDER | WS_VISIBLE, 10, 260, 320, 80, hwnd, (HMENU)0x104, hInstance, 0);
break;
case WM_CLOSE:
DestroyWindow(hwnd);
PostQuitMessage(0);
break;
case WM_COMMAND://标准控件的消息
{
WORD ControlId = LOWORD(wParam);//wParam低两个字节存储的是每个控件的不同IP
switch (ControlId)
{
case 0x100:
{
break;
}
case 0x101:
{
break;
}
case 0x102:
{
break;
}
case 0x103:
{
break;
}
case 0x105:
{
break;
}
default:
break;
}
break;
}
}
return DefWindowProcW(hwnd, uMsg, wParam, lParam);
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPreInstance, LPSTR lpCmdLine, int nCmdShow)
{
//1、创建窗口类
WNDCLASSW myWndClass{ 0 };
myWndClass.lpfnWndProc = WindowProc;
myWndClass.lpszClassName = L"dsdWindows";
myWndClass.hbrBackground = CreateSolidBrush(RGB(255, 255, 255, 255));//背景画布
myWndClass.lpszMenuName = MAKEINTRESOURCEW(IDR_MENU1);
//2、注册窗口类
RegisterClassW(&myWndClass);
//3、创建窗口
HWND hwnd = CreateWindowW(
myWndClass.lpszClassName,
L"dsdWindows",
WS_OVERLAPPEDWINDOW,//重叠窗口样式,其他窗口写在该窗口上方即16行代码
CW_USEDEFAULT,
0,
CW_USEDEFAULT,
0,
NULL,
NULL,
hInstance,
0
);
//4、显示窗口
ShowWindow(hwnd, SW_SHOWNORMAL);//SHOWWINDOWS展示样式
MSG msg{ 0 };
while (GetMessageW(&msg, 0, 0, 0)) {
TranslateMessage(&msg);//翻译消息为WM_CHAR 可以在文本框控件中对文字进行输入
DispatchMessageW(&msg);
}
return 0;
}
ICON的加载和更换
实现菜单窗口
#include<Windows.h>
#include<CommCtrl.h>
#include"resource.h"
void print(LPCWSTR format, ...)
{
WCHAR outBuff[1024] = { 0 };
va_list args;
va_start(args, format);
wvsprintfW(outBuff, format, args);
va_end(args);
OutputDebugStringW(outBuff);
}
BOOL CALLBACK EnumChildProc(
_In_ HWND hwnd,
_In_ LPARAM lParam
)
{
WCHAR buff[100]{ 0 };
GetWindowTextW(hwnd, buff, 100);
print(L"窗口名称:%ls\n", buff);
return TRUE;
}
LRESULT CALLBACK WindowProc(
_In_ HWND hwnd,
_In_ UINT uMsg,
_In_ WPARAM wParam,//低两位存储控件ID
_In_ LPARAM lParam//存储控件句柄
)
{
static HINSTANCE hInstance = GetModuleHandle(NULL);//获取当前程序的实例句柄
switch (uMsg)
{
case WM_CREATE:
//添加控件
CreateWindowW(WC_BUTTON, L"移动按钮", WS_CHILD | WS_VISIBLE, 10, 10, 120, 40, hwnd, (HMENU)0x100, hInstance, 0);
CreateWindowW(WC_BUTTON, L"设置菜单", WS_CHILD | WS_VISIBLE, 10, 60, 120, 40, hwnd, (HMENU)0x101, hInstance, 0);
CreateWindowW(WC_EDIT, L"文本框内容", WS_CHILD | WS_BORDER | WS_VISIBLE, 10, 260, 320, 80, hwnd, (HMENU)0x104, hInstance, 0);
break;
case WM_CLOSE:
DestroyWindow(hwnd);
PostQuitMessage(0);
break;
case WM_COMMAND://标准控件的消息
{
WORD ControlId = LOWORD(wParam);//wParam低两个字节存储的是每个控件的不同IP
switch (ControlId)
{
case 0x100:
{
break;
}
case 0x101:
{
HMENU hMenu = LoadMenuW(hInstance, MAKEINTRESOURCEW(IDR_MENU1));
SetMenu(hwnd, hMenu);
break;
}
case 0x102:
{
break;
}
case 0x103:
{
break;
}
case 0x105:
{
break;
}
case ID_40001:
MessageBoxW(hwnd, L"子菜单1被点击了", L"提示", MB_OK);
break;
default:
break;
}
break;
}
}
return DefWindowProcW(hwnd, uMsg, wParam, lParam);
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPreInstance, LPSTR lpCmdLine, int nCmdShow)
{
//1、创建窗口类
WNDCLASSW myWndClass{ 0 };
myWndClass.lpfnWndProc = WindowProc;
myWndClass.lpszClassName = L"dsdWindows";
myWndClass.hbrBackground = CreateSolidBrush(RGB(255, 255, 255, 255));//背景画布
//myWndClass.lpszMenuName = MAKEINTRESOURCEW(IDR_MENU1);
//2、注册窗口类
RegisterClassW(&myWndClass);
//3、创建窗口
//HMENU hMenu = LoadMenuW(hInstance, MAKEINTRESOURCEW(IDR_MENU1));
HWND hwnd = CreateWindowW(
myWndClass.lpszClassName,
L"dsdWindows",
WS_OVERLAPPEDWINDOW,//重叠窗口样式,其他窗口写在该窗口上方即16行代码
CW_USEDEFAULT,
0,
CW_USEDEFAULT,
0,
NULL,
NULL,
hInstance,
0
);
//4、显示窗口
ShowWindow(hwnd, SW_SHOWNORMAL);//SHOWWINDOWS展示样式
MSG msg{ 0 };
while (GetMessageW(&msg, 0, 0, 0)) {
TranslateMessage(&msg);//翻译消息为WM_CHAR 可以在文本框控件中对文字进行输入
DispatchMessageW(&msg);
}
return 0;
}
方法一:
把整数值转化为能被使用的资源类型。
方法二:
在创建窗口时,放入句柄的参数中。
方法三:
通过按钮来执行菜单窗口。
实现右键下拉菜单
在平常的工作中我们会使用右键来打开关于一个应用的内置下拉菜单,我们通过窗口机制来实现。
#include<Windows.h>
#include<CommCtrl.h>
#include"resource.h"
void print(LPCWSTR format, ...)
{
WCHAR outBuff[1024] = { 0 };
va_list args;
va_start(args, format);
wvsprintfW(outBuff, format, args);
va_end(args);
OutputDebugStringW(outBuff);
}
BOOL CALLBACK EnumChildProc(
_In_ HWND hwnd,
_In_ LPARAM lParam
)
{
WCHAR buff[100]{ 0 };
GetWindowTextW(hwnd, buff, 100);
print(L"窗口名称:%ls\n", buff);
return TRUE;
}
LRESULT CALLBACK WindowProc(
_In_ HWND hwnd,
_In_ UINT uMsg,
_In_ WPARAM wParam,//低两位存储控件ID
_In_ LPARAM lParam//存储控件句柄
)
{
static HINSTANCE hInstance = GetModuleHandle(NULL);//获取当前程序的实例句柄
switch (uMsg)
{
case WM_CREATE:
//添加控件
CreateWindowW(WC_BUTTON, L"移动按钮", WS_CHILD | WS_VISIBLE, 10, 10, 120, 40, hwnd, (HMENU)0x100, hInstance, 0);
CreateWindowW(WC_BUTTON, L"设置菜单", WS_CHILD | WS_VISIBLE, 10, 60, 120, 40, hwnd, (HMENU)0x101, hInstance, 0);
CreateWindowW(WC_EDIT, L"文本框内容", WS_CHILD | WS_BORDER | WS_VISIBLE, 10, 260, 320, 80, hwnd, (HMENU)0x104, hInstance, 0);
break;
case WM_RBUTTONDOWN:
{
//实现右键下拉菜单
/*WORD X = LOWORD(lParam);
WORD Y = HIWORD(lParam);*/
POINT point{ 0 };
/*point.x = X;
point.y = Y;*/
ClientToScreen(hwnd, &point);//ClientToScreen 函数将指定点的工作区坐标转换为屏幕坐标。
GetCursorPos(&point);//检索鼠标在屏幕中的位置
HMENU hMenu = LoadMenuW(hInstance, MAKEINTRESOURCEW(IDR_MENU1));//出现顶级菜单而不是下拉子菜单
HMENU hSubMenu = GetSubMenu(hMenu, 0);
TrackPopupMenu(hSubMenu,TPM_LEFTALIGN,point.x,point.y,0,hwnd,NULL);//弹出菜单,靠左显示窗口
SetMenu(hwnd, hMenu);
break;
}
case WM_CLOSE:
DestroyWindow(hwnd);
PostQuitMessage(0);
break;
case WM_COMMAND://标准控件的消息
{
WORD ControlId = LOWORD(wParam);//wParam低两个字节存储的是每个控件的不同IP
switch (ControlId)
{
case 0x100:
{
break;
}
case 0x101:
{
HMENU hMenu = LoadMenuW(hInstance, MAKEINTRESOURCEW(IDR_MENU1));
SetMenu(hwnd, hMenu);
break;
}
case 0x102:
{
break;
}
case 0x103:
{
break;
}
case 0x105:
{
break;
}
case ID_40001:
MessageBoxW(hwnd, L"子菜单1被点击了", L"提示", MB_OK);
break;
default:
break;
}
break;
}
}
return DefWindowProcW(hwnd, uMsg, wParam, lParam);
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPreInstance, LPSTR lpCmdLine, int nCmdShow)
{
//1、创建窗口类
WNDCLASSW myWndClass{ 0 };
myWndClass.lpfnWndProc = WindowProc;
myWndClass.lpszClassName = L"dsdWindows";
myWndClass.hbrBackground = CreateSolidBrush(RGB(255, 255, 255, 255));//背景画布
//myWndClass.lpszMenuName = MAKEINTRESOURCEW(IDR_MENU1);
//2、注册窗口类
RegisterClassW(&myWndClass);
//3、创建窗口
//HMENU hMenu = LoadMenuW(hInstance, MAKEINTRESOURCEW(IDR_MENU1));
HWND hwnd = CreateWindowW(
myWndClass.lpszClassName,
L"dsdWindows",
WS_OVERLAPPEDWINDOW,//重叠窗口样式,其他窗口写在该窗口上方即16行代码
CW_USEDEFAULT,
0,
CW_USEDEFAULT,
0,
NULL,
NULL,
hInstance,
0
);
//4、显示窗口
ShowWindow(hwnd, SW_SHOWNORMAL);//SHOWWINDOWS展示样式
MSG msg{ 0 };
while (GetMessageW(&msg, 0, 0, 0)) {
TranslateMessage(&msg);//翻译消息为WM_CHAR 可以在文本框控件中对文字进行输入
DispatchMessageW(&msg);
}
return 0;
}
方法一:
方法二:
在这我们获取的都是顶级菜单的ID而不是子菜单的ID,要想获得子菜单的ID用以下的方法。
实现对话框资源添加
对话框有两种:模态对话框和非模态对话框。
#include<Windows.h>
#include<CommCtrl.h>
#include"resource1.h"
INT_PTR CALLBACK Dlgproc(
HWND hwnd,
UINT uMsg,
WPARAM wParam,
LPARAM lParam
)
{
switch (uMsg)
{
case WM_INITDIALOG://创建窗口
MessageBoxW(hwnd, L"窗口创建了", L"提示", MB_OK);
break;
case WM_CLOSE:
EndDialog(hwnd, 0);
//非模态对话框关闭窗口
/*DestroyWindow(hwnd);
PostQuitMessage(0);*/
break;
default:
return FALSE;
}
return TRUE;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPreInstance, LPSTR lpCmdLine, int nCmdShow)
{
//创建模态对话框
DialogBoxW(hInstance, MAKEINTRESOURCEW(IDD_DIALOG1), NULL, Dlgproc);
//创建非模态对话框
//HWND hwnd = CreateDialogW(hInstance, MAKEINTRESOURCEW(IDD_DIALOG1), NULL, Dlgproc);
/*ShowWindow(hwnd,SW_SHOWNORMAL);
MSG msg{ 0 };
while (GetMessage(&msg,0,0,0))
{
TranslateMessage(&msg);
DispatchMessageW(&msg);
}*/
return 0;
}