Win32 SDK 定制模态和非模态窗口小记
typedef enum ChildrenControls {
IDCC_MINIMUM = WM_USER,
IDCC_BUTTON_TEST,
IDCC_MAXIMUM,
};
std::unordered_map<uint16_t, WNDPROC> cc_umap;
std::unordered_map<HWND, WNDPROC> cc_wndproc_umap;
HWND CreatePpsdlg(HWND hParent = NULL, LPVOID lpWndProc = NULL, BOOL bModal = TRUE, BOOL bCenter = TRUE)
{
HWND hWnd = NULL;
WNDCLASSEX wcex = { sizeof(WNDCLASSEX) };
bModal &= (hParent != NULL);
if (bModal) { EnableWindow(hParent, FALSE); }
GetClassInfoEx(GetModuleHandle(NULL), WC_DIALOG, &wcex);
wcex.lpszClassName = TEXT(__func__);
wcex.lpfnWndProc = ([](HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)->LRESULT
{
WNDPROC fnWndProc = NULL;
switch (uMsg)
{
case WM_CREATE:
{
if ((lParam != NULL) && (fnWndProc = *(WNDPROC*)lParam) != NULL)
{
fnWndProc(hWnd, uMsg, wParam, lParam);
SetProp(hWnd, TEXT(__func__), (HANDLE)(fnWndProc));
}
}
break;
case WM_DESTROY:
{
PostMessage(hWnd, WM_QUIT, (WPARAM)0, (LPARAM)0);
}
break;
default:
{
if ((fnWndProc = (WNDPROC)GetProp(hWnd, TEXT(__func__))) != NULL )
{
fnWndProc(hWnd, uMsg, wParam, lParam);
}
}
break;
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
});
RegisterClassEx(&wcex);
/////////////////////////////////////////////////
if ((hWnd = CreateWindowEx(
WS_EX_DLGMODALFRAME,
wcex.lpszClassName,
wcex.lpszClassName,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
CW_USEDEFAULT,
hParent,
NULL,
wcex.hInstance,
lpWndProc)
) != NULL) {
if (bCenter == TRUE)
{
if (hParent != NULL)
{
CenterWindowInParent(hWnd, hParent);
}
else
{
CenterWindowInScreen(hWnd);
}
}
ShowWindow(hWnd, SW_SHOW);
UpdateWindow(hWnd);
while (1)
{
MSG msg = { 0 };
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
if (msg.message == WM_QUIT)
{
break;
}
else
{
if (bModal && (msg.hwnd != hWnd))
{
continue;
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
else
{
// 完成某些工作的其他行程式
}
}
}
if (bModal) { EnableWindow(hParent, TRUE); SetForegroundWindow(hParent); }
return 0;
}
LRESULT CALLBACK HandleButtonTestWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
CreatePpsdlg(hWnd, NULL, TRUE);
return 0;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_CREATE:
{
cc_umap.emplace(IDCC_BUTTON_TEST, HandleButtonTestWndProc);
CreateWindowEx(0, WC_BUTTON, TEXT("test"), BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE, 0, 0, 60, 40, hWnd, (HMENU)IDCC_BUTTON_TEST, NULL, NULL);
}
return 0;
case WM_COMMAND:
{
if (cc_umap.find(LOWORD(wParam)) != cc_umap.end()) {
cc_umap.at(LOWORD(wParam))(hWnd, uMsg, wParam, lParam);
}
}
break;
case WM_PAINT:
{
HDC hdc;
PAINTSTRUCT ps;
hdc = BeginPaint(hWnd, &ps);
TextOut(hdc, 0, 0, TEXT("Hello world!"), lstrlen(TEXT("Hello world!")));
TextOut(hdc, 32, 32, TEXT("Win32 Api!"), lstrlen(TEXT("Win32 Api!")));
EndPaint(hWnd, &ps);
}
break;
}
return 0;
}