CompuServe Messages

CBitmap w/user CPalette

    11-Jul-94 22:03:35
Sb: CBitmap w/user CPalette
Fm: Jeremy Wise 71564,1135
To: all
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