www.pudn.com > vc开发的精美界面.zip > BCGOutlookButton.cpp
//******************************************************************************* // COPYRIGHT NOTES // --------------- // This source code is a part of BCGControlBar library. // You may use, compile or redistribute it as part of your application // for free. You cannot redistribute it as a part of a software development // library without the agreement of the author. If the sources are // distributed along with the application, you should leave the original // copyright notes in the source code without any changes. // This code can be used WITHOUT ANY WARRANTIES on your own risk. // // For the latest updates to this library, check my site: // http://welcome.to/bcgsoft // // Stas Levin//******************************************************************************* // BCGOutlookButton.cpp: implementation of the CBCGOutlookButton class. // ////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "bcgcontrolbar.h" #include "BCGOutlookButton.h" #include "BCGOutlookBar.h" #include "MenuImages.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif IMPLEMENT_SERIAL(CBCGOutlookButton, CBCGToolbarButton, 1) #define BUTTON_OFFSET 10 inline static COLORREF PixelAlpha (COLORREF srcPixel, int percent); ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CBCGOutlookButton::CBCGOutlookButton() { m_pWndParentBar = NULL; m_iPageNumber = 0; } //*************************************************************************************** CBCGOutlookButton::~CBCGOutlookButton() { } //*************************************************************************************** void CBCGOutlookButton::OnDraw (CDC* pDC, const CRect& rect, CBCGToolBarImages* pImages, BOOL bHorz, BOOL bCustomizeMode, BOOL bHighlight, BOOL /*bDrawBorder*/, BOOL /*bGrayDisabledButtons*/) { ASSERT_VALID (this); ASSERT_VALID (m_pWndParentBar); CSize csOffset (0, 0); if (!bCustomizeMode && (bHighlight && (m_nStyle & TBBS_PRESSED))) { csOffset = CSize (1, 1); } CRect rectBorder = rect; CRect rectText = rect; rectText.top += BUTTON_OFFSET / 2; if (pImages != NULL && GetImage () >= 0) { int x, y; CSize csImage = pImages->GetImageSize (); if (!bHorz) { int iImageHorzOffset = (rect.Width () - csImage.cx) / 2; x = rect.left + iImageHorzOffset; y = rect.top + BUTTON_OFFSET / 2; rectText.top += csImage.cy + 2; } else { int iImageVertOffset = (rect.Height () - csImage.cy) / 2; x = rect.left + BUTTON_OFFSET / 2; y = rect.top + iImageVertOffset; rectText.left += csImage.cx + 2; CRect rect = rectText; int iTextHeight = pDC->DrawText (m_strText, rect, DT_CALCRECT | DT_WORDBREAK); rectText.top = rect.top + (rect.Height () - iTextHeight) / 2; } rectBorder = CRect (CPoint (x, y), csImage); rectBorder.InflateRect (2, 2); if (bHighlight && m_pWndParentBar->IsDrawShadedHighlight () && !bCustomizeMode) { ShadowRect (pDC, rectBorder); } pImages->Draw (pDC, x + csOffset.cx, y + csOffset.cy, GetImage (), FALSE, (m_nStyle & TBBS_DISABLED) && !m_pWndParentBar->IsBackgroundTexture ()); // Draw grayed images for "non-backgound" only! } else { if (bHighlight && m_pWndParentBar->IsDrawShadedHighlight () && !bCustomizeMode) { ShadowRect (pDC, rectBorder); } } if (!bCustomizeMode && (bHighlight || (m_nStyle & TBBS_PRESSED))) { if ((m_nStyle & TBBS_PRESSED) && bHighlight) { pDC->Draw3dRect (rectBorder,::GetSysColor (COLOR_3DDKSHADOW), ::GetSysColor (COLOR_3DHILIGHT)); } else { pDC->Draw3dRect (rectBorder,::GetSysColor (COLOR_3DHILIGHT), ::GetSysColor (COLOR_3DDKSHADOW)); } } if (m_bTextBelow && !m_strText.IsEmpty ()) { if (m_nStyle & TBBS_DISABLED) { if (m_pWndParentBar->IsBackgroundTexture ()) { pDC->SetTextColor (::GetSysColor (COLOR_GRAYTEXT)); } else { pDC->SetTextColor (globalData.clrBtnFace); } } else { pDC->SetTextColor (m_pWndParentBar->GetRegularColor ()); } pDC->DrawText (m_strText, rectText, DT_WORDBREAK | DT_CENTER); } } //**************************************************************************************** SIZE CBCGOutlookButton::OnCalculateSize (CDC* pDC, const CSize& sizeDefault, BOOL bHorz) { ASSERT_VALID (this); ASSERT_VALID (pDC); CSize sizeResult = sizeDefault; if (!bHorz) { CRect rectText (0, 0, sizeDefault.cx, 1); int iTextHeight = m_bTextBelow ? pDC->DrawText (m_strText, rectText, DT_CALCRECT | DT_WORDBREAK) : 0; sizeResult.cy = sizeDefault.cy + iTextHeight + BUTTON_OFFSET; } else { CRect rectText (0, 0, 0, sizeDefault.cy); int iTextHeight = 0; if (m_bTextBelow) { do { rectText.right ++; iTextHeight = pDC->DrawText (m_strText, rectText, DT_CALCRECT | DT_WORDBREAK); } while (iTextHeight < pDC->GetTextExtent (m_strText).cy && rectText.Height () > sizeDefault.cy); } sizeResult.cx = sizeDefault.cx + rectText.Width () + BUTTON_OFFSET; } return sizeResult; } //*************************************************************************************** void CBCGOutlookButton::OnChangeParentWnd (CWnd* pWndParent) { m_pWndParentBar = DYNAMIC_DOWNCAST (CBCGOutlookBar, pWndParent); ASSERT_VALID (m_pWndParentBar); } //*************************************************************************************** BOOL CBCGOutlookButton::CanBeDropped (CBCGToolBar* pToolbar) { ASSERT_VALID (pToolbar); return pToolbar->IsKindOf (RUNTIME_CLASS (CBCGOutlookBar)); } //*************************************************************************************** void CBCGOutlookButton::SetImage (int iImage) { // Don't add image to hash! m_iImage = iImage; } //*************************************************************************************** void CBCGOutlookButton::ShadowRect (CDC* pDC, CRect& rect) { ASSERT_VALID (pDC); CDC dcMem; if (!dcMem.CreateCompatibleDC (pDC)) { return; } CBitmap bmpMem; if (!bmpMem.CreateCompatibleBitmap (pDC, rect.Width (), rect.Height ())) { return; } CBitmap* pOldBmp = dcMem.SelectObject(&bmpMem); ASSERT (pOldBmp != NULL); LPBITMAPINFO lpbi; // Fill in the BITMAPINFOHEADER lpbi = (LPBITMAPINFO) new BYTE[sizeof(BITMAPINFOHEADER) ]; lpbi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); lpbi->bmiHeader.biWidth = rect.Width (); lpbi->bmiHeader.biHeight = rect.Height (); lpbi->bmiHeader.biPlanes = 1; lpbi->bmiHeader.biBitCount = 32; lpbi->bmiHeader.biCompression = BI_RGB; lpbi->bmiHeader.biSizeImage = rect.Width () * rect.Height (); lpbi->bmiHeader.biXPelsPerMeter = 0; lpbi->bmiHeader.biYPelsPerMeter = 0; lpbi->bmiHeader.biClrUsed = 0; lpbi->bmiHeader.biClrImportant = 0; COLORREF* pBits = NULL; HBITMAP hmbpDib = CreateDIBSection ( dcMem.m_hDC, lpbi, DIB_RGB_COLORS, (void **)&pBits, NULL, NULL); if (hmbpDib == NULL || pBits == NULL) { delete lpbi; return; } dcMem.SelectObject (hmbpDib); dcMem.BitBlt (0, 0, rect.Width (), rect.Height (), pDC, rect.left, rect.top, SRCCOPY); for (int x = 0; x < rect.Width (); x++) { for (int y = 0; y < rect.Width (); y++) { COLORREF* pColor = (COLORREF*) (pBits + rect.Width () * y + x); *pColor = PixelAlpha (*pColor, 85); } } //----------------------------------------- // Copy shadowed bitmap back to the screen: //----------------------------------------- pDC->BitBlt (rect.left, rect.top, rect.Width (), rect.Height (), &dcMem, 0, 0, SRCCOPY); dcMem.SelectObject (pOldBmp); DeleteObject (hmbpDib); delete lpbi; } COLORREF PixelAlpha (COLORREF srcPixel, int percent) { // My formula for calculating the transpareny is as // follows (for each single color): // // percent // destPixel = sourcePixel * ( ------- ) // 100 // // This is not real alpha blending, as it only modifies the brightness, // but not the color (a real alpha blending had to mix the source and // destination pixels, e.g. mixing green and red makes yellow). // For our nice "menu" shadows its good enough. COLORREF clrFinal = RGB ( (GetRValue (srcPixel) * percent) / 100, (GetGValue (srcPixel) * percent) / 100, (GetBValue (srcPixel) * percent) / 100); return (clrFinal); }