www.pudn.com > ExpBar_src.zip > bmpengine.c


/* 
 * file           : bmpengine.c 
 * language       : ANSI/ISO C 
 * plattform      : Win32 (Windows 98/Me/NT/2000/XP) 
 * description    : bitmap helper function for xp-style explorer bar 
 * 
 * revision history: 
 * ================= 
 * 
 * date:       author:           description: 
 * -------------------------------------------------------------------------- 
 * 02/17/2004  Ingo A. Kubbilun  first published version 1.0 
 */ 
 
#include  
#include  
 
HBITMAP APIENTRY CreateRenderBitmap ( int iWidth, int iHeight ) 
{ 
  HDC           hDC = GetDC(NULL); 
  HBITMAP       hBitmap; 
  BITMAPINFO    bif; 
  LPVOID        pvBits; 
 
  if (!hDC) return NULL; 
 
  memset(&bif,0,sizeof(BITMAPINFO)); 
  bif.bmiHeader.biSize        = sizeof(BITMAPINFOHEADER); 
  bif.bmiHeader.biWidth       = iWidth; 
  bif.bmiHeader.biHeight      = iHeight; 
  bif.bmiHeader.biPlanes      = 1; 
  bif.bmiHeader.biBitCount    = 32; 
  bif.bmiHeader.biCompression = BI_RGB; 
 
  hBitmap = CreateDIBSection(hDC,&bif,DIB_RGB_COLORS,&pvBits,NULL,0); 
  ReleaseDC(NULL,hDC); 
 
  if ((!hBitmap) || (!pvBits)) 
  { 
    if (hBitmap) DeleteObject(hBitmap); 
    return NULL; 
  } 
 
  return hBitmap; 
} 
 
HBITMAP APIENTRY CreateBkBitmap ( int iWidth, int iHeight ) 
{ 
  HDC           hDC = GetDC(NULL); 
  HBITMAP       hBitmap; 
  BITMAPINFO    bif; 
  LPVOID        pvBits; 
  int           i,j,k; 
  DWORD         dwColor; 
  float         fR1,fG1,fB1; 
  float         fR2,fG2,fB2; 
  float         fR,fG,fB,fVal1,fVal2; 
  PDWORD        pdwRow; 
 
  if (!hDC) return NULL; 
 
  memset(&bif,0,sizeof(BITMAPINFO)); 
  bif.bmiHeader.biSize        = sizeof(BITMAPINFOHEADER); 
  bif.bmiHeader.biWidth       = iWidth; 
  bif.bmiHeader.biHeight      = iHeight; 
  bif.bmiHeader.biPlanes      = 1; 
  bif.bmiHeader.biBitCount    = 32; 
  bif.bmiHeader.biCompression = BI_RGB; 
 
  hBitmap = CreateDIBSection(hDC,&bif,DIB_RGB_COLORS,&pvBits,NULL,0); 
  ReleaseDC(NULL,hDC); 
 
  if ((!hBitmap) || (!pvBits)) 
  { 
    if (hBitmap) DeleteObject(hBitmap); 
    return NULL; 
  } 
 
  if ((g_sEBI.taskpane.iValue<=0) || (g_sEBI.taskpane.crBackground1==g_sEBI.taskpane.crBackground2)) 
  { 
    dwColor = XCHGCOLORREF(g_sEBI.taskpane.crBackground1)|0xFF000000L; 
    for (i=0;i>0)&0xFFL)); 
    fG1 = (float)((int)((g_sEBI.taskpane.crBackground1>>8)&0xFFL)); 
    fB1 = (float)((int)((g_sEBI.taskpane.crBackground1>>16)&0xFFL)); 
    fR2 = (float)((int)((g_sEBI.taskpane.crBackground2>>0)&0xFFL)); 
    fG2 = (float)((int)((g_sEBI.taskpane.crBackground2>>8)&0xFFL)); 
    fB2 = (float)((int)((g_sEBI.taskpane.crBackground2>>16)&0xFFL)); 
 
    for (i=0;i>16); 
          pbyData[j*3+1] = pbyData[j*3+2] = pbyData[j*3+0]; 
        } 
      } 
    } 
    memset(&bif,0,sizeof(BITMAPINFO)); 
    memset(&bih,0,sizeof(BITMAPINFOHEADER)); 
    bih.biSize        = sizeof(BITMAPINFOHEADER); 
    bih.biWidth       = ds.dsBm.bmWidth; 
    bih.biHeight      = ds.dsBm.bmHeight; 
    bih.biPlanes      = 1; 
    bih.biBitCount    = 24; 
    bih.biCompression = BI_RGB; 
    memcpy(&bif.bmiHeader,&bih,sizeof(BITMAPINFOHEADER)); 
   
    hBitmap = CreateDIBitmap(hDC,&bih,CBM_INIT,pbyBuffer,&bif,DIB_RGB_COLORS); 
    if (!hBitmap) 
      goto Exit3; 
 
    hIList2 = ImageList_Create((int)uIconWidth,ds.dsBm.bmHeight,ILC_COLORDDB|ILC_MASK, 
                               (int)(*puNumIcons),(int)(*puNumIcons)); 
 
    if (!hIList2) 
    { 
      DeleteObject(hBitmap); 
      goto Exit3; 
    } 
 
    ImageList_Add(hIList2,hBitmap,hBmpMask); 
 
    DeleteObject(hBitmap); 
 
    *phIListDisabled = hIList2; 
  } 
 
  goto Exit3; 
} 
 
