void CSkinButton::DrawBitmap(CDC* dc, HBITMAP hbmp, RECT r, int DrawMode)
{
if(DrawMode==2)
{
FillWithBitmap(dc,hbmp,r);
return;
}
if(!hbmp)
return; //safe check int cx=r.right - r.left;
int cy=r.bottom - r.top;
HDC hdcBmp = NULL;
HDC hdcMask = NULL;
HDC hdcMem = NULL;
HBITMAP hbmOldBmp = NULL;
dcBmp.CreateCompatibleDC(dc);
// hdcBmp = ::CreateCompatibleDC(dc->m_hDC);
hdcBmp = ::CreateCompatibleDC(NULL);
if(hdcBmp == NULL)
{
AfxMessageBox("CSkinButton::DrawBitmap()异常hdcBmp == NULL");
int iErrorCode = GetLastError();
LPVOID lpMsgBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
iErrorCode, //错误代码
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf,
0,
NULL
);
CString str;
str.Format("%s,ErrorCode = %d",lpMsgBuf,iErrorCode);
AfxMessageBox(str);
LocalFree( lpMsgBuf );
return;
}
hbmOldBmp = (HBITMAP)::SelectObject(hdcBmp,hbmp);
if (m_bMask.m_hObject!=NULL)
{
// hdcMask = ::CreateCompatibleDC(dc->m_hDC);
hdcMask = ::CreateCompatibleDC(NULL);
if(hdcMask == NULL)
{
AfxMessageBox("CSkinButton::DrawBitmap()异常hdcMask == NULL");
int iErrorCode = GetLastError();
LPVOID lpMsgBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
iErrorCode, //错误代码
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf,
0,
NULL
);
CString str;
str.Format("%s,ErrorCode = %d",lpMsgBuf,iErrorCode);
AfxMessageBox(str);
LocalFree( lpMsgBuf );
return;
}
::SelectObject(hdcMask,m_bMask); hdcMem = ::CreateCompatibleDC(NULL);
if(hdcMem == NULL)
{
AfxMessageBox("CSkinButton::DrawBitmap()异常hdcMem == NULL");
int iErrorCode = GetLastError();
LPVOID lpMsgBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
iErrorCode, //错误代码
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf,
0,
NULL
);
CString str;
str.Format("%s,ErrorCode = %d",lpMsgBuf,iErrorCode);
AfxMessageBox(str);
LocalFree( lpMsgBuf );
return;
}
CBitmap hBitmap;
hBitmap.CreateCompatibleBitmap(dc,cx,cy);
::SelectObject(hdcMem,hBitmap); ::BitBlt(hdcMem,r.left,r.top,cx,cy,dc->m_hDC,0,0,SRCCOPY);
if(!DrawMode)
{
::BitBlt(hdcMem,r.left,r.top,cx,cy,hdcBmp,0,0,SRCINVERT);
::BitBlt(hdcMem,r.left,r.top,cx,cy,hdcMask,0,0,SRCAND);
::BitBlt(hdcMem,r.left,r.top,cx,cy,hdcBmp,0,0,SRCINVERT);
}
else
{
int bx=GetBitmapWidth(hbmp);
int by=GetBitmapHeight(hbmp);
::StretchBlt(hdcMem,r.left,r.top,cx,cy,hdcBmp,0,0,bx,by,SRCINVERT);
::StretchBlt(hdcMem,r.left,r.top,cx,cy,hdcMask,0,0,bx,by,SRCAND);
::StretchBlt(hdcMem,r.left,r.top,cx,cy,hdcBmp,0,0,bx,by,SRCINVERT);
}
::BitBlt(dc->m_hDC,r.left,r.top,cx,cy,hdcMem,0,0,SRCCOPY); ::DeleteDC(hdcMem);
hBitmap.DeleteObject(); ::DeleteDC(hdcMask);
}
else
{
if(!DrawMode)
{
::BitBlt(dc->m_hDC,r.left,r.top,cx,cy,hdcBmp,0,0,SRCCOPY);
}
else
{
int bx=GetBitmapWidth(hbmp);
int by=GetBitmapHeight(hbmp);
::StretchBlt(dc->m_hDC,r.left,r.top,cx,cy,hdcBmp,0,0,bx,by,SRCCOPY);
}
}
::DeleteDC(hdcBmp);
}
{
if(DrawMode==2)
{
FillWithBitmap(dc,hbmp,r);
return;
}
if(!hbmp)
return; //safe check int cx=r.right - r.left;
int cy=r.bottom - r.top;
HDC hdcBmp = NULL;
HDC hdcMask = NULL;
HDC hdcMem = NULL;
HBITMAP hbmOldBmp = NULL;
dcBmp.CreateCompatibleDC(dc);
// hdcBmp = ::CreateCompatibleDC(dc->m_hDC);
hdcBmp = ::CreateCompatibleDC(NULL);
if(hdcBmp == NULL)
{
AfxMessageBox("CSkinButton::DrawBitmap()异常hdcBmp == NULL");
int iErrorCode = GetLastError();
LPVOID lpMsgBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
iErrorCode, //错误代码
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf,
0,
NULL
);
CString str;
str.Format("%s,ErrorCode = %d",lpMsgBuf,iErrorCode);
AfxMessageBox(str);
LocalFree( lpMsgBuf );
return;
}
hbmOldBmp = (HBITMAP)::SelectObject(hdcBmp,hbmp);
if (m_bMask.m_hObject!=NULL)
{
// hdcMask = ::CreateCompatibleDC(dc->m_hDC);
hdcMask = ::CreateCompatibleDC(NULL);
if(hdcMask == NULL)
{
AfxMessageBox("CSkinButton::DrawBitmap()异常hdcMask == NULL");
int iErrorCode = GetLastError();
LPVOID lpMsgBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
iErrorCode, //错误代码
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf,
0,
NULL
);
CString str;
str.Format("%s,ErrorCode = %d",lpMsgBuf,iErrorCode);
AfxMessageBox(str);
LocalFree( lpMsgBuf );
return;
}
::SelectObject(hdcMask,m_bMask); hdcMem = ::CreateCompatibleDC(NULL);
if(hdcMem == NULL)
{
AfxMessageBox("CSkinButton::DrawBitmap()异常hdcMem == NULL");
int iErrorCode = GetLastError();
LPVOID lpMsgBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
iErrorCode, //错误代码
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf,
0,
NULL
);
CString str;
str.Format("%s,ErrorCode = %d",lpMsgBuf,iErrorCode);
AfxMessageBox(str);
LocalFree( lpMsgBuf );
return;
}
CBitmap hBitmap;
hBitmap.CreateCompatibleBitmap(dc,cx,cy);
::SelectObject(hdcMem,hBitmap); ::BitBlt(hdcMem,r.left,r.top,cx,cy,dc->m_hDC,0,0,SRCCOPY);
if(!DrawMode)
{
::BitBlt(hdcMem,r.left,r.top,cx,cy,hdcBmp,0,0,SRCINVERT);
::BitBlt(hdcMem,r.left,r.top,cx,cy,hdcMask,0,0,SRCAND);
::BitBlt(hdcMem,r.left,r.top,cx,cy,hdcBmp,0,0,SRCINVERT);
}
else
{
int bx=GetBitmapWidth(hbmp);
int by=GetBitmapHeight(hbmp);
::StretchBlt(hdcMem,r.left,r.top,cx,cy,hdcBmp,0,0,bx,by,SRCINVERT);
::StretchBlt(hdcMem,r.left,r.top,cx,cy,hdcMask,0,0,bx,by,SRCAND);
::StretchBlt(hdcMem,r.left,r.top,cx,cy,hdcBmp,0,0,bx,by,SRCINVERT);
}
::BitBlt(dc->m_hDC,r.left,r.top,cx,cy,hdcMem,0,0,SRCCOPY); ::DeleteDC(hdcMem);
hBitmap.DeleteObject(); ::DeleteDC(hdcMask);
}
else
{
if(!DrawMode)
{
::BitBlt(dc->m_hDC,r.left,r.top,cx,cy,hdcBmp,0,0,SRCCOPY);
}
else
{
int bx=GetBitmapWidth(hbmp);
int by=GetBitmapHeight(hbmp);
::StretchBlt(dc->m_hDC,r.left,r.top,cx,cy,hdcBmp,0,0,bx,by,SRCCOPY);
}
}
::DeleteDC(hdcBmp);
}
这样的错误..也有可能是这个创建成功..但是后面两个DC没成功...也就是hdcBmp = ::CreateCompatibleDC(NULL);调用失败了...但是我代码里弹出的GetLastError又是0,提示操作成功完成...DeleteDC()也对应调用过了..我还用hdcBmp = ::CreateCompatibleDC(dc->m_hDC);试过也一样大家都来帮帮忙..解决了的话需要这个多态按钮类的朋友我可以发源码给你们..谢谢了
dcBmp没有删除,好像也没有用到:),去掉吧
{
::BitBlt(hdcMem,r.left,r.top,cx,cy,hdcBmp,0,0,SRCINVERT);
::BitBlt(hdcMem,r.left,r.top,cx,cy,hdcMask,0,0,SRCAND);
::BitBlt(hdcMem,r.left,r.top,cx,cy,hdcBmp,0,0,SRCINVERT);
}
else
{
int bx=GetBitmapWidth(hbmp);
int by=GetBitmapHeight(hbmp);
::StretchBlt(hdcMem,r.left,r.top,cx,cy,hdcBmp,0,0,bx,by,SRCINVERT);
::StretchBlt(hdcMem,r.left,r.top,cx,cy,hdcMask,0,0,bx,by,SRCAND);
::StretchBlt(hdcMem,r.left,r.top,cx,cy,hdcBmp,0,0,bx,by,SRCINVERT);
}这里有用到hdcBmp::DeleteDC(hdcBmp);
这里最后也删了主要奇怪的是能正常跑几个小时..然后出错
dcBmp.CreateCompatibleDC(dc);这句实际上已经被我注释掉了的,我编辑帖子的时候错了..
我都没定义..编译都通不过的..
不好意思..
这里怎么编辑自己发过的帖子?
::DeleteDC(hdcBmp); //销毁hdc
//::DeleteObject(hbmp); //销毁hbmp,这个可以省略,因为你的程序
//里面这个hbmp不是你创建的
有这个要求么?
有这个要求么?==========================>好象微软并没有这样的建议,怪不得返回值是正确的^_^
但是事实确实如此.如果少了这个动作,无论DeleteDC还是DeleteObject都会导致资源泄露.
不相信的话,可以用第三方的检测工具检测一下
但是之后如果把选入的Bmp,brush之类的东东统统DeleteOject一遍就不会泄露了
这个错误有没有可能是程序其他地方Create了DC却没Delete造成的?
或者说另外一个程序里有这种频繁出现的没Delete
我用boundschecker编译程序后运行报的比较多的错误都是Reading uninitialized memory,这个好象关系不大吧.然后很奇怪的是报出的几个泄露错误都是底层的
Memory leak:17 bytes allocated by operator new in strcore.cpp (118), HANDLE: 0x021B3050Resource leak: allocated by LoadLibraryA in dllinit.cpp (505), HANDLE: 0x61BE0000还有另外几个都是底层泄露,我都不知道是从哪进的.
还有我特意在程序里的某个地方调用CreateCompatibleDC()后没调用DeleteDC(),但是boundschecker却没有捕捉到.晕倒了.
我第一次用boundschecker,可能有些地方用的不对.请楼上的兄弟指点下
First-chance exception in TDKClient.exe (KERNEL32.DLL): 0xC0000005: Access Violation.这是什么意思?
如果你看到的是系统的文件错误,那么你就要查找到你自己使用的哪条语句调用到了系统文件.
还有,一定要用debug版的跑,这样才能定位到你的程序里面
DEBUG输出框里经常出现First-chance exception in TDKClient.exe (KERNEL32.DLL): 0xC0000005: Access Violation.又没办法跟踪进去看是哪里导致的...这是内存泄露的提示么?
DEBUG输出框里经常出现First-chance exception in TDKClient.exe (KERNEL32.DLL): 0xC0000005: Access Violation.又没办法跟踪进去看是哪里导致的...这是内存泄露的提示么?
=============================>
单单从First-chance exception in TDKClient.exe (KERNEL32.DLL): 0xC0000005: Access Violation.不能判断是不是有问题我怀疑你可能没有正确使用boundschecker.先运行boundschecker,然后从boundschecker的菜单里面打开你的程序的debug版本,从boundschecker里面运行(就是说不用vc环境也可以,只要有debug版本的程序)
但是经常有这个提示Reading uninitialized memory..CreateCompatibleDC()失败是不是总是API的资源泄露..和内存泄露没有关系?也就是说有地方new了内存没delete不会引起CreateCompatibleDC()的失败..
只有没有DeleteDC()或者没有DeleteObject()才会导致??
class CFaceEdit : public CRichEditCtrl这个类是可以用来显示表情图象的Edit控件...是我从网上down的代码..其中下面的函数被频繁调用
void CFaceEdit::InsertBitmap(stFace &face)
{
int nBegin = face.nPos;
int nEnd = nBegin + face.nLength;
SetSel(nBegin, nEnd); HBITMAP bmp = NULL;
if(m_pIDBmp != NULL)
//从资源创建HBITMAP
bmp = ::LoadBitmap(AfxGetApp()->m_hInstance, MAKEINTRESOURCE(m_pIDBmp[face.nFaceIndex]));
else
//从文件创建HBITMAP
bmp = (HBITMAP)::LoadImage(NULL, m_pBmpFile[face.nFaceIndex], IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE); if(bmp==NULL)
{
throw "无效的HBITMAP类型。\r\n\r\n可能的原因是:\r\n位图文件的路径不正确。";
} ::InsertBitmap(this, bmp); if(bmp != NULL)
{
int rs = DeleteObject(bmp);
if(rs == 0)
AfxMessageBox("Error DeleteObject(bmp)");//这里也会出现
}
}/*--------------------------------------------------------------------------
* 函数名:InsertBitmap
*
* 功能 :底层的一个InsertBitmap,使用OLE容器,向CRichEditCtrl中插入表情。
* 根据位图句柄创建OleCreateStaticFromData();用这个函数可以把资源中的图片插入到文本框中
*
* 头文件:<Richole.h>、<afxodlgs.h>
--------------------------------------------------------------------------*/
void InsertBitmap(CRichEditCtrl *pRichEdit, HBITMAP hBitmap) //底层的一个InsertBitmap
{
STGMEDIUM stgm;
stgm.tymed = TYMED_GDI; // Storage medium = HBITMAP handle
stgm.hBitmap = hBitmap;
stgm.pUnkForRelease = NULL; // Use ReleaseStgMedium
FORMATETC fm;
fm.cfFormat = CF_BITMAP; // Clipboard format = CF_BITMAP
fm.ptd = NULL; // Target Device = Screen
fm.dwAspect = DVASPECT_CONTENT; // Level of detail = Full content
fm.lindex = -1; // Index = Not applicaple
fm.tymed = TYMED_GDI;
//创建输入数据源
IStorage *pStorage;
//分配内存
LPLOCKBYTES lpLockBytes = NULL;
SCODE sc = ::CreateILockBytesOnHGlobal(NULL, TRUE, &lpLockBytes);
if (sc != S_OK)
AfxThrowOleException(sc);
ASSERT(lpLockBytes != NULL);
sc = ::StgCreateDocfileOnILockBytes(lpLockBytes,
STGM_SHARE_EXCLUSIVE|STGM_CREATE|STGM_READWRITE, 0, &pStorage);//内存泄露
if (sc != S_OK)
{
VERIFY(lpLockBytes->Release() == 0);
lpLockBytes = NULL;
AfxThrowOleException(sc);
AfxMessageBox("StgCreateDocfileOnILockBytes Error");
}
ASSERT(pStorage != NULL);
COleDataSource *pDataSource = new COleDataSource;
pDataSource->CacheData(CF_BITMAP, &stgm);
LPDATAOBJECT lpDataObject = (LPDATAOBJECT)pDataSource->GetInterface(&IID_IDataObject);
//获取RichEdit的OLEClientSite
LPOLECLIENTSITE lpClientSite;
pRichEdit->GetIRichEditOle()->GetClientSite( &lpClientSite );
//创建OLE对象
IOleObject *pOleObject;
sc = OleCreateStaticFromData(lpDataObject,IID_IOleObject,OLERENDER_FORMAT,
&fm,lpClientSite,pStorage,(void **)&pOleObject);//内存泄露
if(sc!=S_OK)
AfxThrowOleException(sc);
//插入OLE对象
REOBJECT reobject;
ZeroMemory(&reobject, sizeof(REOBJECT));
reobject.cbStruct = sizeof(REOBJECT);
CLSID clsid;
sc = pOleObject->GetUserClassID(&clsid);
if (sc != S_OK)
AfxThrowOleException(sc);
reobject.clsid = clsid;
reobject.cp = REO_CP_SELECTION;
reobject.dvaspect = DVASPECT_CONTENT;
reobject.poleobj = pOleObject;
reobject.polesite = lpClientSite;
reobject.pstg = pStorage;
HRESULT hr = pRichEdit->GetIRichEditOle()->InsertObject( &reobject );
int rs1 = lpLockBytes->Release();//2
int rs2 = pStorage->Release();//3
// lpDataObject->Release();
int rs3 = pOleObject->Release();//1
// CString str;
// str.Format("%d %d %d",rs1,rs2,rs3);
// AfxMessageBox(str);
// delete pOleObject;
// delete pStorage;
pDataSource->Empty();
delete pDataSource;}最后BoundChecker提示很多sc = ::StgCreateDocfileOnILockBytes(lpLockBytes,
STGM_SHARE_EXCLUSIVE|STGM_CREATE|STGM_READWRITE, 0, &pStorage);//内存泄露和sc = OleCreateStaticFromData(lpDataObject,IID_IOleObject,OLERENDER_FORMAT,
&fm,lpClientSite,pStorage,(void **)&pOleObject);//内存泄露这两个地方有Interface leak..但是函数最后的确调用了Release()了然后在void CFaceEdit::InsertBitmap(stFace &face)的最后int rs = DeleteObject(bmp);
返回0,也就是删除bmp失败了.求解啊.快晕头了
看解决方案也是说要调用Release()..
给我一个吧,[email protected]