重绘客户端窗口


我希望能够单击客户区中的按钮并重新绘制客户区。
我的主要问题是我似乎无法让它正常工作。
按下按钮后我得到的是闪烁。

我尝试过的:

我试过了。

C++
void CButtonTestView::OnButtonClicked()
{
	AfxMessageBox(L"Button clicked");
	Clicked = TRUE;
	Invalidate();
	UpdateWindow();
}

void CButtonTestView::OnDraw(CDC* pDC)
{
	CButtonTestDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	if (!pDoc)
		return;
	// TODO: add draw code for native data here
	pDC->TextOutW(800, 100, _T("Button test"));

	if (Clicked)
	{
		InvalidateRect(nullptr, TRUE);
	}
}

视觉工作室2017。
任何贡献表示赞赏

解决方案1

据我所知你不应该打电话 InvalidateRect 里面 OnDraw 因为,最后,这重新安排了 OnDraw 再次。

解决方案2

CPallini 提到,您不需要在 OnDraw 处理程序中调用 InvalidateRect。 你这样做会让自己陷入无限循环。 至少,将 Clicked 设置为 false 以停止循环。

闪烁的原因是调用 Invalidate(),因为它有一个默认参数擦除,设置为 true,这意味着它会擦除整个窗口。 这会导致调用 OnEraseBkgnd,用背景颜色填充整个窗口,然后调用 OnDraw 方法。 所有这些都会导致闪烁。

有(至少)两种可能的方法来避免闪烁。 一种是调用 Invalidate 并将 false 传递给它,这样它就不会擦除背景。 仅当您的 OnDraw 方法完全绘制所有前景图像时,这才有效,但通常不会。 另一种方法是绘制到内存设备上下文中。 MFC 有一个名为 CMemDC 的内置类来帮助解决此问题。 这里还有一篇由 Keith Rule 撰写的文章,其中介绍了运行良好的内存 DC 的简单实现。 为此,您的 OnDraw 处理程序还必须绘制背景,并且您希望有一个 OnEraseBkgnd 处理程序,它只返回 TRUE 来指示它已绘制,但实际上什么也不做。

解决方案3

我在用户界面线程中显示无模式对话框时遇到问题。 使用“创建”激活的对话框与另一个对话框显示重叠模式。 即使我缩小或展开,重叠的对话框也会变大。 我该如何解决这个问题

コメント

タイトルとURLをコピーしました