00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "StdAfx.h"
00023 #include "Shareaza.h"
00024 #include "CoolInterface.h"
00025 #include "CoolMenu.h"
00026 #include "CtrlCoolMenuBar.h"
00027
00028 #ifdef _SHAREAZA
00029 #include "WndChild.h"
00030 #endif
00031
00032 #ifdef _DEBUG
00033 #define new DEBUG_NEW
00034 #undef THIS_FILE
00035 static char THIS_FILE[] = __FILE__;
00036 #endif
00037
00038 BEGIN_MESSAGE_MAP(CCoolMenuBarCtrl, CCoolBarCtrl)
00039
00040 ON_WM_LBUTTONDOWN()
00041 ON_WM_TIMER()
00042 ON_WM_MEASUREITEM()
00043 ON_WM_DRAWITEM()
00044 ON_WM_INITMENUPOPUP()
00045 ON_WM_MENUSELECT()
00046 ON_WM_ENTERIDLE()
00047
00048 ON_WM_ENTERMENULOOP()
00049 ON_WM_EXITMENULOOP()
00050 END_MESSAGE_MAP()
00051
00052
00054
00055
00056 CCoolMenuBarCtrl::CCoolMenuBarCtrl()
00057 {
00058 m_bMenuGray = TRUE;
00059 m_bGripper = TRUE;
00060
00061 m_bStretch = theApp.GetProfileInt( _T(""), _T("MenuStretch"), TRUE );
00062 if ( theApp.GetProfileInt( _T(""), _T("MenuHalfHeight"), TRUE ) ) m_nHeight = 28;
00063
00064 m_hMenu = NULL;
00065 }
00066
00067 CCoolMenuBarCtrl::~CCoolMenuBarCtrl()
00068 {
00069 }
00070
00072
00073
00074 void CCoolMenuBarCtrl::SetMenu(HMENU hMenu)
00075 {
00076 m_hMenu = hMenu;
00077
00078 Clear();
00079
00080 if ( ! m_hMenu ) return;
00081
00082 CMenu pMenu;
00083 pMenu.Attach( m_hMenu );
00084
00085 for ( UINT nItem = 0 ; nItem < pMenu.GetMenuItemCount() ; nItem++ )
00086 {
00087 CString strMenu;
00088 pMenu.GetMenuString( nItem, strMenu, MF_BYPOSITION );
00089
00090 int nAmp = strMenu.Find( '&' );
00091 if ( nAmp >= 0 ) strMenu = strMenu.Left( nAmp ) + strMenu.Mid( nAmp + 1 );
00092
00093 CCoolBarItem* pItem = new CCoolBarItem( this, nItem + 1 );
00094 pItem->SetText( _T(" ") + strMenu + _T(" ") );
00095 m_pItems.AddTail( pItem );
00096 }
00097
00098 pMenu.Detach();
00099 }
00100
00101 void CCoolMenuBarCtrl::OpenMenuBar()
00102 {
00103 if ( m_pDown == NULL )
00104 {
00105 if ( m_pSelect = GetIndex( 0 ) ) PostMessage( WM_TIMER, 5 );
00106 }
00107 }
00108
00109 BOOL CCoolMenuBarCtrl::OpenMenuChar(UINT nChar)
00110 {
00111 CMenu pMenu;
00112 pMenu.Attach( m_hMenu );
00113
00114 for ( UINT nItem = 0 ; nItem < pMenu.GetMenuItemCount() ; nItem++ )
00115 {
00116 CString strMenu;
00117 pMenu.GetMenuString( nItem, strMenu, MF_BYPOSITION );
00118
00119 LPCTSTR pszChar = _tcschr( strMenu, '&' );
00120 if ( ! pszChar++ ) continue;
00121
00122 if ( toupper( *pszChar ) == toupper( nChar ) )
00123 {
00124 pMenu.Detach();
00125 if ( m_pSelect = GetIndex( nItem ) ) PostMessage( WM_TIMER, 5 );
00126 return TRUE;
00127 }
00128 }
00129
00130 pMenu.Detach();
00131 return FALSE;
00132 }
00133
00135
00136
00137 void CCoolMenuBarCtrl::ShowMenu()
00138 {
00139 if ( m_pHot == NULL || ! IsMenu( m_hMenu ) ) return;
00140
00141 CMenu* pMenu = CMenu::FromHandle( m_hMenu )->GetSubMenu( m_pHot->m_nID - 1 );
00142
00143 if ( pMenu == NULL )
00144 {
00145 m_pHot = m_pDown = NULL;
00146 Invalidate();
00147 return;
00148 }
00149
00150 UINT nFirstID = pMenu->GetMenuItemID( 0 );
00151
00152 if ( nFirstID == ID_WINDOW_CASCADE ||
00153 nFirstID == ID_WINDOW_NAVBAR )
00154 {
00155 UpdateWindowMenu( pMenu );
00156 }
00157
00158 m_pDown = m_pHot;
00159 Invalidate();
00160
00161 KillTimer( 1 );
00162
00163 TPMPARAMS tpm;
00164 CRect rc;
00165
00166 GetItemRect( m_pDown, &rc );
00167 ClientToScreen( &rc );
00168 rc.DeflateRect( 1, 2 );
00169
00170 tpm.cbSize = sizeof(tpm);
00171 tpm.rcExclude = rc;
00172
00173 m_pMenuBar = this;
00174 m_hMsgHook = SetWindowsHookEx( WH_MSGFILTER, MenuFilter, NULL, GetCurrentThreadId() );
00175
00176 CoolMenu.RegisterEdge( theApp.m_bRTL ? rc.right : rc.left, rc.bottom, rc.Width() );
00177
00178 UINT nCmd = TrackPopupMenuEx( pMenu->GetSafeHmenu(),
00179 TPM_LEFTALIGN|TPM_LEFTBUTTON|TPM_VERTICAL|TPM_RETURNCMD,
00180 theApp.m_bRTL ? rc.right : rc.left, rc.bottom, GetSafeHwnd(), &tpm );
00181
00182 UnhookWindowsHookEx( m_hMsgHook );
00183
00184 m_hMsgHook = NULL;
00185 m_pMenuBar = NULL;
00186
00187 m_pDown = NULL;
00188 OnTimer( 1 );
00189
00190 if ( m_pHot != NULL )
00191 {
00192 SetTimer( 1, 100, NULL );
00193 m_bTimer = TRUE;
00194 }
00195
00196 Invalidate();
00197 UpdateWindow();
00198
00199 if ( nCmd ) GetOwner()->PostMessage( WM_COMMAND, nCmd );
00200 }
00201
00202 void CCoolMenuBarCtrl::UpdateWindowMenu(CMenu* pMenu)
00203 {
00204 for ( UINT nItem = 0 ; nItem < pMenu->GetMenuItemCount() ; nItem++ )
00205 {
00206 UINT nID = pMenu->GetMenuItemID( nItem );
00207
00208 if ( nID >= AFX_IDM_FIRST_MDICHILD )
00209 {
00210 for ( UINT nRemove = nItem ; nRemove < pMenu->GetMenuItemCount() ; )
00211 pMenu->RemoveMenu( nItem, MF_BYPOSITION );
00212 pMenu->RemoveMenu( nItem - 1, MF_BYPOSITION );
00213 break;
00214 }
00215 }
00216
00217 CMDIFrameWnd* pFrame = (CMDIFrameWnd*)AfxGetMainWnd();
00218 if ( ! pFrame->IsKindOf( RUNTIME_CLASS(CMDIFrameWnd) ) ) return;
00219
00220 CWnd* pClient = pFrame->GetWindow( GW_CHILD );
00221 for ( ; pClient ; pClient = pClient->GetNextWindow() )
00222 {
00223 TCHAR szClass[64];
00224 GetClassName( pClient->GetSafeHwnd(), szClass, 64 );
00225 if ( _tcsicmp( szClass, _T("MDIClient") ) == 0 ) break;
00226 }
00227
00228 if ( pClient == NULL ) return;
00229
00230 CMDIChildWnd* pActive = pFrame->MDIGetActive();
00231 BOOL bSeparator = TRUE;
00232
00233 for ( UINT nIndex = 1, nID = AFX_IDM_FIRST_MDICHILD ; nIndex <= 10 ; nIndex++, nID++ )
00234 {
00235 CWnd* pWnd = pClient->GetDlgItem( nID );
00236 if ( ! pWnd ) break;
00237
00238 #ifdef _SHAREAZA
00239 CChildWnd* pChildWnd = (CChildWnd*)pWnd;
00240 if ( pChildWnd->m_bTabMode )
00241 {
00242 nIndex--;
00243 continue;
00244 }
00245 #endif
00246
00247 if ( bSeparator )
00248 {
00249 pMenu->AppendMenu( MF_SEPARATOR, ID_SEPARATOR );
00250 bSeparator = FALSE;
00251 }
00252
00253 CString strMenu, strWindow;
00254 pWnd->GetWindowText( strWindow );
00255
00256 strMenu.Format( _T("&%i %s"), nIndex, (LPCTSTR)strWindow );
00257
00258 pMenu->AppendMenu( MF_STRING | ( pWnd == pActive ? MF_CHECKED : 0 ),
00259 nID, strMenu );
00260 }
00261 }
00262
00263 void CCoolMenuBarCtrl::ShiftMenu(int nOffset)
00264 {
00265 int nIndex = 0;
00266
00267 if ( m_pDown )
00268 {
00269 nIndex = (int)m_pDown->m_nID - 1 + nOffset;
00270 if ( nIndex < 0 ) nIndex = GetCount() - 1;
00271 if ( nIndex >= GetCount() ) nIndex = 0;
00272 }
00273
00274 SendMessage( WM_CANCELMODE, 0, 0 );
00275 m_pSelect = GetIndex( nIndex );
00276 m_pHot = m_pDown = NULL;
00277 PostMessage( WM_TIMER, 5 );
00278 }
00279
00280 void CCoolMenuBarCtrl::OnTimer(UINT nIDEvent)
00281 {
00282 switch ( nIDEvent )
00283 {
00284 case 5:
00285 m_pHot = m_pSelect;
00286 case 4:
00287 ShowMenu();
00288 break;
00289 default:
00290 CCoolBarCtrl::OnTimer( nIDEvent );
00291 break;
00292 }
00293 }
00294
00295 void CCoolMenuBarCtrl::OnLButtonDown(UINT nFlags, CPoint point)
00296 {
00297 CCoolBarItem* pHit = HitTest( point );
00298
00299 if ( pHit && pHit == m_pHot )
00300 {
00301 ShowMenu();
00302 return;
00303 }
00304
00305 CCoolBarCtrl::OnLButtonDown( nFlags, point );
00306 }
00307
00309
00310
00311 void CCoolMenuBarCtrl::OnUpdateCmdUI(CFrameWnd* pTarget, BOOL bDisableIfNoHndler)
00312 {
00313 }
00314
00315 void CCoolMenuBarCtrl::OnInitMenuPopup(CMenu* pPopupMenu, UINT nIndex, BOOL bSysMenu)
00316 {
00317 GetOwner()->SendMessage( WM_INITMENUPOPUP, (WPARAM)pPopupMenu->GetSafeHmenu(),
00318 MAKELONG( nIndex, bSysMenu ) );
00319 }
00320
00321 void CCoolMenuBarCtrl::OnMeasureItem(int nIDCtl, LPMEASUREITEMSTRUCT lpMeasureItemStruct)
00322 {
00323 GetOwner()->SendMessage( WM_MEASUREITEM, (WPARAM)nIDCtl, (LPARAM)lpMeasureItemStruct );
00324 }
00325
00326 void CCoolMenuBarCtrl::OnDrawItem(int nIDCtl, LPDRAWITEMSTRUCT lpDrawItemStruct)
00327 {
00328 GetOwner()->SendMessage( WM_DRAWITEM, (WPARAM)nIDCtl, (LPARAM)lpDrawItemStruct );
00329 }
00330
00331 void CCoolMenuBarCtrl::OnMenuSelect(UINT nItemID, UINT nFlags, HMENU hSysMenu)
00332 {
00333 GetOwner()->SendMessage( WM_MENUSELECT, MAKELONG( nItemID, nFlags ), (LPARAM)hSysMenu );
00334 }
00335
00336 void CCoolMenuBarCtrl::OnEnterMenuLoop(BOOL bIsTrackPopupMenu)
00337 {
00338 GetOwner()->SendMessage( WM_ENTERMENULOOP, (WPARAM)bIsTrackPopupMenu );
00339 }
00340
00341 void CCoolMenuBarCtrl::OnExitMenuLoop(BOOL bIsTrackPopupMenu)
00342 {
00343 GetOwner()->SendMessage( WM_EXITMENULOOP, (WPARAM)bIsTrackPopupMenu );
00344 }
00345
00346 void CCoolMenuBarCtrl::OnEnterIdle(UINT nWhy, CWnd* pWho)
00347 {
00348 GetOwner()->SendMessage( WM_ENTERIDLE, (WPARAM)nWhy, (LPARAM)pWho->GetSafeHwnd() );
00349 }
00350
00352
00353
00354 CCoolMenuBarCtrl* CCoolMenuBarCtrl::m_pMenuBar = NULL;
00355 HHOOK CCoolMenuBarCtrl::m_hMsgHook = NULL;
00356
00357 LRESULT CCoolMenuBarCtrl::MenuFilter(int nCode, WPARAM wParam, LPARAM lParam)
00358 {
00359 MSG* pMsg = (MSG*)lParam;
00360
00361 if ( m_pMenuBar && nCode == MSGF_MENU )
00362 {
00363 if ( m_pMenuBar->OnMenuMessage( pMsg ) ) return TRUE;
00364 }
00365
00366 return CallNextHookEx( m_hMsgHook, nCode, wParam, lParam );
00367 }
00368
00369 BOOL CCoolMenuBarCtrl::OnMenuMessage(MSG* pMsg)
00370 {
00371 switch ( pMsg->message )
00372 {
00373 case WM_MOUSEMOVE:
00374 {
00375
00376 CPoint pt( pMsg->lParam );
00377 ScreenToClient( &pt );
00378
00379 if ( m_pMouse == pt ) return TRUE;
00380 m_pMouse = pt;
00381
00382 CCoolBarItem* pHit = HitTest( pt );
00383
00384 if ( pHit && pHit != m_pDown )
00385 {
00386 SendMessage( WM_CANCELMODE, 0, 0 );
00387 m_pHot = pHit;
00388 m_pDown = NULL;
00389 PostMessage( WM_TIMER, 4 );
00390 return TRUE;
00391 }
00392 }
00393 break;
00394 case WM_LBUTTONDOWN:
00395 {
00396
00397 CPoint pt( pMsg->lParam );
00398
00399 CWnd* pWnd = CWnd::WindowFromPoint( pt );
00400
00401 if ( pWnd )
00402 {
00403 TCHAR szClass[2];
00404 GetClassName( pWnd->GetSafeHwnd(), szClass, 2 );
00405 if ( szClass[0] == '#' ) return FALSE;
00406 }
00407
00408 ScreenToClient( &pt );
00409
00410 CCoolBarItem* pHit = HitTest( pt );
00411
00412 if ( pHit == NULL )
00413 {
00414 m_pHot = m_pDown = NULL;
00415 SendMessage( WM_CANCELMODE, 0, 0 );
00416 return TRUE;
00417 }
00418 else if ( pHit == m_pDown )
00419 {
00420 m_pDown = NULL;
00421 PostMessage( WM_CANCELMODE, 0, 0 );
00422 return TRUE;
00423 }
00424 }
00425 break;
00426 case WM_KEYDOWN:
00427 switch ( pMsg->wParam )
00428 {
00429 case VK_LEFT:
00430 ShiftMenu( -1 );
00431 return TRUE;
00432 case VK_RIGHT:
00433 ShiftMenu( 1 );
00434 return TRUE;
00435 case VK_ESCAPE:
00436 PostMessage( WM_CANCELMODE, 0, 0 );
00437 m_pHot = m_pDown = NULL;
00438 return TRUE;
00439 }
00440 break;
00441 default:
00442 break;
00443 }
00444
00445 return FALSE;
00446 }
00447