void APIENTRY CreateBarBackground ( BOOL bForced, HWND hwnd, PCBSTRUCT pCBS, int iAllPanesHeight, BOOL bRepaint ) 
{ 
  int iNewBkBitmapHeight  = max(iAllPanesHeight,pCBS->rcClient.bottom); 
  int iWndWidth           = pCBS->bScrollVisible ? pCBS->iWndWidthMin : pCBS->iWndWidthMax; 
 
  if ((bForced) || ((pCBS->hBkBitmap) && ((pCBS->iBkBmpHeight!=iNewBkBitmapHeight) || (pCBS->iBkBmpWidth!=iWndWidth)))) 
  { 
    if (pCBS->hBkBitmap) DeleteObject(pCBS->hBkBitmap); 
    pCBS->iBkBmpWidth = pCBS->iBkBmpHeight = 0; 
    pCBS->hBkBitmap = NULL; 
  } 
 
  if (!pCBS->hBkBitmap) 
  { 
    pCBS->iBkBmpWidth   = iWndWidth; 
    pCBS->iBkBmpHeight  = iNewBkBitmapHeight; 
    pCBS->hBkBitmap     = CreateBkBitmap(pCBS->iBkBmpWidth,pCBS->iBkBmpHeight); 
  } 
 
  if ((bRepaint) && (pCBS->hBkBitmap)) // repaint background 
  { 
    HDC               hDC = GetDC(hwnd); 
    RECT              rcClient; 
    int               y = 0; 
    HDC               hDCMem; 
    HBITMAP           hOldBitmap; 
 
    if (hDC) 
    { 
      GetClientRect(hwnd,&rcClient); 
 
      if (pCBS->bScrollVisible) 
      { 
        SCROLLINFO      si; 
 
        si.cbSize = sizeof(SCROLLINFO); 
        si.fMask  = SIF_POS; 
        GetScrollInfo(hwnd,SB_VERT,&si); 
        y = si.nPos; 
      } 
 
      hDCMem = CreateCompatibleDC(hDC); 
      if (hDCMem) 
      { 
        hOldBitmap = SelectObject(hDCMem,pCBS->hBkBitmap); 
        BitBlt(hDC,0,0,rcClient.right,rcClient.bottom,hDCMem,0,y,SRCCOPY); 
        SelectObject(hDCMem,hOldBitmap); 
        DeleteDC(hDCMem); 
      } 
 
      ReleaseDC(hwnd,hDC); 
    } 
  } 
} 
 
