资源
概念
- 资源:所有除代码以外的东西都可称为资源
- ID:SDK所有添加的资源都可以设置唯一的ID
- 若用字符串命名资源ID,需要字符串外加入双引号("")
- 可用指定API将资源ID转换为对应指针 宏函数
MAKEINTRESOURCE(MN_EDIT) // ID转指针
带资源的EXE文件生成流程
WM_COMMAND在窗口菜单程序中使用
// Win32Test.cpp : 定义应用程序的入口点。
//
#include "stdafx.h"
#include "Win32Test.h"
#include "resource.h"
void ShowErrorMessage()
{
LPVOID lpMsgBuf;
//将错误码转化为错误信息,参数可以抄MSDN
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR)&lpMsgBuf,
0,
NULL
);
// Process any inserts in lpMsgBuf.
// ...
// 弹出错误提示窗口.
MessageBox(NULL, (LPCTSTR)lpMsgBuf, TEXT("Error"), MB_OK | MB_ICONINFORMATION);
// Free the buffer.
LocalFree(lpMsgBuf);
}
LRESULT CALLBACK MyWindowPro
(HWND hwnd, // 窗口句柄
UINT uMsg, // 消息标识
WPARAM wParam, // 附加在消息上的参数
LPARAM lParam // 附加在消息上的参数
)
{
switch (uMsg)
{
case WM_COMMAND:
{
//高位判断通知类型如果来自菜单,则为0, 如果来自快捷键,则为1
WORD wFrom = HIWORD(wParam);
//低位保存菜单\快捷键的ID
WORD wID = LOWORD(wParam);
//菜单
if (wFrom == 0)
{
switch (wID)
{
case IDM_OPEN:
MessageBox(hwnd, TEXT("打开菜单"), NULL, MB_OK);
break;
case IDM_CLSOE:
MessageBox(hwnd, TEXT("关闭菜单"), NULL, MB_OK);
break;
default:
break;
}
}
else if (wFrom == 1)
{
switch (wID)
{
case IDA_ALT_O:
MessageBox(hwnd, TEXT("打开菜单"), NULL, MB_OK);
break;
case IDA_ALT_C:
MessageBox(hwnd, TEXT("关闭菜单"), NULL, MB_OK);
break;
default:
break;
}
}
break;
}
//点击关闭窗口会发送WM_CLOSE消息
case WM_CLOSE:
{
int nRet = MessageBox(hwnd, TEXT("是否退出"), TEXT("询问"), MB_OKCANCEL);
if (nRet == IDCANCEL)//取消关闭
{
return 0;
}
else
{
//摧毁窗口发送WM_DESTROY消息
DestroyWindow(hwnd);
}
break;
}
case WM_DESTROY:
{
//向消息队列投递WM_QUIT消息 WM_QUIT使消息循环退出,程序退出。
PostQuitMessage(0);
break;
}
default:
break;
}
//系统默认处理消息窗口函数
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
//句柄可以理解为标识ID,如窗口句柄就表示这个标识这个窗口的唯一ID
int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,//应用程序当前实例的句柄
_In_opt_ HINSTANCE hPrevInstance,//应用程序的先前实例的句柄
_In_ LPTSTR lpCmdLine,//指向应用程序命令行的字符串的指针
_In_ int nCmdShow)//指明窗口如何显示,查msdn帮助文档,有各种宏
{
WNDCLASS wc;
wc.style = CS_HREDRAW | CS_VREDRAW; //默认风格,窗口尺寸被修改后重画窗口
wc.lpfnWndProc = MyWindowPro; //窗口回调
wc.cbClsExtra = 0; //窗口类的额外空间
wc.cbWndExtra = 0; //窗口实例的额外空间
wc.hInstance = hInstance;
wc.hIcon = NULL; //图标
wc.hCursor = NULL; //光标
wc.hbrBackground = (HBRUSH)(COLOR_HIGHLIGHT);//背景
wc.lpszMenuName = MAKEINTRESOURCE(IDM_TEST);//菜单
wc.lpszClassName = TEXT("MyWindow");
//加载菜单
HMENU hMenu = LoadMenu(hInstance, TEXT("testmenu"));
ATOM nRet = RegisterClass(&wc);
if (nRet == 0)
{
ShowErrorMessage();
}
//创建窗口实例
HWND hWnd = CreateWindow(
TEXT("MyWindow"), //窗口类名
TEXT("Hello World"), //窗口标题
WS_OVERLAPPEDWINDOW, //重叠窗口
CW_USEDEFAULT, CW_USEDEFAULT, //默认坐标
CW_USEDEFAULT, CW_USEDEFAULT,//默认长和宽
NULL, //没有父窗口
NULL, //加载菜单
hInstance,//main函数的实例句柄
NULL//暂时不用,(LPVOID)0x87654093,可用来做参数标记
);
if (hWnd == NULL)
{
ShowErrorMessage();
}
//显示窗口
ShowWindow(hWnd, SW_SHOW);
//更新窗口
UpdateWindow(hWnd);
MSG msg;
//消息循环
//加载快捷键
HACCEL hAccel = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDA_TEST));
while (GetMessage(&msg, NULL, 0, 0) != 0)
{
//转换WM_KEYDOWN消息为快捷键消息
if (!TranslateAccelerator(hWnd, hAccel, &msg))
{
//将keydown消息转换为字符消息
TranslateMessage(&msg);
//派发消息到对应的窗口过程函数
DispatchMessage(&msg);
}
}
return 0;
}
概念
对话框是一种特殊的视窗,用来在用户界面中向用户显示信息,或者在需要的时候获得用户的输入响应。
对话框三要素
- 编辑对话框模板资源(CTRL+T 可预览创建的对话框)
- 实现对话框过程函数
- 创建对话框示例
非模态对话框和模态对话框
联系
创建时都会发送VM_INITDIALOG消息
区别
- 创建函数不同
//创建模态对话框
DialogBox(g_hInstance,
MAKEINTRESOURCE(DLG_TEST),//对话框ID
hwnd,
ModDialogProc);//对话框过程函数
//创建非模态对话框
CreateDialog(g_hInstance,
MAKEINTRESOURCE(DLG_TEST),//对话框ID
hwnd,
ModDialogProc);//对话框过程函数
- 销毁函数不同
//销毁模态对话框
EndDialog(hwndDlg, 0);
//销毁非模态对话框
DestroyWindow(hwndDlg);
- 对话框实现原理不同
//模态对话框创建时会调用此函数,禁止父窗口接受鼠标键盘操作
EnableWindow(g_hWnd, false);
//模态对话框销毁时会调用此函数,允许父窗口接受鼠标键盘操作
EnableWindow(g_hWnd, true);
- 对话框显示方式不同
//非模态对话框创建完,需要调指定函数才可显示
HWND hWnd = CreateDialog(g_hInstance,
MAKEINTRESOURCE(DLG_TEST),
hwnd,
ModlessDialogProc);
ShowWindow(hWnd, SW_SHOW);
创建对话框代码
// Win32Test.cpp : 定义应用程序的入口点。
//
#include "stdafx.h"
#include "Win32Test.h"
#include "resource.h"
/* 全局变量 */
/************************************************************************/
HINSTANCE g_hInstance = NULL;
HWND g_hWnd = NULL;
void ShowErrorMessage()
{
LPVOID lpMsgBuf;
//将错误码转化为错误信息,参数可以抄MSDN
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR)&lpMsgBuf,
0,
NULL
);
// Process any inserts in lpMsgBuf.
// ...
// 弹出错误提示窗口.
MessageBox(NULL, (LPCTSTR)lpMsgBuf, TEXT("Error"), MB_OK | MB_ICONINFORMATION);
// Free the buffer.
LocalFree(lpMsgBuf);
}
/************************************************************************/
/* 对话框处理函数 */
/************************************************************************/
BOOL CALLBACK ModDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
// //创建显示对话框之前触发的消息
//case WM_INITDIALOG:
// //允许父窗口接受鼠标键盘操作
// EnableWindow(g_hWnd, TRUE);
// break;
case WM_CLOSE:
//模态对话框销毁使用EndDialog
EndDialog(hwndDlg, 0);
break;
default:
break;
}
return FALSE;
}
//非模态对话框的处理函数
BOOL CALLBACK ModlessDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
////把非模态对话框修为模态对话框
//case WM_INITDIALOG:
// //允许父窗口接受鼠标键盘操作
// EnableWindow(g_hWnd, FALSE);
// break;
case WM_CLOSE:
//非模态对话框销毁使用DestroyWindow
DestroyWindow(hwndDlg);
break;
default:
break;
}
return FALSE;
}
LRESULT CALLBACK MyWindowPro
(HWND hwnd, // 窗口句柄
UINT uMsg, // 消息标识
WPARAM wParam, // 附加在消息上的参数
LPARAM lParam // 附加在消息上的参数
)
{
switch (uMsg)
{
case WM_COMMAND:
{
//高位判断通知类型如果来自菜单,则为0, 如果来自快捷键,则为1
WORD wFrom = HIWORD(wParam);
//低位保存菜单\快捷键的ID
WORD wID = LOWORD(wParam);
//菜单
if (wFrom == 0)
{
switch (wID)
{
case IDM_MODE_DIALOG:
{
//创建对话框
DialogBox(g_hInstance,
MAKEINTRESOURCE(IDD_DIALOG1),
hwnd,
ModDialogProc);
break;
}
case IDM_DIALOG:
{
//创建非模态对话框
HWND hWnd = CreateDialog(g_hInstance,
MAKEINTRESOURCE(IDD_DIALOG1),
hwnd,
ModlessDialogProc);
ShowWindow(hWnd, SW_SHOW);
break;
}
default:
break;
}
}
break;
}
//点击关闭窗口会发送WM_CLOSE消息
case WM_CLOSE:
{
int nRet = MessageBox(hwnd, TEXT("是否退出"), TEXT("询问"), MB_OKCANCEL);
if (nRet == IDCANCEL)//取消关闭
{
return 0;
}
else
{
//摧毁窗口发送WM_DESTROY消息
DestroyWindow(hwnd);
}
break;
}
case WM_DESTROY:
{
//向消息队列投递WM_QUIT消息 WM_QUIT使消息循环退出,程序退出。
PostQuitMessage(0);
break;
}
default:
break;
}
//系统默认处理消息窗口函数
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
//句柄可以理解为标识ID,如窗口句柄就表示这个标识这个窗口的唯一ID
int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,//应用程序当前实例的句柄
_In_opt_ HINSTANCE hPrevInstance,//应用程序的先前实例的句柄
_In_ LPTSTR lpCmdLine,//指向应用程序命令行的字符串的指针
_In_ int nCmdShow)//指明窗口如何显示,查msdn帮助文档,有各种宏
{
g_hInstance = hInstance;
WNDCLASS wc;
wc.style = CS_HREDRAW | CS_VREDRAW; //默认风格,窗口尺寸被修改后重画窗口
wc.lpfnWndProc = MyWindowPro; //窗口回调
wc.cbClsExtra = 0; //窗口类的额外空间
wc.cbWndExtra = 0; //窗口实例的额外空间
wc.hInstance = hInstance;
wc.hIcon = NULL; //图标
wc.hCursor = NULL; //光标
wc.hbrBackground = (HBRUSH)(COLOR_HIGHLIGHT);//背景
wc.lpszMenuName = MAKEINTRESOURCE(IDM_TEST);//菜单
wc.lpszClassName = TEXT("MyWindow");
//加载菜单
HMENU hMenu = LoadMenu(hInstance, TEXT("testmenu"));
ATOM nRet = RegisterClass(&wc);
if (nRet == 0)
{
ShowErrorMessage();
}
//创建窗口实例
HWND hWnd = CreateWindow(
TEXT("MyWindow"), //窗口类名
TEXT("Hello World"), //窗口标题
WS_OVERLAPPEDWINDOW, //重叠窗口
CW_USEDEFAULT, CW_USEDEFAULT, //默认坐标
CW_USEDEFAULT, CW_USEDEFAULT,//默认长和宽
NULL, //没有父窗口
NULL, //加载菜单
hInstance,//main函数的实例句柄
NULL//暂时不用,(LPVOID)0x87654093,可用来做参数标记
);
if (hWnd == NULL)
{
ShowErrorMessage();
}
g_hWnd = hWnd;
//显示窗口
ShowWindow(hWnd, SW_SHOW);
//更新窗口
UpdateWindow(hWnd);
MSG msg;
//消息循环
//加载快捷键
HACCEL hAccel = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDA_TEST));
while (GetMessage(&msg, NULL, 0, 0) != 0)
{
//转换WM_KEYDOWN消息为快捷键消息
if (!TranslateAccelerator(hWnd, hAccel, &msg))
{
//将keydown消息转换为字符消息
TranslateMessage(&msg);
//派发消息到对应的窗口过程函数
DispatchMessage(&msg);
}
}
return 0;
}