Почему Drawtext все еще рисует текст, когда я не проверил свой RECT?

Я заменяю BeginPaint-EndPaint в простом окне на GetDC-ReleaseDC. Я читаю Чарльза Петцольда «Программирование Windows 5th Edition».

Вот мой код с изменениями и строками, измененными как комментарии:

#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? Насколько я понимаю (что явно неверно), текст внутри RECT rc не должен появляться, пока я не вызову ValidateRect. Когда окно отображается, нарисованный текст мерцает, что, как я предполагаю, происходит из-за того, что Windows вызывает WM_PAINT и пытается проверить rc (моя клиентская область), но DrawText по-прежнему удается отображать текстовую строку каждый раз. Я немного смущен.

МЕРцающий текст


person strax    schedule 16.02.2015    source источник
comment
Ваш текст отображается снова и снова, потому что вы не вызвали ValidateRect. EndPaint вызывает ValidateRect, чтобы пометить область, визуализируемую во время этого цикла рисования, как допустимую, то есть не требующую визуализации.   -  person IInspectable    schedule 17.02.2015
comment
Если оставить область, помеченную как недействительную, вы не остановите ее, это просто означает, что система не будет думать, что вы нарисовали ее, и будет продолжать просить вас об этом.   -  person Jonathan Potter    schedule 17.02.2015
comment
Спасибо вам обоим, теперь я понял.   -  person strax    schedule 17.02.2015


Ответы (1)


Ваш текст отображается снова и снова, потому что вы не вызвали ValidateRect. EndPaint вызывает ValidateRect, чтобы пометить область, визуализируемую во время этого цикла рисования, как допустимую, то есть не требующую визуализации.

Если оставить область, помеченную как недействительную, вы не остановите ее, это просто означает, что система не будет думать, что вы нарисовали ее, и будет продолжать просить вас об этом.

(опубликовано как вики сообщества, так как на вопрос был дан ответ в комментариях)

person Community    schedule 16.02.2015