第一:成员变量
CRect m_rect;//储存 绘图控件的绘图区域
CDC * m_pDC;//控件的屏幕绘图指针
CDC m_memDC;//内存绘图设备
CBitmap m_memBitmap;//用于内存绘图的位图,给绘图一个地方
CBitmap* m_pOldBitmap;//备份旧的位图指针
CWnd* m_pWnd;//绘图控件指针
第二:
void *****View::OnDraw(CDC* pDC)
{
if ( m_pOldBitmap )
{
m_memBitmap.DeleteObject();
m_memDC.DeleteDC();
}
m_pOldBitmap = NULL;
m_memDC.CreateCompatibleDC(NULL);//创建内存设备,使内存位图的DC与控件DC相关联
m_memBitmap.CreateCompatibleBitmap( pDC, MYWidth, MYHeight );//创建内存兼容位图 m_memBitmap.SetBitmapBits(MYWidth*MYHeight,m_pdibImg->m_lpImage);
m_pOldBitmap = m_memDC.SelectObject( &m_memBitmap );//把内存兼容位图选进设备描述表 pDC->BitBlt( MYWidth/2+100, 0, MYWidth/2 ,MYHeight/2, &m_memDC, 0, 0, SRCCOPY );
m_memDC.SelectObject( m_pOldBitmap );//把内存兼容位图选回来 //销毁位图以及绘图指针
m_memBitmap.DeleteObject();
m_memDC.DeleteDC();
}
第三:现象
程序启动后,从任务管理器中得知,该进程的内存使用量以4K的速度逐渐上涨,先是出现图像错误画在程序的框架窗口外且不断更新;接着过了一会发现图像不再更新,界面混乱并且“死掉”!小弟调试了好几天,还是不知问题出在哪里,请高人指导,自当感觉不尽!
CRect m_rect;//储存 绘图控件的绘图区域
CDC * m_pDC;//控件的屏幕绘图指针
CDC m_memDC;//内存绘图设备
CBitmap m_memBitmap;//用于内存绘图的位图,给绘图一个地方
CBitmap* m_pOldBitmap;//备份旧的位图指针
CWnd* m_pWnd;//绘图控件指针
第二:
void *****View::OnDraw(CDC* pDC)
{
if ( m_pOldBitmap )
{
m_memBitmap.DeleteObject();
m_memDC.DeleteDC();
}
m_pOldBitmap = NULL;
m_memDC.CreateCompatibleDC(NULL);//创建内存设备,使内存位图的DC与控件DC相关联
m_memBitmap.CreateCompatibleBitmap( pDC, MYWidth, MYHeight );//创建内存兼容位图 m_memBitmap.SetBitmapBits(MYWidth*MYHeight,m_pdibImg->m_lpImage);
m_pOldBitmap = m_memDC.SelectObject( &m_memBitmap );//把内存兼容位图选进设备描述表 pDC->BitBlt( MYWidth/2+100, 0, MYWidth/2 ,MYHeight/2, &m_memDC, 0, 0, SRCCOPY );
m_memDC.SelectObject( m_pOldBitmap );//把内存兼容位图选回来 //销毁位图以及绘图指针
m_memBitmap.DeleteObject();
m_memDC.DeleteDC();
}
第三:现象
程序启动后,从任务管理器中得知,该进程的内存使用量以4K的速度逐渐上涨,先是出现图像错误画在程序的框架窗口外且不断更新;接着过了一会发现图像不再更新,界面混乱并且“死掉”!小弟调试了好几天,还是不知问题出在哪里,请高人指导,自当感觉不尽!
2、m_pDC只有声明,没有引用到,检查是否也有问题。
如1楼所说,建议变量用局部变量,用完后delete,release
1、在头文件中有声明
#define MYWidth 720
#define MYHeight 576
2、CWnd* m_pWnd;//绘图控件指针
不再使用,忘记删除了
3、我先全部改为局部变量,看看是否有改善!
void C****View::OnDraw(CDC* pDC)
{
CDC * pDCMy = GetDC();//控件的屏幕绘图指针
CDC * pmemDC = new CDC;//内存绘图设备
CBitmap * pmemBitmap = new CBitmap;//用于内存绘图的位图,给绘图一个地方
pmemDC->CreateCompatibleDC( pDCMy );//创建内存设备,使内存位图的DC与View窗口DC相关联
pmemBitmap->CreateCompatibleBitmap( pDCMy, MYWidth, MYHeight );//创建内存兼容位图
pmemBitmap->SetBitmapBits(MYWidth*MYHeight,m_pdibImg->m_lpImage);
CBitmap* pOldBitmap = pmemDC->SelectObject( pmemBitmap );
//把内存兼容位图选进设备描述表 //备份旧的位图指针
pDCMy->BitBlt( MYWidth/2+100, 0, MYWidth/2 ,MYHeight/2, pmemDC, 0, 0, SRCCOPY );//把位图拷贝到屏幕上
//销毁位图以及绘图指针
pmemDC->SelectObject( pOldBitmap );//把内存兼容位图选回来
pOldBitmap->DeleteObject();
pmemDC->DeleteDC();
delete pmemBitmap;
delete pmemDC;
ReleaseDC(pDCMy);
}还劳烦前辈们进行热心指导,感谢!
时间 内存使用量
14:36 5420K
14:37 5424K
14:38 5428K
14:39 5432K
14:40 5464K
14:41 5468K
14:42 5432K
14:43 5704K
14:44 5708K
14:45 5720K
14:46 5720K
14:47 5732K
14:48 5736K
14:49 5740K
14:50 5748K
14:51 5764K
总体趋势是以4K的速度上升!!!!
第二:我是在网上下载了一个CDib的类,图像更新前,涉及到CDib的对象创建与释放的过程,
具体操作如下:
BOOL CImageProcess::DoublePeakSegment(CDib *SrcImg)
{
CDib* pDesDib = new CDib(*SrcImg);
.....(其它图像处理的代码)
//图像的复制
*SrcImg = *pDesDib; //内存回收
delete pDesDib;
return TRUE;
}
每运行一次上面的代码,GDIndicator显示调色板这一项的数据有上升。第三: 不过我不知道如何解决!请指导,谢谢!
#define _INSIDE_VISUAL_CPP_CDIB
#define IS_WIN30_DIB(lpbi) ((*(LPDWORD)(lpbi)) == sizeof(BITMAPINFOHEADER))class CImgProcess;class CDib : public CObject
{
public:
enum Alloc {noAlloc, crtAlloc, heapAlloc}; // 枚举类型,表示内存分配的状况
DECLARE_SERIAL(CDib)
public:
LPVOID m_lpvColorTable;// // 调色板指针
HBITMAP m_hBitmap;// // BITMAP结构指针
LPBYTE m_lpImage; // DIB位图数据块地址
LPBITMAPINFOHEADER m_lpBMIH; // DIB信息头指针
public:
HGLOBAL m_hGlobal; // 全局的句柄,用于内存映射文件中
Alloc m_nBmihAlloc;// 表示信息头内存分配的状况
Alloc m_nImageAlloc;// 表示位图数据分配的状况
DWORD m_dwSizeImage; // DIB位图中的字节数(信息头和调色板数据除外)
int m_nColorTableEntries; // 调色板表项数
HANDLE m_hFile; // 文件句柄
HANDLE m_hMap;// 内存映射文件句柄?
LPVOID m_lpvFile; // 文件句柄?
HPALETTE m_hPalette; // 调色板句柄?
public:
CDib();
CDib(CSize size, int nBitCount, BOOL bDataAlloc = FALSE);
// 根据指定的位图尺寸和象素位数来构造CDib实例 CDib(const CDib&);
~CDib();
int GetSizeImage() {return m_dwSizeImage;} // 获取DIB位图中数据的字节数
int GetSizeHeader()// 获取信息头和调色板的尺寸
{return sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * m_nColorTableEntries;}
CSize GetDimensions()const; // 获取以象素表示的DIB的宽度和高度
BOOL AttachMapFile(const TCHAR* strPathname, BOOL bShare = FALSE);//// 以读模式打开内存映射文件,并将其与CDib对象进行关联]
BOOL CopyToMapFile(const TCHAR* strPathname);//创建一个新的 ????????????内存映射文件,并进行数据的复制
BOOL AttachMemory(LPVOID lpvMem, BOOL bMustDelete = FALSE, HGLOBAL hGlobal = NULL);//用内存中的DIB与已有的CDib对象关联
BOOL Draw(CDC* pDC, CPoint origin, CSize size);//将CDib对象按照指定的尺寸输出到显示器(或者打印机)
HBITMAP CreateSection(CDC* pDC = NULL);//// 创建一个DIB短,图象内存将不被初始化
UINT UsePalette(CDC* pDC, BOOL bBackground = FALSE);// 将CDib对象的逻辑调色板选入设备上下文,然后实现该调色板
BOOL MakePalette();// 如果调色板存在的话,读取调色板,并创建一个Windows调色板
BOOL SetSystemPalette(CDC* pDC);//如果16bpp、24bpp或32bppDIB不举杯调色板,则该函数可以为CDib对象创建一个逻辑调色板,
// 它与由CreatehalftonePalette函数返回的调色板相匹配。如果程序在256色调色板显示器上
// 运行,而你又没有调用SetSystemPalette,那么,你将不具有任何调色板,只有20中标准的
// Windows颜色出现在DIB中
/************************************************************************/
/* */
/************************************************************************/
BOOL Compress(CDC* pDC, BOOL bCompress = TRUE);
HBITMAP CreateBitmap(CDC* pDC);
BOOL Read(CFile* pFile);//从文件中读取数据,并填充文件头、信息头、调色板和位图数据
BOOL ReadSection(CFile* pFile, CDC* pDC = NULL);//从BMP文件中读取信息头,调用CreateDIBSection来分配位图数据内存,然后将位图从该文件读入刚才分配的内存
BOOL Write(CFile* pFile);//将DIB从CDib对象写入文件
void Serialize(CArchive& ar);//串行化过程
void Empty();//清空DIB,释放已经分配的内存,并且关闭映射文件
LONG GetLineBytes() const
{
return m_dwSizeImage/ m_lpBMIH->biHeight;
}
private:
void DetachMapFile();//断开映射文件的关联
void ComputePaletteSize(int nBitCount);//计算调色板的尺寸
void ComputeMetrics();
public:
CDib& operator =(const CDib&);
WORD GetColorNum();
operator CImgProcess*() {return ((CImgProcess *)this);}
};
#endif
如果失败会产生泄漏。
改成try
catch结构试试。