这个VC绘图函数错在哪?

烤火的鱼 2000-02-23 07:24:00
我编写了一个小程序,其中有一段代码是模拟按钮,经简化后如下:

//模拟按钮
void uButton(CDC *pDC,CRect rect)
{
CPen *pNewPen,*pOldPen;

CBrush *pNewBrush=new CBrush;
pNewBrush->CreateSolidBrush(RGB(192,192,192));
pDC->FillRect(rect,pNewBrush);
delete pNewBrush;

pNewPen=new CPen;
pNewPen->CreatePen(PS_SOLID,1,RGB(255,255,255));
pOldPen=pDC->SelectObject(pNewPen);
pDC->MoveTo(rect.left,rect.top );
pDC->LineTo(rect.right-1,rect.top);
pDC->MoveTo(rect.left,rect.top );
pDC->LineTo(rect.left,rect.bottom-1);
delete pNewPen;

//以下代码与上面相同,只是颜色和坐标变了
pNewPen=new CPen;
pNewPen->CreatePen(PS_SOLID,1,RGB(0,0,0));
pDC->SelectObject(pNewPen);
pDC->MoveTo(rect.right,rect.top);
pDC->LineTo(rect.right,rect.bottom);
pDC->MoveTo(rect.left,rect.bottom);
pDC->LineTo(rect.right,rect.bottom);
delete pNewPen;

pNewPen=new CPen;
pNewPen->CreatePen(PS_SOLID,1,RGB(128,128,128));
pDC->SelectObject(pNewPen);
pDC->MoveTo(rect.right-1,rect.top+1);
pDC->LineTo(rect.right-1,rect.bottom-1);
pDC->MoveTo(rect.left+1,rect.bottom-1);
pDC->LineTo(rect.right-1,rect.bottom-1);
delete pNewPen;
pDC->SelectObject(pOldPen);
}

为了测试,我在OnKeyDown()事件中写了如下代码:
{

CDC *pDC=GetDC();
CRect rect;

rect.left=0;
rect.right=100;
rect.top=0;
rect.bottom=70;
uButton(pDC,rect);
//ReleaseDC(pDC);
}

如果你大量调用uButton()函数,如按住回车键不动,过一会儿,图案就变了,再过一会儿就死机了,我实在不知程序错在哪儿,望各为大虾吝指教。
...全文
246 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
skt642 2001-05-31
  • 打赏
  • 举报
回复
4417关注!
zqy 2000-02-28
  • 打赏
  • 举报
回复
在OnKeyDown中最后要
ReleaseDC(pDC);
"
_AFXWIN_INLINE CDC* CWnd::GetDC()
{ ASSERT(::IsWindow(m_hWnd)); return CDC::FromHandle(::GetDC(m_hWnd)); }
"
GetDC所做的只是调用Win32 API GetDC,仅此而已,要自己释放.

下面是MSDN里CWnd::GetDC()里的一段话:
"
Unless the device context belongs to a window class, the ReleaseDC member function must be called to release the context after painting. Since only five common device contexts are available at any given time, failure to release a device context can prevent other applications from accessing a device context.
"

还有MSDN中CGdiObject::DeleteObject有一句话:
"
An application should not call DeleteObject on a CGdiObject object that is currently selected into a device context.
"
在delete pNewPen时,pNewPen还在使用中,虽然这不是造成错误的原因,
但是...



rabbit 2000-02-28
  • 打赏
  • 举报
回复
Before you SelectObject the pOldPen object to the pDC,
You have delete the pNewPen object.
netmare 2000-02-26
  • 打赏
  • 举报
回复
to redoak2000:
这个问题已经有人解决了,分都给了,参见:
http://www.midatech.com/csdn/expert/TopicView.asp?id=2743
另外:
如果
CBrush *pNewBrush=new CBrush;
pNewBrush->CreateSolidBrush(RGB(192,192,192));
pDC->FillRect(rect,pNewBrush);
delete pNewBrush;
就不用DeleteObject了,因为delete pNewBrush时,CBrush的析构函数会自动处理的



redoak2000 2000-02-25
  • 打赏
  • 举报
回复
因为CPen,CBrush,CFont等(包括非MFC的PEN,BRUSH,FONT等)都是GDI对象,使用GDI对象及其指针不同于别的--必须遵守以下原则:
1.用了Create???,就必须在不用时使用DeleteObject()将其删除。
2.如果用SelectObject选入了某个GDI对象,最好将由SelectObject返回的原来的相关GDI对象保存下来,不用时再将其恢复.
例1:(在View类中)
CRect rect;//API的GDI同MFC的GDI混用也可以
this->GetClientRect(&rect);
HBRUSH hBr=::CreateSolidBrush(RGB(255,0,0));//!!!!

pDC->FillRect(&rect,hBr);
DeleteObject(hBr);//删除GDI对象!!!!
delete pNewBrush;//删除指针



例2: CPen redPen(PS_SOLID,3,RGB(255,0,0));
CPen* pOldPen=(CPen*)SelectObject(&redPen);
......
SelectObject(pOldPen);
delet pOldPen;
Try and reply me!
Is it OK?

kxy 2000-02-23
  • 打赏
  • 举报
回复
When you no longer need the pen, call the DeleteObject function to delete it.
CreatePen本身创建了一个对象实例,new也创建了
你只释放了一个:)
欢迎去www.midatech.com/kxy下载ChatFtp我一般都在使用这个聊天.

16,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

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