// use x,y = (0,0) in HDC 
void APIENTRY FillBackground ( HDC hDC, PCBSTRUCT pCBS, PCBPANE pCBP, int iWidth, int iHeight, LPRECT pRC ) 
{ 
  RECT            rcFill; 
  BOOL            bSpecialGroup = GetWindowLong(pCBP->hwndHeader,GWL_STYLE) & CHS_SPECIALGROUP ? TRUE : FALSE; 
  HBRUSH          hBrush; 
  BKGNDFILL       bkf; 
  RECT            rcBorder; 
  COLORREF        crColor; 
 
  if (bSpecialGroup) 
  { 
    memcpy(&rcBorder,&g_sEBI.headerspecial.rcTLBorderThickness,sizeof(RECT)); 
    crColor = g_sEBI.headerspecial.crTLBorder; 
  } 
  else 
  { 
    memcpy(&rcBorder,&g_sEBI.headernormal.rcTLBorderThickness,sizeof(RECT)); 
    crColor = g_sEBI.headernormal.crTLBorder; 
  } 
 
  if ((GetWindowLong(pCBP->hwndHeader,GWL_STYLE) & CHS_CUSTOMBACKGND) && ((pCBP->PD.pDialogProc) || (pCBP->PD.hwndMsg))) 
  { 
    bkf.cbSize     = sizeof(BKGNDFILL); 
    bkf.hDC        = hDC; 
    bkf.iWidth     = iWidth; 
    bkf.iHeight    = iHeight; 
    bkf.crColor    = crColor; 
    bkf.lpFillRect = pRC; 
    if (pCBP->PD.pDialogProc) 
    { 
      if (!pCBP->PD.pDialogProc(pCBP->hwndDlg,CBM_FILLBKGND,(WPARAM)&bkf,0L)) 
        goto FillBackground; 
    } 
    else 
    { 
      RELAYMSG msg; 
 
      msg.hwndDlg = pCBP->hwndDlg; 
      msg.uPaneId = pCBP->PD.uPaneId; 
      msg.message = CBM_FILLBKGND; 
      msg.wParam  = (WPARAM)&bkf; 
      msg.lParam  = 0L; 
      if (!SendMessage(pCBP->PD.hwndMsg,CBM_RELAYMSG,(WPARAM)sizeof(RELAYMSG),(LPARAM)&msg)) 
        goto FillBackground; 
    } 
  } 
  else 
  { 
    FillBackground: 
 
    hBrush = CreateSolidBrush( bSpecialGroup ? g_sEBI.headerspecial.crTLbackground : g_sEBI.headernormal.crTLbackground); 
    rcFill.left   =  
    rcFill.top    = 0; 
    if (pRC) 
    { 
      rcFill.right  = pRC->right-pRC->left; 
      rcFill.bottom = pRC->bottom-pRC->top; 
    } 
    else 
    { 
      rcFill.right  = iWidth; 
      rcFill.bottom = iHeight; 
    } 
    FillRect(hDC,&rcFill,hBrush); 
    DeleteObject(hBrush); 
  } 
 
  if (!pRC) 
  { 
    hBrush = CreateSolidBrush(crColor); 
 
    if (rcBorder.top) 
    { 
      rcFill.left   = 0; 
      rcFill.top    = 0; 
      rcFill.right  = iWidth; 
      rcFill.bottom = rcBorder.top; 
      FillRect(hDC,&rcFill,hBrush); 
    } 
    if (rcBorder.bottom) 
    { 
      rcFill.bottom = iHeight; 
      rcFill.top    = iHeight-rcBorder.bottom; 
      rcFill.left   = 0; 
      rcFill.right  = iWidth; 
      FillRect(hDC,&rcFill,hBrush); 
    } 
    if (rcBorder.left) 
    { 
      rcFill.left   = 0; 
      rcFill.top    = 0; 
      rcFill.right  = rcBorder.left; 
      rcFill.bottom = iHeight; 
      FillRect(hDC,&rcFill,hBrush); 
    } 
    if (rcBorder.right) 
    { 
      rcFill.left   = iWidth-rcBorder.right; 
      rcFill.top    = 0; 
      rcFill.right  = iWidth; 
      rcFill.bottom = iHeight; 
      FillRect(hDC,&rcFill,hBrush); 
    } 
 
    DeleteObject(hBrush); 
  } 
} 
 
