bool CBitmapShow::PaintDIB(HDC hDC,LPRECT lpDCRect,LPRECT lpDIBRect) { if(m_lpBitmapInfo==NULL) return false; if(lpDIBBits==NULL) return false; BOOL bSuccess=false; HPALETTE hPal=NULL; HPALETTE hOldPal= NULL; CRect DIBRect(lpDIBRect->left,Height-lpDIBRect->bottom-1,lpDIBRect->right,Height-lpDIBRect->top-1); CPalette*pPal=Palette; if(pPal!=NULL) { hPal=(HPALETTE)pPal->m_hObject; hOldPal=::SelectPalette(hDC,hPal,TRUE); } ::SetStretchBltMode(hDC,COLORONCOLOR); if((RECTWIDTH(lpDCRect)==RECTWIDTH(lpDIBRect))&& (RECTHEIGHT(lpDCRect)==RECTHEIGHT(lpDIBRect))) { bSuccess=::SetDIBitsToDevice(hDC, lpDCRect->left, lpDCRect-> top, RECTWIDTH(lpDCRect), RECTHEIGHT(lpDCRect), DIBRect.left, DIBRect.top, 0, Height, lpDIBBits, m_lpBitmapInfo, DIB_RGB_COLORS); } else { bSuccess=::StretchDIBits(hDC, lpDCRect->left, lpDCRect->top, RECTWIDTH(lpDCRect), RECTHEIGHT(lpDCRect), DIBRect.left, DIBRect.top, DIBRect.Width()+1, DIBRect.Height()+1, lpDIBBits, m_lpBitmapInfo, DIB_RGB_COLORS, SRCCOPY); } if(hOldPal!=NULL) { ::SelectPalette(hDC,hOldPal,TRUE); } return bSuccess; }
LRESULT AeroControlBase::ProgressbarWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_ENABLE: case WM_STYLECHANGED: { LRESULT res = DefSubclassProc(hWnd, uMsg, wParam, lParam); InvalidateRgn(hWnd, NULL, FALSE); return res; } break; case WM_PAINT: { PAINTSTRUCT ps; HDC hdc = BeginPaint(hWnd, &ps); RECT rc; GetWindowRect(hWnd, &rc); MapWindowPoints(NULL, hWnd, (LPPOINT)&rc, 2); if (hdc) { PaintControl(hWnd, hdc, &ps.rcPaint, false); BP_PAINTPARAMS params = { sizeof(BP_PAINTPARAMS) }; params.dwFlags = 0L; HDC hdcPaint = NULL; HPAINTBUFFER hBufferedPaint = BeginBufferedPaint(hdc, &rc, BPBF_TOPDOWNDIB, ¶ms, &hdcPaint); if (hdcPaint) { COLORREF cr = RGB(0x00, 0x00, 0x00); SetPixel(hdcPaint, 0, 0, cr); SetPixel(hdcPaint, 0, RECTHEIGHT(rc) - 1, cr); SetPixel(hdcPaint, RECTWIDTH(rc) - 1, 0, cr); SetPixel(hdcPaint, RECTWIDTH(rc) - 1, RECTHEIGHT(rc) - 1, cr); EndBufferedPaint(hBufferedPaint, TRUE); } } EndPaint(hWnd, &ps); return 0; } break; case WM_NCDESTROY: case WM_DESTROY: RemoveWindowSubclass(hWnd, SubclassProc, Static); subclassedControls.erase(hWnd); break; } return DefSubclassProc(hWnd, uMsg, wParam, lParam); }
//--------------------------------------------------------------------- // // Function: DIBPaint // // Purpose: Painting routine for a DIB. Calls StretchDIBits() or // SetDIBitsToDevice() to paint the DIB. The DIB is // output to the specified DC, at the coordinates given // in lpDCRect. The area of the DIB to be output is // given by lpDIBRect. The specified palette is used. // // Parms: hDC == DC to do output to. // lpDCRect == Rectangle on DC to do output to. // hDIB == Handle to global memory with a DIB spec // in it (either a BITMAPINFO or BITMAPCOREINFO // followed by the DIB bits). // lpDIBRect == Rect of DIB to output into lpDCRect. // hPal == Palette to be used. // // History: Date Reason // 6/01/91 Created // //--------------------------------------------------------------------- static void DIBPaint (HDC hDC,LPRECT lpDCRect,HANDLE hDIB) { LPSTR lpDIBHdr, lpDIBBits; if (!hDIB) return; // Lock down the DIB, and get a pointer to the beginning of the bit // buffer. lpDIBHdr = GlobalLock (hDIB); lpDIBBits = FindDIBBits (lpDIBHdr); // Make sure to use the stretching mode best for color pictures. SetStretchBltMode (hDC, COLORONCOLOR); SetDIBitsToDevice (hDC, // hDC lpDCRect->left, // DestX lpDCRect->top, // DestY RECTWIDTH (lpDCRect), // nDestWidth RECTHEIGHT (lpDCRect), // nDestHeight 0, // SrcX 0, // (int) DIBHeight (lpDIBHdr), // SrcY 0, // nStartScan (WORD) DIBHeight (lpDIBHdr), // nNumScans lpDIBBits, // lpBits (LPBITMAPINFO) lpDIBHdr, // lpBitsInfo DIB_RGB_COLORS); // wUsage GlobalUnlock (hDIB); }
void DrawWndOnParentTransparent(HWND hWnd, PAERO_SUBCLASS_WND_DATA pWndData) { RECT rcWnd; VERIFY(GetWindowRect(hWnd, &rcWnd)); HWND hParent = GetParent(hWnd); if(hParent) { ScreenToClient(hParent, &rcWnd); HDC hdc = GetDC(hParent); if(hdc) { BP_PAINTPARAMS params = { sizeof(BP_PAINTPARAMS) }; params.dwFlags = BPPF_ERASE; HDC hdcPaint = NULL; HPAINTBUFFER hBufferedPaint = NULL; hBufferedPaint = pWndData->m_pUxTheme->BeginBufferedPaint(hdc, &rcWnd, BPBF_TOPDOWNDIB, ¶ms, &hdcPaint); if (hdcPaint) { VERIFY(PatBlt(hdcPaint, 0, 0, RECTWIDTH(rcWnd), RECTHEIGHT(rcWnd), BLACKNESS)); VERIFY(S_OK==pWndData->m_pUxTheme->BufferedPaintSetAlpha(hBufferedPaint, &rcWnd, 0x00)); VERIFY(S_OK==pWndData->m_pUxTheme->EndBufferedPaint(hBufferedPaint, TRUE)); } VERIFY(1==ReleaseDC(hParent, hdc)); } } }
static void RelayoutDlg(PWLAN_INFO psInfo) { if (NULL != psInfo) { HWND hwndStatic = GetDlgItem(psInfo->hDlg, IDC_WZC_STATIC_NO_WIRELESS_CARD_PRESEND); BOOL fShowList = psInfo->fWirelessCardPresent; RECT rect; GetWindowRect(psInfo->hwndNetList, &rect); MapWindowPoints(NULL, psInfo->hDlg, (LPPOINT)&rect, 2 ); SetWindowPos(hwndStatic, NULL, rect.left, rect.top, RECTWIDTH(rect), fShowList ? 10 : RECTHEIGHT(rect), (fShowList ? SWP_HIDEWINDOW : SWP_SHOWWINDOW) | SWP_NOZORDER); // In order to let RCML resize wireless network listview, it just hide // it behind the static text when wireless card is not present SetWindowPos(psInfo->hwndNetList, hwndStatic, 0, 0, 0, 0, (fShowList ? SWP_NOZORDER : 0) | SWP_NOMOVE | SWP_NOSIZE); // When the rectangle surrounding the listview is moved, our text get's // clipped. Plus when we setwindowpos ourself and change our width // we aren't invalidating ourself, so we don't clear out old text. InvalidateRect(hwndStatic, NULL, TRUE); // Don't want network list to get input if it hides below the static text EnableWindow(psInfo->hwndNetList, fShowList); } }
bool CRGBBitmapShow::PaintDIB(HDC hDC,LPRECT lpDCRect,LPRECT lpDIBRect,COLORREF TransparentColor) { CDC*pDC=CDC::FromHandle(hDC); CDC memDC,tempDC; HBITMAP m_bitmap =CreateCompatibleBitmap(hDC,RECTWIDTH(lpDCRect),RECTHEIGHT(lpDCRect)); //创建位图内存 memDC.CreateCompatibleDC(pDC); HBITMAP pOldBitmap=(HBITMAP)SelectObject(memDC, m_bitmap); CRect memrt(0,0,RECTWIDTH(lpDCRect),RECTHEIGHT(lpDCRect)); if(!PaintDIB(memDC.m_hDC,memrt,lpDIBRect)) { memDC.SelectObject(pOldBitmap); DeleteObject(m_bitmap); memDC.DeleteDC(); return false; } tempDC.CreateCompatibleDC(pDC); HBITMAP maskBMP =CreateBitmap(RECTWIDTH(lpDCRect),RECTHEIGHT(lpDCRect),1,1,NULL); //创建单色掩码位图 HBITMAP oldmaskBMP=(HBITMAP)SelectObject(tempDC, maskBMP); SetBkColor(memDC.m_hDC, TransparentColor);// 设置透明色 BitBlt(tempDC.m_hDC,0,0,RECTWIDTH(lpDCRect),RECTHEIGHT(lpDCRect),memDC.m_hDC,0,0,SRCCOPY); SetBkColor(memDC.m_hDC, RGB(0,0,0)); SetTextColor(memDC.m_hDC, RGB(255,255,255)); // 白色 BitBlt(memDC.m_hDC,0,0,RECTWIDTH(lpDCRect),RECTHEIGHT(lpDCRect),tempDC.m_hDC,0,0,SRCAND); SetBkColor(hDC,RGB(255,255,255)); // 透明部分保持屏幕不变,其它部分变成黑色 SetTextColor(hDC,RGB(0,0,0)); // 黑色 BitBlt(hDC,lpDCRect->left, lpDCRect->top,RECTWIDTH(lpDCRect),RECTHEIGHT(lpDCRect),tempDC.m_hDC,0,0,SRCAND); //"与"运算,在hdc0生成掩模 BitBlt(hDC,lpDCRect->left, lpDCRect->top,RECTWIDTH(lpDCRect),RECTHEIGHT(lpDCRect),memDC.m_hDC,0,0,SRCPAINT); memDC.SelectObject(pOldBitmap); tempDC.SelectObject(oldmaskBMP); DeleteObject(m_bitmap); DeleteObject(maskBMP); memDC.DeleteDC(); tempDC.DeleteDC(); return true; }
void PaintControl(HWND hWnd, HDC hdc, RECT* prc, bool bDrawBorder) { HDC hdcPaint = NULL; PAERO_SUBCLASS_WND_DATA pwd = (PAERO_SUBCLASS_WND_DATA)GetProp(hWnd, WINDOW_DATA_STRING); ASSERT(pwd); if(bDrawBorder) VERIFY(InflateRect(prc, 1, 1)); HPAINTBUFFER hBufferedPaint = pwd->m_pUxTheme->BeginBufferedPaint(hdc, prc, BPBF_TOPDOWNDIB, NULL, &hdcPaint); if (hdcPaint) { RECT rc; VERIFY(GetWindowRect(hWnd, &rc)); PatBlt(hdcPaint, 0, 0, RECTWIDTH(rc), RECTHEIGHT(rc), BLACKNESS); VERIFY(S_OK==pwd->m_pUxTheme->BufferedPaintSetAlpha(hBufferedPaint, &rc, 0x00)); /// /// first blit white so list ctrls don't look ugly: /// VERIFY(PatBlt(hdcPaint, 0, 0, RECTWIDTH(rc), RECTHEIGHT(rc), WHITENESS)); if(bDrawBorder) VERIFY(InflateRect(prc, -1, -1)); // Tell the control to paint itself in our memory buffer SendMessage(hWnd, WM_PRINTCLIENT, (WPARAM) hdcPaint, PRF_CLIENT|PRF_ERASEBKGND |PRF_NONCLIENT|PRF_CHECKVISIBLE); if(bDrawBorder) { VERIFY(InflateRect(prc, 1, 1)); VERIFY(FrameRect(hdcPaint, prc, (HBRUSH)GetStockObject(BLACK_BRUSH))); } // Make every pixel opaque VERIFY(S_OK==pwd->m_pUxTheme->BufferedPaintMakeOpaque_(hBufferedPaint, prc)); VERIFY(S_OK==pwd->m_pUxTheme->EndBufferedPaint(hBufferedPaint, TRUE)); } }
void AeroControlBase::PaintControl(HWND hWnd, HDC hdc, RECT* prc, bool bDrawBorder) { HDC hdcPaint = NULL; if(bDrawBorder) VERIFY(InflateRect(prc, 1, 1)); HPAINTBUFFER hBufferedPaint = BeginBufferedPaint(hdc, prc, BPBF_TOPDOWNDIB, NULL, &hdcPaint); if (hdcPaint) { RECT rc; VERIFY(GetWindowRect(hWnd, &rc)); PatBlt(hdcPaint, 0, 0, RECTWIDTH(rc), RECTHEIGHT(rc), BLACKNESS); VERIFY(S_OK==BufferedPaintSetAlpha(hBufferedPaint, &rc, 0x00)); /// /// first blit white so list ctrls don't look ugly: /// VERIFY(PatBlt(hdcPaint, 0, 0, RECTWIDTH(rc), RECTHEIGHT(rc), WHITENESS)); if(bDrawBorder) VERIFY(InflateRect(prc, -1, -1)); // Tell the control to paint itself in our memory buffer SendMessage(hWnd, WM_PRINTCLIENT, (WPARAM) hdcPaint, PRF_CLIENT|PRF_ERASEBKGND |PRF_NONCLIENT|PRF_CHECKVISIBLE); if(bDrawBorder) { VERIFY(InflateRect(prc, 1, 1)); VERIFY(FrameRect(hdcPaint, prc, (HBRUSH)GetStockObject(BLACK_BRUSH))); } // don't make a possible border opaque, only the inner part of the control VERIFY(InflateRect(prc, -2, -2)); // Make every pixel opaque VERIFY(S_OK == BufferedPaintSetAlpha(hBufferedPaint, prc, 255)); VERIFY(S_OK==EndBufferedPaint(hBufferedPaint, TRUE)); } }
bool CRGBBitmapShow::PaintDIB(HDC hDC,LPRECT lpDCRect,LPRECT lpDIBRect) { CDC*pDC=CDC::FromHandle(hDC); CDC memDC; memDC.CreateCompatibleDC(pDC); HBITMAP m_bitmap =CreateCompatibleBitmap(hDC,RECTWIDTH(lpDCRect),RECTHEIGHT(lpDCRect)); //创建位图内存 HBITMAP pOldBitmap=(HBITMAP)SelectObject(memDC, m_bitmap); CRect memrt(0,0,RECTWIDTH(lpDCRect),RECTHEIGHT(lpDCRect)); if(!PaintDIB(memDC.m_hDC,memrt,lpDIBRect,0)) { memDC.SelectObject(pOldBitmap); DeleteObject(m_bitmap); memDC.DeleteDC(); return false; } BitBlt(hDC,lpDCRect->left, lpDCRect->top,RECTWIDTH(lpDCRect),RECTHEIGHT(lpDCRect),memDC.m_hDC,0,0,SRCCOPY); if(!PaintDIB(memDC.m_hDC,memrt,lpDIBRect,1)) { memDC.SelectObject(pOldBitmap); DeleteObject(m_bitmap); memDC.DeleteDC(); return false; } BitBlt(hDC,lpDCRect->left, lpDCRect->top,RECTWIDTH(lpDCRect),RECTHEIGHT(lpDCRect),memDC.m_hDC,0,0,SRCPAINT); if(!PaintDIB(memDC.m_hDC,memrt,lpDIBRect,2)) { memDC.SelectObject(pOldBitmap); DeleteObject(m_bitmap); memDC.DeleteDC(); return false; } BitBlt(hDC,lpDCRect->left, lpDCRect->top,RECTWIDTH(lpDCRect),RECTHEIGHT(lpDCRect),memDC.m_hDC,0,0,SRCPAINT); memDC.SelectObject(pOldBitmap); DeleteObject(m_bitmap); memDC.DeleteDC(); return true; }
void CBrushButton::_OnDraw(HDC hdc, RECT *prc, EGACOLOR color) { // Fill with the background color. CDC *pDC = CDC::FromHandle(hdc); if (pDC) { // Ask the pattern to draw itself RECT rcLocal = *prc; // Black border. pDC->FillSolidRect(rcLocal.left, rcLocal.top, RECTWIDTH(rcLocal), RECTHEIGHT(rcLocal), RGB(0, 0, 0)); // Pen style is always black. color.color1 = 0x0; color.color2 = 0x0; InflateRect(&rcLocal, -1, -1); // Shink for the borders. int cMin = 16; SCIBitmapInfo bmi(cMin, cMin); scoped_array<BYTE> dataBrush(new BYTE[cMin * cMin]); // Fill with white. memset(dataBrush.get(), 0x0f, cMin * cMin); // Fake a PicData to draw into, with a visual brush. PicData data = { DRAW_ENABLE_VISUAL, dataBrush.get(), NULL, NULL, NULL }; DrawPatternInRect(cMin, cMin, &data, 8, 8, color, 0, 0, DRAW_ENABLE_VISUAL, &_penStyle); int nOldMode = pDC->SetStretchBltMode(HALFTONE); StretchDIBits((HDC)*pDC, rcLocal.left, rcLocal.top, RECTWIDTH(rcLocal), RECTHEIGHT(rcLocal), 0, 0, cMin, cMin, dataBrush.get(), &bmi, DIB_RGB_COLORS, SRCCOPY); pDC->SetStretchBltMode(nOldMode); } }
// Scroll the icons void backdrop_scroll_objects(BackdropInfo *info,short off_x,short off_y) { // Lock window GetSemaphore(&info->window_lock,SEMF_EXCLUSIVE,0); // Window open? if (info->window) { short damage=0,clear=0; // Bounds-check the deltas if (off_x<0 && off_x<-RECTWIDTH(&info->size)) clear=1; else if (off_x>0 && off_x>RECTWIDTH(&info->size)) clear=1; else if (off_y<0 && off_y<-RECTHEIGHT(&info->size)) clear=1; else if (off_y>0 && off_y>RECTHEIGHT(&info->size)) clear=1; // Clear instead of scrolling? if (clear) { // Clear the whole window EraseRect( info->window->RPort, info->size.MinX, info->size.MinY, info->size.MaxX, info->size.MaxY); } // Scroll else { // Check for 39 if(((struct Library *)GfxBase)->lib_Version>=39) { // Scroll backdrop window ScrollRasterBF( info->window->RPort, off_x,off_y, info->size.MinX, info->size.MinY, info->size.MaxX, info->size.MaxY); } // No backfills else { // Scroll backdrop window ScrollRaster( info->window->RPort, off_x,off_y, info->size.MinX, info->size.MinY, info->size.MaxX, info->size.MaxY); } // Damaged simple-refresh? if (info->window->Flags&WFLG_SIMPLE_REFRESH && info->window->WLayer->Flags&LAYERREFRESH) { // Forbid #ifdef LOCKLAYER_OK LockScreenLayer(info->window->WScreen); #else Forbid(); #endif // Begin refreshing BeginRefresh(info->window); // Clear the new bits EraseRect( info->window->RPort, info->size.MinX, info->size.MinY, info->size.MaxX, info->size.MaxY); // End refreshing for the moment EndRefresh(info->window,FALSE); damage=1; } } // Got temporary region? if (info->temp_region) { struct Rectangle rect; // Get refresh region rect.MinX=(off_x==0)?info->size.MinX:((off_x>0)?info->size.MaxX-off_x:info->size.MinX); rect.MaxX=(off_x==0)?info->size.MaxX:((off_x>0)?info->size.MaxX:info->size.MinX-off_x); rect.MinY=(off_y==0)?info->size.MinY:((off_y>0)?info->size.MaxY-off_y:info->size.MinY); rect.MaxY=(off_y==0)?info->size.MaxY:((off_y>0)?info->size.MaxY:info->size.MinY-off_y); // Bounds check region if (rect.MinX<info->size.MinX) rect.MinX=info->size.MinX; if (rect.MinY<info->size.MinY) rect.MinY=info->size.MinY; if (rect.MaxX>info->size.MaxX) rect.MaxX=info->size.MaxX; if (rect.MaxY>info->size.MaxY) rect.MaxY=info->size.MaxY; // Add to damage list? if (damage) { // Or rectangle in OrRectRegion(info->window->WLayer->DamageList,&rect); } // Manually refresh else { // Set refresh region ClearRegion(info->temp_region); OrRectRegion(info->temp_region,&rect); // Install region InstallClipRegion(info->window->WLayer,info->temp_region); } } // Manual refresh? if (!damage) { // Refresh backdrop_show_objects(info,BDSF_NO_CLIP); // Remove clip region InstallClipRegion(info->window->WLayer,0); } // Automatic refresh else { // Lister? if (info->lister) lister_refresh_callback(IDCMP_REFRESHWINDOW,info->window,info->lister); // Other type else { struct IntuiMessage msg; // Fake IntuiMessage msg.Class=IDCMP_REFRESHWINDOW; // Handle refresh backdrop_idcmp(info,&msg,0); } // Enable multi-tasking #ifdef LOCKLAYER_OK UnlockScreenLayer(info->window->WScreen); #else Permit(); #endif } } // Unlock window FreeSemaphore(&info->window_lock); }
BOOL WINAPI PaintDIB(HDC hDC, LPRECT lpDCRect, HDIB hDIB, LPRECT lpDIBRect, CPalette* pPal) { LPSTR lpDIBHdr; // Pointer to BITMAPINFOHEADER LPSTR lpDIBBits; // Pointer to DIB bits BOOL bSuccess=FALSE; // Success/fail flag HPALETTE hPal=NULL; // Our DIB's palette HPALETTE hOldPal=NULL; // Previous palette /* Check for valid DIB handle */ if (hDIB == NULL) return FALSE; /* Lock down the DIB, and get a pointer to the beginning of the bit * buffer */ lpDIBHdr = (LPSTR) ::GlobalLock((HGLOBAL) hDIB); lpDIBBits = ::FindDIBBits(lpDIBHdr); // Get the DIB's palette, then select it into DC if (pPal != NULL) { hPal = (HPALETTE) pPal->m_hObject; // Select as background since we have // already realized in forground if needed hOldPal = ::SelectPalette(hDC, hPal, TRUE); } /* Make sure to use the stretching mode best for color pictures */ ::SetStretchBltMode(hDC, COLORONCOLOR); /* Determine whether to call StretchDIBits() or SetDIBitsToDevice() */ if ((RECTWIDTH(lpDCRect) == RECTWIDTH(lpDIBRect)) && (RECTHEIGHT(lpDCRect) == RECTHEIGHT(lpDIBRect))) bSuccess = ::SetDIBitsToDevice(hDC, // hDC lpDCRect->left, // DestX lpDCRect->top, // DestY RECTWIDTH(lpDCRect), // nDestWidth RECTHEIGHT(lpDCRect), // nDestHeight lpDIBRect->left, // SrcX (int)DIBHeight(lpDIBHdr) - lpDIBRect->top - RECTHEIGHT(lpDIBRect), // SrcY 0, // nStartScan (WORD)DIBHeight(lpDIBHdr), // nNumScans lpDIBBits, // lpBits (LPBITMAPINFO)lpDIBHdr, // lpBitsInfo DIB_RGB_COLORS); // wUsage else bSuccess = ::StretchDIBits(hDC, // hDC lpDCRect->left, // DestX lpDCRect->top, // DestY RECTWIDTH(lpDCRect), // nDestWidth RECTHEIGHT(lpDCRect), // nDestHeight lpDIBRect->left, // SrcX lpDIBRect->top, // SrcY RECTWIDTH(lpDIBRect), // wSrcWidth RECTHEIGHT(lpDIBRect), // wSrcHeight lpDIBBits, // lpBits (LPBITMAPINFO)lpDIBHdr, // lpBitsInfo DIB_RGB_COLORS, // wUsage SRCCOPY); // dwROP ::GlobalUnlock((HGLOBAL) hDIB); /* Reselect old palette */ if (hOldPal != NULL) { ::SelectPalette(hDC, hOldPal, TRUE); } return bSuccess; }
LRESULT AeroControlBase::ButtonWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch(uMsg) { case WM_SETTEXT: case WM_ENABLE: case WM_STYLECHANGED: { LRESULT res = DefSubclassProc(hWnd, uMsg, wParam, lParam); InvalidateRgn(hWnd, NULL, FALSE); return res; } break; case WM_PAINT: { PAINTSTRUCT ps; HDC hdc = BeginPaint(hWnd, &ps); if(hdc) { LONG_PTR dwStyle = GetWindowLongPtr(hWnd, GWL_STYLE); LONG_PTR dwButtonStyle = LOWORD(dwStyle); LONG_PTR dwButtonType = dwButtonStyle&0xF; RECT rcClient; VERIFY(GetClientRect(hWnd, &rcClient)); if((dwButtonType&BS_GROUPBOX)==BS_GROUPBOX) { /// /// it must be a group box /// HTHEME hTheme = OpenThemeData(hWnd, L"Button"); if(hTheme) { BP_PAINTPARAMS params = { sizeof(BP_PAINTPARAMS) }; params.dwFlags = BPPF_ERASE; RECT rcExclusion = rcClient; params.prcExclude = &rcExclusion; /// /// We have to calculate the exclusion rect and therefore /// calculate the font height. We select the control's font /// into the DC and fake a drawing operation: /// HFONT hFontOld = (HFONT)SendMessage(hWnd, WM_GETFONT, 0L, NULL); if(hFontOld) hFontOld = (HFONT) SelectObject(hdc, hFontOld); RECT rcDraw = rcClient; DWORD dwFlags = DT_SINGLELINE; /// /// we use uppercase A to determine the height of text, so we /// can draw the upper line of the groupbox: /// DrawTextW(hdc, L"A", -1, &rcDraw, dwFlags|DT_CALCRECT); if (hFontOld) { SelectObject(hdc, hFontOld); hFontOld = NULL; } VERIFY(InflateRect(&rcExclusion, -1, -1*RECTHEIGHT(rcDraw))); HDC hdcPaint = NULL; HPAINTBUFFER hBufferedPaint = BeginBufferedPaint(hdc, &rcClient, BPBF_TOPDOWNDIB, ¶ms, &hdcPaint); if (hdcPaint) { /// /// now we again retrieve the font, but this time we select it into /// the buffered DC: /// hFontOld = (HFONT)SendMessage(hWnd, WM_GETFONT, 0L, NULL); if(hFontOld) hFontOld = (HFONT) SelectObject(hdcPaint, hFontOld); VERIFY(PatBlt(hdcPaint, 0, 0, RECTWIDTH(rcClient), RECTHEIGHT(rcClient), BLACKNESS)); VERIFY(S_OK==BufferedPaintSetAlpha(hBufferedPaint, &ps.rcPaint, 0x00)); int iPartId = BP_GROUPBOX; int iState = GetStateFromBtnState(dwStyle, FALSE, FALSE, 0L, iPartId, FALSE); DTTOPTS DttOpts = {sizeof(DTTOPTS)}; DttOpts.dwFlags = DTT_COMPOSITED | DTT_GLOWSIZE; DttOpts.crText = RGB(255, 255, 255); DttOpts.iGlowSize = 12; // Default value VERIFY(DetermineGlowSize(&DttOpts.iGlowSize)); COLORREF cr = RGB(0x00, 0x00, 0x00); VERIFY(GetEditBorderColor(hWnd, &cr)); /// /// add the alpha value: /// cr |= 0xff000000; std::unique_ptr<Pen> myPen( new Pen(Color(cr), 1) ); std::unique_ptr<Graphics> myGraphics( new Graphics(hdcPaint) ); int iY = RECTHEIGHT(rcDraw)/2; Rect rr = Rect(rcClient.left, rcClient.top+iY, RECTWIDTH(rcClient), RECTHEIGHT(rcClient)-iY-1); GraphicsPath path; GetRoundRectPath(&path, rr, 10); myGraphics->DrawPath(myPen.get(), &path); //myGraphics->DrawRectangle(myPen, rcClient.left, rcClient.top + iY, // RECTWIDTH(rcClient)-1, RECTHEIGHT(rcClient) - iY-1); myGraphics.reset(); myPen.reset(); int iLen = GetWindowTextLength(hWnd); if(iLen) { iLen+=5; // 1 for terminating zero, 4 for DT_MODIFYSTRING LPWSTR szText = (LPWSTR)LocalAlloc(LPTR, sizeof(WCHAR)*iLen); if(szText) { iLen = GetWindowTextW(hWnd, szText, iLen); if(iLen) { int iX = RECTWIDTH(rcDraw); rcDraw = rcClient; rcDraw.left += iX; DrawTextW(hdcPaint, szText, -1, &rcDraw, dwFlags|DT_CALCRECT); VERIFY(PatBlt(hdcPaint, rcDraw.left, rcDraw.top , RECTWIDTH(rcDraw) + 3, RECTHEIGHT(rcDraw), BLACKNESS)); rcDraw.left++; rcDraw.right++; VERIFY(S_OK==DrawThemeTextEx(hTheme, hdcPaint, iPartId, iState, szText, -1, dwFlags, &rcDraw, &DttOpts)); } VERIFY(!LocalFree(szText)); } } if (hFontOld) { SelectObject(hdcPaint, hFontOld); hFontOld = NULL; } VERIFY(S_OK==EndBufferedPaint(hBufferedPaint, TRUE)); } VERIFY(S_OK==CloseThemeData(hTheme)); } } else if(dwButtonType==BS_CHECKBOX || dwButtonType==BS_AUTOCHECKBOX || dwButtonType==BS_3STATE || dwButtonType==BS_AUTO3STATE || dwButtonType==BS_RADIOBUTTON || dwButtonType==BS_AUTORADIOBUTTON) { HTHEME hTheme = OpenThemeData(hWnd, L"Button"); if(hTheme) { HDC hdcPaint = NULL; BP_PAINTPARAMS params = { sizeof(BP_PAINTPARAMS) }; params.dwFlags = BPPF_ERASE; HPAINTBUFFER hBufferedPaint = BeginBufferedPaint(hdc, &rcClient, BPBF_TOPDOWNDIB, ¶ms, &hdcPaint); if (hdcPaint) { VERIFY(PatBlt(hdcPaint, 0, 0, RECTWIDTH(rcClient), RECTHEIGHT(rcClient), BLACKNESS)); VERIFY(S_OK==BufferedPaintSetAlpha(hBufferedPaint, &ps.rcPaint, 0x00)); LRESULT dwCheckState = SendMessage(hWnd, BM_GETCHECK, 0, NULL); POINT pt; RECT rc; GetWindowRect(hWnd, &rc); GetCursorPos(&pt); BOOL bHot = PtInRect(&rc, pt); BOOL bFocus = GetFocus()==hWnd; int iPartId = BP_CHECKBOX; if(dwButtonType==BS_RADIOBUTTON || dwButtonType==BS_AUTORADIOBUTTON) iPartId = BP_RADIOBUTTON; int iState = GetStateFromBtnState(dwStyle, bHot, bFocus, dwCheckState, iPartId, FALSE); int bmWidth = int(ceil(13.0 * GetDeviceCaps(hdcPaint, LOGPIXELSX) / 96.0)); UINT uiHalfWidth = (RECTWIDTH(rcClient) - bmWidth)/2; /// /// we have to use the whole client area, otherwise we get only partially /// drawn areas: /// RECT rcPaint = rcClient; if(dwButtonStyle & BS_LEFTTEXT) { rcPaint.left += uiHalfWidth; rcPaint.right += uiHalfWidth; } else { rcPaint.left -= uiHalfWidth; rcPaint.right -= uiHalfWidth; } /// /// we assume that bmWidth is both the horizontal and the vertical /// dimension of the control bitmap and that it is square. bm.bmHeight /// seems to be the height of a striped bitmap because it is an absurdly /// high dimension value /// if((dwButtonStyle&BS_VCENTER)==BS_VCENTER) /// BS_VCENTER is BS_TOP|BS_BOTTOM { int h = RECTHEIGHT(rcPaint); rcPaint.top = (h - bmWidth) / 2; rcPaint.bottom = rcPaint.top + bmWidth; } else if(dwButtonStyle&BS_TOP) { rcPaint.bottom = rcPaint.top + bmWidth; } else if(dwButtonStyle&BS_BOTTOM) { rcPaint.top = rcPaint.bottom - bmWidth; } else // default: center the checkbox/radiobutton vertically { int h = RECTHEIGHT(rcPaint); rcPaint.top = (h - bmWidth) / 2; rcPaint.bottom = rcPaint.top + bmWidth; } VERIFY(S_OK==DrawThemeBackground(hTheme, hdcPaint, iPartId, iState, &rcPaint, NULL)); rcPaint = rcClient; VERIFY(S_OK==GetThemeBackgroundContentRect(hTheme, hdcPaint, iPartId, iState, &rcPaint, &rc)); if(dwButtonStyle & BS_LEFTTEXT) rc.right -= bmWidth + 2 * GetSystemMetrics(SM_CXEDGE); else rc.left += bmWidth + 2 * GetSystemMetrics(SM_CXEDGE); DTTOPTS DttOpts = {sizeof(DTTOPTS)}; DttOpts.dwFlags = DTT_COMPOSITED | DTT_GLOWSIZE; DttOpts.crText = RGB(255, 255, 255); DttOpts.iGlowSize = 12; // Default value VERIFY(DetermineGlowSize(&DttOpts.iGlowSize)); HFONT hFontOld = (HFONT)SendMessage(hWnd, WM_GETFONT, 0L, NULL); if(hFontOld) hFontOld = (HFONT) SelectObject(hdcPaint, hFontOld); int iLen = GetWindowTextLength(hWnd); if(iLen) { iLen+=5; // 1 for terminating zero, 4 for DT_MODIFYSTRING LPWSTR szText = (LPWSTR)LocalAlloc(LPTR, sizeof(WCHAR)*iLen); if(szText) { iLen = GetWindowTextW(hWnd, szText, iLen); if(iLen) { DWORD dwFlags = DT_SINGLELINE /*|DT_VCENTER*/; if(dwButtonStyle&BS_MULTILINE) { dwFlags|=DT_WORDBREAK; dwFlags&= ~(DT_SINGLELINE |DT_VCENTER); } if((dwButtonStyle&BS_CENTER)==BS_CENTER) /// BS_CENTER is BS_LEFT|BS_RIGHT dwFlags|=DT_CENTER; else if(dwButtonStyle&BS_LEFT) dwFlags|=DT_LEFT; else if(dwButtonStyle&BS_RIGHT) dwFlags|=DT_RIGHT; if((dwButtonStyle&BS_VCENTER)==BS_VCENTER) /// BS_VCENTER is BS_TOP|BS_BOTTOM dwFlags|=DT_VCENTER; else if(dwButtonStyle&BS_TOP) dwFlags|=DT_TOP; else if(dwButtonStyle&BS_BOTTOM) dwFlags|=DT_BOTTOM; else dwFlags|=DT_VCENTER; VERIFY(S_OK==DrawThemeTextEx(hTheme, hdcPaint, iPartId, iState, szText, -1, dwFlags, &rc, &DttOpts)); /// /// if our control has the focus, we also have to draw the focus rectangle: /// if(bFocus) { /// /// now calculate the text size: /// RECT rcDraw = rc; /// /// we use GDI's good old DrawText, because it returns much more /// accurate data than DrawThemeTextEx, which takes the glow /// into account which we don't want: /// VERIFY(DrawTextW(hdcPaint, szText, -1, &rcDraw, dwFlags|DT_CALCRECT)); if(dwFlags&DT_SINGLELINE) { dwFlags &= ~DT_VCENTER; RECT rcDrawTop; DrawTextW(hdcPaint, szText, -1, &rcDrawTop, dwFlags|DT_CALCRECT); rcDraw.top = rcDraw.bottom - RECTHEIGHT(rcDrawTop); } if(dwFlags & DT_RIGHT) { int iWidth = RECTWIDTH(rcDraw); rcDraw.right = rc.right; rcDraw.left = rcDraw.right - iWidth; } RECT rcFocus; VERIFY(IntersectRect(&rcFocus, &rc, &rcDraw)); DrawFocusRect(&rcFocus, hdcPaint); } } VERIFY(!LocalFree(szText)); } } if (hFontOld) { SelectObject(hdcPaint, hFontOld); hFontOld = NULL; } VERIFY(S_OK==EndBufferedPaint(hBufferedPaint, TRUE)); } VERIFY(S_OK==CloseThemeData(hTheme)); } } else if(BS_PUSHBUTTON==dwButtonType || BS_DEFPUSHBUTTON==dwButtonType) { /// /// it is a push button /// HTHEME hTheme = OpenThemeData(hWnd, L"Button"); if(hTheme) { HDC hdcPaint = NULL; BP_PAINTPARAMS params = { sizeof(BP_PAINTPARAMS) }; params.dwFlags = BPPF_ERASE; HPAINTBUFFER hBufferedPaint = BeginBufferedPaint(hdc, &rcClient, BPBF_TOPDOWNDIB, ¶ms, &hdcPaint); if (hdcPaint) { VERIFY(PatBlt(hdcPaint, 0, 0, RECTWIDTH(rcClient), RECTHEIGHT(rcClient), BLACKNESS)); VERIFY(S_OK==BufferedPaintSetAlpha(hBufferedPaint, &ps.rcPaint, 0x00)); LRESULT dwCheckState = SendMessage(hWnd, BM_GETCHECK, 0, NULL); POINT pt; RECT rc; GetWindowRect(hWnd, &rc); GetCursorPos(&pt); BOOL bHot = PtInRect(&rc, pt); BOOL bFocus = GetFocus()==hWnd; int iPartId = BP_PUSHBUTTON; if(dwButtonStyle==BS_RADIOBUTTON || dwButtonStyle==BS_AUTORADIOBUTTON) iPartId = BP_RADIOBUTTON; int iState = GetStateFromBtnState(dwStyle, bHot, bFocus, dwCheckState, iPartId, GetCapture()==hWnd); /// /// we have to use the whole client area, otherwise we get only partially /// drawn areas: /// RECT rcPaint = rcClient; VERIFY(S_OK==DrawThemeBackground(hTheme, hdcPaint, iPartId, iState, &rcPaint, NULL)); VERIFY(S_OK==GetThemeBackgroundContentRect(hTheme, hdcPaint, iPartId, iState, &rcPaint, &rc)); DTTOPTS DttOpts = {sizeof(DTTOPTS)}; DttOpts.dwFlags = DTT_COMPOSITED | DTT_GLOWSIZE; DttOpts.crText = RGB(255, 255, 255); DttOpts.iGlowSize = 12; // Default value VERIFY(DetermineGlowSize(&DttOpts.iGlowSize)); HFONT hFontOld = (HFONT)SendMessage(hWnd, WM_GETFONT, 0L, NULL); if(hFontOld) hFontOld = (HFONT) SelectObject(hdcPaint, hFontOld); int iLen = GetWindowTextLength(hWnd); if(iLen) { iLen+=5; // 1 for terminating zero, 4 for DT_MODIFYSTRING LPWSTR szText = (LPWSTR)LocalAlloc(LPTR, sizeof(WCHAR)*iLen); if(szText) { iLen = GetWindowTextW(hWnd, szText, iLen); if(iLen) { DWORD dwFlags = DT_SINGLELINE | DT_CENTER | DT_VCENTER; VERIFY(S_OK==DrawThemeTextEx(hTheme, hdcPaint, iPartId, iState, szText, -1, dwFlags, &rc, &DttOpts)); /// /// if our control has the focus, we also have to draw the focus rectangle: /// if(bFocus) { RECT rcDraw = rcClient; VERIFY(InflateRect(&rcDraw, -3, -3)); DrawFocusRect(&rcDraw, hdcPaint); } } VERIFY(!LocalFree(szText)); } } if (hFontOld) { SelectObject(hdcPaint, hFontOld); hFontOld = NULL; } VERIFY(S_OK==EndBufferedPaint(hBufferedPaint, TRUE)); } VERIFY(S_OK==CloseThemeData(hTheme)); } } else //PaintControl(hWnd, hdc, &ps.rcPaint, (m_dwFlags & WD_DRAW_BORDER)!=0); PaintControl(hWnd, hdc, &ps.rcPaint, false); } EndPaint(hWnd, &ps); return 0; } break; case WM_DESTROY: case WM_NCDESTROY: RemoveWindowSubclass(hWnd, SubclassProc, Button); subclassedControls.erase(hWnd); break; } return DefSubclassProc(hWnd, uMsg, wParam, lParam); }
HRESULT COverlayCallback::OnUpdateOverlay(BOOL bBefore, DWORD dwFlags, BOOL bOldVisible, const RECT *prcSrcOld, const RECT *prcDestOld, BOOL bNewVisible, const RECT *prcSrcNew, const RECT *prcDestNew) { DbgLog((LOG_TRACE, 5, TEXT("COverlayCallback::OnUpdateOverlay(%s, ...) entered"), bBefore ? "TRUE" : "FALSE")) ; if (NULL == m_pDDrawObj) { DbgLog((LOG_ERROR, 1, TEXT("ERROR: NULL DDraw object pointer was specified"))) ; return E_POINTER ; } if (bBefore) // overlay is going to be updated { DbgLog((LOG_TRACE, 5, TEXT("Just turn off color keying and return"))) ; m_pDDrawObj->SetOverlayState(FALSE) ; // don't paint color key in video's position #ifndef NOFLIP m_pDDrawObj->UpdateAndFlipSurfaces() ; // flip the surface so that video doesn't show anymore #endif // NOFLIP return S_OK ; } // // After overlay has been updated. Turn on/off overlay color keying based on // flags and use new source/dest position etc. // if (dwFlags & (AM_OVERLAY_NOTIFY_VISIBLE_CHANGE | // it's a valid flag AM_OVERLAY_NOTIFY_SOURCE_CHANGE | AM_OVERLAY_NOTIFY_DEST_CHANGE)) { m_pDDrawObj->SetOverlayState(bNewVisible) ; // paint/don't paint color key based on param } if (dwFlags & AM_OVERLAY_NOTIFY_VISIBLE_CHANGE) // overlay visibility state change { DbgLog((LOG_TRACE, 5, TEXT(".._NOTIFY_VISIBLE_CHANGE from %s to %s"), bOldVisible ? "TRUE" : "FALSE", bNewVisible ? "TRUE" : "FALSE")) ; } if (dwFlags & AM_OVERLAY_NOTIFY_SOURCE_CHANGE) // overlay source rect change { ASSERT(prcSrcOld); ASSERT(prcSrcNew); DbgLog((LOG_TRACE, 5, TEXT(".._NOTIFY_SOURCE_CHANGE from (%ld, %ld, %ld, %ld) to (%ld, %ld, %ld, %ld)"), prcSrcOld->left, prcSrcOld->top, prcSrcOld->right, prcSrcOld->bottom, prcSrcNew->left, prcSrcNew->top, prcSrcNew->right, prcSrcNew->bottom)) ; } if (dwFlags & AM_OVERLAY_NOTIFY_DEST_CHANGE) // overlay destination rect change { ASSERT(prcDestOld); ASSERT(prcDestNew); DbgLog((LOG_TRACE, 5, TEXT(".._NOTIFY_DEST_CHANGE from (%ld, %ld, %ld, %ld) to (%ld, %ld, %ld, %ld)"), prcDestOld->left, prcDestOld->top, prcDestOld->right, prcDestOld->bottom, prcDestNew->left, prcDestNew->top, prcDestNew->right, prcDestNew->bottom)) ; m_pDDrawObj->SetVideoPosition(prcDestNew->left, prcDestNew->top, RECTWIDTH(*prcDestNew), RECTHEIGHT(*prcDestNew)) ; } return S_OK ; }
BOOL CClientCapture::DrawBitmap(CDC *dc, HDC hDC, CRect *rect, CRect *dest, CBitmap &bitmap){ ////////////////////////////////////////////////////// // Create logical palette if device support a palette if( dc->GetDeviceCaps(RASTERCAPS) & RC_PALETTE ) { UINT nSize = sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * 256); LOGPALETTE *pLP = (LOGPALETTE *) new BYTE[nSize]; pLP->palVersion = 0x300; pLP->palNumEntries = GetSystemPaletteEntries( *dc, 0, 255, pLP->palPalEntry ); // Create the palette pal.CreatePalette( pLP ); delete[] pLP; } // END CREATE PALETTE ////////////////////////////////////////////////////// ///////////////////////////// ///////////////////////////// BITMAP bm; BITMAPINFOHEADER bi; DWORD dwLen; HANDLE handle; HDC hPDC; HPALETTE hPal; ASSERT( bitmap.GetSafeHandle() ); // If a palette has not been supplied use defaul palette hPal = (HPALETTE) pal.GetSafeHandle(); if (hPal==NULL) hPal = (HPALETTE) GetStockObject(DEFAULT_PALETTE); // Get bitmap information bitmap.GetObject(sizeof(bm),(LPSTR)&bm); // Initialize the bitmapinfoheader bi.biSize = sizeof(BITMAPINFOHEADER); bi.biWidth = bm.bmWidth; bi.biHeight = bm.bmHeight; bi.biPlanes = 1; bi.biBitCount = bm.bmPlanes * bm.bmBitsPixel; bi.biCompression = BI_RGB; bi.biSizeImage = 0; bi.biXPelsPerMeter = 0; bi.biYPelsPerMeter = 0; bi.biClrUsed = 0; bi.biClrImportant = 0; // Compute the size of the infoheader and the color table int nColors = (1 << bi.biBitCount); if( nColors > 256 ) nColors = 0; dwLen = bi.biSize + nColors * sizeof(RGBQUAD); // We need a device context to get the DIB from hPDC = dc->GetSafeHdc(); //hDC = GetDC(NULL); hPal = SelectPalette(hPDC,hPal,FALSE); RealizePalette(hPDC); // Allocate enough memory to hold bitmapinfoheader and color table if(hDIB) GlobalFree( hDIB ); hDIB = GlobalAlloc(GMEM_FIXED,dwLen); if (!hDIB){ SelectPalette(hPDC,hPal,FALSE); return NULL; } lpbi = (LPBITMAPINFOHEADER)hDIB; *lpbi = bi; // Call GetDIBits with a NULL lpBits param, so the device driver // will calculate the biSizeImage field GetDIBits(hPDC, (HBITMAP)bitmap.GetSafeHandle(), 0L, (DWORD)bi.biHeight, (LPBYTE)NULL, (LPBITMAPINFO)lpbi, (DWORD)DIB_RGB_COLORS); bi = *lpbi; // If the driver did not fill in the biSizeImage field, then compute it // Each scan line of the image is aligned on a DWORD (32bit) boundary if (bi.biSizeImage == 0){ bi.biSizeImage = ((((bi.biWidth * bi.biBitCount) + 31) & ~31) / 8) * bi.biHeight; } // Realloc the buffer so that it can hold all the bits dwLen += bi.biSizeImage; if (handle = GlobalReAlloc(hDIB, dwLen, GMEM_MOVEABLE)) hDIB = handle; else{ GlobalFree(hDIB); hDIB = 0; // Reselect the original palette SelectPalette(hDC,hPal,FALSE); return NULL; } // Get the bitmap bits lpbi = (LPBITMAPINFOHEADER)hDIB; m_pBMI = (LPBITMAPINFO)hDIB; m_pBits = (LPBYTE)hDIB + (bi.biSize + nColors * sizeof(RGBQUAD)); /////////////////////////////////////////////// /////////////////////////////////////////////// HPALETTE hOldPal = NULL; // Previous palette // Get the DIB's palette, then select it into DC if (&pal != NULL) { hPal = (HPALETTE) pal.m_hObject; // Select as background since we have // already realized in forground if needed hOldPal = ::SelectPalette(hDC, hPal, TRUE); } /* Make sure to use the stretching mode best for color pictures */ ::SetStretchBltMode(hDC, COLORONCOLOR); BOOL bSuccess = FALSE; UINT start(0), end, step_size(1);//, offset_y(0); end = step_size; if((UINT)bm.bmHeight < step_size) end = (int)bm.bmHeight; while(start < (UINT)bm.bmHeight){ GetDIBits( hPDC, (HBITMAP)bitmap.GetSafeHandle(), start, // Start scan line end - start, // # of scan lines (LPBYTE) m_pBits, //lpbi // address for bitmap bits (LPBITMAPINFO)lpbi, // address of bitmapinfo (DWORD)DIB_RGB_COLORS); // Use RGB for color table bSuccess = ::SetDIBitsToDevice(hDC, // hDC rect->left, // DestX rect->top, // DestY RECTWIDTH(rect), // nDestWidth RECTHEIGHT(rect), // nDestHeight rect->left, // SrcX (int)Height() - rect->top - RECTHEIGHT(rect), // SrcY start, // nStartScan end - start, // nNumScans m_pBits, // lpBits m_pBMI, // lpBitsInfo DIB_RGB_COLORS); // wUsage start = end; end = start + step_size; if((UINT)bm.bmHeight < end) end = (UINT)bm.bmHeight; } /* Reselect old palette */ if (hOldPal != NULL) { ::SelectPalette(hDC, hOldPal, TRUE); } return bSuccess; }
BOOL CClientCapture::Paint(HDC hDC, CPalette * m_pPalette, LPRECT lpDCRect, LPRECT lpDIBRect) const { if (!m_pBMI) return FALSE; HPALETTE hPal = NULL; // Our DIB's palette HPALETTE hOldPal = NULL; // Previous palette // Get the DIB's palette, then select it into DC if (m_pPalette != NULL) { hPal = (HPALETTE) m_pPalette->m_hObject; // Select as background since we have // already realized in forground if needed hOldPal = ::SelectPalette(hDC, hPal, TRUE); } /* Make sure to use the stretching mode best for color pictures */ ::SetStretchBltMode(hDC, COLORONCOLOR); /* Determine whether to call StretchDIBits() or SetDIBitsToDevice() */ BOOL bSuccess = FALSE; if ((RECTWIDTH(lpDCRect) == RECTWIDTH(lpDIBRect)) && (RECTHEIGHT(lpDCRect) == RECTHEIGHT(lpDIBRect))){ bSuccess = ::SetDIBitsToDevice(hDC, // hDC lpDCRect->left, // DestX lpDCRect->top, // DestY RECTWIDTH(lpDCRect), // nDestWidth RECTHEIGHT(lpDCRect), // nDestHeight lpDIBRect->left, // SrcX (int)Height() - lpDIBRect->top - RECTHEIGHT(lpDIBRect), // SrcY 0, // nStartScan (WORD)Height(), // nNumScans m_pBits, // lpBits m_pBMI, // lpBitsInfo DIB_RGB_COLORS); // wUsage } else bSuccess = ::StretchDIBits(hDC, // hDC lpDCRect->left, // DestX lpDCRect->top, // DestY RECTWIDTH(lpDCRect), // nDestWidth RECTHEIGHT(lpDCRect), // nDestHeight lpDIBRect->left, // SrcX lpDIBRect->top, // SrcY RECTWIDTH(lpDIBRect), // wSrcWidth RECTHEIGHT(lpDIBRect), // wSrcHeight m_pBits, // lpBits m_pBMI, // lpBitsInfo DIB_RGB_COLORS, // wUsage SRCCOPY); // dwROP /* Reselect old palette */ if (hOldPal != NULL) { ::SelectPalette(hDC, hOldPal, TRUE); } return bSuccess; }
LRESULT CALLBACK WndProcc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { PAERO_SUBCLASS_WND_DATA pWndData = (PAERO_SUBCLASS_WND_DATA)GetProp(hWnd, WINDOW_DATA_STRING); ASSERT(pWndData); ASSERT(pWndData->m_pDwmApiImpl); WNDPROC pOldProc = pWndData->m_oldWndProc; ASSERT(pOldProc); BOOL bCompositionEnabled = pWndData->m_pDwmApiImpl->IsDwmCompositionEnabled(); /// /// if aero glass is turned off and if we are not in destruction code, /// just call the original wnd proc we had prior to subclassing: /// if(WM_COMMAND!=uMsg && WM_DWMCOMPOSITIONCHANGED!=uMsg && WM_DESTROY!=uMsg && WM_NCDESTROY!=uMsg && !bCompositionEnabled) return CallWindowProc(pOldProc, hWnd, uMsg, wParam, lParam); if (uMsg == pWndData->m_uiRedrawMsg) { HWND hControl = (HWND)lParam; ASSERT(hControl); ASSERT(::IsWindow(hControl)); PAERO_SUBCLASS_WND_DATA pCtrlData = (PAERO_SUBCLASS_WND_DATA)GetProp(hControl, WINDOW_DATA_STRING); if(pCtrlData && pCtrlData->m_dwFlags & WD_IN_PAINT_CONTROL) { HDC hdc = GetDC(hControl); if(hdc) { RECT rc; VERIFY(GetWindowRect(hControl, &rc)); VERIFY(MapWindowPoints(NULL, hControl, (LPPOINT) &rc, 2)); PaintControl(hControl, hdc, &rc, (pCtrlData->m_dwFlags & WD_DRAW_BORDER)!=0); VERIFY(1==ReleaseDC(hControl, hdc)); } pCtrlData->m_dwFlags &= ~WD_IN_PAINT_CONTROL; return 0; } } switch(uMsg) { case WM_CTLCOLORSTATIC: { HWND hControl = (HWND)lParam; ASSERT(hControl); ASSERT(IsWindow(hControl)); PAERO_SUBCLASS_WND_DATA pCtrlData = (PAERO_SUBCLASS_WND_DATA)GetProp(hControl, WINDOW_DATA_STRING); if(pCtrlData) { if(pCtrlData->m_dwFlags&WD_RETURN_BLACK_BRUSH) return (LRESULT)GetStockObject(BLACK_BRUSH); else if(pCtrlData->m_dwFlags&WD_RETURN_WHITE_BRUSH) return (LRESULT)GetStockObject(WHITE_BRUSH); else { pCtrlData->m_dwFlags|=WD_IN_PAINT_CONTROL; PostMessage((HWND)lParam, pWndData->m_uiRedrawMsg, 0, NULL); } } } break; case WM_CTLCOLOREDIT: { PAERO_SUBCLASS_WND_DATA pCtrlData = (PAERO_SUBCLASS_WND_DATA)GetProp((HWND)lParam, WINDOW_DATA_STRING); if(pCtrlData) pCtrlData->m_dwFlags|=WD_IN_PAINT_CONTROL; PostMessage((HWND)lParam, pWndData->m_uiRedrawMsg, 0, NULL); } break; case WM_PAINT: { if(!IsIconic(hWnd) && !(pWndData->m_dwFlags&WD_NO_FRAME_EXTEND)) { PAINTSTRUCT ps; HDC hdc = BeginPaint(hWnd, &ps); /// /// we have to paint the *entire* client area in black, not only the /// paint area inside ps, because otherwise we get ugly areas of white /// if we partially move the window out of the desktop and back in again: /// /// MARGINS marGlassInset = {0, 0, 0, 302}; // -1 means the whole window if(hdc && pWndData->m_pDwmApiImpl->IsDwmCompositionEnabled() && SUCCEEDED(pWndData->m_pDwmApiImpl->DwmExtendFrameIntoClientArea(hWnd, &marGlassInset))) { RECT rcClient; VERIFY(GetClientRect(hWnd, &rcClient)); VERIFY(PatBlt(hdc, 0, 0, RECTWIDTH(rcClient), RECTHEIGHT(rcClient), BLACKNESS)); } EndPaint(hWnd, &ps); return 1; } } break; case WM_COMMAND: { if(bCompositionEnabled) { if(LBN_SELCHANGE==HIWORD(wParam)) { InvalidateRgn((HWND)lParam, NULL, TRUE); VERIFY(UpdateWindow((HWND)lParam)); } } if(ACN_STOP==HIWORD(wParam)) { /// /// if it is an animation control that has just stopped playing, /// reset the WD_PLAY flag so it repaints itself properly again if /// e.g. Aero is turned off an on again: /// PAERO_SUBCLASS_WND_DATA pCtrlData = (PAERO_SUBCLASS_WND_DATA)GetProp((HWND)lParam, WINDOW_DATA_STRING); if(pCtrlData) { pCtrlData->m_dwFlags&=~WD_PLAY; } } if(ACN_START==HIWORD(wParam)) { PAERO_SUBCLASS_WND_DATA pCtrlData = (PAERO_SUBCLASS_WND_DATA)GetProp((HWND)lParam, WINDOW_DATA_STRING); if(pCtrlData) { pCtrlData->m_dwFlags|=WD_PLAY; } } } break; case WM_NOTIFY: { LPNMHDR lpnmh = (LPNMHDR)lParam; if(lpnmh) { ASSERT(lpnmh->hwndFrom); ASSERT(IsWindow(lpnmh->hwndFrom)); switch(lpnmh->code) { case LVN_ITEMCHANGED: { /// /// if we select and deselect list view items, /// its header control sometimes vanishes so /// we have to force a redraw: /// HWND hHeader = ListView_GetHeader(lpnmh->hwndFrom); if(hHeader) { InvalidateRgn(hHeader, NULL, TRUE); VERIFY(UpdateWindow(hHeader)); } } break; default: break; } } } break; case WM_DESTROY: ASSERT(pWndData->m_pUxTheme); ASSERT(pWndData->m_pDwmApiImpl); VERIFY(SUCCEEDED(pWndData->m_pUxTheme->BufferedPaintUnInit())); delete pWndData->m_pUxTheme; delete pWndData->m_pDwmApiImpl; if(WndProcc==(WNDPROC)GetWindowLongPtr(hWnd, GWLP_WNDPROC)) { VERIFY(WndProcc==(WNDPROC) SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LONG_PTR) pWndData->m_oldWndProc)); VERIFY(pWndData==RemoveProp(hWnd, WINDOW_DATA_STRING)); VERIFY(!LocalFree(pWndData)); } break; case WM_NCDESTROY: if(WndProcc==(WNDPROC)GetWindowLongPtr(hWnd, GWLP_WNDPROC)) { VERIFY(WndProcc==(WNDPROC) SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LONG_PTR) pWndData->m_oldWndProc)); VERIFY(pWndData==RemoveProp(hWnd, WINDOW_DATA_STRING)); VERIFY(!LocalFree(pWndData)); } break; } return CallWindowProc(pOldProc, hWnd, uMsg, wParam, lParam); }
SrcOffsetY=info->bounds.MinY-(info->bounds.MinY-offsety); SrcOffsetY=MOD(SrcOffsetY,pattern->height); // The width of the first tile, this is either the rest of the tile right to SrcOffsetX // or the width of the dest rect, if the rect is narrow FirstSizeX=MIN((pattern->width-SrcOffsetX),(RECTWIDTH(&info->bounds))); // The start for the second tile (if used) SecondMinX=info->bounds.MinX+FirstSizeX; // The width of the second tile (we want the whole tile to be pattern->width pixels wide, // if we use pattern->width-SrcOffsetX pixels for the left part we'll use SrcOffsetX for the right part) SecondSizeX=MIN(SrcOffsetX,(info->bounds.MaxX-SecondMinX+1)); // The same values are calculated for y direction FirstSizeY=MIN((pattern->height-SrcOffsetY),(RECTHEIGHT(&info->bounds))); SecondMinY=info->bounds.MinY+FirstSizeY; SecondSizeY=MIN(SrcOffsetY,(info->bounds.MaxY-SecondMinY+1)); // Wait for the blitter, for some reason... WaitBlit(); // Blit the first piece of the tile BltBitMap( pattern->bitmap, SrcOffsetX,SrcOffsetY, rp.BitMap, info->bounds.MinX,info->bounds.MinY, FirstSizeX,FirstSizeY, 0xc0,0xff,0);
LRESULT AeroControlBase::StaticWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { case WM_SETTEXT: case WM_ENABLE: case WM_STYLECHANGED: { LRESULT res = DefSubclassProc(hWnd, uMsg, wParam, lParam); InvalidateRgn(hWnd, NULL, FALSE); return res; } break; case WM_PAINT: { PAINTSTRUCT ps; HDC hdc = BeginPaint(hWnd, &ps); if(hdc) { HDC hdcPaint = NULL; RECT rcClient; VERIFY(GetClientRect(hWnd, &rcClient)); LONG_PTR dwStyle = GetWindowLongPtr(hWnd, GWL_STYLE); LONG_PTR dwStyleEx = GetWindowLongPtr(hWnd, GWL_EXSTYLE); HTHEME hTheme = OpenThemeData(NULL, L"ControlPanelStyle"); if(hTheme) { HPAINTBUFFER hBufferedPaint = NULL; if (dwStyleEx & WS_EX_TRANSPARENT) { BP_PAINTPARAMS paintParams = {0}; paintParams.cbSize = sizeof(paintParams); paintParams.dwFlags = BPPF_ERASE; BLENDFUNCTION blendf = {0}; blendf.BlendOp = AC_SRC_OVER; blendf.AlphaFormat = AC_SRC_ALPHA; blendf.SourceConstantAlpha = 255; paintParams.pBlendFunction = &blendf; hBufferedPaint = BeginBufferedPaint(hdc, &rcClient, BPBF_TOPDOWNDIB, &paintParams, &hdcPaint); } else hBufferedPaint = BeginBufferedPaint(hdc, &rcClient, BPBF_TOPDOWNDIB, NULL, &hdcPaint); if (hdcPaint) { VERIFY(PatBlt(hdcPaint, 0, 0, RECTWIDTH(rcClient), RECTHEIGHT(rcClient), BLACKNESS)); VERIFY(S_OK==BufferedPaintSetAlpha(hBufferedPaint, &ps.rcPaint, 0x00)); LONG_PTR dwStaticStyle = dwStyle&0x1F; if(dwStaticStyle==SS_ICON || dwStaticStyle==SS_BITMAP) { bool bIcon = dwStaticStyle==SS_ICON; HANDLE hBmpIco = (HANDLE)SendMessage(hWnd, STM_GETIMAGE, bIcon ? IMAGE_ICON:IMAGE_BITMAP, NULL); if(hBmpIco) { std::unique_ptr<Bitmap> pBmp( bIcon ? new Bitmap((HICON)hBmpIco) : new Bitmap((HBITMAP)hBmpIco, NULL) ); std::unique_ptr<Graphics> myGraphics( new Graphics(hdcPaint) ); std::unique_ptr<CachedBitmap> pcbmp( new CachedBitmap(pBmp.get(), myGraphics.get()) ); VERIFY(Ok==myGraphics->DrawCachedBitmap(pcbmp.get(), 0,0)); } } else if(SS_BLACKRECT==dwStaticStyle || SS_GRAYRECT==dwStaticStyle || SS_WHITERECT==dwStaticStyle) { ARGB argb = 0L; switch (dwStaticStyle) { case SS_BLACKRECT: argb = 0xFF000000; break; case SS_GRAYRECT: argb = 0xFF808080; break; case SS_WHITERECT: argb = 0xFFFFFFFF; break; default: ASSERT(0); break; } Color clr(argb); FillRect(&rcClient, hdcPaint, clr); } else if(SS_BLACKFRAME==dwStaticStyle || SS_GRAYFRAME==dwStaticStyle || SS_WHITEFRAME==dwStaticStyle) { ARGB argb = 0L; switch (dwStaticStyle) { case SS_BLACKFRAME: argb = 0xFF000000; break; case SS_GRAYFRAME: argb = 0xFF808080; break; case SS_WHITEFRAME: argb = 0xFFFFFFFF; break; } Color clr(argb); DrawRect(&rcClient, hdcPaint, DashStyleSolid, clr, 1.0); } else { DTTOPTS DttOpts = {sizeof(DTTOPTS)}; DttOpts.dwFlags = DTT_COMPOSITED | DTT_GLOWSIZE; DttOpts.crText = RGB(255, 255, 255); DttOpts.iGlowSize = 12; // Default value VERIFY(DetermineGlowSize(&DttOpts.iGlowSize)); HFONT hFontOld = (HFONT)SendMessage(hWnd, WM_GETFONT, 0L, NULL); if(hFontOld) hFontOld = (HFONT) SelectObject(hdcPaint, hFontOld); int iLen = GetWindowTextLength(hWnd); if(iLen) { iLen+=5; // 1 for terminating zero, 4 for DT_MODIFYSTRING LPWSTR szText = (LPWSTR)LocalAlloc(LPTR, sizeof(WCHAR)*iLen); if(szText) { iLen = GetWindowTextW(hWnd, szText, iLen); if(iLen) { DWORD dwFlags = DT_WORDBREAK; switch (dwStaticStyle) { case SS_CENTER: dwFlags |= DT_CENTER; break; case SS_RIGHT: dwFlags |= DT_RIGHT; break; case SS_LEFTNOWORDWRAP: dwFlags &= ~DT_WORDBREAK; break; } if(dwStyle & SS_CENTERIMAGE) { dwFlags |= DT_VCENTER; dwFlags &= ~DT_WORDBREAK; } if(dwStyle & SS_ENDELLIPSIS) dwFlags |= DT_END_ELLIPSIS|DT_MODIFYSTRING; else if(dwStyle & SS_PATHELLIPSIS) dwFlags |= DT_PATH_ELLIPSIS|DT_MODIFYSTRING; else if(dwStyle & SS_WORDELLIPSIS) dwFlags |= DT_WORD_ELLIPSIS|DT_MODIFYSTRING; if (dwStyleEx&WS_EX_RIGHT) dwFlags |= DT_RIGHT; if(dwStyle & SS_NOPREFIX) dwFlags |= DT_NOPREFIX; VERIFY(S_OK==DrawThemeTextEx(hTheme, hdcPaint, 0, 0, szText, -1, dwFlags, &rcClient, &DttOpts)); if(dwStyle&SS_SUNKEN || dwStyle&WS_BORDER) DrawRect(&rcClient, hdcPaint, DashStyleSolid, Color(0xFF, 0,0,0), 1.0); } VERIFY(!LocalFree(szText)); } } if (hFontOld) { SelectObject(hdcPaint, hFontOld); hFontOld = NULL; } } VERIFY(S_OK==EndBufferedPaint(hBufferedPaint, TRUE)); } VERIFY(S_OK==CloseThemeData(hTheme)); } } EndPaint(hWnd, &ps); return 0; } break; case WM_NCDESTROY: case WM_DESTROY: RemoveWindowSubclass(hWnd, SubclassProc, Static); subclassedControls.erase(hWnd); break; } return DefSubclassProc(hWnd, uMsg, wParam, lParam); }
BOOL CMyDib::Paint(CDC* pDC, LPRECT lpDCRect, LPRECT lpViewRect, LPRECT lpDIBRect) const { //重载一个函数以避免闪烁 if (!m_pBMI || pDC == NULL) return FALSE; HDC hDC = pDC->GetSafeHdc(); HPALETTE hPal = NULL; // Our DIB's palette HPALETTE hOldPal = NULL; // Previous palette // Get the DIB's palette, then select it into DC if (m_pPalette != NULL) { hPal = (HPALETTE) m_pPalette->m_hObject; // Select as background since we have // already realized in foreground if needed hOldPal = ::SelectPalette(hDC, hPal, TRUE); } /* Make sure to use the stretching mode best for color pictures */ ::SetStretchBltMode(hDC, COLORONCOLOR); CDC* pMemDC = new CDC(); CBitmap bm,*pOldBM; pMemDC->CreateCompatibleDC(pDC); bm.CreateCompatibleBitmap(pDC,RECTWIDTH(lpDCRect),RECTHEIGHT(lpDCRect)); pOldBM = pMemDC->SelectObject(&bm); CBrush BlueBrush; BlueBrush.CreateSolidBrush(RGB(10,10,100)); CBrush* pOldBrush = (CBrush* )pMemDC->SelectObject(&BlueBrush); pMemDC->Rectangle(CRect(lpDCRect->left,lpDCRect->top,RECTWIDTH(lpDCRect),RECTHEIGHT(lpDCRect))); pMemDC->SelectObject(pOldBrush); pMemDC->SetStretchBltMode(HALFTONE); SetBrushOrgEx(pMemDC->GetSafeHdc(),0,0,NULL); BOOL bSuccess; if ((RECTWIDTH(lpViewRect) == RECTWIDTH(lpDIBRect)) && (RECTHEIGHT(lpViewRect) == RECTHEIGHT(lpDIBRect))) bSuccess = ::SetDIBitsToDevice(pMemDC->GetSafeHdc(), // hDC lpViewRect->left, // DestX lpViewRect->top, // DestY RECTWIDTH(lpViewRect), // nDestWidth RECTHEIGHT(lpViewRect), // nDestHeight lpDIBRect->left, // SrcX (int)Height() - lpDIBRect->top - RECTHEIGHT(lpDIBRect), // SrcY 0, // nStartScan (WORD)Height(), // nNumScans m_pBits, // lpBits m_pBMI, // lpBitsInfo DIB_RGB_COLORS); // wUsage else bSuccess = ::StretchDIBits(pMemDC->GetSafeHdc(), // hDC lpViewRect->left, // DestX lpViewRect->top, // DestY RECTWIDTH(lpViewRect), // nDestWidth RECTHEIGHT(lpViewRect), // nDestHeight lpDIBRect->left, // SrcX lpDIBRect->top, // SrcY RECTWIDTH(lpDIBRect), // wSrcWidth RECTHEIGHT(lpDIBRect), // wSrcHeight m_pBits, // lpBits m_pBMI, // lpBitsInfo DIB_RGB_COLORS, // wUsage SRCCOPY); // dwROP pDC->BitBlt(0,0,RECTWIDTH(lpDCRect),RECTHEIGHT(lpDCRect),pMemDC,0,0,SRCCOPY); pMemDC->SelectObject(pOldBM); bm.DeleteObject(); if(pMemDC != NULL) { pMemDC->DeleteDC(); delete pMemDC; pMemDC = NULL; } /* Reselect old palette */ if (hOldPal != NULL) { ::SelectPalette(hDC, hOldPal, TRUE); } return bSuccess; //return CDib::Paint(pDC, lpDCRect, lpViewRect, lpDIBRect); }
BOOL FAR PaintDIB(HDC hDC, LPRECT lpDCRect, HDIB hDIB, LPRECT lpDIBRect, HPALETTE hPal) { LPSTR lpDIBHdr; // Pointer to BITMAPINFOHEADER LPSTR lpDIBBits; // Pointer to DIB bits BOOL bSuccess=FALSE; // Success/fail flag HPALETTE hOldPal=NULL; // Previous palette /* Check for valid DIB handle */ if (!hDIB) return FALSE; /* Lock down the DIB, and get a pointer to the beginning of the bit * buffer */ lpDIBHdr = GlobalLock(hDIB); lpDIBBits = FindDIBBits(lpDIBHdr); /* Select and realize our palette as background */ if (hPal) { hOldPal = SelectPalette(hDC, hPal, TRUE); RealizePalette(hDC); } /* Make sure to use the stretching mode best for color pictures */ SetStretchBltMode(hDC, COLORONCOLOR); /* Determine whether to call StretchDIBits() or SetDIBitsToDevice() */ if ((RECTWIDTH(lpDCRect) == RECTWIDTH(lpDIBRect)) && (RECTHEIGHT(lpDCRect) == RECTHEIGHT(lpDIBRect))) bSuccess = SetDIBitsToDevice(hDC, // hDC lpDCRect->left, // DestX lpDCRect->top, // DestY RECTWIDTH(lpDCRect), // nDestWidth RECTHEIGHT(lpDCRect), // nDestHeight lpDIBRect->left, // SrcX (int)DIBHeight(lpDIBHdr) - lpDIBRect->top - RECTHEIGHT(lpDIBRect), // SrcY 0, // nStartScan (WORD)DIBHeight(lpDIBHdr), // nNumScans lpDIBBits, // lpBits (LPBITMAPINFO)lpDIBHdr, // lpBitsInfo DIB_RGB_COLORS); // wUsage else bSuccess = StretchDIBits(hDC, // hDC lpDCRect->left, // DestX lpDCRect->top, // DestY RECTWIDTH(lpDCRect), // nDestWidth RECTHEIGHT(lpDCRect), // nDestHeight lpDIBRect->left, // SrcX lpDIBRect->top, // SrcY RECTWIDTH(lpDIBRect), // wSrcWidth RECTHEIGHT(lpDIBRect), // wSrcHeight lpDIBBits, // lpBits (LPBITMAPINFO)lpDIBHdr, // lpBitsInfo DIB_RGB_COLORS, // wUsage SRCCOPY); // dwROP /* Unlock the memory block */ GlobalUnlock(hDIB); /* Reselect old palette */ if (hOldPal) SelectPalette(hDC, hOldPal, FALSE); /* Return with success/fail flag */ return bSuccess; }
BOOL FAR PaintBitmap(HDC hDC, LPRECT lpDCRect, HBITMAP hDDB, LPRECT lpDDBRect, HPALETTE hPal) { HDC hMemDC; // Handle to memory DC HBITMAP hOldBitmap; // Handle to previous bitmap HPALETTE hOldPal1 = NULL; // Handle to previous palette HPALETTE hOldPal2 = NULL; // Handle to previous palette BOOL bSuccess = FALSE; // Success/fail flag /* Create a memory DC */ hMemDC = CreateCompatibleDC (hDC); /* If this failed, return FALSE */ if (!hMemDC) return FALSE; /* If we have a palette, select and realize it */ if (hPal) { hOldPal1 = SelectPalette(hMemDC, hPal, TRUE); hOldPal2 = SelectPalette(hDC, hPal, TRUE); RealizePalette(hDC); } /* Select bitmap into the memory DC */ hOldBitmap = SelectObject (hMemDC, hDDB); /* Make sure to use the stretching mode best for color pictures */ SetStretchBltMode (hDC, COLORONCOLOR); /* Determine whether to call StretchBlt() or BitBlt() */ if ((RECTWIDTH(lpDCRect) == RECTWIDTH(lpDDBRect)) && (RECTHEIGHT(lpDCRect) == RECTHEIGHT(lpDDBRect))) bSuccess = BitBlt(hDC, lpDCRect->left, lpDCRect->top, lpDCRect->right - lpDCRect->left, lpDCRect->bottom - lpDCRect->top, hMemDC, lpDDBRect->left, lpDDBRect->top, SRCCOPY); else bSuccess = StretchBlt(hDC, lpDCRect->left, lpDCRect->top, lpDCRect->right - lpDCRect->left, lpDCRect->bottom - lpDCRect->top, hMemDC, lpDDBRect->left, lpDDBRect->top, lpDDBRect->right - lpDDBRect->left, lpDDBRect->bottom - lpDDBRect->top, SRCCOPY); /* Clean up */ SelectObject(hMemDC, hOldBitmap); if (hOldPal1) SelectPalette (hMemDC, hOldPal1, FALSE); if (hOldPal2) SelectPalette (hDC, hOldPal2, FALSE); DeleteDC (hMemDC); /* Return with success/fail flag */ return bSuccess; }
// Update toolbar cache BOOL GetToolBarCache(ToolBarInfo *toolbar,BOOL real) { short depth,width,height,num,x,y; short last_width=0,last_height=0; Cfg_Button *button; struct TagItem tags[4]; struct Rectangle rect; // Invalid toolbar? if (!toolbar) return 0; // Free existing cache FreeToolBarCache(toolbar); // Remap toolbar if this is for real if (real && !toolbar->done_remap) { // Do remap RemapToolBar(toolbar); toolbar->done_remap=1; } // Initialise tags tags[0].ti_Tag=IM_Depth; tags[0].ti_Data=1; tags[1].ti_Tag=IM_Width; tags[1].ti_Data=0; tags[2].ti_Tag=IM_Height; tags[2].ti_Data=0; tags[3].ti_Tag=TAG_DONE; // Minimum depth depth=1; // Count items in toolbar for (button=(Cfg_Button *)toolbar->buttons->buttons.lh_Head,toolbar->count=0; button->node.ln_Succ; button=(Cfg_Button *)button->node.ln_Succ,toolbar->count++); // Allocate position array if (!(toolbar->button_array=AllocVec(sizeof(struct Rectangle)*(toolbar->count+2),MEMF_CLEAR))) { FreeToolBarCache(toolbar); return 0; } // Go through buttons again for (button=(Cfg_Button *)toolbar->buttons->buttons.lh_Head,num=0,toolbar->max_width=0; button->node.ln_Succ; button=(Cfg_Button *)button->node.ln_Succ,num++) { Cfg_ButtonFunction *func; short width,height,x; // Get left button image if ((func=(Cfg_ButtonFunction *) FindFunctionType((struct List *)&button->function_list,FTYPE_LEFT_BUTTON)) && func->image) { // Get depth and other info GetImageAttrs(func->image,tags); // Biggest depth so far? if (tags[0].ti_Data>depth) depth=tags[0].ti_Data; // Get size width=tags[1].ti_Data; height=tags[2].ti_Data; } // Or textual button? else if (!(button->button.flags&BUTNF_GRAPHIC) && func) { struct TextExtent extent; // Get length of label TextExtent(&GUI->screen_pointer->RastPort,func->label,strlen(func->label),&extent); // Get size width=extent.te_Width; height=extent.te_Height; } // Use last size else { width=last_width; height=last_height; } // Minimum size if (width<2) width=8; if (height<2) height=8; // Save size last_width=width; last_height=height; // Increase size for border if (!(toolbar->buttons->window.flags&BTNWF_BORDERLESS)) { width+=2; height+=2; } // Biggest width so far? if (width>toolbar->max_width) toolbar->max_width=width; // Get last position x=(num>0)?toolbar->button_array[num-1].MaxX+1:0; // Store position in array toolbar->button_array[num].MinX=x; toolbar->button_array[num].MinY=0; toolbar->button_array[num].MaxX=x+width-1; toolbar->button_array[num].MaxY=height-1; } // No actual buttons? if (toolbar->count<1 || depth<1) { FreeToolBarCache(toolbar); return 0; } // Store rows/cols toolbar->cols=toolbar->count; toolbar->rows=1; // Valid toolbar arrow? if (GUI->toolbar_arrow_image) { short width,height; // Get size of the arrow button GetImageAttrs(GUI->toolbar_arrow_image,tags); // Biggest depth so far? if (tags[0].ti_Data>depth) depth=tags[0].ti_Data; // Get size width=tags[1].ti_Data; height=tags[2].ti_Data; // Increase size for border if (!(toolbar->buttons->window.flags&BTNWF_BORDERLESS)) { width+=2; height+=2; } // Store size in array toolbar->button_array[toolbar->count].MaxX=width-1; toolbar->button_array[toolbar->count].MaxY=height-1; // Add to maximum width toolbar->max_width+=width; } // Get height of toolbar for (num=0,height=0;num<=toolbar->count;num++) { if ((width=RECTHEIGHT(&toolbar->button_array[num]))>height) height=width; } // Store toolbar height toolbar->button_height=height; // Get cache size toolbar->width=toolbar->button_array[toolbar->count-1].MaxX+1; toolbar->height=toolbar->button_height; // Don't want cache? if (!real) return 1; // Allocate cache bitmap if (!(toolbar->bitmap= NewBitMap( toolbar->width, toolbar->height, depth, BMF_CLEAR, GUI->screen_pointer->RastPort.BitMap))) // 0))) { // Failed FreeToolBarCache(toolbar); return 0; } // Initialise RastPort InitRastPort(&toolbar->rp); toolbar->rp.BitMap=toolbar->bitmap; // Got cache successfully toolbar->cache=1; // Set pens and font SetAPen(&toolbar->rp,1); SetBPen(&toolbar->rp,0); SetFont(&toolbar->rp,GUI->screen_pointer->RastPort.Font); // Initialise draw tags tags[0].ti_Tag=IM_Rectangle; tags[0].ti_Data=(ULONG)▭ tags[1].ti_Tag=IM_ClipBoundary; tags[1].ti_Data=(toolbar->buttons->window.flags&BTNWF_BORDERLESS)?0:2; tags[2].ti_Tag=IM_NoIconRemap; tags[2].ti_Data=(environment->env->desktop_flags&DESKTOPF_NO_REMAP)?TRUE:FALSE; tags[3].ti_Tag=TAG_DONE; // Go through buttons for (button=(Cfg_Button *)toolbar->buttons->buttons.lh_Head,x=0,y=0,num=0; button->node.ln_Succ; button=(Cfg_Button *)button->node.ln_Succ,num++) { Cfg_ButtonFunction *func; BOOL ok=0; // Get button rectangle rect=toolbar->button_array[num]; // Get left button image if ((func=(Cfg_ButtonFunction *)FindFunctionType((struct List *)&button->function_list,FTYPE_LEFT_BUTTON)) && func->image) { // Draw button image RenderImage(&toolbar->rp,func->image,0,0,tags); ok=1; } // Or textual button? else if (!(button->button.flags&BUTNF_GRAPHIC) && func && func->label && *func->label) { // Draw label Move(&toolbar->rp,x,y+toolbar->rp.TxBaseline); Text(&toolbar->rp,func->label,strlen(func->label)); ok=1; } // Draw button border if (!ok || !(toolbar->buttons->window.flags&BTNWF_BORDERLESS)) DrawBox(&toolbar->rp,&rect,GUI->draw_info,0); } return 1; }
void FCCmdLayerMerge::Execute (FCObjCanvas & canvas, FCObjProgress * Percent) { if (m_LayerIndex.size() <= 1) return ; int * arIndex = new int[m_LayerIndex.size()], i ; for (i=0 ; i < (int)m_LayerIndex.size() ; i++) arIndex[i] = m_LayerIndex[i] ; // 先按从小到大排序,删除时要从大的删起 fooBubbleSort (arIndex, m_LayerIndex.size()) ; // 计算合并后图层大小 RECT rcNewLayer = {0x7FFFFFFF, 0x7FFFFFFF, 0x80000000, 0x80000000} ; // 最大最小值 for (i=0 ; i < (int)m_LayerIndex.size() ; i++) { FCObjLayer * pLayer = canvas.GetLayer(arIndex[i]) ; if (pLayer == NULL) { delete[] arIndex ; return ; } POINT ptLayer = pLayer->GetGraphObjPos() ; if (ptLayer.x < rcNewLayer.left) rcNewLayer.left = ptLayer.x ; if (ptLayer.x + (int)pLayer->Width() > rcNewLayer.right) rcNewLayer.right = ptLayer.x + (int)pLayer->Width() ; if (ptLayer.y < rcNewLayer.top) rcNewLayer.top = ptLayer.y ; if (ptLayer.y + (int)pLayer->Height() > rcNewLayer.bottom) rcNewLayer.bottom = ptLayer.y + (int)pLayer->Height() ; } // 制作合并图层 FCObjLayer * pNewLayer = new FCObjLayer ; if (!pNewLayer->Create (RECTWIDTH(rcNewLayer), RECTHEIGHT(rcNewLayer), 32)) { delete[] arIndex ; delete pNewLayer ; return ; } // 绘制各个图层(从底层往上绘制) for (i=0 ; i < (int)m_LayerIndex.size() ; i++) { FCObjLayer * pLayer = canvas.GetLayer(arIndex[i]) ; if (pLayer->ColorBits() < 32) // 只支持32bit图层 continue ; // pLayer在新图层上的位置 POINT ptLayer = pLayer->GetGraphObjPos() ; ptLayer.x -= rcNewLayer.left ; ptLayer.y -= rcNewLayer.top ; for (int y=0 ; y < pLayer->Height() ; y++) { RGBQUAD * pDest = (RGBQUAD*)pNewLayer->GetBits (ptLayer.x, y+ptLayer.y), * pSrc = (RGBQUAD*)pLayer->GetBits (y) ; for (int x=0 ; x < pLayer->Width() ; x++, pDest++, pSrc++) { int nSrcA = pSrc->rgbReserved * pLayer->GetLayerTransparent() / 100 ; FCColor::CombineAlphaPixel (pDest, *pDest, pDest->rgbReserved, *pSrc, nSrcA) ; } } if (Percent != NULL) Percent->SetProgress (100 * (i + 1) / m_LayerIndex.size()) ; } pNewLayer->SetGraphObjPos (rcNewLayer.left, rcNewLayer.top) ; // 插入删除组和命令 m_cmdList.push_back (new FCCmdLayerAdd (pNewLayer, arIndex[0])) ; // 插在最小index图层 for (i = m_LayerIndex.size()-1 ; i >=0 ; i--) m_cmdList.push_back (new FCCmdLayerRemove (canvas.GetLayer(arIndex[i]))) ; FCCmdImgCmdComposite::Execute (canvas, Percent) ; delete[] arIndex ; }