这个VC绘图函数错在哪?
我编写了一个小程序,其中有一段代码是模拟按钮,经简化后如下:
//模拟按钮
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()函数,如按住回车键不动,过一会儿,图案就变了,再过一会儿就死机了,我实在不知程序错在哪儿,望各为大虾吝指教。
问题点数:50、回复次数:6Top
1 楼kxy(手举穿肠毒药,怀抱刮骨钢刀)回复于 2000-02-23 20:00:00 得分 0
When you no longer need the pen, call the DeleteObject function to delete it.
CreatePen本身创建了一个对象实例,new也创建了
你只释放了一个:)
欢迎去www.midatech.com/kxy下载ChatFtp我一般都在使用这个聊天.
Top
2 楼redoak2000(小舟一叶)回复于 2000-02-25 20:21:00 得分 50
因为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?
Top
3 楼netmare()回复于 2000-02-26 17:43:00 得分 0
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的析构函数会自动处理的
Top
4 楼rabbit(Mail_Man)回复于 2000-02-28 18:24:00 得分 0
Before you SelectObject the pOldPen object to the pDC,
You have delete the pNewPen object.Top
5 楼zqy()回复于 2000-02-28 21:59:00 得分 0
在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还在使用中,虽然这不是造成错误的原因,
但是...
Top
6 楼skt642()回复于 2001-05-31 18:02:00 得分 0
4417关注!Top




