如何在WndProc外部触发WM_PAINT消息执行?
问题描述
我是WinAPI初学者,若问题表述幼稚请见谅。我想要实现的是:点击对话框中的按钮后,触发主窗口执行对应TextOut绘制文本。但目前修改pageID后,文本要等到WndProc下次执行才会显示。我知道UpdateWindow可触发重绘,但在对话框回调中无法获取主窗口hWnd,请求快速解决思路。
注:代码中部分变量暂未生效,是我尝试解决问题时添加的,但尚未成功。
相关代码
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { WCHAR greeting[] = _T("line1"); WCHAR greeting1[] = _T("another line"); switch (message) { case WM_COMMAND: { int wmId = LOWORD(wParam); // Parse the menu selections: switch (wmId) { case IDM_ABOUT: DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About); break; case IDM_EXIT: DestroyWindow(hWnd); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } } break; case WM_PAINT: { repaint = false; PAINTSTRUCT ps; HDC hdc = BeginPaint(hWnd, &ps); switch (pageID) { case 1: {//display first string TextOut(hdc, 5, 5, greeting, _tcslen(greeting)); break; } case 2: {//display the other string TextOut(hdc, 5, 100, greeting1, _tcslen(greeting1)); break; } } EndPaint(hWnd, &ps); } break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; } /*****************************************************************************/ // Message handler for about box. INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { UNREFERENCED_PARAMETER(lParam); switch (message) { case WM_INITDIALOG: return (INT_PTR)TRUE; case WM_COMMAND: if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) { EndDialog(hDlg, LOWORD(wParam)); return (INT_PTR)TRUE; pageID = 1; repaint = true; } if (LOWORD(wParam) == IDC_BUTTON1) { pageID = 2; return (INT_PTR)TRUE; } break; } return (INT_PTR)FALSE; }
快速解决思路
- 获取主窗口句柄:在对话框回调
About中,调用GetParent(hDlg)即可拿到主窗口的句柄——因为对话框是由主窗口作为父窗口创建的。 - 强制触发重绘:拿到主窗口句柄后,先用
InvalidateRect(hMainWnd, NULL, TRUE)标记整个窗口区域为需要重绘,再调用UpdateWindow(hMainWnd)立即发送WM_PAINT消息,让主窗口立刻重新绘制。 - 修正代码顺序错误:当前
IDOK/IDCANCEL分支中,return (INT_PTR)TRUE;写在了pageID = 1;之前,会导致后续代码完全不执行,必须把return语句移到变量修改和重绘操作之后。
修改后的关键代码片段
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { UNREFERENCED_PARAMETER(lParam); switch (message) { case WM_INITDIALOG: return (INT_PTR)TRUE; case WM_COMMAND: if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) { pageID = 1; HWND hMainWnd = GetParent(hDlg); InvalidateRect(hMainWnd, NULL, TRUE); UpdateWindow(hMainWnd); EndDialog(hDlg, LOWORD(wParam)); return (INT_PTR)TRUE; } if (LOWORD(wParam) == IDC_BUTTON1) { pageID = 2; HWND hMainWnd = GetParent(hDlg); InvalidateRect(hMainWnd, NULL, TRUE); UpdateWindow(hMainWnd); return (INT_PTR)TRUE; } break; } return (INT_PTR)FALSE; }
补充说明:确保pageID是全局变量或能被对话框回调访问到的变量,否则修改无法同步到主窗口的WM_PAINT逻辑中。
内容的提问来源于stack exchange,提问作者Vroom ZOOM
相关产品推荐
相关产品推荐

