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

📄 toolbarex.cpp

📁 The ITU-T(Telecommunication Standardization Sector)is a permanent organ of the International Telecom
💻 CPP
📖 第 1 页 / 共 4 页
字号:
// ToolBarEx.cpp : implementation file
//

#include "stdafx.h"
#include "ToolBarEx.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CToolBarEx

IMPLEMENT_DYNCREATE( CToolBarEx,CToolBar);

//Image sizes
const CSize CToolBarEx::m_szImageSmall( 16, 15 );
const CSize CToolBarEx::m_szImageLarge( 24, 24 );

const TextOptions CToolBarEx:: m_eInitialTextOptions =  toNoTextLabels;
const IconOptions CToolBarEx:: m_eInitialIconOptions =  ioSmallIcons;
								  


int CToolBarEx::m_nBarNumber = 0;
CCustomizeDialog*   CToolBarEx::m_pCustomizeDlg = NULL;
HHOOK               CToolBarEx::m_hCBTHook      = NULL;


#define STR_CUSTOMIZE  _T("&Customize...")


// for determining version of COMCTL32.DLL
#define VERSION_WIN4        MAKELONG(0, 4)
#define VERSION_IE3         MAKELONG(70, 4)
#define VERSION_IE4         MAKELONG(71, 4)
#define VERSION_IE401       MAKELONG(72, 4)
#define VERSION_IE5			MAKELONG(80, 5)
#define VERSION_IE5_2000    MAKELONG(81, 5)

struct AFX_DLLVERSIONINFO
{
	DWORD cbSize;
	DWORD dwMajorVersion;                   // Major version
	DWORD dwMinorVersion;                   // Minor version
	DWORD dwBuildNumber;                    // Build number
	DWORD dwPlatformID;                     // DLLVER_PLATFORM_*
};

typedef HRESULT (CALLBACK* AFX_DLLGETVERSIONPROC)(AFX_DLLVERSIONINFO *);

static int _ComCtlVersion = -1;

static DWORD AFXAPI _GetComCtlVersion()
{
	// return cached version if already determined...
	if (_ComCtlVersion != -1)
		return _ComCtlVersion;
	
	// otherwise determine comctl32.dll version via DllGetVersion
	HINSTANCE hInst = ::GetModuleHandleA("COMCTL32.DLL");
	ASSERT(hInst != NULL);
	AFX_DLLGETVERSIONPROC pfn;
	pfn = (AFX_DLLGETVERSIONPROC)GetProcAddress(hInst, "DllGetVersion");
	DWORD dwVersion = VERSION_WIN4;
	if (pfn != NULL)
	{
		AFX_DLLVERSIONINFO dvi;
		memset(&dvi, 0, sizeof(dvi));
		dvi.cbSize = sizeof(dvi);
		HRESULT hr = (*pfn)(&dvi);
		if (SUCCEEDED(hr))
		{
			ASSERT(dvi.dwMajorVersion <= 0xFFFF);
			ASSERT(dvi.dwMinorVersion <= 0xFFFF);
			dwVersion = MAKELONG(dvi.dwMinorVersion, dvi.dwMajorVersion);
		}
		
		TRACE(_T("Using CommCtl32.dll Ver:%d.%d.%d\n"),dvi.dwMajorVersion,dvi.dwMinorVersion,dvi.dwBuildNumber);

	}
	_ComCtlVersion = dwVersion;
	return dwVersion;
}


CToolBarEx::CToolBarEx()
{
	m_pControls		 = NULL;
	m_pDropButtons	 = NULL;		// list of drop-down buttons
//	m_bShowDropdownArrowWhenVertical = FALSE;
	m_bHideChildWndOnVertical=TRUE;

	m_clrBtnHilight=::GetSysColor(COLOR_BTNHILIGHT);
	m_clrBtnShadow=::GetSysColor(COLOR_BTNSHADOW);
	m_clrBtnFace  = ::GetSysColor(COLOR_BTNFACE);

	++m_nBarNumber; //Increase the Bar number

	CWinApp  *pApp = AfxGetApp();
	ASSERT_VALID(pApp);
	m_strValueName.Format( _T("ToolBarEx%d"), m_nBarNumber );
	m_strSubKey.Format( _T("Software\\%s\\%s\\Settings"),
		pApp->m_pszRegistryKey, pApp->m_pszProfileName );

    m_eTextOptions = toNone;    // no options selected yet
    m_eIconOptions = ioNone;    // no options selected yet

	m_nResButtons=0;

}

CToolBarEx::~CToolBarEx()
{
	while (m_pDropButtons)
	{
		CDropDownButtonInfo* pnext = m_pDropButtons->pNext;
		delete m_pDropButtons;
		m_pDropButtons = pnext;
	}

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

		delete m_pControls;
	}

}


BEGIN_MESSAGE_MAP(CToolBarEx, CToolBar)
	//{{AFX_MSG_MAP(CToolBarEx)
	ON_WM_CREATE()
	ON_WM_PAINT()
	ON_WM_SYSCOLORCHANGE()
	ON_WM_CONTEXTMENU()
	ON_WM_NCPAINT()
	//}}AFX_MSG_MAP
	ON_NOTIFY_REFLECT_EX(TBN_DROPDOWN,	 OnToolBarBtnDropDown)
	ON_NOTIFY_REFLECT(TBN_BEGINADJUST,	 OnToolBarBeginAdjust)
	ON_NOTIFY_REFLECT(TBN_CUSTHELP,		 OnToolBarCustomHelp)
	ON_NOTIFY_REFLECT(TBN_ENDADJUST,	 OnToolBarEndAdjust)
	ON_NOTIFY_REFLECT(TBN_GETBUTTONINFO, OnToolBarGetButtonInfo)
	ON_NOTIFY_REFLECT(TBN_QUERYDELETE,	 OnToolBarQueryDelete)
	ON_NOTIFY_REFLECT(TBN_QUERYINSERT,	 OnToolBarQueryInsert)
	ON_NOTIFY_REFLECT(TBN_RESET,		 OnToolBarReset)
	ON_NOTIFY_REFLECT(TBN_TOOLBARCHANGE, OnToolBarChange)
	ON_MESSAGE(TB_CUSTOMIZE, OnCustomize)
    ON_NOTIFY_REFLECT( TBN_INITCUSTOMIZE, OnInitCustomize )

    // Saving and restoring toolbar
    ON_NOTIFY_REFLECT( TBN_SAVE, OnSave )
    ON_NOTIFY_REFLECT( TBN_RESTORE, OnRestore )
END_MESSAGE_MAP()


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

//////////////////////////////////////////////////////////////////////
// 1999 Kirk Stowell - Inserts a control into the toolbar at the given button id.
//
CWnd* CToolBarEx::InsertControl( CRuntimeClass* pClass, LPCTSTR lpszWindowName, CRect& rect, UINT nID, DWORD dwStyle )
{
	CWnd *pCtrl = NULL;
	
	if( pClass->IsDerivedFrom( RUNTIME_CLASS( CComboBox )))	// CComboBox control.
	{
		pCtrl = new CComboBox;

		ASSERT_VALID( pCtrl );

		if(((CComboBox*)pCtrl)->Create( WS_CHILD|WS_VISIBLE|dwStyle, rect, this, nID ) == FALSE )
		{
			delete pCtrl;
			return NULL;
		}
	}
	//////////// xu add//////////////////////////
	else if( pClass->IsDerivedFrom( RUNTIME_CLASS( CProgressCtrl )))		// CProgressCtrl control.
	{
		pCtrl = new CProgressCtrl;
							
		ASSERT_VALID( pCtrl );

		if(((CProgressCtrl*)pCtrl)->Create( WS_CHILD|WS_VISIBLE|dwStyle, rect, this, nID ) == FALSE )
		{
			delete pCtrl;
			return NULL;
		}
	}
	else if( pClass->IsDerivedFrom( RUNTIME_CLASS( CStatic )))		// CStatic control.
	{
		pCtrl = new CProgressCtrl;
							
		ASSERT_VALID( pCtrl );

		if(((CProgressCtrl*)pCtrl)->Create( WS_CHILD|WS_VISIBLE|dwStyle, rect, this, nID ) == FALSE )
		{
			delete pCtrl;
			return NULL;
		}
	}
	//////////// xu add//////////////////////////
	else if( pClass->IsDerivedFrom( RUNTIME_CLASS( CEdit )))		// CEdit control.
	{
		pCtrl = new CEdit;
							
		ASSERT_VALID( pCtrl );

		if(((CEdit*)pCtrl)->Create( WS_CHILD|WS_VISIBLE|dwStyle, rect, this, nID ) == FALSE )
		{
			delete pCtrl;
			return NULL;
		}
	}
	else if( pClass->IsDerivedFrom( RUNTIME_CLASS( CButton )))		// CButton control.
	{
		pCtrl = new CButton;

		ASSERT_VALID( pCtrl );

		if(((CButton*)pCtrl)->Create( lpszWindowName, WS_CHILD|WS_VISIBLE|dwStyle, rect, this, nID ) == FALSE )
		{
			delete pCtrl;
			return NULL;
		}
	}
	else if( pClass->IsDerivedFrom( RUNTIME_CLASS( CWnd )))			// CWnd object.
	{
		pCtrl = new CWnd;
		
		ASSERT_VALID( pCtrl );

#ifdef _UNICODE
		TCHAR szClassName[ 256 ];

		MultiByteToWideChar( CP_ACP,
							 MB_PRECOMPOSED,
							 pClass->m_lpszClassName,
							 -1,
							 szClassName,
							 255 );

		if(((CWnd*)pCtrl)->Create( szClassName, lpszWindowName, WS_CHILD|WS_VISIBLE|dwStyle, rect, this, nID ) == FALSE )
		{
			delete pCtrl;
			return NULL;
		}
#else
		if(((CWnd*)pCtrl)->Create( pClass->m_lpszClassName, lpszWindowName, WS_CHILD|WS_VISIBLE|dwStyle, rect, this, nID ) == FALSE )
		{
			delete pCtrl;
			return NULL;
		}
#endif
	}
	else	// An invalid object was passed in
	{
		ASSERT( FALSE );
		return NULL;
	}

	// if our object list has not been allocated, do it now...
	if( m_pControls == NULL )
	{
		m_pControls = new CObList();
		ASSERT( m_pControls );
	}

	// we have to remember this control, so we can delete it later
	m_pControls->AddTail( pCtrl );

	return InsertControl( pCtrl, rect, nID );
}

CWnd* CToolBarEx::InsertControl(CWnd* pCtrl, CRect & rect, UINT nID)
{
	ASSERT_VALID( pCtrl );
	ASSERT(IsWindow(pCtrl->m_hWnd));

	// make sure the id is valid, and set the button 
	// style for a seperator.
	int nIndex = CommandToIndex( nID ) ;
	if (nIndex>-1)
	{
		ASSERT( nIndex >= 0 );
		SetButtonInfo( nIndex, nID, TBBS_SEPARATOR, rect.Width());
		// insert the control into the toolbar.
		GetItemRect( nIndex, &rect );
		CRect rt;
		pCtrl->GetWindowRect(&rt);
		rect.top+=max((rect.Height()-rt.Height())/2,0);	 //move to middle
		pCtrl->SetWindowPos(0, rect.left, rect.top, 0, 0,
			SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOCOPYBITS );
		pCtrl->SetFont( GetFont( ));

		BOOL bVert =  IsVertDocked(); //(m_dwStyle & CBRS_ORIENT_VERT) != 0;

		if (bVert && m_bHideChildWndOnVertical)
		{
		   	int nState=GetToolBarCtrl().GetState(nIndex);
		   	GetToolBarCtrl().SetState(nID,(nState | TBSTATE_HIDDEN));
			pCtrl->ShowWindow( SW_HIDE );
		}
		else
		{
		   	int nState=GetToolBarCtrl().GetState(nIndex);
		   	GetToolBarCtrl().SetState(nIndex,(nState & ~TBSTATE_HIDDEN));
			pCtrl->ShowWindow( SW_SHOW );
		}

	}
	else
	{
		pCtrl->ShowWindow( SW_HIDE);
	}

	ModifyStyle(0,WS_CLIPCHILDREN);
	return pCtrl;
}

BOOL CToolBarEx::AddDropDownButton(UINT nIDButton, UINT nIDMenu,BOOL bArrow)
{
	ASSERT_VALID(this);
	
	CDropDownButtonInfo* pb = FindDropDownButtonInfo(nIDButton);

	if (!pb) 
	{
		pb = new CDropDownButtonInfo;
		ASSERT(pb);
		pb->pNext = m_pDropButtons;
		m_pDropButtons = pb;
	}

	pb->idButton = nIDButton;
	pb->idMenu   = nIDMenu;
	
   return SetDropDownButton(nIDButton,bArrow);
}

CToolBarEx::CDropDownButtonInfo* CToolBarEx::FindDropDownButtonInfo(UINT nID)
{
	for (CDropDownButtonInfo* pb = m_pDropButtons; pb; pb = pb->pNext) 
	{
		if (pb->idButton == nID)
			return pb;
	}
	return NULL;
}

BOOL CToolBarEx::OnToolBarBtnDropDown(NMHDR* pNMHDR, LRESULT* pRes)
{
	UNUSED_ALWAYS( pRes );
	
	const NMTOOLBAR& nmtb = *(NMTOOLBAR*)pNMHDR;
														  
	// get location of button
	CRect rc;
	GetToolBarCtrl().GetRect(nmtb.iItem, rc);
	ClientToScreen(&rc);
	
	// call virtual function to display dropdown menu
	return OnDropDownButtonInfo(nmtb, nmtb.iItem, rc);
}

BOOL CToolBarEx::OnDropDownButtonInfo(const NMTOOLBAR& nmtb, UINT nID, CRect rc)
{
	UNUSED_ALWAYS( nID );

	CDropDownButtonInfo* pb = FindDropDownButtonInfo(nmtb.iItem);
	if (pb && pb->idMenu) 
	{
		
		// load and display popup menu
		CMenu menu;
		VERIFY(menu.LoadMenu(pb->idMenu));
		CMenu* pPopup = (CMenu*)menu.GetSubMenu(0);
		ASSERT(pPopup);
		pPopup->TrackPopupMenu(TPM_LEFTALIGN|TPM_LEFTBUTTON|TPM_VERTICAL,
			rc.left, rc.bottom, AfxGetMainWnd(), &rc);
		return TRUE;
	}

	return FALSE;
}


// This function saves the state (visible buttons, toolbar position, etc.)
// of the toolbar, using the registry key provided to the Create(...) function.
void CToolBarEx::SaveState()
{
	// if there is an associated registry subkey
	if (m_strSubKey.GetLength())
	{
		// save the toolbar state to the registry
		GetToolBarCtrl().SaveState( HKEY_CURRENT_USER, m_strSubKey, m_strValueName );
	}
}

// This function restores the state (visible buttons, toolbar position, etc.)
// of the toolbar, using the registry key provided to the Create(...) function.
void CToolBarEx::RestoreState()
{
	IconOptions eIconOptions=GetIconOptions();
	TextOptions eTextOptions=GetTextOptions();

	// if there is an associated registry subkey
	if (m_strSubKey.GetLength())
	{
		// restore the toolbar state from the registry
		GetToolBarCtrl().RestoreState( HKEY_CURRENT_USER, m_strSubKey, m_strValueName );
	}

	//Set Icon/Text options if changed
	if (eTextOptions!=GetTextOptions()) SetTextOptions(GetTextOptions(),TRUE);
	if (eIconOptions!=GetIconOptions()) SetIconOptions(GetIconOptions(),TRUE);

}

