为什么在我没有验证我的 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
仍然设法每次都显示文本行。
我有点困惑。
您的文本被一次又一次地渲染,因为您没有调用 ValidateRect
。 EndPaint
调用 ValidateRect
将此绘制周期中渲染的区域标记为有效,即不需要渲染。
将标记为无效的区域保留下来并不会阻止您向其绘图,这只是意味着系统不会认为您已向其绘图并会继续要求您这样做。
(发布为社区维基,因为问题已在评论中得到解答)
我正在用一个简单的 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
仍然设法每次都显示文本行。
我有点困惑。
您的文本被一次又一次地渲染,因为您没有调用 ValidateRect
。 EndPaint
调用 ValidateRect
将此绘制周期中渲染的区域标记为有效,即不需要渲染。
将标记为无效的区域保留下来并不会阻止您向其绘图,这只是意味着系统不会认为您已向其绘图并会继续要求您这样做。
(发布为社区维基,因为问题已在评论中得到解答)