HBITMAP APIENTRY CreateHeaderBitmap ( PCBSTRUCT pCBS, PCBPANE pCBP, LPVOID *ppvBits, int *piWidth, int *piHeight ) 
{ 
  int                 iWidth,iHeight; 
  BITMAPINFO          bif; 
  HBITMAP             hBitmap,hOldBitmap,hOldBitmap2; 
  LPVOID              pvBits; 
  HDC                 hDCMem,hDCMem2,hDC = GetDC(NULL); 
  POINT               ptOfs = {0,0}; 
 
  if (ppvBits) *ppvBits = NULL; 
  if (pCBS->bScrollVisible) 
  { 
    iWidth  = pCBP->rcHeaderMin.right-pCBP->rcHeaderMin.left; 
    iHeight = pCBP->rcHeaderMin.bottom-pCBP->rcHeaderMin.top; 
  } 
  else 
  { 
    iWidth  = pCBP->rcHeaderMax.right-pCBP->rcHeaderMax.left; 
    iHeight = pCBP->rcHeaderMax.bottom-pCBP->rcHeaderMax.top; 
  } 
  if (piWidth) *piWidth = iWidth; 
  if (piHeight) *piHeight = iHeight; 
 
  memset(&bif,0,sizeof(BITMAPINFO)); 
  bif.bmiHeader.biSize        = sizeof(BITMAPINFOHEADER); 
  bif.bmiHeader.biWidth       = iWidth; 
  bif.bmiHeader.biHeight      = iHeight; 
  bif.bmiHeader.biPlanes      = 1; 
  bif.bmiHeader.biBitCount    = 32; 
  bif.bmiHeader.biCompression = BI_RGB; 
 
  hBitmap = CreateDIBSection(hDC,&bif,DIB_RGB_COLORS,&pvBits,NULL,0); 
  if ((!hBitmap) || (!pvBits)) 
  { 
    if (hBitmap) DeleteObject(hBitmap); 
    ReleaseDC(NULL,hDC); 
    return NULL; 
  } 
  if (ppvBits) *ppvBits = pvBits; 
 
  hDCMem = CreateCompatibleDC(hDC); 
  hDCMem2 = CreateCompatibleDC(hDC); 
  if ((!hDCMem) || (!hDCMem2)) 
  { 
    if (hDCMem) DeleteDC(hDCMem); 
    if (hDCMem2) DeleteDC(hDCMem2); 
    if (hBitmap) DeleteObject(hBitmap); 
    ReleaseDC(NULL,hDC); 
    return NULL; 
  } 
 
  hOldBitmap = SelectObject(hDCMem,hBitmap); 
  if (pCBS->hBkBitmap) 
  { 
    hOldBitmap2 = SelectObject(hDCMem2,pCBS->hBkBitmap); 
    BitBlt(hDCMem,0,0,iWidth,iHeight,hDCMem2,pCBP->x,pCBP->y,SRCCOPY); 
    SelectObject(hDCMem2,hOldBitmap2); 
  } 
  ColHeaderPaintDC(pCBP->hwndHeader,hDCMem,ptOfs,FALSE,iWidth); 
 
  SelectObject(hDCMem,hOldBitmap); 
  DeleteDC(hDCMem); 
  DeleteDC(hDCMem2); 
  ReleaseDC(NULL,hDC); 
  return hBitmap; 
} 
 
HBITMAP APIENTRY CreatePaneBitmap ( PCBSTRUCT pCBS, PCBPANE pCBP, LPVOID *ppvBits, int *piWidth, int *piHeight ) 
{ 
  int                 iWidth,iHeight; 
  BITMAPINFO          bif; 
  HBITMAP             hBitmap,hOldBitmap; 
  LPVOID              pvBits; 
  HDC                 hDCMem,hDC = GetDC(NULL); 
 
  if (ppvBits) *ppvBits = NULL; 
  if (pCBS->bScrollVisible) 
  { 
    iWidth  = pCBP->rcPaneMinCurrent.right-pCBP->rcPaneMinCurrent.left; 
    iHeight = pCBP->rcPaneMinCurrent.bottom-pCBP->rcPaneMinCurrent.top; 
  } 
  else 
  { 
    iWidth  = pCBP->rcPaneMaxCurrent.right-pCBP->rcPaneMaxCurrent.left; 
    iHeight = pCBP->rcPaneMaxCurrent.bottom-pCBP->rcPaneMaxCurrent.top; 
  } 
  if (piWidth) *piWidth = iWidth; 
  if (piHeight) *piHeight = iHeight; 
 
  memset(&bif,0,sizeof(BITMAPINFO)); 
  bif.bmiHeader.biSize        = sizeof(BITMAPINFOHEADER); 
  bif.bmiHeader.biWidth       = iWidth; 
  bif.bmiHeader.biHeight      = iHeight; 
  bif.bmiHeader.biPlanes      = 1; 
  bif.bmiHeader.biBitCount    = 32; 
  bif.bmiHeader.biCompression = BI_RGB; 
 
  hBitmap = CreateDIBSection(hDC,&bif,DIB_RGB_COLORS,&pvBits,NULL,0); 
  if ((!hBitmap) || (!pvBits)) 
  { 
    if (hBitmap) DeleteObject(hBitmap); 
    ReleaseDC(NULL,hDC); 
    return NULL; 
  } 
  if (ppvBits) *ppvBits = pvBits; 
 
  hDCMem = CreateCompatibleDC(hDC); 
  if (!hDCMem) 
  { 
    if (hBitmap) DeleteObject(hBitmap); 
    ReleaseDC(NULL,hDC); 
    return NULL; 
  } 
 
  hOldBitmap = SelectObject(hDCMem,hBitmap); 
 
  FillBackground(hDCMem,pCBS,pCBP,iWidth,iHeight,NULL); 
 
  PaintDCPaneControls(hDCMem,pCBS,pCBP,pCBS->bScrollVisible); 
 
  SelectObject(hDCMem,hOldBitmap); 
  DeleteDC(hDCMem); 
  ReleaseDC(NULL,hDC); 
  return hBitmap; 
} 
 
