简体   繁体   English

如何使 WM_PAINT 从 wndproc 外部运行

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM