1 #pragma once 2 3 template <typename T> 4 class ATL_NO_VTABLE CToolBarHelper 5 { 6 HFONT m_nonClientFont; 7 8 CSimpleMap<UINT, UINT> m_mapMenu; 9 10 public: 11 CToolBarHelper() : m_nonClientFont( NULL ) {} 12 13 ~CToolBarHelper() 14 { 15 if ( m_nonClientFont ) 16 { 17 ::DeleteObject( m_nonClientFont ); 18 } 19 } 20 21 BEGIN_MSG_MAP( CToolBarHelper<T> ) 22 COMMAND_CODE_HANDLER( CBN_SELCHANGE, OnSelChangeToolBarCombo ) 23 NOTIFY_CODE_HANDLER( TBN_DROPDOWN, OnToolBarDropDown ) 24 END_MSG_MAP() 25 26 BOOL ModifyToolBarStyle( HWND hWndToolBar ) 27 { 28 CToolBarCtrl tbCtrl; 29 30 tbCtrl = hWndToolBar; 31 ATLASSERT( tbCtrl ); 32 33 return tbCtrl.ModifyStyle( 0, TBSTYLE_LIST ); 34 } 35 36 void AddToolBarDropDownMenu( HWND hWndToolBar, UINT nButtonID, UINT nMenuID ) 37 { 38 DWORD tbStyleEx; 39 TBBUTTONINFO tbBtnInfo; 40 CToolBarCtrl tbCtrl; 41 42 tbCtrl = hWndToolBar; 43 ATLASSERT( tbCtrl ); 44 45 tbStyleEx = tbCtrl.GetExtendedStyle() | TBSTYLE_EX_DRAWDDARROWS; 46 tbCtrl.SetExtendedStyle( tbStyleEx ); 47 48 memset( &tbBtnInfo, 0, sizeof( TBBUTTONINFO ) ); 49 tbBtnInfo.cbSize = sizeof( TBBUTTONINFO ); 50 tbBtnInfo.dwMask = TBIF_STYLE; 51 52 if ( tbCtrl.GetButtonInfo( nButtonID, &tbBtnInfo ) != -1 ) 53 { 54 tbBtnInfo.fsStyle |= TBSTYLE_DROPDOWN; 55 tbCtrl.SetButtonInfo( nButtonID, &tbBtnInfo ); 56 m_mapMenu.Add( nButtonID, nMenuID ); 57 } 58 } 59 60 LRESULT OnToolBarDropDown( int /*idCtrl*/, LPNMHDR pnmh, BOOL& /*bHandled*/ ) 61 { 62 UINT nMenuID; 63 RECT rect; 64 POINT pt; 65 HMENU hMenu, hPopup; 66 CToolBarCtrl tbCtrl; 67 T* pT; 68 69 nMenuID = m_mapMenu.Lookup( ( ( LPNMTOOLBARW )pnmh )->iItem ); 70 71 if ( nMenuID ) 72 { 73 tbCtrl = pnmh->hwndFrom; 74 tbCtrl.GetItemRect( tbCtrl.CommandToIndex( ( ( LPNMTOOLBARW )pnmh )->iItem ), &rect ); 75 pt.x = rect.left; 76 pt.y = rect.bottom; 77 tbCtrl.MapWindowPoints( HWND_DESKTOP, &pt, 1 ); 78 hMenu = ::LoadMenu( ModuleHelper::GetResourceInstance(), MAKEINTRESOURCE( nMenuID ) ); 79 if ( hMenu ) 80 { 81 hPopup = ::GetSubMenu( hMenu, 0 ); 82 if ( hPopup ) 83 { 84 pT = static_cast<T*>( this ); 85 pT->PrepareToolBarMenu( hPopup ); 86 pT->m_CmdBar.TrackPopupMenu( hPopup, \ 87 TPM_RIGHTBUTTON | TPM_VERTICAL, pt.x, pt.y ); 88 } 89 90 ::DestroyMenu( hMenu ); 91 } 92 } 93 94 return 0; 95 } 96 97 void PrepareToolBarMenu( HMENU /*hMenu*/ ) 98 { 99 //ATLASSERT( FALSE ); 100 } 101 102 void AddToolBarButtonText( HWND hWndToolBar, UINT nID, LPCTSTR lpsz ) 103 { 104 UINT nIndex; 105 DWORD tbStyleEx; 106 TBBUTTON tbButton; 107 CToolBarCtrl tbCtrl; 108 109 tbCtrl = hWndToolBar; 110 ATLASSERT( tbCtrl ); 111 112 tbStyleEx = tbCtrl.GetExtendedStyle() | TBSTYLE_EX_MIXEDBUTTONS; 113 tbCtrl.SetExtendedStyle( tbStyleEx ); 114 115 nIndex = tbCtrl.CommandToIndex( nID ); 116 ATLASSERT( nIndex != -1 ); 117 118 memset( &tbButton, 0, sizeof( TBBUTTON ) ); 119 if ( tbCtrl.GetButton( nIndex, &tbButton ) ) 120 { 121 tbButton.iString = tbCtrl.AddStrings( lpsz ); 122 tbButton.fsStyle |= TBSTYLE_AUTOSIZE | BTNS_SHOWTEXT; 123 124 if ( tbCtrl.DeleteButton( nIndex ) ) 125 { 126 tbCtrl.InsertButton( nIndex, &tbButton ); 127 } 128 } 129 } 130 131 132 HWND CreateToolBarComboBox( HWND hWndToolBar, UINT nID, UINT nWidth = 16, UINT nHeight = 16, 133 DWORD dwComboStyle = CBS_DROPDOWNLIST ) 134 { 135 POINT siz; 136 UINT nIndex; 137 UINT cx, cy; 138 RECT rect; 139 DWORD dwStyle; 140 CComboBox cbxCtrl; 141 TBBUTTONINFO tbBtnInfo; 142 CToolBarCtrl tbCtrl; 143 T* pT; 144 145 if ( !GetFontSize( &siz ) ) 146 { 147 return NULL; 148 } 149 150 cx = ( nWidth + 8 ) * siz.x; 151 cy = nHeight * siz.y; 152 153 memset( &tbBtnInfo, 0, sizeof( TBBUTTONINFO ) ); 154 tbBtnInfo.cbSize = sizeof( TBBUTTONINFO ); 155 tbBtnInfo.dwMask = ( TBIF_SIZE | TBIF_STATE | TBIF_STYLE ); 156 //tbBtnInfo.fsState = 0; 157 tbBtnInfo.fsStyle = BTNS_SHOWTEXT; 158 tbBtnInfo.cx = ( WORD )cx; 159 160 161 162 tbCtrl = hWndToolBar; 163 ATLASSERT( tbCtrl ); 164 165 if ( tbCtrl.SetButtonInfo( nID, &tbBtnInfo ) ) 166 { 167 nIndex = tbCtrl.CommandToIndex( nID ); 168 ATLASSERT( nIndex != -1 ); 169 tbCtrl.GetItemRect( nIndex, &rect ); 170 rect.bottom = cy; 171 172 pT = static_cast<T*>( this ); 173 174 dwStyle = WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_TABSTOP | dwComboStyle; 175 cbxCtrl.Create( pT->m_hWnd, rect, NULL, dwStyle, 0, nID ); 176 cbxCtrl.SetFont( m_nonClientFont ); 177 cbxCtrl.SetParent( tbCtrl ); 178 179 MoveToolBarComboBox( tbCtrl, cbxCtrl ); 180 181 return cbxCtrl; 182 } 183 184 return NULL; 185 } 186 187 LRESULT OnSelChangeToolBarCombo( WORD /*wNotifyCode*/, WORD wID, HWND hWndCtl, BOOL& /*bHandled*/ ) 188 { 189 T* pT; 190 191 pT = static_cast<T*>( this ); 192 pT->ToolBarComboboxAction( wID , hWndCtl ); 193 pT->SetFocus(); 194 195 return 0; 196 } 197 198 void ToolBarComboboxAction( WORD /*wID*/, HWND /*hWndCtl*/ ) 199 { 200 //ATLASSERT( FALSE ); 201 } 202 203 private: 204 205 BOOL GetFontSize( LPPOINT lpPoint ) 206 { 207 HDC hDC; 208 BOOL bRet; 209 HFONT hOldFont; 210 TEXTMETRIC textMetric; 211 NONCLIENTMETRICS nonClientMetrics; 212 T* pT; 213 214 if ( !m_nonClientFont ) 215 { 216 memset( &nonClientMetrics, 0, sizeof( NONCLIENTMETRICS ) ); 217 nonClientMetrics.cbSize = sizeof( NONCLIENTMETRICS ); 218 if ( !::SystemParametersInfo( SPI_GETNONCLIENTMETRICS, sizeof( NONCLIENTMETRICS ), &nonClientMetrics, 0 ) || \ 219 !( m_nonClientFont = ::CreateFontIndirect( &nonClientMetrics.lfMenuFont ) ) ) 220 { 221 return FALSE; 222 } 223 } 224 225 pT = static_cast<T*>( this ); 226 227 hDC = ::GetDC( pT->m_hWnd ); 228 hOldFont = ( HFONT )::SelectObject( hDC, m_nonClientFont ); 229 memset( &textMetric, 0, sizeof( TEXTMETRIC ) ); 230 bRet = ::GetTextMetrics( hDC, &textMetric ); 231 ::SelectObject( hDC, hOldFont ); 232 ::ReleaseDC( pT->m_hWnd, hDC ); 233 234 if ( !bRet ) 235 { 236 return FALSE; 237 } 238 239 lpPoint->x = textMetric.tmAveCharWidth; 240 lpPoint->y = textMetric.tmHeight + textMetric.tmExternalLeading; 241 242 return TRUE; 243 } 244 245 void MoveToolBarComboBox( HWND hWndToolBar, HWND hWndComboBox ) 246 { 247 int nDiff; 248 RECT rtToolBar, rtComboBox; 249 CToolBarCtrl tbCtrl; 250 CComboBox cbxCtrl; 251 252 tbCtrl = hWndToolBar; 253 cbxCtrl = hWndComboBox; 254 255 tbCtrl.GetClientRect( &rtToolBar ); 256 cbxCtrl.GetWindowRect( &rtComboBox ); 257 258 nDiff = ( rtToolBar.bottom - rtToolBar.top ) - ( rtComboBox.bottom - rtComboBox.top ); 259 260 if ( nDiff > 1 ) 261 { 262 tbCtrl.ScreenToClient( &rtComboBox ); 263 cbxCtrl.MoveWindow( rtComboBox.left, nDiff / 2, \ 264 rtComboBox.right - rtComboBox.left, rtComboBox.bottom - rtComboBox.top ); 265 } 266 } 267 };
在原来基础上有一些小改动