void APIENTRY PaintDCPCRecursive ( PCBSTRUCT pCBS, HDC hDC, PPANECTRL pPC, BOOL bScrollVisible, BOOL bVisible ) 
{ 
  POINT       ptOfs; 
  int         cx; 
 
  if (!pPC) return; 
 
  if ((bVisible) && (IsWindowVisible(pPC->hwndCtrl))) 
  { 
    if (pPC->bPDCControl) 
    { 
      TCHAR           szWndClass[256]; 
 
      szWndClass[0]=0; 
      GetClassName(pPC->hwndCtrl,szWndClass,256); 
      if (bScrollVisible) 
      { 
        ptOfs.x  = pPC->rcMinCurrent.left; 
        ptOfs.y  = pPC->rcMinCurrent.top; 
        cx       = pPC->rcMinCurrent.right-pPC->rcMinCurrent.left; 
      } 
      else 
      { 
        ptOfs.x = pPC->rcMaxCurrent.left; 
        ptOfs.y = pPC->rcMaxCurrent.top; 
        cx      = pPC->rcMaxCurrent.right-pPC->rcMaxCurrent.left; 
      } 
      if (!__stricmp(szWndClass,TASKLINKCLASSNAME)) 
        TaskLinkPaintDC(pPC->hwndCtrl,hDC,ptOfs,FALSE,cx); 
      else 
      if (!__stricmp(szWndClass,COLHEADERCLASSNAME))  
        ColHeaderPaintDC(pPC->hwndCtrl,hDC,ptOfs,FALSE,cx); 
      else 
      if (!__stricmp(szWndClass,COLBARSTATICCLASSNAME))  
        CBStatic32PaintDC(pPC->hwndCtrl,hDC,ptOfs,FALSE,cx); 
      else 
      if (!__stricmp(szWndClass,COLBARBUTTONCLASSNAME)) 
        CBButtonPaintDC(pPC->hwndCtrl,hDC,ptOfs,FALSE,cx); 
    } 
    else 
    { 
      RECT            rcControl; 
      HDC             hDCMem = CreateCompatibleDC(hDC); 
      HBITMAP         hBmpMem; 
      HGDIOBJ         hOldObj; 
      int             iWidth,iHeight; 
      HWND            hwndParent = GetParent(pPC->hwndCtrl); 
 
      if (hDCMem) 
      { 
        GetWindowRect(pPC->hwndCtrl,&rcControl); 
        iWidth  = rcControl.right-rcControl.left; 
        iHeight = rcControl.bottom-rcControl.top; 
        if ((iWidth>0) && (iHeight>0)) 
        { 
          hBmpMem = CreateCompatibleBitmap(hDC,iWidth,iHeight); 
          if (hBmpMem) 
          { 
            hOldObj = SelectObject(hDCMem,hBmpMem); 
 
            if (bScrollVisible) 
            { 
              ptOfs.x  = pPC->rcMinCurrent.left; 
              ptOfs.y  = pPC->rcMinCurrent.top; 
            } 
            else 
            { 
              ptOfs.x = pPC->rcMaxCurrent.left; 
              ptOfs.y = pPC->rcMaxCurrent.top; 
            } 
 
            BitBlt(hDCMem,0,0,iWidth,iHeight,hDC,ptOfs.x,ptOfs.y,SRCCOPY); 
 
            // CAUTION: the control MUST NOT send any messages like WM_CTLCOLORxxx to the parent 
            // ======== window during this processing or we have a DEADLOCK 
 
            SendMessage(pPC->hwndCtrl,WM_PRINT,(WPARAM)hDCMem,(LPARAM)(/*PRF_ERASEBKGND|*/PRF_CHILDREN|PRF_CLIENT|PRF_NONCLIENT|PRF_OWNED)); 
 
//            PeekAndProcessPaintMessages(pCBS); 
 
            BitBlt(hDC,ptOfs.x,ptOfs.y,iWidth,iHeight,hDCMem,0,0,SRCCOPY); 
            SelectObject(hDCMem,hOldObj); 
            DeleteObject(hBmpMem); 
          } 
        } 
        DeleteDC(hDCMem); 
      } 
    } 
  } 
 
  if (pPC->bIsHeader) 
  { 
    if (!pPC->bExpanded) 
    { 
      if (pPC->pChildren) 
        PaintDCPCRecursive(pCBS,hDC,pPC->pChildren,bScrollVisible,FALSE); 
    } 
    else 
    { 
      if (pPC->pChildren) 
        PaintDCPCRecursive(pCBS,hDC,pPC->pChildren,bScrollVisible,bVisible); 
    } 
  } 
 
  if (pPC->pNext) 
    PaintDCPCRecursive(pCBS,hDC,pPC->pNext,bScrollVisible,bVisible); 
} 
 
