[英]How to make WM_PAINT run from outside of wndproc
I apologize if this is a dumb question, im just starting to learn winapi.如果这是一个愚蠢的问题,我很抱歉,我刚刚开始学习 winapi。 here is the code in concern:这是相关的代码:
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;
}
I apologize for the seemingly random variables that don't do anything, I was just trying to make this work any way possible, but no dice.对于看似没有任何作用的随机变量,我深表歉意,我只是想以任何方式使这项工作成为可能,但没有骰子。
What I am trying to do, is to have one of the textouts run after a button is pressed in a dialog box.我想要做的是在对话框中按下按钮后运行其中一个文本输出。 Unfortunately, the text isn't displayed until wndproc runs next time.不幸的是,直到 wndproc 下次运行时才会显示文本。 UpdateWindow is useless, because I need to pass hWnd to it, but I can't do that when Im not in wndproc. UpdateWindow 没用,因为我需要将 hWnd 传递给它,但是当我不在 wndproc 中时我不能这样做。 Need a quick tip on how this should be done.需要有关如何完成此操作的快速提示。 Im sure everyone does it every day, just not obvious for me... Thanks!我相信每个人每天都这样做,只是对我来说并不明显......谢谢!
Basically use InvalidateRect
, but this comment基本上使用InvalidateRect
,但是这个评论
UpdateWindow is useless, because I need to pass hWnd to it, but I can't do that when Im not in wndproc. UpdateWindow 没用,因为我需要将 hWnd 传递给它,但是当我不在 wndproc 中时我不能这样做。
exhibits kind of a fundamental misunderstanding of how Win32 programming works.表现出对 Win32 编程如何工作的基本误解。 You always need a window handle to a window you are working with.您总是需要一个 window 句柄来连接您正在使用的 window。 You get window handles when you create windows;当您创建 windows 时,您将获得 window 句柄; you need to store those somewhere.您需要将它们存储在某个地方。
Anyway below is a minimal version of using buttons on one window to drive repainting of another window.无论如何,下面是使用一个 window 上的按钮来驱动另一个 window 重新绘制的最小版本。
#include <windows.h>
HINSTANCE g_hInstance = 0;
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK SomeOtherWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
const int kBtn1ID = 101;
const int kBtn2ID = 102;
int pageID = 1;
HWND g_other_hwnd = NULL;
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
MSG msg = { 0 };
WNDCLASS wc = { 0 };
wc.lpfnWndProc = WndProc;
wc.hInstance = hInstance;
wc.hbrBackground = (HBRUSH)(COLOR_BACKGROUND);
wc.lpszClassName = L"foobar";
if (!RegisterClass(&wc))
return 1;
wc.lpszClassName = L"some_other_window";
wc.lpfnWndProc = SomeOtherWndProc;
if (!RegisterClass(&wc))
return 1;
g_hInstance = hInstance;
if (!CreateWindow(L"foobar",
L"foobar",
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
0, 0, 640, 480, 0, 0, hInstance, NULL))
return 2;
if (!(g_other_hwnd = CreateWindow(L"some_other_window",
L"quux",
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
0, 0, 640, 480, 0, 0, hInstance, NULL)))
return 2;
while (GetMessage(&msg, NULL, 0, 0) > 0)
DispatchMessage(&msg);
return 0;
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_CREATE:
CreateWindow(L"button", L"some button", BS_PUSHBUTTON | WS_VISIBLE | WS_CHILD, 10, 10, 150, 35, hWnd, (HMENU)kBtn1ID, g_hInstance, 0);
CreateWindow(L"button", L"some other button", BS_PUSHBUTTON | WS_VISIBLE | WS_CHILD, 10, 55, 150, 35, hWnd, (HMENU)kBtn2ID, g_hInstance, 0);
break;
case WM_COMMAND: {
int btn_id = LOWORD(wParam);
switch (btn_id) {
case kBtn1ID:
pageID = 1;
InvalidateRect(g_other_hwnd, NULL, TRUE);
break;
case kBtn2ID:
pageID = 2;
InvalidateRect(g_other_hwnd, NULL, TRUE);
break;
}
}
break;
case WM_CLOSE:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
LRESULT CALLBACK SomeOtherWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
static auto greeting = L"hello there.";
static auto greeting1 = L"goodbye.";
switch (pageID) {
case 1: {//display first string
TextOut(hdc, 5, 5, greeting, lstrlenW(greeting));
break;
}
case 2: {//display the other string
TextOut(hdc, 5, 100, greeting1, lstrlenW(greeting1));
break;
}
}
EndPaint(hWnd, &ps);
}
return 0;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.