ToolBarEx.cpp
资源名称:GGBT.rar [点击查看]
上传用户:lds876
上传日期:2013-05-25
资源大小:567k
文件大小:31k
源码类别:
P2P编程
开发平台:
Visual C++
- /////////////////////////////////////////////////////////////////////////////
- // Copyright (C) 1997 by Joerg Koenig
- // All rights reserved
- //
- // Distribute freely, except: don't remove my name from the source or
- // documentation (don't take credit for my work), mark your changes (don't
- // get me blamed for your possible bugs), don't alter or remove this
- // notice.
- // No warrantee of any kind, express or implied, is included with this
- // software; use at your own risk, responsibility for damages (if any) to
- // anyone resulting from the use of this software rests entirely with the
- // user.
- //
- // Send bug reports, bug fixes, enhancements, requests, flames, etc., and
- // I'll try to keep a version up to date. I can be reached as follows:
- // J.Koenig@adg.de (company site)
- // Joerg.Koenig@rhein-neckar.de (private site)
- /////////////////////////////////////////////////////////////////////////////
- // ToolBarEx.cpp : implementation file
- //
- // Description:
- // CToolBarEx provides additional features to the standard toolbar
- // "CToolBar". The main addition is the flat mode (last seen in
- // Developer Studio 5.0).
- // There are no special requirements for having the flat mode in your
- // application (no special comctl32.dll or what ever)!
- // If you need custom draw abilities, then you have to use VC++ >= 4.2
- // However, the flat mode should work with older versions of VC++ too (let
- // me know of your experiences!)
- //
- // Usage:
- // The only task you have to perform, is to
- // #include "ToolBarEx.h"
- // in either StdAfx.h or MainFrm.h and to change the type of
- // CMainFrame::m_wndToolBar from CToolBar to CToolBarEx.
- // Don't forget to recompile :-)
- //
- // Acknowledgements:
- // o The main idea of how to draw a separator and the gripper is stolen
- // from Roger Onslow's MSIE flat toolbar.
- // Thanks for saving my time, Roger ;-)
- // o The embossed drawing of a disabled image came from
- // Victor M. Vogelpoel (victorv@telic.nl)
- // o Some hints for buttons with text came from
- // David Bates (bates@econ.ubc.ca)
- // (I'm still thinking, text on toolbar-buttons is broken.
- // That has to be tooltip's work. However, texts on buttons
- // now work)
- // o Thanks to Patrick Liechty (patrickl@code3.code3.com) for
- // the reports of his experiences with VC++ 4.0/4.1
- // o Thanks to Jeng-Yuan Sheu (m8501511@chu.edu.tw) for the
- // enhanced checked button.
- // o Thanks to Todd C. Wilson (todd@mediatec.com) for his
- // bug report and code-enhancement for users of VC++ 4.2b
- //
- //
- // (known) bugs and limitations:
- // o the CDRF_NEWFONT notification is still untested ...
- // o Assigning texts to buttons may cause the buttons to
- // resize horizontally without notified by CToolBar. This
- // leads to a wrong calculation inside CalcDynamicLayout()
- // and CalcFixedLayout(). One could override both these
- // functions in derived classes to avoid that problem,
- // but that would be a greater pain ...
- // o some features of the toolbars seen in Office97/DevStudio
- // are not implemented (for instance text-only buttons or
- // the way how image+text buttons are displayed. The Alt-drag
- // feature too is unimplemented)
- //
- // if you find others (and have a solution for them ?!), please let me know:
- // Joerg.Koenig@rhein-neckar.de (private site) or
- // J.Koenig@adg.de (company site)
- //
- // Changes:
- // 11/25/97
- // o Some minor modifications to compile with VC++ 4.0/4.1 and 4.2b
- // o checked buttons now look hilighted (as in Office97/DevStudio)
- //
- // 11/07/97
- // (2 minor bugs have been occured as a result of the last update :)
- // o The WRAP state of a separator will be ignored now, if
- // the bar is docked vertically
- // o Draw an image transparently. This is needed only if one
- // uses 256 color images.
- //
- // 10/30/97
- // o texts on buttons now work
- // o gripper improved for a closer look like Office97
- // o disabled images now look embossed
- // o a separator is drawn only if it has no WRAP state set
- #include "stdafx.h"
- #include "ToolBarEx.h"
- #include "testBT.h"
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
- /////////////////////////////////////////////////////////////////////////////
- // local helper class CCustomDrawInfo
- //
- // The helper class CCustomDrawInfo handles the messaging to the docking
- // frame of the toolbar in flat mode only. If flat-mode is disabled, then
- // MFC's own messanger will be used.
- //
- // A few words about custom draw on toolbars:
- // o custom draw is possible for MFC >= 4.2 only (older versions don't know
- // anything about certain structures ...)
- // o MFC does not set the "rc" member of NMCUSTOMDRAW to the rectangle of the
- // button that will be drawn. However, we do, so watch out, wether the
- // toolbar is flat or not (or ignore the "rc" member in both cases).
- // If the current mode is not "flat", then MFC's art of message arrives ...
- // o MFC does not send a message for separators, so we too don't do it.
- // o It seems that MFC toolbars never send *ERASE notifications; instead they
- // send TBN_QUERYDELETE for instance.
- // o The CDRF_NEWFONT notification result is ignored (in flat mode. Never
- // tried with original MFC, because it is broken on toolbars).
- /////////////////////////////////////////////////////////////////////////////
- class CCustomDrawInfo {
- #if _MFC_VER >= 0x0420
- NMCUSTOMDRAW m_CDRW; // custom draw information holder
- LRESULT m_PrePaint; // result from prepaint notification
- LRESULT m_ItemPrePaint; // dito for specific item
- CToolBarEx * m_pToolBar; // the real sender of the notification
- CWnd * m_pReceiver; // the receiver of the notification
- LRESULT NotifyParent();
- #endif // _MFC_VER
- public: // construction
- CCustomDrawInfo( CDC & dc, CToolBarEx * pToolBar );
- public:
- // NotifyItemPrePaint() returns TRUE,
- // if the user wants to do the default
- // (CDRF_DODEFAULT) or FALSE, if the
- // user wants to skip (CDRF_SKIPDEFAULT)
- // Note that CDRF_SKIPDEFAULT is not
- // allowed for CDDS_PREPAINT, CDDS_POSTPAINT !
- // and CDDS_ITEMPOSTPAINT
- void NotifyPrePaint();
- BOOL NotifyItemPrePaint(int item);
- void NotifyItemPostPaint(int item);
- void NotifyPostPaint();
- };
- #if _MFC_VER >= 0x420
- LRESULT CCustomDrawInfo :: NotifyParent() {
- LRESULT lRes = CDRF_DODEFAULT;
- if( m_pReceiver )
- lRes = m_pReceiver->SendMessage(WM_NOTIFY,
- WPARAM(m_CDRW.hdr.idFrom),
- LPARAM(&m_CDRW));
- return lRes;
- }
- CCustomDrawInfo :: CCustomDrawInfo( CDC & dc, CToolBarEx * pBar )
- : m_PrePaint(0)
- , m_ItemPrePaint(0)
- {
- VERIFY((m_pToolBar = pBar) != 0);
- VERIFY((m_CDRW.hdc = dc.GetSafeHdc()) != 0);
- HWND hwnd = pBar->GetSafeHwnd();
- VERIFY(::IsWindow(hwnd));
- // initialise the NMHDR member of the customdraw structure
- m_CDRW.hdr.hwndFrom = hwnd;
- m_CDRW.hdr.idFrom = UINT(::GetWindowLong(hwnd, GWL_ID));
- m_CDRW.hdr.code = NM_CUSTOMDRAW;
- // Do not use CControlBar::GetDockingFrame() to receive
- // the parent. CWnd::GetParent() is inacceptable too.
- // Both these functions don't work, if the toolbar is
- // floating in the air!
- m_pReceiver = pBar->GetParentFrame();
- if( m_pReceiver )
- VERIFY(::IsWindow(m_pReceiver->GetSafeHwnd()));
- }
- void CCustomDrawInfo :: NotifyPrePaint() {
- // fill the customdraw structure with values for CDDS_PREPAINT
- m_CDRW.dwDrawStage = CDDS_PREPAINT;
- // the rest of the structure stays undefined in this stage
- // of drawing.
- m_PrePaint = NotifyParent();
- }
- BOOL CCustomDrawInfo :: NotifyItemPrePaint( int nItem ) {
- BOOL bRet = TRUE; // we assume to do the default
- if( m_PrePaint & CDRF_NOTIFYITEMDRAW ) {
- m_CDRW.dwDrawStage = CDDS_ITEMPREPAINT;
- m_pToolBar->GetItemRect(nItem, &m_CDRW.rc);
- m_CDRW.dwItemSpec = DWORD(m_pToolBar->GetItemID(nItem));
- UINT uStyle = m_pToolBar->GetButtonStyle(nItem);
- BOOL bEnable = m_pToolBar->GetToolBarCtrl()
- .IsButtonEnabled(m_CDRW.dwItemSpec);
- m_CDRW.uItemState = (bEnable ? 0 : CDIS_DISABLED) |
- (((uStyle & TBBS_PRESSED) || (uStyle & TBBS_CHECKED)) ?
- CDIS_CHECKED : 0);
- m_CDRW.lItemlParam = 0;
- m_ItemPrePaint = NotifyParent();
- if( m_ItemPrePaint & CDRF_SKIPDEFAULT )
- bRet = FALSE;
- }
- return bRet;
- }
- void CCustomDrawInfo :: NotifyItemPostPaint( int nItem ) {
- if( m_ItemPrePaint & CDRF_NOTIFYPOSTPAINT ) {
- m_CDRW.dwDrawStage = CDDS_ITEMPOSTPAINT;
- // the rest of the data has not been changed since ITEMPREPAINT
- // make sure it is so:
- ASSERT(m_pToolBar->GetItemID(nItem) == m_CDRW.dwItemSpec);
- NotifyParent();
- }
- }
- void CCustomDrawInfo :: NotifyPostPaint() {
- if( m_PrePaint & CDRF_NOTIFYPOSTPAINT ) {
- m_CDRW.dwDrawStage = CDDS_POSTPAINT;
- NotifyParent();
- }
- }
- #else // _MFC_VER < 4.2
- CCustomDrawInfo :: CCustomDrawInfo( CDC & dc, CToolBarEx * pParent ) {
- }
- void CCustomDrawInfo :: NotifyPrePaint() {
- }
- void CCustomDrawInfo :: NotifyPostPaint() {
- }
- BOOL CCustomDrawInfo :: NotifyItemPrePaint( int ) {
- return TRUE; // we always make the drawing by ourself
- }
- void CCustomDrawInfo :: NotifyItemPostPaint( int ) {
- }
- #endif // _MFC_VER
- /////////////////////////////////////////////////////////////////////////////
- // CToolBarEx
- CToolBarEx::CToolBarEx()
- : m_bFlatLook(TRUE)
- , m_clrBtnFace(::GetSysColor(COLOR_BTNFACE))
- , m_clrBtnHilight(::GetSysColor(COLOR_BTNHILIGHT))
- , m_clrBtnShadow(::GetSysColor(COLOR_BTNSHADOW))
- , m_clrBtnLight(::GetSysColor(COLOR_3DLIGHT))
- , m_nLastBtn(-1)
- , m_uTimerEvent(0)
- {
- // the systems I've tested, made no difference between
- // COLOR_BTNFACE and COLOR_3DLIGHT ...
- if( m_clrBtnFace == m_clrBtnLight )
- m_clrBtnLight = m_clrBtnHilight;
- CalculateOffset();
- // create the default font, used for buttons with text
- CFont Font;
- BOOL bOldSys = FALSE;
- if( ! Font.CreateStockObject( DEFAULT_GUI_FONT ) ) {
- // older versions of Windows* (NT 3.51 for instance)
- // fail with DEFAULT_GUI_FONT
- VERIFY( Font.CreateStockObject( SYSTEM_FONT ) );
- bOldSys = TRUE;
- }
- LOGFONT logfont ;
- Font.GetLogFont( &logfont ) ;
- if( bOldSys ) {
- logfont.lfWeight = 400;
- strcpy(logfont.lfFaceName,"MS Sans Serif");
- }
- logfont.lfHeight = 6 ;
- logfont.lfWidth = 0 ; // let windows compute this.
- VERIFY( m_GuiFont.CreateFontIndirect( &logfont ) ) ;
- m_bTracking = false;
- m_bMouseLeave = false;
- }
- CToolBarEx::~CToolBarEx()
- {
- }
- IMPLEMENT_DYNAMIC(CToolBarEx, CToolBar)
- BEGIN_MESSAGE_MAP(CToolBarEx, CDkToolBar)
- //{{AFX_MSG_MAP(CToolBarEx)
- ON_WM_PAINT()
- ON_WM_SYSCOLORCHANGE()
- ON_WM_NCCALCSIZE()
- ON_WM_MOUSEMOVE()
- ON_WM_NCPAINT()
- ON_WM_CREATE()
- ON_WM_ERASEBKGND()
- //}}AFX_MSG_MAP
- ON_WM_RBUTTONDOWN()
- ON_MESSAGE(TB_SETBUTTONSIZE, OnSetButtonSize)
- ON_MESSAGE(TB_SETBITMAPSIZE, OnSetBitmapSize)
- ON_MESSAGE(WM_MOUSELEAVE, OnMouseLeave)
- END_MESSAGE_MAP()
- /////////////////////////////////////////////////////////////////////////////
- // CToolBarEx message handlers
- void CToolBarEx::OnRButtonDown(UINT nFlags, CPoint point)
- {
- // CToolBar::OnRButtonDown(nFlags, point);
- }
- LRESULT CToolBarEx :: OnSetButtonSize(WPARAM wParam, LPARAM lParam)
- {
- LRESULT lResult = CDkToolBar::OnSetButtonSize(wParam, lParam);
- if( lResult )
- CalculateOffset();
- return lResult;
- }
- LRESULT CToolBarEx :: OnSetBitmapSize(WPARAM wParam, LPARAM lParam)
- {
- LRESULT lResult = CDkToolBar::OnSetBitmapSize(wParam, lParam);
- if( lResult )
- CalculateOffset();
- return lResult;
- }
- void CToolBarEx::OnPaint()
- {
- // DbgGuiLeak dbgGui;
- // HIMAGELIST hImg = GetImageList(TB_GETIMAGELIST);
- /*
- #ifdef _DEBUG
- if( hImg == 0 ) {
- TRACE0("CToolBarEx::OnPaint(): could not get image listn");
- }
- #endif
- //*/
- if( m_bFlatLook)
- {
- CRect rcUpdate;
- if( ! GetUpdateRect(rcUpdate) )
- return;
- if( HasButtonText() )
- CalculateOffset(); // strings may have been added
- // attach image-list for even more MFC feeling :)
- CImageList& imglist = *GetToolBarCtrl().GetImageList();
- CImageList& imglistHot = *GetToolBarCtrl().GetHotImageList();
- CImageList& imglistDisable = *GetToolBarCtrl().GetDisabledImageList();
- POINT cursor;
- ::GetCursorPos(&cursor);
- ScreenToClient(&cursor);
- CPaintDC dc(this); // device context for painting
- CFont * pOldFont = dc.SelectObject(&m_GuiFont);
- // Now it's time for the first custom-draw-notification...
- CCustomDrawInfo cdrw(dc, this);
- cdrw.NotifyPrePaint();
- bool bMouseLeavePaint = false;
- register const int nBtn = GetToolBarCtrl().GetButtonCount();
- for( register int i = 0; i < nBtn; ++i )
- {
- CRect rc;
- GetItemRect(i, rc);
- int nBitmap; UINT uID, uStyleState;
- GetButtonInfo(i, uID, uStyleState, nBitmap);
- WORD wStyle = LOWORD(uStyleState);
- WORD wState = HIWORD(uStyleState);
- if( wState & TBSTATE_HIDDEN )
- continue;
- if( wStyle == TBSTYLE_SEP )
- {
- if( !(wState & TBSTATE_WRAP) || ! IsFloating() )
- {
- DrawSeparator(dc, rc);
- }
- }
- else
- {
- if( ! CRect().IntersectRect(rcUpdate, rc) )
- continue; // this button needs no repaint
- BOOL bBtnDown = (wState & TBSTATE_CHECKED) || (wState & TBSTATE_PRESSED);
- BOOL bBtnEnabled = GetToolBarCtrl().IsButtonEnabled(int(uID));
- BOOL bHasCursor = rc.PtInRect(cursor);
- COLORREF clrRect = (bBtnDown && !bHasCursor) ? m_clrBtnLight : m_clrBtnFace;
- // maybe the button has text
- dc.SetTextColor(RGB(0,0,0));
- dc.SetBkColor(clrRect);
- // There is a bug in CToolBar: If there are texts assigned
- // to buttons, then the button-widths may change transparently
- // (without notified by CToolBar), so we recalculate the
- // horizontal offset here:
- m_sizeOffset.cx = (rc.Width() - m_sizeImage.cx) / 2;
- if( ! cdrw.NotifyItemPrePaint(i) )
- continue; // parent has already drawn the button
- bMouseLeavePaint = true;
- // dc.FillSolidRect(rc, clrRect);
- //CBrush brush(clrRect);
- //dc.FillRect(rc, &brush);
- // it seems, that CDC::Draw3dRect() changes the background color
- COLORREF clrBk = dc.GetBkColor();
- if( bBtnDown )
- {
- // draw a pressed button
- /*
- dc.Draw3dRect(rc, m_clrBtnShadow, m_clrBtnHilight);
- if( ! bHasCursor )
- {
- // draw an invisible frame around the hilighted area
- CRect rcCheck = rc;
- rcCheck.DeflateRect(1,1);
- dc.Draw3dRect(rcCheck, m_clrBtnFace, m_clrBtnFace);
- }
- //*/
- }
- else if( bHasCursor && ! bBtnDown && bBtnEnabled )
- {
- // draw a normal button
- // dc.Draw3dRect(rc, RGB(0, 255, 0), RGB(0, 255, 0));
- // dc.Draw3dRect(rc, m_clrBtnHilight, m_clrBtnShadow);
- }
- else if( ! bBtnDown && bBtnEnabled )
- // Draw an invisible rect around the button.
- // This prevents us from erasing the background
- // if the button was formed before
- // (that would cause the button to flicker ...)
- {
- // dc.Draw3dRect(rc, m_clrBtnFace, m_clrBtnFace);
- /*
- CBrush brush;
- brush.CreatePatternBrush(&m_bkBmp);
- dc.FillRect(rc, &brush);
- //*/
- }
- dc.SetBkColor(clrBk);
- // the point where to start with the image
- //CPoint pt(rc.left + m_sizeOffset.cx + bBtnDown,
- // rc.top + m_sizeOffset.cy + bBtnDown);
- CPoint pt(rc.left + bBtnDown, rc.top + bBtnDown);
- pt.Offset(4, 4);
- if(!bBtnEnabled)
- {
- if (&imglistDisable)
- imglistDisable.Draw(&dc, nBitmap, pt, ILD_TRANSPARENT);
- else
- {
- imglist.Draw(&dc, nBitmap, pt, ILD_TRANSPARENT);
- // DrawDisabledButton(dc, rc);
- }
- }
- else if (bHasCursor && !m_bMouseLeave)
- {
- if (&imglistHot)
- {
- CRect rcItem = rc;
- DrawFace(RGB(255, 212, 139), RGB(255, 174, 86), rcItem, rcItem, &dc);
- DrawFrame(RGB(100, 100, 100), RGB(100, 100, 100), RGB(100, 100, 100), rcItem , &dc);
- imglistHot.Draw(&dc, nBitmap, pt, ILD_TRANSPARENT);
- }
- }
- else
- {
- if (&imglist)
- imglist.Draw(&dc, nBitmap, pt, ILD_TRANSPARENT);
- }
- CString strText = GetButtonText(i);
- if( strText.GetLength() )
- {
- CRect rectText(
- rc.left+3+bBtnDown,
- rc.top+m_sizeOffset.cy+m_sizeImage.cy+1+bBtnDown,
- rc.right-3+bBtnDown,
- rc.bottom-3+bBtnDown
- );
- dc.DrawText(strText, rectText, DT_CENTER|DT_VCENTER|DT_NOCLIP);
- }
- /*
- if( ! bBtnEnabled )
- // gray out that button
- DrawDisabledButton(dc, rc);
- //*/
- cdrw.NotifyItemPostPaint(i);
- }
- }
- dc.SelectObject(pOldFont);
- if( ! m_bDeleteImgList )
- {
- imglist.Detach();
- imglistHot.Detach();
- imglistDisable.Detach();
- }
- // last but not least: inform the parent for end of painting
- cdrw.NotifyPostPaint();
- if (m_bMouseLeave)
- TRACE("rb****on paint(%d, %d, %d)rn", cursor.x, cursor.y, bMouseLeavePaint);
- }
- else
- {
- // classic mode (or couldn't receive imagelist)
- CDkToolBar::OnPaint();
- }
- if (m_bMouseLeave)
- m_bMouseLeave = false;
- }
- void CToolBarEx :: DrawDisabledButton( CDC & dc, const CRect & rc ) const {
- // create a monochrome memory DC
- CDC ddc;
- ddc.CreateCompatibleDC(0);
- CBitmap bmp;
- bmp.CreateCompatibleBitmap(&ddc, rc.Width(), rc.Height());
- CBitmap * pOldBmp = ddc.SelectObject(&bmp);
- // build a mask
- ddc.PatBlt(0, 0, rc.Width(), rc.Height(), WHITENESS);
- dc.SetBkColor(m_clrBtnFace);
- ddc.BitBlt(0, 0, rc.Width(), rc.Height(), &dc, rc.left, rc.top, SRCCOPY);
- dc.SetBkColor(m_clrBtnHilight);
- ddc.BitBlt(0, 0, rc.Width(), rc.Height(), &dc, rc.left, rc.top, SRCPAINT);
- // Copy the image from the toolbar into the memory DC
- // and draw it (grayed) back into the toolbar.
- dc.FillSolidRect(rc.left, rc.top, rc.Width(), rc.Height(), m_clrBtnFace);
- dc.SetBkColor(RGB(0, 0, 0));
- dc.SetTextColor(RGB(255, 255, 255));
- CBrush brShadow, brHilight;
- brHilight.CreateSolidBrush(m_clrBtnHilight);
- brShadow.CreateSolidBrush(m_clrBtnShadow);
- CBrush * pOldBrush = dc.SelectObject(&brHilight);
- dc.BitBlt(rc.left+1, rc.top+1, rc.Width(), rc.Height(), &ddc, 0, 0, 0x00E20746L);
- dc.SelectObject(&brShadow);
- dc.BitBlt(rc.left, rc.top, rc.Width(), rc.Height(), &ddc, 0, 0, 0x00E20746L);
- // reset DCs
- dc.SelectObject(pOldBrush);
- ddc.SelectObject(pOldBmp);
- ddc.DeleteDC();
- bmp.DeleteObject();
- }
- void CToolBarEx :: DrawSeparator( CDC & dc, CRect & rc ) const
- {
- BOOL bHorz = ((m_dwStyle & CBRS_ORIENT_HORZ) != 0) ? TRUE : FALSE;
- // make sure, this separator is not a placeholder for
- // another control.
- if( rc.Width() <= 8 )
- {
- {
- /*
- CDC memdc;
- memdc.CreateCompatibleDC(&dc);
- CBitmap* pold = memdc.SelectObject((CBitmap*)&m_bmpBack);
- BOOL bRet = dc.BitBlt(rc.left, rc.top, rc.Width(), rc.Height(), &memdc, 0, 0, SRCCOPY);
- ASSERT(bRet);
- memdc.SelectObject(pold);
- //*/
- }
- if( bHorz )
- {
- // draw the separator bar in the middle
- int x = (rc.left + rc.right) / 2;
- rc.left = x-1; rc.right = x+1;
- dc.Draw3dRect(
- rc,
- m_clrBtnShadow,
- m_clrBtnHilight
- );
- }
- else
- {
- // draw the separator bar in the middle
- rc.left = rc.left - m_sizeButton.cx;
- rc.right = rc.left + m_sizeButton.cx;
- rc.top = rc.bottom+1;
- rc.bottom = rc.top+3;
- int y = (rc.top+rc.bottom)/2;
- rc.top = y-1; rc.bottom = y+1;
- dc.Draw3dRect(
- rc,
- m_clrBtnShadow,
- m_clrBtnHilight
- );
- }
- }
- }
- void CToolBarEx :: DrawGripper( CDC & dc ) const
- {
- if( m_dwStyle & CBRS_FLOATING )
- return; // no gripper if floating
- CRect gripper;
- GetWindowRect(gripper);
- ScreenToClient(gripper);
- gripper.OffsetRect(-gripper.left, -gripper.top);
- if( m_dwStyle & CBRS_ORIENT_HORZ ) {
- // gripper at left
- gripper.DeflateRect(4, 4);
- gripper.right = gripper.left+3;
- dc.Draw3dRect(
- gripper,
- m_clrBtnHilight,
- m_clrBtnShadow
- );
- gripper.OffsetRect(3, 0);
- dc.Draw3dRect(
- gripper,
- m_clrBtnHilight,
- m_clrBtnShadow
- );
- } else {
- // gripper at top
- gripper.DeflateRect(4, 4);
- gripper.bottom = gripper.top+3;
- dc.Draw3dRect(
- gripper,
- m_clrBtnHilight,
- m_clrBtnShadow
- );
- gripper.OffsetRect(0, 3);
- dc.Draw3dRect(
- gripper,
- m_clrBtnHilight,
- m_clrBtnShadow
- );
- }
- }
- void CToolBarEx :: OnUpdateCmdUI( CFrameWnd* pTarget, BOOL bDisableIfNoHndler ) {
- if( m_bFlatLook ) {
- // save current styles
- register const int nBtn = GetToolBarCtrl().GetButtonCount();
- register int nIdx;
- for( nIdx = 0; nIdx < nBtn; ++nIdx )
- m_Styles.SetAtGrow(nIdx, GetButtonStyle(nIdx));
- // do base class processing
- CDkToolBar::OnUpdateCmdUI(pTarget,bDisableIfNoHndler);
- //check wether styles have been changed
- for( nIdx = 0; nIdx < nBtn; ++nIdx ) {
- if( m_Styles[nIdx] != GetButtonStyle(nIdx) ) {
- // invalidate that button
- CRect rc;
- GetItemRect(nIdx, rc);
- InvalidateRect(rc);
- }
- }
- } else
- // simply delegate
- CDkToolBar::OnUpdateCmdUI(pTarget,bDisableIfNoHndler);
- }
- void CToolBarEx::OnSysColorChange()
- {
- CDkToolBar::OnSysColorChange();
- m_clrBtnFace = ::GetSysColor(COLOR_BTNFACE);
- m_clrBtnHilight = ::GetSysColor(COLOR_BTNHILIGHT);
- m_clrBtnShadow = ::GetSysColor(COLOR_BTNSHADOW);
- m_clrBtnLight = ::GetSysColor(COLOR_3DLIGHT);
- if( m_clrBtnFace == m_clrBtnLight )
- m_clrBtnLight = m_clrBtnHilight;
- }
- void CToolBarEx::OnNcCalcSize(BOOL bCalcValidRects, NCCALCSIZE_PARAMS FAR* lpncsp)
- {
- CDkToolBar::OnNcCalcSize(bCalcValidRects, lpncsp);
- return;
- // adjust non-client area for gripper at left or top
- if( m_dwStyle & CBRS_ORIENT_HORZ )
- {
- lpncsp->rgrc[0].left += 4;
- lpncsp->rgrc[0].right += 4;
- } else {
- lpncsp->rgrc[0].top += 6;
- lpncsp->rgrc[0].bottom += 6;
- }
- }
- void CToolBarEx::OnMouseMove(UINT nFlags, CPoint point)
- {
- if (!m_bTracking)
- {
- TRACKMOUSEEVENT tme;
- tme.cbSize = sizeof(tme);
- tme.hwndTrack = GetSafeHwnd();
- tme.dwFlags = TME_LEAVE;
- tme.dwHoverTime = HOVER_DEFAULT;
- m_bTracking = _TrackMouseEvent(&tme);
- }
- if( m_bFlatLook )
- {
- register const int nBtn = GetToolBarCtrl().GetButtonCount();
- const int nLastBtn = m_nLastBtn;
- m_nLastBtn = -1;
- for( register int i = 0 ; i < nBtn ; ++i )
- {
- CRect rc;
- GetItemRect(i, rc);
- const BOOL bBtnEnabled = GetToolBarCtrl().IsButtonEnabled(int(GetItemID(i)));
- const BOOL bSep = GetButtonStyle(i) & TBBS_SEPARATOR;
- if( bSep || ! bBtnEnabled )
- continue;
- const BOOL bHasCursor = rc.PtInRect(point);
- if( bHasCursor && bBtnEnabled )
- {
- if( nLastBtn != i )
- {
- // force a repaint of the button with the cursor on it
- InvalidateRect(rc, FALSE);
- }
- m_nLastBtn = i;
- }
- else if( !bHasCursor && i == nLastBtn )
- {
- // force a repaint of the last formed button
- InvalidateRect(rc, FALSE);
- }
- }
- // One problem occures with WM_MOUSEMOVE: we cannot detect
- // that the mouse leaves the window. If the mouse moves quick
- // enough, then the last formed button stays visible. To
- // resolve this problem, we set a timer and check, wether
- // the mouse is outside the window ...
- // KillTimer(m_uTimerEvent);
- // m_uTimerEvent = SetTimer(1, 250, 0);
- }
- CDkToolBar::OnMouseMove(nFlags, point);
- }
- LRESULT CToolBarEx::OnMouseLeave(WPARAM wParam, LPARAM lParam)
- {
- m_bTracking = false;
- if (m_nLastBtn >= 0)
- {
- m_bMouseLeave = true;
- CRect rc;
- GetItemRect(m_nLastBtn, rc);
- InvalidateRect(rc, TRUE);
- m_nLastBtn = -1;
- /*
- POINT pt;
- ::GetCursorPos(&pt);
- ScreenToClient(&pt);
- TRACE("rb****mouse leave(%d, %d)rn", pt.x, pt.y);
- //*/
- }
- else
- {
- /*
- CRect rc;
- GetClientRect(rc);
- // InvalidateRect(rc, TRUE);
- TRACE("rb****mouse leave(%d, %d)rn", 12, 12);
- //*/
- }
- return 0;
- }
- void CToolBarEx::OnNcPaint()
- {
- // DbgGuiLeak dbgGui;
- if( m_bFlatLook )
- {
- CDkToolBar::EraseNonClient();
- CWindowDC dc(this);
- // DrawGripper(dc);
- /*
- CRect rc;
- GetWindowRect(rc);
- ScreenToClient(rc);
- rc.OffsetRect(-rc.left, -rc.top);
- CDC memdc;
- memdc.CreateCompatibleDC(&dc);
- CBitmap bmptemp;
- bmptemp.CreateCompatibleBitmap(&memdc, rc.right - rc.left, rc.bottom - rc.top);
- CBitmap* pold = memdc.SelectObject(&bmptemp);
- CRect temprc = rc;
- temprc.OffsetRect(-temprc.left, -temprc.top);
- DrawFace(RGB(255, 255, 255), RGB(0, 0, 0), temprc, temprc, &memdc);
- memdc.FillRect(temprc, &CBrush(RGB(233, 233, 233)));
- BOOL bRet = dc.BitBlt(rc.left, rc.top, rc.Width(), rc.Height(), &memdc, 0, 0, SRCCOPY);
- ASSERT(bRet);
- memdc.SelectObject(pold);
- //*/
- /*
- CDC memdc;
- memdc.CreateCompatibleDC(&dc);
- CBitmap* pold = memdc.SelectObject(&m_bmpBack);
- BOOL bRet = dc.BitBlt(rc.left, rc.top, rc.Width(), rc.Height(), &memdc, 0, 0, SRCCOPY);
- ASSERT(bRet);
- memdc.SelectObject(pold);
- //*/
- }
- else
- CDkToolBar::OnNcPaint();
- }
- /*
- void CToolBarEx::OnTimer(UINT nIDEvent)
- {
- if( nIDEvent == m_uTimerEvent && m_nLastBtn >= 0 ) {
- POINT pt;
- ::GetCursorPos(&pt);
- CRect rc;
- GetWindowRect(rc);
- if( ! rc.PtInRect(pt) ) {
- GetItemRect(m_nLastBtn, rc);
- InvalidateRect(rc, FALSE);
- m_nLastBtn = -1;
- KillTimer(nIDEvent);
- }
- } else
- CDkToolBar::OnTimer(nIDEvent);
- }
- //*/
- int CToolBarEx::OnCreate(LPCREATESTRUCT lpCreateStruct)
- {
- if (CDkToolBar::OnCreate(lpCreateStruct) == -1)
- return -1;
- // Save the parent at creation time. It may change, if
- // the toolbar is floating; but we want to know of the
- // "real" parent (for notification messages)!
- m_hwndParent = lpCreateStruct->hwndParent;
- int iRet = m_bmpBack.LoadBitmap(IDB_BITMAP_REBAR_BK);
- ASSERT(iRet);
- // LoadBitmap(::AfxGetInstanceHandle(), MAKEINTRESOURCE(IDB_BITMAP_REBAR_BK));
- return 0;
- }
- #define PADWIDTH(x) (((x)*8+31)&~31)/8
- HIMAGELIST CToolBarEx :: GetImageList(UINT nImageType)
- {
- m_bDeleteImgList = FALSE;
- HIMAGELIST hImg = 0;
- #ifdef TB_GETIMAGELIST
- // Some older versions of VC++ do not know of
- // the TB_GETIMAGELIST macro (defined in commctrl.h).
- hImg = HIMAGELIST(SendMessage(nImageType));
- #ifdef _DEBUG
- if( hImg == 0 ) {
- TRACE0("CToolBarEx::OnPaint(): could not get image listn");
- }
- #endif
- #endif // TB_GETIMAGELIST
- if( ! hImg )
- {
- // comctl32.dll version prior to 4.70 doesn't know
- // anything of the TB_GETIMAGELIST message
- if( m_hbmImageWell != 0 )
- {
- // Yup - we have a valid image.
- // But beware: Do not use this bitmap directly.
- // We make the copy by ourself. CopyImage() (for
- // instace) produces inacceptable copies under
- // some circumstances ...
- CImageList imglist;
- CBitmap bmp;
- // retrieve the size of the bitmap
- BITMAP bmHdr;
- ::GetObject(m_hbmImageWell, sizeof(BITMAP), &bmHdr);
- DWORD dwWidth, dwHeight = bmHdr.bmHeight;
- if (bmHdr.bmBitsPixel > 8)
- dwWidth = PADWIDTH(bmHdr.bmWidth * 3);
- else
- dwWidth = PADWIDTH(bmHdr.bmWidth);
- // copy the bitmap
- CClientDC cdc(this);
- CDC dc1, dc2;
- dc1.CreateCompatibleDC(&cdc);
- dc2.CreateCompatibleDC(&cdc);
- bmp.CreateCompatibleBitmap(&cdc, dwWidth, dwHeight);
- CBitmap * pOBmp = dc1.SelectObject(&bmp);
- HGDIOBJ hOObj = ::SelectObject(dc2.GetSafeHdc(), m_hbmImageWell);
- dc1.BitBlt(0,0,dwWidth,dwHeight,&dc2,0,0,SRCCOPY);
- ::SelectObject(dc2.GetSafeHdc(), hOObj);
- dc1.SelectObject(pOBmp);
- dc1.DeleteDC();
- dc2.DeleteDC();
- imglist.Create(m_sizeImage.cx, m_sizeImage.cy,TRUE,dwWidth/m_sizeImage.cx,1);
- imglist.SetBkColor(m_clrBtnFace);
- imglist.Add(&bmp,m_clrBtnFace);
- hImg = imglist.Detach();
- bmp.DeleteObject();
- m_bDeleteImgList = TRUE;
- }
- }
- return hImg;
- }
- void CToolBarEx::DrawFace(COLORREF Top, COLORREF Bottom, CRect& rc, CRect CalRc, CDC* pDC)
- {
- if (!CalRc.Height())
- return;
- int R, G, B;
- R = (GetRValue(Top) - GetRValue(Bottom)) / CalRc.Height();
- G = (GetGValue(Top) - GetGValue(Bottom)) / CalRc.Height();
- B = (GetBValue(Top) - GetBValue(Bottom)) / CalRc.Height();
- int ColR = GetRValue(Top), ColG = GetGValue(Top), ColB = GetBValue(Top);
- COLORREF ColMax = Top > Bottom ? Top : Bottom;
- COLORREF ColMin = Top > Bottom ? Bottom: Top;
- for(int i=0; i<rc.Height(); i++)
- {
- ColR -= R;
- ColG -= G;
- ColB -= B;
- CPen Pen;
- Pen.CreatePen(PS_SOLID, 1, RGB(ColR, ColG, ColB));
- CPen* pOldPen = pDC->SelectObject(&Pen);
- // pDC->SelectObject(&Pen);
- pDC->MoveTo(rc.left, rc.top+i);
- pDC->LineTo(rc.right, rc.top+i);
- pDC->SelectObject(pOldPen);
- Pen.DeleteObject();
- }
- }
- void CToolBarEx::DrawFrame(COLORREF HeightLight, COLORREF ShadowLight, COLORREF FrameColor, CRect& rc, CDC* pDC)
- {
- CBrush NullBrush;
- NullBrush.CreateStockObject(NULL_BRUSH);
- CBrush* pOldBrush = pDC->SelectObject(&NullBrush);
- CPen Pen;
- Pen.CreatePen(PS_SOLID, 1, FrameColor);
- CPen* pOldPen = pDC->SelectObject(&Pen);
- pDC->RoundRect(rc, CPoint(3, 3));
- // rc.DeflateRect(1, 1, 1, 1);
- // pDC->Draw3dRect(rc, HeightLight, ShadowLight);
- pDC->SelectObject(pOldPen);
- pDC->SelectObject(pOldBrush);
- }
- BOOL CToolBarEx::OnEraseBkgnd(CDC* pDC)
- {
- // DbgGuiLeak dbgGui;
- CRect rc;
- pDC->GetClipBox(rc);
- if (rc.right < 0 || rc.bottom < 0)
- {
- ASSERT(FALSE);
- return FALSE;
- }
- CDC memdc, memdcbmp;
- BOOL bRet = memdc.CreateCompatibleDC(pDC);
- if (!bRet)
- {
- DWORD dwErr = GetLastError();
- ASSERT(false);
- return FALSE;
- }
- CBitmap bmptemp;
- bRet = bmptemp.CreateCompatibleBitmap(pDC, rc.right, rc.bottom);
- if (!bRet)
- {
- DWORD dwErr = GetLastError();
- ASSERT(false);
- return FALSE;
- }
- CBitmap* pold = memdc.SelectObject(&bmptemp);
- bRet = memdcbmp.CreateCompatibleDC(&memdc);
- if (!bRet)
- {
- DWORD dwErr = GetLastError();
- ASSERT(false);
- return FALSE;
- }
- CBitmap* pOldBmp = memdcbmp.SelectObject(&m_bmpBack);
- // CRect rctemp = rc;
- // rctemp.left = rctemp.top = 0;
- // DrawFace(RGB(243, 243, 241), RGB(217, 214, 217), rctemp, rctemp, &memdc);
- // memdc.FillRect(temprc, &CBrush(RGB(255, 0, 0)));
- for (int i=0; i<(rc.Width()/50 + 1); i++)
- {
- memdc.BitBlt(rc.left + i*50, rc.top, 100, rc.Height(), &memdcbmp, 0, rc.top, SRCCOPY);
- }
- memdcbmp.SelectObject(pOldBmp);
- bRet = memdcbmp.DeleteDC();
- ASSERT(bRet);
- bRet = pDC->BitBlt(rc.left, rc.top, rc.Width(), rc.Height(), &memdc, rc.left, rc.top, SRCCOPY);
- ASSERT(bRet);
- bRet = bmptemp.DeleteObject();
- ASSERT(bRet);
- memdc.SelectObject(pold);
- bRet = memdc.DeleteDC();
- ASSERT(bRet);
- #ifdef _DEBUG
- CString strText;
- strText.Format("rnerase rect = %d, %d, %d, %d rn", rc.left, rc.top, rc.right, rc.bottom);
- TRACE(strText);
- #endif
- return TRUE;
- return CDkToolBar::OnEraseBkgnd(pDC);
- }