📄 toolbarex.cpp
字号:
// 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 + -