CBitmap w/user CPalette
1 messages in this thread
I have been trying to display a CBitmap object with a CPalette user logical
palette and I am having difficulty getting the CBitmap colors to display
properly. I process the WM_QUERYNEWPALETTE & WM_PALETTECHANGED messages as
described in Knowledge Base article "The Palette Manager:How & Why" and as in
the DIBLOOK example, realizing my user palette either in foreground for active
window & background for other windows. Then in the OnDraw member I realize the
palette in background & BitBlt the CBitmap object as follows:
void CPcxView::Display(CDC *PDC)
//Display BitMap in device context passed
// PDC- Device context for display [PTR]
{
//
//Get ->DOCUMENT "pDoc"
//Get, ->IMAGE "pImage" derived from "BITMAP"
CPcxDoc *pDoc=GetDocument(); //->AssocDocument
IMAGE *pImage=pDoc->RtnImage(); //->BitMap to display
//
//Select proper Palette into Dc &Realize it.
CPalette *pPal=pDoc->GetDocPalette(); //Get ->Palette for Image
CPalette *oldPalette= //Select New
palette
PDC->SelectPalette(pPal,TRUE);
UINT nColorsChanged= //Now REALIZE new
palette
PDC->RealizePalette();
//
//Now manage BitMap Bits
pImage->LOCK(); //Lock Memory for bitmap
CDC MemDC;
MemDC.CreateCompatibleDC(PDC);
CBitmap cbitmap;
cbitmap.CreateBitmapIndirect(pImage); //Fill "CBitmap" object pixels
CBitmap *cBitmapOld=
MemDC.SelectObject(&cbitmap);
PDC->BitBlt(0,0,pImage->bmWidth,pImage->bmHeight,
&MemDC,0,0,SRCCOPY);
MemDC.SelectObject(cBitmapOld);
pImage->UNLOCK(); //Release Bitmap memory
PDC->SelectPalette(oldPalette,TRUE); //Realize OLD in BG
nColorsChanged=
//Now REALIZE new palette
PDC->RealizePalette();
}
The problem I have is that the colors do not display correctly. The value for a
single pixel in the bitmap is indexing the system palette and not the logical
palette. For example, if the value in the bitmap for the 1st pixel is 0, the
color displayed is the 0th entry in the SYSTEM palette is displayed and not the
0th entry in the logical palette.
However, if I use a DIB instead of a CPalette object and use "SetDIBsToDevice"
function everything works fine. This code which approximates the code from
"DIBLOOK" is as follows:
void CPcxView::Display(CDC *PDC)
//Display BitMap in device context passed
// PDC- Device context for display
{
//
//Get ->DOCUMENT "pDoc"
//Get ->IMAGE "pImage" [derived from BITMAPINFO]
CPcxDoc *pDoc=GetDocument(); //->Assoc Document
IMAGE *pImage=pDoc->RtnImage(); //->BitMap to display
//
//Select proper Palette into Dc &Realize it.
CPalette *pPal=pDoc->GetDocPalette(); //Get ->Palette for Image
CPalette *oldPalette= //Select New
palette
PDC->SelectPalette(pPal,TRUE);
UINT nColorsChanged= //Now REALIZE new
palette
PDC->RealizePalette();
//
//Now manage BitMap Bits
pImage->LOCK(); //Lock Memory for bitmap
BYTE *lpDIBbits= //Get ->BitInfo
pImage->GetDIBBits();
HDC hDC=PDC->m_hDC; //handle for PDC
::SetStretchBltMode(hDC,COLORONCOLOR); //Set Stretch mode
int iWidth= //Get image width/height
(int)pImage->bmiHeader.biWidth;
int iHeight=
(int)pImage->bmiHeader.biHeight;
BYTE *lpDIBBits=pImage->GetDIBBits(); //Get ->BitInfo
BOOL bSuccess=
::SetDIBitsToDevice(hDC, // hDC
0, // DestX
0, // DestY
iWidth, // nDestWidth
iHeight, // nDestHeight
0, // SrcX
0, // SrcY
0, // nStartScan
iHeight, // nNumScans
lpDIBBits, // lpBits
pImage, // lpBitsInfo
DIB_RGB_COLORS); // wUsage
pImage->UNLOCK(); //Release Bitmap memory
PDC->SelectPalette(oldPalette,TRUE); //Realize OLD in BG
nColorsChanged= //Now REALIZE new palette
PDC->RealizePalette();
}
In the two examples the processing of the WM_QUERYNEWPALETTE &
WM_PALETTECHANGED messages is identical. Is there some good reason why I can't
get the version using "CBitmap" to work??
Thanks in advance, JW