关于调用默认的CDialog::OnPaint()的问题

sghcpt 2010-08-01 11:09:05
请问,我想知道人默认的的窗口调用CDialog::OnPaint()函数那里默认做了些什么操作?
我的问题的出现是怎样的,我在窗口类中响应了CDialog::OnEraseBkGnd(CDC* pDC)函数 ,
把图片画到窗口中,这个函数我Return TRUE.我同时响应了OnPaint函数.我在OnPaint函数中
什么都没有做只调用默认的CDialog::OnPaint()函数。当我用一个窗口在它上面移动的时候,
它会有时候图片正常显示,有时候就有图片中混合白色的区域,请问出现这种情况的原因?
...全文
776 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
sghcpt 2010-08-02
  • 打赏
  • 举报
回复
谢谢了。结贴。
xxd_qd 2010-08-02
  • 打赏
  • 举报
回复
CDialog::OnPaint()什么也不做(当然,除了调用一遍BeginPaint和EndPaint之外),因为对话框本身除了背景之外什么都不需要画。
Eleven 2010-08-02
  • 打赏
  • 举报
回复
另外注意一下LoadPicture函数中GDI资源的释放。。。
arong1234 2010-08-02
  • 打赏
  • 举报
回复
顶,我相信正是楼主调用了GetDC,而不是用系统给的pDC才导致问题的
[Quote=引用 11 楼 na_he 的回复:]
嗬嗬,要用OnEraseBkgnd(CDC* pDC)传递进来的Pdc.
[/Quote]
na_he 2010-08-02
  • 打赏
  • 举报
回复
嗬嗬,要用OnEraseBkgnd(CDC* pDC)传递进来的Pdc.
xxd_qd 2010-08-02
  • 打赏
  • 举报
回复
if (m_hBitmap)
dcMemory.SelectObject(m_hBitmap);
m_hBitmap = (HBITMAP)dcMemory.SelectObject(SelectObject(MemDC, hOldBitmap));
这几句代码是干什么的?
你的dcMemory是LoadPicture传进来的参数,可在此之前却没有做任何赋值:
CDC dc;
LoadPicture(dc);
这样的DC什么也做不了。
还有,我没看见你向屏幕输出的代码。
OnEraseBkgnd给你传进来的参数pDC才真正是你窗口的DC,你根本没用到,怎么可能向屏幕输出?还有,既然OnEraseBkgnd已经把窗口DC传给你了,就不应该再通过GetDC、ReleaseDC之类的函数去获取、释放DC,需要用到DC的时候,老老实实用这个参数就好。
sghcpt 2010-08-02
  • 打赏
  • 举报
