⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 toolbarex.cpp

📁 用Visual C++编写的查看磁盘信息的工具
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/////////////////////////////////////////////////////////////////////////////
// Copyright (C) 1997,'98 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)
/////////////////////////////////////////////////////////////////////////////

// last revised: $Date: 01-04-30 22:47 $ $Revision: 1 $

// 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 :-)
//	if you want to reduce flickering, then you have to include
//	the header of Keith Rule's CMemDC class in your <stdafx.h>.
//	CToolBarEx will use it automagically then.
//	If you want a "real cool" 3D look, then you have to exchange the call
//	to "EnableDocking()" in your CMainFrame::OnCreate() method to
//	"FrameEnableDocking()". This will ensure, that the toolbar has the
//	same outfit as in Office or DevStudio.
//
// 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
//	o	Matthias Drigalla <matthias.drigalla@bluewin.ch> has pointed
//		me out, that the timer is not released in all circumstances.
//	o	thanks to Jonathan Chin <jonathan.chin@scitec.com.au> for his
//		experiences with UNICODE and for his enhancement to conform to
//		the standard interface (the flat toolbar should not perform any
//		hit test (and hence displaying the raised button state) if the
//		parent window (application) does not have the focus or is disabled.)
//	o	thanks to Wang Ruopeng (ripple@thinker.ep.tsinghua.edu.cn) for
//		the enhanced outfit of checked buttons
//
//	o	Many thanks to Victor Vogelpoel, Jonathan Chin and Patrick Liechty
//		for their help to test and correct some bugs in the enhanced version.
//		Their work made this class much cleaner. Thanks.
//
//	o	Wolfgang Loch (W.Loch@intershop.de) sent in a fix for undockable bars
//	o	Thanks to John Armstrong (jarmstrong@runge.com.au) for his fix to
//		the adjustment of gripperspace in "classic" mode
//	o	Thanks to Anatoly Ivasyuk (aivasyuk@clark.net) for a much cooler method
//		to draw checked buttons that does not have the cursor on it.
//
//
// (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.
//
//	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:
//	05/10/98
//	o	buttons that are checked *and* disabled are now looking ok.
//	o	don't draw a gripper if the bar is not dockable
//	o	do not adjust space for gripper in "classic" mode
//
//	01/17/98
//	o	If you have Keith Rule's "MemDC.h" included via
//		"stdafx.h", then CToolBarEx uses it to reduce
//		flickering.
//	o	release the timer in all circumstances
//	o	made the class compile even if UNICODE is #define'ed
//	o	do not make any hit test (and display a raised button state)
//		if the application does not have the focus.
//	o	Changed the outfit of a checked button that does not have
//		the cursor on it.
//	Major enhancements:
//	o	added easy way to add controls to a toolbar
//		(both: replacing a button with a control and
//		inserting/appending new controls)
//	o	Added many functions especially for the often
//		requested need for additional controls
//	o	ALT-Drag feature implemented. You just can move buttons
//		(and controls!) from one CToolBarEx-object to another
//		in the style of the Developer Studio. There is no additional
//		requirement for having this feature in your application.
//		Just follow the online-help for how to enable customizable
//		toolbars. CToolBarEx uses the same technique.
//
//	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"

#ifndef __AFXPRIV_H__
	#include <afxpriv.h>	// one of the most interesting headers ;-)
							// if you plan to change CToolBarEx, then you
							// should better insert it in your "stdafx.h"
							// to speed up compilation
#endif


#ifdef _MEMDC_H_
	//#undef _MEMDC_H_		// this is for testing purposes
#endif



#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, whether 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  --  class static data

HCURSOR			CToolBarEx :: m_hOrigCursor		= 0;
HCURSOR			CToolBarEx :: m_hDragCursor		= 0;
HCURSOR			CToolBarEx :: m_hNoDragCursor	= 0;
BOOL			CToolBarEx :: m_bDragging		= FALSE;
BOOL			CToolBarEx :: m_bDragCursor		= FALSE;
int				CToolBarEx :: m_nDragButton		= -1;
CToolBarEx *	CToolBarEx :: m_pDropBar		= 0;
CPoint			CToolBarEx :: m_ptDrop(0,0);

/////////////////////////////////////////////////////////////////////////////
// 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)
	, m_pControls(0)
	, m_bReal3DBorder(FALSE)	// set to TRUE, if you're using FrameEnableDocking()
	, m_bDragChild(FALSE)
{
	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;
		_tcscpy(logfont.lfFaceName,_T("MS Sans Serif"));

	}
	logfont.lfHeight = 6 ;
	logfont.lfWidth = 0 ;	// let windows compute this.
	VERIFY( m_GuiFont.CreateFontIndirect( &logfont ) ) ;
}

CToolBarEx::~CToolBarEx()
{
	if( m_pControls ) {
		for( POSITION pos = m_pControls->GetHeadPosition() ; pos ; )
			delete m_pControls->GetNext(pos);
		delete m_pControls;
	}
}


IMPLEMENT_DYNAMIC(CToolBarEx, CToolBar)


BEGIN_MESSAGE_MAP(CToolBarEx, CToolBar)
	//{{AFX_MSG_MAP(CToolBarEx)
	ON_WM_PAINT()
	ON_WM_SYSCOLORCHANGE()
	ON_WM_NCCALCSIZE()
	ON_WM_MOUSEMOVE()
	ON_WM_NCPAINT()
	ON_WM_TIMER()
	ON_WM_CREATE()
	ON_WM_LBUTTONDOWN()
	ON_WM_LBUTTONUP()
	ON_WM_WINDOWPOSCHANGING()
	ON_WM_CAPTURECHANGED()
	ON_WM_PARENTNOTIFY()
	ON_WM_KILLFOCUS()
	//}}AFX_MSG_MAP
	ON_MESSAGE(TB_SETBUTTONSIZE, OnSetButtonSize)
	ON_MESSAGE(TB_SETBITMAPSIZE, OnSetBitmapSize)
	ON_MESSAGE(TB_ADDBITMAP, OnAddBitmap)
	ON_MESSAGE(TB_DELETEBUTTON, OnDeleteButton)
#ifdef _MEMDC_H_
	ON_WM_ERASEBKGND()
#endif
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CToolBarEx message handlers

LRESULT CToolBarEx :: OnSetButtonSize(WPARAM wParam, LPARAM lParam) {
	LRESULT lResult = CToolBar::OnSetButtonSize(wParam, lParam);
	if( lResult )
		CalculateOffset();
	return lResult;
}

LRESULT CToolBarEx :: OnSetBitmapSize(WPARAM wParam, LPARAM lParam) {
	LRESULT lResult = CToolBar::OnSetBitmapSize(wParam, lParam);
	if( lResult )
		CalculateOffset();
	return lResult;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -