MFC中OnPaint OnDraw 自动生成的代码的含义

u0116snail 2014-08-20 10:11:25
MFC中,关于绘图的函数,我有几个不懂的问题:

1. 在OnPaint 中,自动生成的代码是做什么用的,有什么含义?
void CtestDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting

SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;

// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialogEx::OnPaint();
}

}



2. 在 OnDraw中,自动生成的代码,有什么含义,有什么用?

void CtestView::OnDraw(CDC* /*pDC*/)
{
Ctest2Doc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;

// TODO: add draw code for native data here
}

...全文
301 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
schlafenhamster 2014-08-20
  • 打赏
  • 举报
回复
可以 “贴图代码之前 调用 CDialogEx::OnPaint(); ” 但 贴图代码 不能再使用 CPaintDC dc(this); 应该使用 CClientDC dc(this);
快乐鹦鹉 2014-08-20
  • 打赏
  • 举报
回复
对啊,如果你不需要基类重画,就注释掉它,完全由你来实现绘制;或者你在基类绘制完后,增加你的补充绘制代码。不应该在自己的绘制代码之后,再执行基类的绘制,肯定把你的绘制内容给覆盖掉了。
u0116snail 2014-08-20
  • 打赏
  • 举报
回复
引用 1 楼 happyparrot 的回复:
OnPaint中考虑窗口是否最小化状态,最小化时显示程序图标;不是最小化时调用基类的OnPaint。其实你不响应OnPaint,它本身就是这么处理的,你响应后,就可以调整处理过程 OnDraw中只是预先判断对应的文档对象是否存在,不存在就不需要处理了,因为OnDraw是视图类的绘图处理
恩 ,OnDraw 懂了。向您请教一下 OnPaint吧: 在 OnPaint 中,调用基类的 CDialogEx::OnPaint(); 函数,会有什么影响? 例如,我在做MFC贴图的时候,如果贴图代码之前 调用了 CDialogEx::OnPaint(); 那么贴图效果就没有了。
wangyubuct1 2014-08-20
  • 打赏
  • 举报
回复
学习了。这两个函数关系还是挺复杂啊。
快乐鹦鹉 2014-08-20
  • 打赏
  • 举报
回复
OnPaint中考虑窗口是否最小化状态,最小化时显示程序图标;不是最小化时调用基类的OnPaint。其实你不响应OnPaint,它本身就是这么处理的,你响应后,就可以调整处理过程 OnDraw中只是预先判断对应的文档对象是否存在,不存在就不需要处理了,因为OnDraw是视图类的绘图处理
u0116snail 2014-08-20
  • 打赏
  • 举报
回复
本帖子虽然看似一个简单问题,却迎来三位大神前来助阵,非常感谢!结贴给分!
schlafenhamster 2014-08-20
  • 打赏
  • 举报
回复
CPaintDC 和 CClientDC 区别 CPaintDC 用于 有 无效 区的 绘制。 绘制后 这个dc 就没有 无效区了, 你 就 不能 再 绘制东西了。 CClientDC 与 无效区 无关, 但 通常 用于 窗口 没有 无效区时 的 绘制。
cjfdqchwhj 2014-08-20
  • 打赏
  • 举报
回复
CPaintDC 构造中调用了 BeginPaint,在析构中调用 EndPaint,它析构自动消除消息队列中的 WM_PAINT消息。 CClientDC 构造调用 GetDC, 析构中调用 ReleaseDC, CClientDC 只能在客户区中绘制。 这种绘图变化的,用CClientDC好些,如果要绘制标题栏等,就用CPaintDC。
u0116snail 2014-08-20
  • 打赏
  • 举报
回复
引用 4 楼 happyparrot 的回复:
引用 5 楼 schlafenhamster 的回复:
下面是我在 OnPaint中的贴图代码,这样看着代码,便于两位更加明白:
void CtestDlg::OnPaint()
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{	
		CDialogEx::OnPaint();
	}

//	CPaintDC dc(this); //使用光栅操作
	CClientDC dc(this);
	CDC memDC;
	memDC.CreateCompatibleDC(&dc);

	CBitmap	bitmap;
	//	bitmap.LoadBitmapW(BMP_TEST2);
	bitmap.LoadBitmapW(BMP_TIGER);
	BITMAP bm;
	bitmap.GetBitmap(&bm);
	memDC.SelectObject(&bitmap);

	CDC dcmask;
	dcmask.CreateCompatibleDC(&dc);
	CBitmap bmpmask;
	bmpmask.CreateBitmap(bm.bmWidth, bm.bmHeight, 1, 1, NULL);
	dcmask.SelectObject(&bmpmask);
	memDC.SetBkColor(RGB(255,255,255));

	dcmask.BitBlt(0, 0, bm.bmWidth, bm.bmHeight, &memDC, 0, 0, SRCCOPY);
	dc.BitBlt(0, 0, bm.bmWidth, bm.bmHeight, &memDC, 0, 0, SRCINVERT);
	dc.BitBlt(0, 0, bm.bmWidth, bm.bmHeight, &dcmask, 0, 0, SRCAND);
	dc.BitBlt(0, 0, bm.bmWidth, bm.bmHeight, &memDC, 0, 0, SRCINVERT);
}
上面这段代码,我初步总结如下: 如果使用 CPaintDC 那么,在我自己的贴图代码之前,(是之前,在最后调用没有影响)调用积基类的 CDialogEx::OnPaint(); 导致贴图代码没有影响。 如果使用CClientDC ,没有上面的问题发生。不管 CDialogEx::OnPaint(); 在什么地方调用,没有什么影响。
u0116snail 2014-08-20
  • 打赏
  • 举报
回复
引用 4 楼 happyparrot 的回复:
对啊,如果你不需要基类重画,就注释掉它,完全由你来实现绘制;或者你在基类绘制完后,增加你的补充绘制代码。不应该在自己的绘制代码之后,再执行基类的绘制,肯定把你的绘制内容给覆盖掉了。
恩恩,其实,跟用 CPaintDC 和 CClientDC 有很大关系。我却没有弄明白为什么
u0116snail 2014-08-20
  • 打赏
  • 举报
回复
引用 5 楼 schlafenhamster 的回复:
可以 “贴图代码之前 调用 CDialogEx::OnPaint(); ” 但 贴图代码 不能再使用 CPaintDC dc(this); 应该使用 CClientDC dc(this);
您说的非常对,那么我就又有一个疑问了: CPaintDC 和 CClielntDC 有何区别?使用时需要注意什么吗?

15,978

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 界面
社区管理员
  • 界面
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