回复
xxd_pd,你好。谢谢你的回答。我的代码如下,就出现上面说的情况。
void CBaseClasse::OnPaint()
{
CDialog::OnPaint();
}
BOOL CBaseClasse::OnEraseBkgnd(CDC* pDC)
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
CRect rcClient;
GetClientRect(&rcClient);
CDC dc;
LoadPicture(dc);
return TRUE;
}
void CBaseClasse::LoadPicture(CDC& dcMemory)
{
CString strFileName = m_strFileName;
int nPicMode = m_nPicMode;
COLORREF crBg = m_crBg;
CRect rc;
GetClientRect(&rc);
//设置背景色
CBrush brush;
brush.CreateSolidBrush(crBg);

CDC * pDC = GetDC();
HBITMAP hOldBitmap, hOldBmp;
BITMAP bmInfo;
CBitmap MemBitmap, bitMap, *pOldBmp;
//双缓冲绘图
CDC MemDC, oldDC;
MemDC.CreateCompatibleDC(NULL);
MemBitmap.CreateCompatibleBitmap(pDC, rc.Size().cx, rc.Size().cy);
hOldBitmap = (HBITMAP)SelectObject(MemDC.GetSafeHdc(), MemBitmap);

TCHAR curDirectory[1024];
CString tempfile;
GetTempPath(1024 , curDirectory);
if (curDirectory[lstrlen(curDirectory) - 1] == '\\')
tempfile.Format(_T("%sTemp\\bgpic.bmp"), curDirectory);
else
tempfile.Format(_T("%s\\Temp\\bgpic.bmp"), curDirectory);

CString file = strFileName;
CImage image;
if (file != _T(""))
{
file = file.Right(file.GetLength() - file.Find('.') - 1);

if(file != _T("bmp"))
{
//加载所在地址的图片
image.Load(strFileName) ;
// 图像另存为BMP格式
image.Save(tempfile,Gdiplus::ImageFormatBMP);
image.Destroy();
}
else
tempfile = strFileName;

hOldBmp = (HBITMAP)LoadImage(NULL, tempfile, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION | LR_DEFAULTSIZE | LR_LOADFROMFILE);
bitMap.Attach(hOldBmp);
bitMap.GetObject(sizeof(bmInfo), &bmInfo);

oldDC.CreateCompatibleDC(NULL);
pOldBmp = oldDC.SelectObject(&bitMap);

SetStretchBltMode(MemDC.m_hDC, COLORONCOLOR);
//居中效果
{
MemDC.SelectObject(&brush);
MemDC.Rectangle(0, 0, rc.Width(), rc.Height());
MemDC.BitBlt(0,0,rc.Width(),rc.Height(),&oldDC,
(bmInfo.bmWidth-rc.Width())/2, (bmInfo.bmHeight-rc.Height())/2,SRCCOPY);
}

oldDC.SelectObject(pOldBmp);
bitMap.DeleteObject();
oldDC.DeleteDC();
}
else
{
MemDC.SelectObject(&brush);
MemDC.Rectangle(0, 0, rc.Width(), rc.Height());
}
if (m_hBitmap)
dcMemory.SelectObject(m_hBitmap);
m_hBitmap = (HBITMAP)dcMemory.SelectObject(SelectObject(MemDC, hOldBitmap));
MemBitmap.DeleteObject();
MemDC.DeleteDC();
ReleaseDC(pDC);
}
xxd_qd 2010-08-02
  • 打赏
  • 举报
回复
没看见代码,我也不清楚你说的问题到底出在哪里。
sghcpt 2010-08-02
  • 打赏
  • 举报
回复
那请问,楼上说的OnPaint函数,什么都不做,那为什么会出现图片中带有白色的区域,但又窗口在上面移动的时候??
xxd_qd 2010-08-02
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 zxdlms 的回复:]
没必要在自己的OnPaint代码中调用CDialog::OnPaint。
[/Quote]
如果自己的OnPaint代码什么也没做的话(至少没有声明过CPaintDC类型的变量),还必须调用一下CDialog::OnPaint,否则BeginPaint和EndPaint就没有办法被调用了。

总之,在响应WM_PAINT消息的时候,必须调用一遍BeginPaint和EndPaint。调用的方法有三种:
1、声明一个CPaintDC类型的变量(即使你什么也不画),CPaintDC的构造函数就是调用BeginPaint,析构函数就是调用EndPaint。
2、调用基类的OnPaint(实际上就是调用API的DefWindowProc,它会自动调用BeginPaint和EndPaint)。
3、自己直接调用BeginPaint和EndPaint。
上述三种方法,必须选择其一,而且也只能选择其一(因为在一个WM_PAINT消息内不能调用两次BeginPaint和EndPaint)。
zxdlms 2010-08-02
  • 打赏
  • 举报
回复
没必要在自己的OnPaint代码中调用CDialog::OnPaint。
bdxxxx 2010-08-02
  • 打赏
  • 举报
回复
当然也不一定是白色 看你窗口类的设置了
bdxxxx 2010-08-02
  • 打赏
  • 举报
回复
LS正解 onpaint是什么都不做 onerasebkgnd画白色背景
sghcpt 2010-08-01
  • 打赏
  • 举报
回复
怎么没有人回答,我顶。

15,979

社区成员

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

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