为什么在我没有验证我的 RECT 时 Drawtext 仍在绘制文本?

Why Drawtext is still drawing text when I haven`t validated my RECT?

我正在用一个简单的 window 将 BeginPaint-EndPaint 替换为 GetDC-ReleaseDC。 我正在阅读 Charles Petzold Programming Windows 第 5 版。

这是我的代码,其中的更改和行更改为注释:

#include<Windows.h>
#include<mmsystem.h>



LRESULT CALLBACK myWndProc(HWND windowHandle, UINT winMessage, WPARAM wParam, LPARAM lParam);

int 
WINAPI 
WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
    WNDCLASSEX myWndClass;
    MSG msg;
    HWND myWndHandle;

    wchar_t szmyWndClassName[] = TEXT("SotoWindClass");
    wchar_t szmyWndowName[] = TEXT("SotoWindow");

    myWndClass.cbClsExtra = 0;
    myWndClass.cbSize = sizeof(WNDCLASSEX);
    myWndClass.cbWndExtra = 0;
    myWndClass.hbrBackground = (HBRUSH)GetStockObject(GRAY_BRUSH);
    myWndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
    myWndClass.hIcon = LoadIcon(NULL, IDI_HAND);
    myWndClass.hIconSm = NULL;
    myWndClass.hInstance = hInstance;
    myWndClass.lpfnWndProc = myWndProc;
    myWndClass.lpszClassName = szmyWndClassName;
    myWndClass.lpszMenuName = NULL;
    myWndClass.style = CS_HREDRAW | CS_VREDRAW;

    if (!RegisterClassEx(&myWndClass))
    {
        MessageBoxEx(NULL, TEXT("I need at least WINNT"), szmyWndClassName, MB_ICONERROR, 0);
    }


    myWndHandle = CreateWindowEx(
        WS_EX_LEFT,
        szmyWndClassName,
        szmyWndowName,
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        NULL,
        NULL,
        hInstance,
        NULL);

    ShowWindow(myWndHandle, iCmdShow);
    UpdateWindow(myWndHandle);

    while (GetMessage(&msg,NULL,0,0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return msg.wParam;
}

LRESULT CALLBACK myWndProc(HWND windowHandle, UINT winMessage, WPARAM wParam, LPARAM lParam)
{
    HDC hdc;
    //PAINTSTRUCT ps;
    RECT rc;

    wchar_t displayText[] = TEXT("Display My Text!!!!");

    switch (winMessage)
    {
        case WM_CREATE:
        {
            PlaySound(TEXT("hellowin.wav"), NULL, SND_FILENAME | SND_ASYNC);
            return(0);
        }break;

        case WM_PAINT:
        {
            /*
            hdc = BeginPaint(WindowHandle, &ps);
            DrawText(hdc, TEXT("Hello Win 7!!!"), -1, &rc, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
            EndPaint(WindowHandle, &ps);
            return(0);
            */

            hdc = GetDC(windowHandle);
            GetClientRect(windowHandle, &rc);
            //ValidateRect(windowHandle, &rc);
            DrawText(hdc, displayText, -1, &rc, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
            ReleaseDC(windowHandle, hdc);
            return(0);
        }

        case WM_DESTROY:
        {
            PlaySound(NULL, NULL, SND_FILENAME | SND_ASYNC);
            PostQuitMessage(0);
            return(0);
        }
    }

    return(DefWindowProc(windowHandle, winMessage, wParam, lParam));
}

我的问题是: 为什么 DrawText 在我没有打电话给 ValidateRect 时仍然显示消息? 根据我的理解(这显然是不正确的),除非我调用 ValidateRect,否则 RECT rc 中的文本不应出现。 当显示 window 时,绘制的文本会闪烁,我认为这是因为 Windows 正在调用 WM_PAINT 并试图验证 rc (我的客户区)但是 DrawText 仍然设法每次都显示文本行。 我有点困惑。

您的文本被一次又一次地渲染,因为您没有调用 ValidateRectEndPaint 调用 ValidateRect 将此绘制周期中渲染的区域标记为有效,即不需要渲染。

将标记为无效的区域保留下来并不会阻止您向其绘图,这只是意味着系统不会认为您已向其绘图并会继续要求您这样做。

(发布为社区维基,因为问题已在评论中得到解答)