void APIENTRY PaintDCPaneControls ( HDC hDC, PCBSTRUCT pCBS, PCBPANE pCBP, BOOL bMinSize ) 
{ 
  BOOL      bShowHide = FALSE; 
 
  ShowHidePaneControls(pCBS,pCBP,bMinSize); 
 
  if (!IsWindowVisible(pCBP->hwndDlg)) 
  { 
    bShowHide = TRUE; 
    if (bMinSize) 
      SetWindowPos(pCBP->hwndDlg,NULL, 
                   pCBP->rcPaneMinCurrent.left+pCBP->x,pCBS->rcClient.bottom+1024, 
                   pCBP->rcPaneMinCurrent.right-pCBP->rcPaneMinCurrent.left, 
                   pCBP->rcPaneMinCurrent.bottom-pCBP->rcPaneMinCurrent.top, 
                   /*SWP_SHOWWINDOW|*/SWP_NOACTIVATE|SWP_NOCOPYBITS| 
                   SWP_NOOWNERZORDER|SWP_NOSENDCHANGING|SWP_NOZORDER); 
    else 
      SetWindowPos(pCBP->hwndDlg,NULL, 
                   pCBP->rcPaneMaxCurrent.left+pCBP->x,pCBS->rcClient.bottom+1024, 
                   pCBP->rcPaneMaxCurrent.right-pCBP->rcPaneMaxCurrent.left, 
                   pCBP->rcPaneMaxCurrent.bottom-pCBP->rcPaneMaxCurrent.top, 
                   /*SWP_SHOWWINDOW|*/SWP_NOACTIVATE|SWP_NOCOPYBITS| 
                   SWP_NOOWNERZORDER|SWP_NOSENDCHANGING|SWP_NOZORDER); 
    ShowWindow(pCBP->hwndDlg,SW_SHOW); 
  } 
 
  PaintDCPCRecursive(pCBS,hDC,pCBP->pPC,bMinSize,TRUE); 
 
  if (bShowHide) 
    ShowWindow(pCBP->hwndDlg,SW_HIDE); 
} 
 
