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

时间:2015-02-16 21:49:08

标签: c winapi drawtext

我在GetDC-ReleaseDC的简单窗口中替换BeginPaint-EndPaint。 我正在阅读Charles Petzold编程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仍在显示消息? 根据我的理解(显然不正确)RECT rc中的文字不应出现,除非我致电ValidateRect。 当显示窗口时,绘制的文本闪烁,我认为这是因为Windows正在调用WM_PAINT并且正在尝试验证rc(我的客户区域),但DrawText仍设法显示文本每次都行。 我有点困惑。

FLICKERING TEXT

1 个答案:

答案 0 :(得分:1)

您的文字会一次又一次地呈现,因为您尚未调用ValidateRectEndPaint调用ValidateRect将此绘制周期中渲染的区域标记为有效,即不需要渲染。

留下标记为无效的区域不会阻止您绘制它,它只是意味着系统不会认为您已经吸引它并且会继续要求您。

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