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;i 254) 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;i hBkBitmap) { 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; }