BOOL APIENTRY CreateFadeBitmaps ( PCBSTRUCT  pCBS, 
                                  PCBPANE    pCBP,  
                                  int        iBkBitmapYOfs, 
                                  int        iNumLevels, 
                                  HBITMAP   *phBitmaps, 
                                  int       *piHeights ) 
{ 
  int                 i,y,iWidth,iHeight,iBmpHeight,iAlpha,iLevel; 
  BITMAPINFO          bif; 
  HBITMAP             hBmpTemp; 
  LPVOID              pvSrcBits,pvTmpBits,pvBits; 
  HDC                 hDC,hDCSrc,hDCDst; 
  PDWORD              pdwSource,pdwTarget; 
  BLENDFUNCTION       bf; 
  HGDIOBJ             hOldObj1,hOldObj2; 
 
  if (!iNumLevels) return FALSE; 
 
  memset(phBitmaps,0,sizeof(HBITMAP)*iNumLevels); 
  memset(piHeights,0,sizeof(int)*iNumLevels); 
 
  if (pCBS->bScrollVisible) 
  { 
    iWidth  = pCBP->rcPaneMinCurrent.right-pCBP->rcPaneMinCurrent.left; 
    iHeight = pCBP->rcPaneMinCurrent.bottom-pCBP->rcPaneMinCurrent.top; 
  } 
  else 
  { 
    iWidth  = pCBP->rcPaneMaxCurrent.right-pCBP->rcPaneMaxCurrent.left; 
    iHeight = pCBP->rcPaneMaxCurrent.bottom-pCBP->rcPaneMaxCurrent.top; 
  } 
 
  if (!(phBitmaps[iNumLevels-1] = CreatePaneBitmap(pCBS,pCBP,&pvSrcBits,NULL,NULL))) 
    return FALSE; 
 
  piHeights[iNumLevels-1] = iHeight; 
 
  hDC    = GetDC(NULL); 
  hDCSrc = CreateCompatibleDC(hDC); 
  hDCDst = CreateCompatibleDC(hDC); 
 
  memset(&bif,0,sizeof(BITMAPINFO)); 
  bif.bmiHeader.biSize        = sizeof(BITMAPINFOHEADER); 
  bif.bmiHeader.biWidth       = iWidth; 
  bif.bmiHeader.biHeight      = iHeight; 
  bif.bmiHeader.biPlanes      = 1; 
  bif.bmiHeader.biBitCount    = 32; 
  bif.bmiHeader.biCompression = BI_RGB; 
 
  hBmpTemp = CreateDIBSection(hDC,&bif,DIB_RGB_COLORS,&pvTmpBits,NULL,0); 
 
  if (!hBmpTemp) 
  { 
    ErrorExit: 
    if (hBmpTemp) DeleteObject(hBmpTemp); 
    if (hDCSrc) DeleteDC(hDCSrc); 
    if (hDCDst) DeleteDC(hDCDst); 
    ReleaseDC(NULL,hDC); 
    for (i=0;i254) iAlpha=254; 
      bf.SourceConstantAlpha = (BYTE)iAlpha; 
 
      memset(&bif,0,sizeof(BITMAPINFO)); 
      bif.bmiHeader.biSize        = sizeof(BITMAPINFOHEADER); 
      bif.bmiHeader.biWidth       = iWidth; 
      bif.bmiHeader.biHeight      = iBmpHeight; 
      bif.bmiHeader.biPlanes      = 1; 
      bif.bmiHeader.biBitCount    = 32; 
      bif.bmiHeader.biCompression = BI_RGB; 
 
      phBitmaps[iLevel] = CreateDIBSection(hDC,&bif,DIB_RGB_COLORS,&pvBits,NULL,0); 
      if ((!phBitmaps[iLevel]) || (!pvBits)) 
        goto ErrorExit; 
 
      piHeights[iLevel] = iBmpHeight; 
 
      pdwTarget = ((PDWORD)pvTmpBits)+(iHeight-1)*iWidth; 
 
      for (i=0;ihBkBitmap) 
      { 
        hOldObj2 = SelectObject(hDCSrc,pCBS->hBkBitmap); 
        BitBlt(hDCDst,0,0,iWidth,iBmpHeight,hDCSrc,pCBS->iBorderLeft,iBkBitmapYOfs,SRCCOPY); 
        SelectObject(hDCSrc,hOldObj2); 
      } 
 
      hOldObj2 = SelectObject(hDCSrc,hBmpTemp); 
      AlphaBlend(hDCDst,0,0,iWidth,iBmpHeight,hDCSrc,0,0,iWidth,iBmpHeight,bf); 
      SelectObject(hDCSrc,hOldObj2); 
 
      SelectObject(hDCDst,hOldObj1); 
    } 
  } 
 
  DeleteObject(hBmpTemp); 
  DeleteDC(hDCSrc); 
  DeleteDC(hDCDst); 
  ReleaseDC(NULL,hDC); 
 
  return TRUE; 
}