窗口未显示 WM_PAINT 中的线条

Posted

技术标签:

【中文标题】窗口未显示 WM_PAINT 中的线条【英文标题】:window isn't showing line made in WM_PAINT 【发布时间】:2011-09-11 09:58:52 【问题描述】:

我对这个领域有点陌生,所以.. 据我了解,我在 WM_PAINT 中制作了以下代码,我正在创建一条线,但是我看不到这条线,因为窗口根本没有显示。 我有一个每 2 秒调用一次 WM_PAINT 的线程,但是每次运行程序后都没有显示任何内容。

先谢谢了。

#include <windows.h>
#include <stdio.h>

DWORD WINAPI StartThread1(LPVOID LPElm); 

//---------------------------------------------------------------------------
HWND hWnd;
LPCTSTR ClsName = L"WndMsg";
LPCTSTR WindowCaption = L"Windows and Controls Messages";
LRESULT CALLBACK WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
//---------------------------------------------------------------------------
INT WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                   LPSTR lpCmdLine, int nCmdShow)

    MSG         Msg;
    WNDCLASSEX  WndClsEx;

    WndClsEx.cbSize        = sizeof(WNDCLASSEX);
    WndClsEx.style         = CS_HREDRAW | CS_VREDRAW;
    WndClsEx.lpfnWndProc   = WndProc;
    WndClsEx.cbClsExtra    = NULL;
    WndClsEx.cbWndExtra    = NULL;
    WndClsEx.hInstance     = hInstance;
    WndClsEx.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
    WndClsEx.hCursor       = LoadCursor(NULL, IDC_ARROW);
    WndClsEx.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
    WndClsEx.lpszMenuName  = NULL;
    WndClsEx.lpszClassName = ClsName;
    WndClsEx.hIconSm       = LoadIcon(NULL, IDI_APPLICATION);

    RegisterClassEx(&WndClsEx);

    hWnd = CreateWindowEx(WS_EX_OVERLAPPEDWINDOW,
                          ClsName,
                          WindowCaption,
                          WS_OVERLAPPEDWINDOW,
                          100,
                          120,
                          640,
                          480,
                          NULL,
                          NULL,
                          hInstance,
                          NULL);

    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);

    DWORD ThreadId1, ThreadId2;
    HANDLE HandleThread1 = CreateThread(0,0,StartThread1,0,0,&ThreadId1);

    while( GetMessage(&Msg, NULL, 0, 0) )
    
        TranslateMessage(&Msg);
        DispatchMessage(&Msg);
    

    return Msg.wParam;


//---------------------------------------------------------------------------
LRESULT CALLBACK WndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)

        HDC hDC;
    PAINTSTRUCT Ps;
    switch(Msg)
    
    case WM_CREATE:
    //MessageBox(NULL, L"The window is being created", WindowCaption, MB_OK);
    break;
    case WM_SHOWWINDOW:
        break;

    case WM_PAINT:
    hDC = BeginPaint(hWnd, &Ps);
    MoveToEx(hDC, 0, 0, NULL);
    LineTo(hDC, 10, 10);
    EndPaint(hWnd, &Ps);

    break;

    case WM_DESTROY:
        PostQuitMessage(WM_QUIT);
        break;
    default:
        return DefWindowProc(hWnd, Msg, wParam, lParam);
    
    return 0;

//---------------------------------------------------------------------------


DWORD WINAPI StartThread1(LPVOID LPElm)

    int n = 5000,i,j;

    for (i=0; i<n; i++)
    
        SendMessage(hWnd,WM_PAINT,NULL,NULL);
        Sleep(2000);
        /*for (j=0;j<10;j++)
            a[j] = (rand() % 100);
        printf("\n");*/
    

    return 0;

【问题讨论】:

很久没做Win32了,难道你不应该在HDC中加载一个画笔吗?谁说这不是画线,但线是白色的。在hbrBackground 行的某处不应该有+ 1... 【参考方案1】:

您不应该自己发送WM_PAINT。您需要使用InvalidateRect。您还需要用某些东西进行绘图 - 您需要使用SelectObject 将有效的笔对象选择到 DC。

【讨论】:

我尝试像这样编写函数 startthread1,但是当我尝试调试时它仍然没有到达 WM_PAINT。不知道为什么 DWORD WINAPI StartThread1(LPVOID LPElm) InvalidateRect(hWnd,NULL,TRUE);返回0; 即使我尝试在函数中放置一个矩形结构,然后调用 updatewindow,它也不会调用 WM_PAINT。我不明白为什么。我的窗户有问题吗?? 解决了,只是使用 updatewindow 而不是 incalidaterect。【参考方案2】:

WM_PAINT消息是系统在重绘窗口时发送的,所以不需要你自己发送消息。如果要重绘窗口,请使用InvalidateRect。如果你在你的程序中使用Thread,你应该以ExitProcess(ThreadID)退出线程,然后执行下面的代码。笔的默认颜色是黑色,因此您可以看到它。在你的情况下,你的线程没有退出,所以程序停在那里。窗户永远不会油漆。你可以在你的程序中使用MessageBox()来测试现在在哪里运行。

【讨论】:

以上是关于窗口未显示 WM_PAINT 中的线条的主要内容,如果未能解决你的问题,请参考以下文章

VC SDK中关于WM_PAINT的新手问题

挂钩时覆盖窗口未正确绘制

文本视图下方的可绘制线条未显示

调整窗口大小以适应 WM_PAINT 之后的内容

线条未正确显示d3.js geo和google地图

位图未在 Win32 C++ 中绘制