我在Frame Window Class中有以下代码
void CMainFrame::OnPaint()
{
CPaintDC dc(this);
}
我有一个按钮事件处理程序
void CMainFrame::OnLButtonUp(UINT nFlags, CPoint point) {
CShapes shape;
CFrameWnd::OnLButtonUp(nFlags, point);
CPaintDC dc(this);
CRect client;
GetClientRect(&client);
shape.DrawRectangle(&dc, client, 10,10, 10,10);
shape.DrawRoundRectangle(&dc, client, 50, 50, 50, 50, 20, 20);
}
但是按钮后面没有绘制矩形。但是,当我从void CPaintDC dc(this);
中移除CMainFrame::OnPaint()
时,它可以正常工作,但窗口的响应速度非常慢。它耗费了太多的内存。
还尝试在AfxGetMainWnd()
的{{1}}中使用this
代替CPaintDC dc()
,但它无效。
答案 0 :(得分:2)
它变得如此缓慢的原因是你正在创造一个无限的“无所事事”循环。你必须遵守两条绝对规则:
OnPaint处理程序必须具有CPaintDC(this);
所有其他消息处理程序不得包含CPaintDC。
将您的绘画移动到OnPaint中。
答案 1 :(得分:0)
不要在按钮处理程序中执行您的绘制代码。在OnLButtonUp
电话后,将代码从OnPaint
移至CPaintDC dc(this)
例程(但请取出CFrameWnd::OnLButtonUp(nFlags, point);
代码。)
CPaintDC dc(this)
只能在OnPaint
例程中调用,而不能在按钮处理程序中调用。 (http://msdn.microsoft.com/en-us/library/a48eab8d.aspx - CPaintDC对象只能在响应WM_PAINT消息时使用,通常在OnPaint消息处理程序成员函数中。)
在绘图例程中调用Invalidate
将导致无限循环。
答案 2 :(得分:0)
CPaintDC
是一个RAII对象,它将BeingPaint()
ctor
和EndPaint()
中的dtor
包裹在一起(发生在函数末尾)。所以在这种情况下,你不是在画任何东西。只要窗口需要绘画,就会调用OnPaint
。它甚至不是由用户驱动的。它发生在很多事件上,如窗口激活,重叠等。按钮单击不会触发OnPaint
事件,除非它导致重新绘制窗口或强制Invalidate
。 CPaintDC也只在OnPaint函数中使用。对于其他绘图,您将使用CDC类。 (调用GetDC()
执行绘制操作和ReleaseDC()
)
我建议在OnPaint
函数中编写绘图代码以进行持久绘图。绘制矩形的数据可以存储在类中,并指示使用标志(尽管基于标志的编码不是一个好主意)并在OnPaint
函数内绘制。在事件处理程序(按钮单击)中绘制的问题是当窗口刷新时绘图将消失。这样的事情怎么样?
void CMainFrame::OnPaint()
{
CPaintDC dc(this);
if(draw_rect)
{
CShapes shape;
CRect client;
GetClientRect(&client);
shape.DrawRectangle(&dc, client, 10,10, 10,10);
shape.DrawRoundRectangle(&dc, client, 50, 50, 50, 50, 20, 20);
}
}
void CMainFrame::OnLButtonUp(UINT nFlags, CPoint point) {
CFrameWnd::OnLButtonUp(nFlags, point);
draw_rect = true;
}
答案 3 :(得分:-2)
它工作..
我在Invalidate();
方法的末尾添加了CMainFrame::OnPaint()
,但它确实有效。
void CMainFrame::OnPaint()
{
CPaintDC dc(this);
Invalidate();
}