我已经用C++写了用WinApi绘制的程序。我的回调函数:
/* This function is called by the Windows function DispatchMessage() */
LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message) /* handle the messages */
{
case WM_DESTROY:
PostQuitMessage(0); /* send a WM_QUIT to the message queue */
break;
case WM_ERASEBKGND:
{
elWidget *widget = (elWidget *)GetWindowLong(hwnd, GWL_USERDATA);
if (widget)
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hwnd, &ps);
HBRUSH hBrush = CreateSolidBrush(widget->color.ColorRef());
FillRect((HDC)wParam, &ps.rcPaint, hBrush);
DeleteObject(hBrush);
EndPaint(hwnd, &ps);
}
}
break;
default: /* for messages that we don't deal with */
return DefWindowProc(hwnd, message, wParam, lParam);
}
return 0;
}它适用于独立窗口(样式为WS_OVERLAPPED),但当样式为WS_CHILD或WS_CHILD | WS_VISIBLE时,始终ps.rcPaint为(0,0,0,0)。我不知道该怎么解决。
elButton::elButton(elWidget *owner)
: elWidget(owner)
{
WNDCLASSEX winclChild; /* Data structure for the windowclass */
/* The Window structure */
winclChild.hInstance = gThisInstance; //global variable instance
winclChild.lpszClassName = L"Child";
winclChild.lpfnWndProc = WindowProcedure; /* This function is called by windows */
winclChild.style = CS_DBLCLKS; /* Catch double-clicks */
winclChild.cbSize = sizeof (WNDCLASSEX);
/* Use default icon and mouse-pointer */
winclChild.hIcon = LoadIcon (NULL, IDI_APPLICATION);
winclChild.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
winclChild.hCursor = LoadCursor (NULL, IDC_ARROW);
winclChild.lpszMenuName = NULL; /* No menu */
winclChild.cbClsExtra = 0; /* No extra bytes after the window class */
winclChild.cbWndExtra = 0; /* structure or the window instance */
/* Use Windows's default colour as the background of the window */
winclChild.hbrBackground = 0;// CreateSolidBrush(RGB(255, 200, 200));//(HBRUSH)COLOR_WINDOW;//COLOR_BACKGROUND;
/* Register the window class, and if it fails quit the program */
if (!RegisterClassEx(&winclChild))
return;
hwnd = CreateWindowEx(
0, /* Extended possibilites for variation */
L"Child", /* Classname */
L"Title", /* Title Text */
WS_CHILD | WS_VISIBLE,
100,
100,
40,
40,
owner->getHwnd(), /* The window is a child-window to desktop */
NULL, /* No menu */
gThisInstance, /* Program Instance handler */
this /* to lParam */
);
SetWindowLong(hwnd, GWL_USERDATA, (long)this);
}我可以添加到谷歌磁盘上的整个项目的链接,但我不能保证它将是永久的多年。
发布于 2015-11-29 16:16:21
只能在WM_PAINT上调用BeginPaint,
要获取WM_ERASEBKGND上的剪贴框,请调用GetClipBox((HDC)wParam,&rect);
发布于 2015-11-29 05:26:04
仅对WM_PAINT使用BeginPaint/EndPaint。
来自:的Windows文档
除非响应WM_PAINT消息,否则
应用程序不应该调用
BeginPaint。每个对BeginPaint的调用都必须有一个对EndPaint函数的对应调用。
虽然您的代码看起来似乎可以工作,但它很可能会在其他地方造成问题,例如在WM_PAINT中
要从WM_PAINT外部获取更新区域,请使用GetUpdateRect。但是,不能在WM_ERASEBKGND中使用GetUpdateRect。另请参阅
一个简单的解决方案是强制WM_ERASEBKGND什么都不做,然后在WM_PAINT中处理所有事情
switch(msg)
{
case WM_ERASEBKGND:
return TRUE;
case WM_PAINT:
...
}发布于 2015-11-29 06:10:55
这段代码非常适合我。答案是我们必须分别为父窗口和子窗口定义单独的窗口类。我看到SetWindowLong在所有情况下都能正常工作。但是如果你想立即用新数据重绘新窗口,你必须删除WS_VISIBLE作为你的创建风格,并且在ShowWindow之前使用SetWindowLong。ShowWindow函数使您的窗口可见,并使用新参数重新绘制窗口。
#include <windows.h>
LRESULT CALLBACK WndProc(HWND hWnd,
UINT message,
WPARAM wParam,
LPARAM lParam);
int RegClass(HINSTANCE hInstance,LPCTSTR lpszClassName)
{
WNDCLASS wc;
wc.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS | CS_OWNDC;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.lpfnWndProc = WndProc;
wc.lpszClassName = (LPCTSTR)lpszClassName;
wc.lpszMenuName = (LPCTSTR)NULL;
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW);
wc.hCursor = (HCURSOR)LoadCursor(NULL,IDC_CROSS);
wc.hIcon = (HICON)LoadIcon(NULL,IDI_APPLICATION);
return RegisterClass(&wc);
}
HWND hWnd0, hWnd1;
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nShowCmd)
{
MSG message;
static LPCTSTR lpszClName = L"Wnd Class";
static LPCTSTR lpszCl0Name = L"Child Class";
if(!RegClass(hInstance,lpszClName))
exit(0);
if(!RegClass(hInstance,lpszCl0Name))
exit(0);
hWnd0 = CreateWindow(
lpszClName,
L"Привіт!",
WS_OVERLAPPEDWINDOW | WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
CW_USEDEFAULT,
CW_USEDEFAULT,
800,
600,
0,
0,
hInstance,
NULL
);
hWnd1 = CreateWindow(
lpszCl0Name,
L"Привіт!",
WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
40,
40,
400,
300,
hWnd0,
0,
hInstance,
NULL
);
ShowWindow(hWnd0,SW_SHOWNORMAL);
UpdateWindow(hWnd0);
RECT WndRect;
// For parent redraw
GetWindowRect(hWnd0, &WndRect);
MoveWindow(hWnd0, WndRect.left, WndRect.top, 801, 601, TRUE);
SetWindowLong(hWnd0, GWL_USERDATA, RGB(0, 255, 0));
ShowWindow(hWnd1,SW_SHOWNORMAL);
UpdateWindow(hWnd1);
while (GetMessage(&message,0,0,0))
{
TranslateMessage(&message);
DispatchMessage(&message);
}
return message.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd,
UINT message,
WPARAM wParam,
LPARAM lParam)
{
switch (message) /* handle the messages */
{
case WM_CREATE:
InvalidateRect(hWnd, NULL, TRUE);
break;
case WM_DESTROY:
PostQuitMessage(0); /* send a WM_QUIT to the message queue */
break;
case WM_ERASEBKGND:
{
if (true)
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
COLORREF color = (hWnd == hWnd0) ? RGB(255, 0, 0) : GetWindowLong(hWnd0, GWL_USERDATA);
HBRUSH hBrush = CreateSolidBrush(color);
FillRect((HDC)wParam, &ps.rcPaint, hBrush);
DeleteObject(hBrush);
EndPaint(hWnd, &ps);
ValidateRect(hWnd, NULL);
}
}
break;
default: /* for messages that we don't deal with */
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}结果将会是。

https://stackoverflow.com/questions/33976115
复制相似问题