您的位置:首页 > 编程语言 > C语言/C++

引用 Debug Assertion Failed!File:wingdi.cpp Line:1120

2011-11-01 11:44 561 查看
原因1:

去年开始处理图像时到现在一直有这样一个问题:如果打开一幅位24真彩色图像,进行各种处理,都没有问题,但如果不是真彩色图像,如黑白图、灰度图或伪彩色图,那么只能处理一次,再进行任何一种处理时都会弹出对话框提示:Debug Assertion Failed! File:wingdi.cpp Line:1120 For information on how your program can cause an assertion failure,see the Visual C++ documentation
on asserts.

然后,我打开wingdi.cpp,定位到1120行,内容如下:

BOOL CGdiObject::Attach(HGDIOBJ hObject)

{

ASSERT(m_hObject == NULL); // only attach once, detach on destroy 1120行

if (hObject == NULL) return FALSE;

CHandleMap* pMap = afxMapHGDIOBJ(TRUE); // create map if not exist

ASSERT(pMap != NULL);

pMap->SetPermanent(m_hObject = hObject, this);

return TRUE;

}

HGDIOBJ CGdiObject::Detach()

{

HGDIOBJ hObject = m_hObject;

if (hObject != NULL)

{

CHandleMap* pMap = afxMapHGDIOBJ(); // don't create if not exist

if (pMap != NULL) pMap->RemoveHandle(m_hObject);

}

m_hObject = NULL;

return hObject;

}

我调试运G行时,打开调用堆栈,显示部分代码如下:

CGdiObject::Attach(void * 0x6f081467) line 1120 + 28 bytes

CPalette::CreatePalette(tagLOPALETTE * 0x0013f62c) line 431 + 26 bytes

CImageView2::CreateBitmapPalette(CDibImage * 0x00034d10 {CDibImage}) line 151

CImageView2::OnDraw(CDC * 0x0013fac8 {CPaintDC hWnd=0x00010b2e}) line 95 + 15 bytes

选中某一条,定位到各个函数,函数内容及定位的行如下:

void CImageView2::OnDraw(CDC* pDC)

{

CImageDoc* pDoc = GetDocument();

ASSERT_VALID(pDoc);

if( pDoc->statedoc==1 && state2==1 )

{

BYTE* pBitmapData = CDibNew1->GetData();

LPBITMAPINFO pBitmapInfo = CDibNew1->GetInfo();

int m_scale=1;

int bitmapHeight = CDibNew1->GetHeight();

int bitmapWidth = CDibNew1->GetWidth();

int scaledWidth = (int)(bitmapWidth * m_scale);

int scaledHeight = (int)(bitmapHeight * m_scale);

if (CDibNew1->GetRGB()) // Has a color table

{

CPalette * hPalette2=CreateBitmapPalette(CDibNew1);

CPalette * hOldPalette = pDC->SelectPalette(hPalette2, true);

pDC->RealizePalette();

::StretchDIBits(pDC->GetSafeHdc(),0, 0, scaledWidth, scaledHeight,

0, 0, bitmapWidth, bitmapHeight,

pBitmapData, pBitmapInfo,

DIB_RGB_COLORS, SRCCOPY);

pDC->SelectPalette(hOldPalette, true);

::DeleteObject(hPalette2);

}

else

{

StretchDIBits(pDC->GetSafeHdc(), 0, 0, scaledWidth, scaledHeight,

0, 0, bitmapWidth, bitmapHeight, pBitmapData, pBitmapInfo,

DIB_RGB_COLORS, SRCCOPY);

}

}

}

CPalette *CImageView2::CreateBitmapPalette(CDibImage *pBitmap)

{

CPalette hPalette;

struct

{

WORD Version;

WORD NumberOfEntries;

PALETTEENTRY aEntries[256];

} palette = { 0x300, 256 };

LPRGBQUAD pRGBTable = pBitmap->GetRGB();

UINT numberOfColors = pBitmap->GetNumberOfColors();

for(UINT x=0; x<numberOfColors; ++x)

{

palette.aEntries[x].peRed = pRGBTable[x].rgbRed;

palette.aEntries[x].peGreen = pRGBTable[x].rgbGreen;

palette.aEntries[x].peBlue = pRGBTable[x].rgbBlue;

palette.aEntries[x].peFlags = 0;

}

hPalette.CreatePalette((LPLOGPALETTE)&palette);

return &hPalette;

::DeleteObject(hPalette);

}

_AFXWIN_INLINE BOOL CPalette::CreatePalette(LPLOGPALETTE lpLogPalette)

{ return Attach(::CreatePalette(lpLogPalette)); }

通过红字部分的提示和我自己的分析,发现hPalette是全局变量,因为 // only attach once, detach on destroy
,所以在程序运行期间第一次处理时attach了,没有出错,第二次处理时,又要attach,但第一次处理完后还没有detach

,因为它是全局变量,程序结束时才销毁,也就是程序结束时才detach。所以,这样分析,问题就解决了,将hPalette设为局部变量,进入函数后,attach,走出函数时,变量销毁,便dettach。绿色代码是新加的。

原因2:

是由于字体设置的方式有问题,下边没有被注释掉的是正确的设置方式。

// NONCLIENTMETRICS ncm;

// memset(&ncm, 0, sizeof(NONCLIENTMETRICS));

// ncm.cbSize = sizeof(NONCLIENTMETRICS);

//

// VERIFY(::SystemParametersInfo(SPI_GETNONCLIENTMETRICS,

// sizeof(NONCLIENTMETRICS), &ncm, 0));

// ncm.lfMessageFont.lfWeight = 500;

// m_headerCtrl.m_HeaderFont.CreateFontIndirect(&ncm.lfMessageFont);

// SetFont(&(m_headerCtrl.m_HeaderFont));

//////////////////////////////////////////////////////////////////////////

CFont m_font;

LOGFONT lf; // Used to create the CFont.

memset(&lf, 0, sizeof(LOGFONT)); // Clear out structure.

lf.lfWeight = 500; // Request a 20-pixel-high font

lf.lfHeight = 15;

strcpy(lf.lfFaceName, "宋体"); // with face name "Arial".

m_font.CreateFontIndirect(&lf); // Create the font.

// Use the font to paint a control. This code assumes

// a control named IDC_TEXT1 in the dialog box.

SetFont(&m_font);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: