windows-nt/Source/XPSP1/NT/shell/themes/uxtheme/blackrect.cpp
2020-09-26 16:20:57 +08:00

146 lines
4.3 KiB
C++

//---------------------------------------------------------------------------
// blackrect.cpp - special code for debugging the infamous black rect
// problem. not compiled; keep around until we fix this
// problem.
//---------------------------------------------------------------------------
HRESULT CRenderObj::CreateBitmapFromData(HDC hdc, int iDibOffset, OUT HBITMAP *phBitmap)
{
RESOURCE HDC hdcTemp = NULL;
RESOURCE HBITMAP hBitmap = NULL;
HRESULT hr = S_OK;
BYTE *pDibData = (BYTE *)(_pbThemeData + iDibOffset);
BITMAPINFOHEADER *pBitmapHdr;
pBitmapHdr = (BITMAPINFOHEADER *)pDibData;
BOOL fAlphaChannel;
fAlphaChannel = (pBitmapHdr->biBitCount == 32);
if (! hdc)
{
hdcTemp = GetWindowDC(NULL);
if (! hdcTemp)
{
Log(LOG_ERROR, L"GetWindowDC() failed in CreateBitmapFromData");
hr = MakeErrorLast();
goto exit;
}
hdc = hdcTemp;
}
//---- create the actual bitmap ----
//---- if using alpha channel, we must use a DIB ----
if (fAlphaChannel)
{
void *pv;
hBitmap = CreateDIBSection(hdc, (BITMAPINFO *)pBitmapHdr, DIB_RGB_COLORS,
&pv, NULL, 0);
//Log(LOG_TM, L"CreateDIBSection() returned hBitmap=0x%x, lasterr=0x%x", hBitmap, GetLastError());
}
else
{
hBitmap = CreateCompatibleBitmap(hdc, pBitmapHdr->biWidth, pBitmapHdr->biHeight);
//Log(LOG_TM, L"CreateCompatibleBitmap() returned hBitmap=0x%x, lasterr=0x%x", hBitmap, GetLastError());
}
if (! hBitmap)
{
hr = MakeErrorLast();
goto exit;
}
int iSetVal;
#if 1
//---- SetDIBits() can take unaligned data, right? ----
iSetVal = SetDIBits(hdc, hBitmap, 0, pBitmapHdr->biHeight, DIBDATA(pBitmapHdr), (BITMAPINFO *)pBitmapHdr,
DIB_RGB_COLORS);
#else
//---- ensure all is DWORD aligned for SetDIBits() call ----
BITMAPINFOHEADER AlignedHdr;
int iBytesPerPixel, iRawBytes, iBytesPerRow, iTotalBytes;
BYTE *pbAlignedBits;
iBytesPerPixel = pBitmapHdr->biBitCount/8; // bitcount will be 24 or 32
iRawBytes = pBitmapHdr->biWidth * iBytesPerPixel;
iBytesPerRow = 4*((iRawBytes+3)/4);
iTotalBytes = pBitmapHdr->biHeight * iBytesPerRow;
pbAlignedBits = new BYTE[iTotalBytes];
if (! pbAlignedBits)
{
hr = E_OUTOFMEMORY;
goto exit;
}
memcpy(pbAlignedBits, DIBDATA(pBitmapHdr), iTotalBytes);
AlignedHdr = *pBitmapHdr;
Log(LOG_TM, L"Calling SetDIBits() with BITMAPINFOHEADER and bits DWORD aligned");
iSetVal = SetDIBits(hdc, hBitmap, 0, AlignedHdr.biHeight, pbAlignedBits, (BITMAPINFO *)&AlignedHdr,
DIB_RGB_COLORS);
delete [] pbAlignedBits;
#endif
//Log(LOG_TM, L"SetDIBits() returned iSetVal=%d, lasterr=0x%x", iSetVal, GetLastError());
#if 0 // #ifdef LOGGING
if ((pBitmapHdr->biWidth == 16) && (pBitmapHdr->biHeight == 16)) // problem bitmap we are debugging
{
const int len = 3*16*16;
DWORD pbNewBits[16*16]; // aligned, quadwords (when we only use 3 bytes) to make GetDIBits() happy
BITMAPINFOHEADER NewHdr = *pBitmapHdr;
int iGetVal;
iGetVal = GetDIBits(hdc, hBitmap, 0, pBitmapHdr->biHeight, pbNewBits, (LPBITMAPINFO)&NewHdr, DIB_RGB_COLORS);
Log(LOG_TM, L"GetDIBits() returned iGetVal=%d, lasterr=0x%x", iGetVal, GetLastError());
if (iGetVal)
{
BYTE *bOrig = DIBDATA(pBitmapHdr);
BYTE *bNew = (BYTE *)pbNewBits;
for (int b=0; b < len; b++)
{
if (*bOrig != *bNew)
{
Log(LOG_TM, L"old/new bitmap bytes do not match: offset=%d, bOrig=0x%x, bNew=0x%x",
b, bOrig, bNew);
DEBUG_BREAK;
break;
}
bOrig++;
bNew++;
}
}
}
#endif
if (! iSetVal)
{
hr = MakeErrorLast();
goto exit;
}
*phBitmap = hBitmap;
exit:
if (hdcTemp)
ReleaseDC(NULL, hdcTemp);
if (FAILED(hr))
{
if (hBitmap)
DeleteObject(hBitmap);
}
return hr;
}
//---------------------------------------------------------------------------