// This function is called when the user begins dragging a toolbar
// button or when the customization dialog is being populated with
// toolbar information.  Basically, *pResult should be populated with
// your answer to the question, "is the user allowed to delete this
// button?".
void CToolBarEx::OnToolBarQueryDelete(NMHDR *pNMHDR, LRESULT *pResult)
{
	UNUSED_ALWAYS( pNMHDR );

	NMTOOLBAR * tbStruct=(TBNOTIFY *)pNMHDR;


	ASSERT(tbStruct);
	// do not allow hidden button to be deleted as they just do not go
	// to the Add listbox.
	if ((tbStruct->tbButton.idCommand) && 
		GetToolBarCtrl().IsButtonHidden(tbStruct->tbButton.idCommand))
			*pResult = FALSE;
	else					 
			*pResult = TRUE;  

}

// This function is called when the user begins dragging a toolbar
// button or when the customization dialog is being populated with
// toolbar information.  Basically, *pResult should be populated with
// your answer to the question, "is the user allowed to insert a
// button to the left of this one?".
void CToolBarEx::OnToolBarQueryInsert(NMHDR *pNMHDR, LRESULT *pResult)
{
	UNUSED_ALWAYS( pNMHDR );
	*pResult = TRUE;


}

// This function is called whenever the user makes a change to the
// layout of the toolbar.  Calling the mainframe's RecalcLayout forces
// the toolbar to repaint itself.
void CToolBarEx::OnToolBarChange(NMHDR *pNMHDR, LRESULT *pResult)
{
	UNUSED_ALWAYS( pNMHDR );
	UNUSED_ALWAYS( pResult );


	SetTextOptions(m_eTextOptions,FALSE);
	PositionControls();

	// force the frame window to recalculate the size
	GetParentFrame()->RecalcLayout();
	OnIdleUpdateCmdUI(TRUE, 0L);

}


// This function is called when the user initially calls up the toolbar
// customization dialog box.
void CToolBarEx::OnToolBarBeginAdjust(NMHDR *pNMHDR, LRESULT *pResult)
{
	UNUSED_ALWAYS( pNMHDR );
	UNUSED_ALWAYS( pResult );


    *pResult = 0;

}

LRESULT CToolBarEx::OnCustomize(WPARAM,LPARAM)
{
	LONG lResult;

	ASSERT(m_pCustomizeDlg==NULL);
    m_pCustomizeDlg = new CCustomizeDialog( this, m_eTextOptions, m_eIconOptions );
    m_hCBTHook = ::SetWindowsHookEx( WH_CBT, CBTProc, 0, ::GetCurrentThreadId() );
    ASSERT( m_hCBTHook != 0 );
	 
    lResult = Default();

    VERIFY( ::UnhookWindowsHookEx( m_hCBTHook ) );
    m_hCBTHook = 0;

#ifndef CUSTOM_DRAW
	 // if custom draw is not done then update Icon Draw at end
	 if (GetIconOptions()!=m_pCustomizeDlg->GetIconOptions())
		SetIconOptions(m_pCustomizeDlg->GetIconOptions(),TRUE);
#endif // CUSTOM_DRAW

    delete m_pCustomizeDlg;
    m_pCustomizeDlg = NULL;

	SaveState();
	ASSERT(m_pCustomizeDlg==NULL);

	return 	lResult;

}

// This function is called when the user clicks on the help button on the
// toolbar customization dialog box.
void CToolBarEx::OnToolBarCustomHelp(NMHDR *pNMHDR, LRESULT *pResult)
{
	UNUSED_ALWAYS( pNMHDR );
	UNUSED_ALWAYS( pResult );

	TRACE(_T("Help on Customize Toolbar called.\n"));
}

// This function is called when the user dismisses the toolbar customization
// dialog box.
void CToolBarEx::OnToolBarEndAdjust(NMHDR *pNMHDR, LRESULT *pResult)
{
	UNUSED_ALWAYS( pNMHDR );
	UNUSED_ALWAYS( pResult );

}

// This function is called to populate the toolbar customization dialog box
// with information regarding all of the possible toolbar buttons.
void CToolBarEx::OnToolBarGetButtonInfo(NMHDR *pNMHDR, LRESULT *pResult)
{
	UNUSED_ALWAYS( pResult );

	TBNOTIFY* tbStruct;		// data needed by customize dialog box

	// init the pointer
	tbStruct = (TBNOTIFY *)pNMHDR;

	// if the index is valid

⌨️ 快捷键说明

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