資源
概念
- 資源:所有除代碼以外的東西都可稱為資源
- ID:SDK所有添加的資源都可以設定唯一的ID
- 若用字元串命名資源ID,需要字元串外加入雙引号("")
- 可用指定API将資源ID轉換為對應指針 宏函數
MAKEINTRESOURCE(MN_EDIT) // ID轉指針
帶資源的EXE檔案生成流程
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsICM38FdsYkRGZkRG9lcvx2bjxiNx8VZ6l2cskXRE1kMJRkTx0keYhnRzwEMW1mY1RzRapnTtxkb5ckYplTeMZTTINGMShUYfRHelRHLwEzX39GZhh2css2RkBnVHFmb1clWvB3MaVnRtp1XlBXe0xyayFWbyVGdhd3LcV2Zh1Wa9M3clN2byBXLzN3btg3Pn5GcuUDN0MDNzEDM2IjNwkTMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
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;
}