Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members

CtrlCoolMenuBar.cpp

Go to the documentation of this file.
00001 //
00002 // CtrlCoolMenuBar.cpp
00003 //
00004 // Copyright (c) Shareaza Development Team, 2002-2005.
00005 // This file is part of SHAREAZA (www.shareaza.com)
00006 //
00007 // Shareaza is free software; you can redistribute it
00008 // and/or modify it under the terms of the GNU General Public License
00009 // as published by the Free Software Foundation; either version 2 of
00010 // the License, or (at your option) any later version.
00011 //
00012 // Shareaza is distributed in the hope that it will be useful,
00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 // GNU General Public License for more details.
00016 //
00017 // You should have received a copy of the GNU General Public License
00018 // along with Shareaza; if not, write to the Free Software
00019 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
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         //{{AFX_MSG_MAP(CCoolMenuBarCtrl)
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         //}}AFX_MSG_MAP
00048         ON_WM_ENTERMENULOOP()
00049         ON_WM_EXITMENULOOP()
00050 END_MESSAGE_MAP()
00051 
00052 
00054 // CCoolMenuBarCtrl construction
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 // CCoolMenuBarCtrl operations
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 // CCoolMenuBarCtrl message handlers
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 // CCoolMenuBarCtrl menu message forwarding
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 // CCoolMenuBarCtrl menu message hooking
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                         //CPoint pt( LOWORD( pMsg->lParam ), HIWORD( pMsg->lParam ) );
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                         //CPoint pt( LOWORD( pMsg->lParam ), HIWORD( pMsg->lParam ) );
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 

Generated on Thu Dec 15 10:39:34 2005 for Shareaza 2.2.1.0 by  doxygen 1.4.2