2014-02-12 16:48:36 +00:00
/*
* Shell Menu Band
*
* Copyright 2014 David Quintana
*
* This library is free software ; you can redistribute it and / or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation ; either
* version 2.1 of the License , or ( at your option ) any later version .
*
* This library is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the GNU
* Lesser General Public License for more details .
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library ; if not , write to the Free Software
* Foundation , Inc . , 51 Franklin St , Fifth Floor , Boston , MA 02110 - 1301 , USA
*/
# include "precomp.h"
2014-02-17 15:38:55 +00:00
# include <windowsx.h>
2014-02-23 18:13:43 +00:00
# include <CommonControls.h>
2014-02-19 12:19:50 +00:00
# include <shlwapi_undoc.h>
2014-02-12 16:48:36 +00:00
2014-02-23 18:13:43 +00:00
extern " C "
HRESULT WINAPI SHGetImageList (
_In_ int iImageList ,
_In_ REFIID riid ,
_Out_ void * * ppv
) ;
2014-02-17 15:38:55 +00:00
# define TBSTYLE_EX_VERTICAL 4
2014-02-20 16:18:49 +00:00
WINE_DEFAULT_DEBUG_CHANNEL ( CMenuBand ) ;
2014-02-17 15:38:55 +00:00
# define TIMERID_HOTTRACK 1
# define SUBCLASS_ID_MENUBAND 1
2014-02-12 16:48:36 +00:00
extern " C " BOOL WINAPI Shell_GetImageLists ( HIMAGELIST * lpBigList , HIMAGELIST * lpSmallList ) ;
class CMenuBand ;
2014-02-19 20:35:50 +00:00
class CMenuFocusManager ;
2014-02-12 16:48:36 +00:00
class CMenuToolbarBase
{
2014-02-24 11:07:16 +00:00
private :
HWND m_hwnd ; // May be the pager
2014-02-20 16:18:49 +00:00
protected :
CMenuBand * m_menuBand ;
2014-02-24 11:07:16 +00:00
HWND m_hwndToolbar ;
2014-02-20 16:18:49 +00:00
DWORD m_dwMenuFlags ;
INT m_hotItem ;
WNDPROC m_SubclassOld ;
2014-02-24 11:07:16 +00:00
BOOL m_hasIdealSize ;
SIZE m_idealSize ;
BOOL m_usePager ;
2014-02-20 16:18:49 +00:00
private :
static LRESULT CALLBACK s_SubclassProc ( HWND hWnd , UINT uMsg , WPARAM wParam , LPARAM lParam ) ;
2014-02-12 16:48:36 +00:00
public :
2014-02-24 11:07:16 +00:00
CMenuToolbarBase ( CMenuBand * menuBand , BOOL usePager ) ;
2014-02-12 16:48:36 +00:00
virtual ~ CMenuToolbarBase ( ) { }
2014-02-20 16:18:49 +00:00
HRESULT IsWindowOwner ( HWND hwnd ) ;
2014-02-12 16:48:36 +00:00
HRESULT CreateToolbar ( HWND hwndParent , DWORD dwFlags ) ;
HRESULT GetWindow ( HWND * phwnd ) ;
HRESULT ShowWindow ( BOOL fShow ) ;
HRESULT Close ( ) ;
2014-02-17 16:41:10 +00:00
2014-02-12 16:48:36 +00:00
virtual HRESULT FillToolbar ( ) = 0 ;
2014-02-17 15:38:55 +00:00
virtual HRESULT PopupItem ( UINT uItem ) = 0 ;
virtual HRESULT HasSubMenu ( UINT uItem ) = 0 ;
2014-02-17 18:38:31 +00:00
virtual HRESULT OnContextMenu ( NMMOUSE * rclick ) = 0 ;
2014-02-20 16:18:49 +00:00
virtual HRESULT OnCommand ( WPARAM wParam , LPARAM lParam , LRESULT * theResult ) ;
2014-02-17 15:38:55 +00:00
2014-02-24 11:07:16 +00:00
HRESULT PopupSubMenu ( UINT itemId , UINT index , IShellMenu * childShellMenu ) ;
2014-02-18 18:18:08 +00:00
HRESULT PopupSubMenu ( UINT index , HMENU menu ) ;
2014-02-18 10:26:50 +00:00
HRESULT DoContextMenu ( IContextMenu * contextMenu ) ;
2014-02-17 17:16:55 +00:00
2014-02-20 16:18:49 +00:00
HRESULT ChangeHotItem ( DWORD changeType ) ;
HRESULT OnHotItemChange ( const NMTBHOTITEM * hot ) ;
2014-02-20 12:12:42 +00:00
2014-02-24 11:07:16 +00:00
HRESULT GetIdealSize ( SIZE & size ) ;
HRESULT SetPosSize ( int x , int y , int cx , int cy ) ;
void InvalidateDraw ( ) ;
2014-02-12 16:48:36 +00:00
protected :
2014-02-17 15:38:55 +00:00
LRESULT CALLBACK SubclassProc ( HWND hWnd , UINT uMsg , WPARAM wParam , LPARAM lParam ) ;
2014-02-12 16:48:36 +00:00
} ;
2014-02-20 16:18:49 +00:00
class CMenuStaticToolbar :
public CMenuToolbarBase
2014-02-12 16:48:36 +00:00
{
2014-02-20 16:18:49 +00:00
private :
HMENU m_hmenu ;
2014-02-12 16:48:36 +00:00
public :
CMenuStaticToolbar ( CMenuBand * menuBand ) ;
virtual ~ CMenuStaticToolbar ( ) { }
HRESULT SetMenu ( HMENU hmenu , HWND hwnd , DWORD dwFlags ) ;
HRESULT GetMenu ( HMENU * phmenu , HWND * phwnd , DWORD * pdwFlags ) ;
virtual HRESULT FillToolbar ( ) ;
2014-02-17 15:38:55 +00:00
virtual HRESULT PopupItem ( UINT uItem ) ;
virtual HRESULT HasSubMenu ( UINT uItem ) ;
2014-02-17 11:20:35 +00:00
virtual HRESULT OnCommand ( WPARAM wParam , LPARAM lParam , LRESULT * theResult ) ;
2014-02-17 18:38:31 +00:00
virtual HRESULT OnContextMenu ( NMMOUSE * rclick ) ;
2014-02-12 16:48:36 +00:00
} ;
2014-02-20 16:18:49 +00:00
class CMenuSFToolbar :
public CMenuToolbarBase
2014-02-12 16:48:36 +00:00
{
2014-02-20 16:18:49 +00:00
private :
IShellFolder * m_shellFolder ;
LPCITEMIDLIST m_idList ;
HKEY m_hKey ;
2014-02-12 16:48:36 +00:00
public :
CMenuSFToolbar ( CMenuBand * menuBand ) ;
virtual ~ CMenuSFToolbar ( ) ;
HRESULT SetShellFolder ( IShellFolder * psf , LPCITEMIDLIST pidlFolder , HKEY hKey , DWORD dwFlags ) ;
HRESULT GetShellFolder ( DWORD * pdwFlags , LPITEMIDLIST * ppidl , REFIID riid , void * * ppv ) ;
virtual HRESULT FillToolbar ( ) ;
2014-02-17 15:38:55 +00:00
virtual HRESULT PopupItem ( UINT uItem ) ;
virtual HRESULT HasSubMenu ( UINT uItem ) ;
2014-02-17 11:20:35 +00:00
virtual HRESULT OnCommand ( WPARAM wParam , LPARAM lParam , LRESULT * theResult ) ;
2014-02-17 18:38:31 +00:00
virtual HRESULT OnContextMenu ( NMMOUSE * rclick ) ;
2014-02-12 16:48:36 +00:00
private :
2014-02-20 16:18:49 +00:00
LPITEMIDLIST GetPidlFromId ( UINT uItem , INT * pIndex = NULL ) ;
2014-02-12 16:48:36 +00:00
} ;
class CMenuBand :
public CComCoClass < CMenuBand > ,
public CComObjectRootEx < CComMultiThreadModelNoCS > ,
public IDeskBand ,
public IObjectWithSite ,
public IInputObject ,
public IPersistStream ,
public IOleCommandTarget ,
public IServiceProvider ,
public IMenuPopup ,
public IMenuBand ,
public IShellMenu2 ,
public IWinEventHandler ,
public IShellMenuAcc
{
private :
2014-02-20 16:18:49 +00:00
CMenuFocusManager * m_focusManager ;
CMenuStaticToolbar * m_staticToolbar ;
CMenuSFToolbar * m_SFToolbar ;
2014-02-12 16:48:36 +00:00
2014-02-20 16:18:49 +00:00
CComPtr < IOleWindow > m_site ;
CComPtr < IShellMenuCallback > m_psmc ;
2014-02-21 10:00:00 +00:00
CComPtr < IMenuPopup > m_subMenuChild ;
CComPtr < IMenuPopup > m_subMenuParent ;
2014-02-12 16:48:36 +00:00
2014-02-20 16:18:49 +00:00
UINT m_uId ;
UINT m_uIdAncestor ;
2014-02-12 16:48:36 +00:00
DWORD m_dwFlags ;
PVOID m_UserData ;
HMENU m_hmenu ;
2014-02-20 16:18:49 +00:00
HWND m_menuOwner ;
2014-02-12 16:48:36 +00:00
BOOL m_useBigIcons ;
2014-02-19 12:19:50 +00:00
HWND m_topLevelWindow ;
2014-02-20 12:12:42 +00:00
CMenuToolbarBase * m_hotBar ;
2014-02-20 16:18:49 +00:00
INT m_hotItem ;
2014-02-24 11:07:16 +00:00
INT m_popupItem ;
HFONT m_marlett ;
2014-02-20 12:12:42 +00:00
2014-02-12 16:48:36 +00:00
public :
2014-02-20 16:18:49 +00:00
CMenuBand ( ) ;
~ CMenuBand ( ) ;
DECLARE_NOT_AGGREGATABLE ( CMenuBand )
DECLARE_PROTECT_FINAL_CONSTRUCT ( )
BEGIN_COM_MAP ( CMenuBand )
COM_INTERFACE_ENTRY_IID ( IID_IDeskBar , IMenuPopup )
COM_INTERFACE_ENTRY_IID ( IID_IShellMenu , IShellMenu )
COM_INTERFACE_ENTRY_IID ( IID_IOleCommandTarget , IOleCommandTarget )
COM_INTERFACE_ENTRY_IID ( IID_IOleWindow , IDeskBand )
COM_INTERFACE_ENTRY_IID ( IID_IDockingWindow , IDockingWindow )
COM_INTERFACE_ENTRY_IID ( IID_IDeskBand , IDeskBand )
COM_INTERFACE_ENTRY_IID ( IID_IObjectWithSite , IObjectWithSite )
COM_INTERFACE_ENTRY_IID ( IID_IInputObject , IInputObject )
COM_INTERFACE_ENTRY_IID ( IID_IPersistStream , IPersistStream )
COM_INTERFACE_ENTRY_IID ( IID_IPersist , IPersistStream )
COM_INTERFACE_ENTRY_IID ( IID_IServiceProvider , IServiceProvider )
COM_INTERFACE_ENTRY_IID ( IID_IMenuPopup , IMenuPopup )
COM_INTERFACE_ENTRY_IID ( IID_IMenuBand , IMenuBand )
COM_INTERFACE_ENTRY_IID ( IID_IShellMenu2 , IShellMenu2 )
COM_INTERFACE_ENTRY_IID ( IID_IWinEventHandler , IWinEventHandler )
COM_INTERFACE_ENTRY_IID ( IID_IShellMenuAcc , IShellMenuAcc )
END_COM_MAP ( )
2014-02-12 16:48:36 +00:00
// *** IDeskBand methods ***
virtual HRESULT STDMETHODCALLTYPE GetBandInfo ( DWORD dwBandID , DWORD dwViewMode , DESKBANDINFO * pdbi ) ;
// *** IDockingWindow methods ***
virtual HRESULT STDMETHODCALLTYPE ShowDW ( BOOL fShow ) ;
virtual HRESULT STDMETHODCALLTYPE CloseDW ( DWORD dwReserved ) ;
virtual HRESULT STDMETHODCALLTYPE ResizeBorderDW ( LPCRECT prcBorder , IUnknown * punkToolbarSite , BOOL fReserved ) ;
// *** IOleWindow methods ***
virtual HRESULT STDMETHODCALLTYPE GetWindow ( HWND * phwnd ) ;
virtual HRESULT STDMETHODCALLTYPE ContextSensitiveHelp ( BOOL fEnterMode ) ;
// *** IObjectWithSite methods ***
virtual HRESULT STDMETHODCALLTYPE SetSite ( IUnknown * pUnkSite ) ;
virtual HRESULT STDMETHODCALLTYPE GetSite ( REFIID riid , PVOID * ppvSite ) ;
// *** IInputObject methods ***
virtual HRESULT STDMETHODCALLTYPE UIActivateIO ( BOOL fActivate , LPMSG lpMsg ) ;
virtual HRESULT STDMETHODCALLTYPE HasFocusIO ( ) ;
virtual HRESULT STDMETHODCALLTYPE TranslateAcceleratorIO ( LPMSG lpMsg ) ;
// *** IPersistStream methods ***
virtual HRESULT STDMETHODCALLTYPE IsDirty ( ) ;
virtual HRESULT STDMETHODCALLTYPE Load ( IStream * pStm ) ;
virtual HRESULT STDMETHODCALLTYPE Save ( IStream * pStm , BOOL fClearDirty ) ;
virtual HRESULT STDMETHODCALLTYPE GetSizeMax ( ULARGE_INTEGER * pcbSize ) ;
// *** IPersist methods ***
virtual HRESULT STDMETHODCALLTYPE GetClassID ( CLSID * pClassID ) ;
// *** IOleCommandTarget methods ***
virtual HRESULT STDMETHODCALLTYPE QueryStatus ( const GUID * pguidCmdGroup , ULONG cCmds , OLECMD prgCmds [ ] , OLECMDTEXT * pCmdText ) ;
virtual HRESULT STDMETHODCALLTYPE Exec ( const GUID * pguidCmdGroup , DWORD nCmdID , DWORD nCmdexecopt , VARIANT * pvaIn , VARIANT * pvaOut ) ;
// *** IServiceProvider methods ***
virtual HRESULT STDMETHODCALLTYPE QueryService ( REFGUID guidService , REFIID riid , void * * ppvObject ) ;
// *** IMenuPopup methods ***
virtual HRESULT STDMETHODCALLTYPE Popup ( POINTL * ppt , RECTL * prcExclude , MP_POPUPFLAGS dwFlags ) ;
virtual HRESULT STDMETHODCALLTYPE OnSelect ( DWORD dwSelectType ) ;
virtual HRESULT STDMETHODCALLTYPE SetSubMenu ( IMenuPopup * pmp , BOOL fSet ) ;
// *** IDeskBar methods ***
virtual HRESULT STDMETHODCALLTYPE SetClient ( IUnknown * punkClient ) ;
virtual HRESULT STDMETHODCALLTYPE GetClient ( IUnknown * * ppunkClient ) ;
virtual HRESULT STDMETHODCALLTYPE OnPosRectChangeDB ( RECT * prc ) ;
// *** IMenuBand methods ***
virtual HRESULT STDMETHODCALLTYPE IsMenuMessage ( MSG * pmsg ) ;
virtual HRESULT STDMETHODCALLTYPE TranslateMenuMessage ( MSG * pmsg , LRESULT * plRet ) ;
// *** IShellMenu methods ***
virtual HRESULT STDMETHODCALLTYPE Initialize ( IShellMenuCallback * psmc , UINT uId , UINT uIdAncestor , DWORD dwFlags ) ;
virtual HRESULT STDMETHODCALLTYPE GetMenuInfo ( IShellMenuCallback * * ppsmc , UINT * puId , UINT * puIdAncestor , DWORD * pdwFlags ) ;
virtual HRESULT STDMETHODCALLTYPE SetShellFolder ( IShellFolder * psf , LPCITEMIDLIST pidlFolder , HKEY hKey , DWORD dwFlags ) ;
virtual HRESULT STDMETHODCALLTYPE GetShellFolder ( DWORD * pdwFlags , LPITEMIDLIST * ppidl , REFIID riid , void * * ppv ) ;
virtual HRESULT STDMETHODCALLTYPE SetMenu ( HMENU hmenu , HWND hwnd , DWORD dwFlags ) ;
virtual HRESULT STDMETHODCALLTYPE GetMenu ( HMENU * phmenu , HWND * phwnd , DWORD * pdwFlags ) ;
virtual HRESULT STDMETHODCALLTYPE InvalidateItem ( LPSMDATA psmd , DWORD dwFlags ) ;
virtual HRESULT STDMETHODCALLTYPE GetState ( LPSMDATA psmd ) ;
virtual HRESULT STDMETHODCALLTYPE SetMenuToolbar ( IUnknown * punk , DWORD dwFlags ) ;
// *** IWinEventHandler methods ***
virtual HRESULT STDMETHODCALLTYPE OnWinEvent ( HWND hWnd , UINT uMsg , WPARAM wParam , LPARAM lParam , LRESULT * theResult ) ;
virtual HRESULT STDMETHODCALLTYPE IsWindowOwner ( HWND hWnd ) ;
// *** IShellMenu2 methods ***
virtual HRESULT STDMETHODCALLTYPE GetSubMenu ( THIS ) ;
virtual HRESULT STDMETHODCALLTYPE SetToolbar ( THIS ) ;
virtual HRESULT STDMETHODCALLTYPE SetMinWidth ( THIS ) ;
virtual HRESULT STDMETHODCALLTYPE SetNoBorder ( THIS ) ;
virtual HRESULT STDMETHODCALLTYPE SetTheme ( THIS ) ;
// *** IShellMenuAcc methods ***
virtual HRESULT STDMETHODCALLTYPE GetTop ( THIS ) ;
virtual HRESULT STDMETHODCALLTYPE GetBottom ( THIS ) ;
virtual HRESULT STDMETHODCALLTYPE GetTracked ( THIS ) ;
virtual HRESULT STDMETHODCALLTYPE GetParentSite ( THIS ) ;
virtual HRESULT STDMETHODCALLTYPE GetState ( THIS ) ;
virtual HRESULT STDMETHODCALLTYPE DoDefaultAction ( THIS ) ;
virtual HRESULT STDMETHODCALLTYPE IsEmpty ( THIS ) ;
2014-02-20 16:18:49 +00:00
HRESULT _CallCBWithItemId ( UINT Id , UINT uMsg , WPARAM wParam , LPARAM lParam ) ;
HRESULT _CallCBWithItemPidl ( LPITEMIDLIST pidl , UINT uMsg , WPARAM wParam , LPARAM lParam ) ;
HRESULT _TrackSubMenuUsingTrackPopupMenu ( HMENU popup , INT x , INT y ) ;
HRESULT _GetTopLevelWindow ( HWND * topLevel ) ;
HRESULT _OnHotItemChanged ( CMenuToolbarBase * tb , INT id ) ;
HRESULT _MenuItemHotTrack ( DWORD changeType ) ;
2014-02-24 11:07:16 +00:00
HRESULT _OnPopupSubMenu ( INT popupItem , IMenuPopup * popup , POINTL * pAt , RECTL * pExclude ) ;
2014-02-12 16:48:36 +00:00
2014-02-20 16:18:49 +00:00
BOOL UseBigIcons ( )
{
2014-02-12 16:48:36 +00:00
return m_useBigIcons ;
}
private :
2014-02-18 10:26:50 +00:00
HRESULT _CallCB ( UINT uMsg , WPARAM wParam , LPARAM lParam , UINT id = 0 , LPITEMIDLIST pidl = NULL ) ;
2014-02-12 16:48:36 +00:00
} ;
2014-02-19 20:35:50 +00:00
class CMenuFocusManager :
public CComCoClass < CMenuFocusManager > ,
public CComObjectRootEx < CComMultiThreadModelNoCS >
{
private :
static DWORD TlsIndex ;
static CMenuFocusManager * GetManager ( )
{
return reinterpret_cast < CMenuFocusManager * > ( TlsGetValue ( TlsIndex ) ) ;
}
public :
static CMenuFocusManager * AcquireManager ( )
{
CMenuFocusManager * obj = NULL ;
if ( ! TlsIndex )
{
if ( ( TlsIndex = TlsAlloc ( ) ) = = TLS_OUT_OF_INDEXES )
return NULL ;
}
obj = GetManager ( ) ;
if ( ! obj )
{
obj = new CComObject < CMenuFocusManager > ( ) ;
TlsSetValue ( TlsIndex , obj ) ;
}
obj - > AddRef ( ) ;
return obj ;
}
static void ReleaseManager ( CMenuFocusManager * obj )
{
if ( ! obj - > Release ( ) )
{
TlsSetValue ( TlsIndex , NULL ) ;
}
}
private :
static LRESULT CALLBACK s_GetMsgHook ( INT nCode , WPARAM wParam , LPARAM lParam )
{
return GetManager ( ) - > GetMsgHook ( nCode , wParam , lParam ) ;
}
private :
2014-02-22 22:59:28 +00:00
CMenuBand * m_currentBand ;
HWND m_currentFocus ;
HHOOK m_hHook ;
DWORD m_threadId ;
2014-02-19 20:35:50 +00:00
// TODO: make dynamic
2014-02-21 10:00:00 +00:00
# define MAX_RECURSE 20
2014-02-19 20:35:50 +00:00
CMenuBand * m_bandStack [ MAX_RECURSE ] ;
int m_bandCount ;
HRESULT PushToArray ( CMenuBand * item )
{
if ( m_bandCount > = MAX_RECURSE )
return E_OUTOFMEMORY ;
m_bandStack [ m_bandCount + + ] = item ;
return S_OK ;
}
HRESULT PopFromArray ( CMenuBand * * pItem )
{
if ( pItem )
* pItem = NULL ;
if ( m_bandCount < = 0 )
return E_FAIL ;
m_bandCount - - ;
if ( pItem )
* pItem = m_bandStack [ m_bandCount ] ;
2014-02-21 10:00:00 +00:00
m_bandStack [ m_bandCount ] = NULL ;
2014-02-19 20:35:50 +00:00
return S_OK ;
}
HRESULT PeekArray ( CMenuBand * * pItem )
{
if ( ! pItem )
return E_FAIL ;
* pItem = NULL ;
if ( m_bandCount < = 0 )
return E_FAIL ;
* pItem = m_bandStack [ m_bandCount - 1 ] ;
return S_OK ;
}
protected :
CMenuFocusManager ( ) :
m_currentBand ( NULL ) ,
m_currentFocus ( NULL ) ,
m_bandCount ( 0 )
{
m_threadId = GetCurrentThreadId ( ) ;
}
~ CMenuFocusManager ( )
{
}
public :
DECLARE_NOT_AGGREGATABLE ( CMenuFocusManager )
DECLARE_PROTECT_FINAL_CONSTRUCT ( )
BEGIN_COM_MAP ( CMenuFocusManager )
END_COM_MAP ( )
LRESULT GetMsgHook ( INT nCode , WPARAM wParam , LPARAM lParam )
{
if ( nCode < 0 )
return CallNextHookEx ( m_hHook , nCode , wParam , lParam ) ;
if ( nCode = = HC_ACTION )
{
2014-02-22 22:59:28 +00:00
BOOL callNext = TRUE ;
MSG * msg = reinterpret_cast < MSG * > ( lParam ) ;
2014-02-19 20:35:50 +00:00
// Do whatever is necessary here
switch ( msg - > message )
{
case WM_CLOSE :
break ;
case WM_SYSKEYDOWN :
case WM_KEYDOWN :
switch ( msg - > wParam )
{
case VK_MENU :
case VK_LMENU :
case VK_RMENU :
2014-02-20 16:18:49 +00:00
m_currentBand - > _MenuItemHotTrack ( MPOS_FULLCANCEL ) ;
2014-02-19 20:35:50 +00:00
break ;
case VK_LEFT :
2014-02-20 16:18:49 +00:00
m_currentBand - > _MenuItemHotTrack ( MPOS_SELECTLEFT ) ;
2014-02-19 20:35:50 +00:00
break ;
case VK_RIGHT :
2014-02-20 16:18:49 +00:00
m_currentBand - > _MenuItemHotTrack ( MPOS_SELECTRIGHT ) ;
2014-02-19 20:35:50 +00:00
break ;
case VK_UP :
2014-02-20 16:18:49 +00:00
m_currentBand - > _MenuItemHotTrack ( VK_UP ) ;
2014-02-19 20:35:50 +00:00
break ;
case VK_DOWN :
2014-02-20 16:18:49 +00:00
m_currentBand - > _MenuItemHotTrack ( VK_DOWN ) ;
2014-02-19 20:35:50 +00:00
break ;
}
break ;
case WM_CHAR :
//if (msg->wParam >= 'a' && msg->wParam <= 'z')
//{
// callNext = FALSE;
// PostMessage(m_currentFocus, WM_SYSCHAR, wParam, lParam);
//}
break ;
}
if ( ! callNext )
return 0 ;
}
return CallNextHookEx ( m_hHook , nCode , wParam , lParam ) ;
}
HRESULT PlaceHooks ( HWND window )
{
//SetCapture(window);
m_hHook = SetWindowsHookEx ( WH_GETMESSAGE , s_GetMsgHook , NULL , m_threadId ) ;
return S_OK ;
}
HRESULT RemoveHooks ( HWND window )
{
UnhookWindowsHookEx ( m_hHook ) ;
//ReleaseCapture();
return S_OK ;
}
HRESULT UpdateFocus ( CMenuBand * newBand )
{
HRESULT hr ;
2014-02-22 22:59:28 +00:00
HWND newFocus ;
2014-02-19 20:35:50 +00:00
2014-02-22 22:59:28 +00:00
if ( newBand = = NULL )
2014-02-19 20:35:50 +00:00
{
2014-02-22 22:59:28 +00:00
hr = RemoveHooks ( m_currentFocus ) ;
2014-02-19 20:35:50 +00:00
m_currentFocus = NULL ;
m_currentBand = NULL ;
return S_OK ;
}
2014-02-20 16:18:49 +00:00
hr = newBand - > _GetTopLevelWindow ( & newFocus ) ;
2014-02-19 20:35:50 +00:00
if ( FAILED ( hr ) )
return hr ;
2014-02-22 22:59:28 +00:00
if ( ! m_currentBand )
{
hr = PlaceHooks ( newFocus ) ;
if ( FAILED ( hr ) )
return hr ;
}
2014-02-19 20:35:50 +00:00
m_currentFocus = newFocus ;
m_currentBand = newBand ;
return S_OK ;
}
public :
HRESULT PushMenu ( CMenuBand * mb )
{
HRESULT hr ;
hr = PushToArray ( mb ) ;
if ( FAILED ( hr ) )
return hr ;
return UpdateFocus ( mb ) ;
}
HRESULT PopMenu ( CMenuBand * mb )
{
CMenuBand * mbc ;
HRESULT hr ;
hr = PopFromArray ( & mbc ) ;
if ( FAILED ( hr ) )
return hr ;
if ( mb ! = mbc )
return E_FAIL ;
hr = PeekArray ( & mbc ) ;
return UpdateFocus ( mbc ) ;
}
} ;
DWORD CMenuFocusManager : : TlsIndex = 0 ;
2014-02-12 16:48:36 +00:00
extern " C "
HRESULT CMenuBand_Constructor ( REFIID riid , LPVOID * ppv )
{
* ppv = NULL ;
CMenuBand * site = new CComObject < CMenuBand > ( ) ;
if ( ! site )
return E_OUTOFMEMORY ;
HRESULT hr = site - > QueryInterface ( riid , ppv ) ;
if ( FAILED ( hr ) )
site - > Release ( ) ;
return hr ;
}
2014-02-24 11:07:16 +00:00
CMenuToolbarBase : : CMenuToolbarBase ( CMenuBand * menuBand , BOOL usePager ) :
2014-02-12 16:48:36 +00:00
m_hwnd ( NULL ) ,
2014-02-24 11:07:16 +00:00
m_menuBand ( menuBand ) ,
m_hwndToolbar ( NULL ) ,
m_dwMenuFlags ( 0 ) ,
m_hasIdealSize ( FALSE )
2014-02-12 16:48:36 +00:00
{
}
2014-02-20 16:18:49 +00:00
HRESULT CMenuToolbarBase : : IsWindowOwner ( HWND hwnd )
{
2014-02-24 11:07:16 +00:00
return ( m_hwnd & & m_hwnd = = hwnd ) | |
( m_hwndToolbar & & m_hwndToolbar = = hwnd ) ? S_OK : S_FALSE ;
}
void CMenuToolbarBase : : InvalidateDraw ( )
{
InvalidateRect ( m_hwnd , NULL , FALSE ) ;
2014-02-20 16:18:49 +00:00
}
2014-02-12 16:48:36 +00:00
HRESULT CMenuToolbarBase : : ShowWindow ( BOOL fShow )
{
: : ShowWindow ( m_hwnd , fShow ? SW_SHOW : SW_HIDE ) ;
HIMAGELIST ilBig , ilSmall ;
Shell_GetImageLists ( & ilBig , & ilSmall ) ;
if ( m_menuBand - > UseBigIcons ( ) )
{
2014-02-24 11:07:16 +00:00
SendMessageW ( m_hwndToolbar , TB_SETIMAGELIST , 0 , reinterpret_cast < LPARAM > ( ilBig ) ) ;
2014-02-12 16:48:36 +00:00
}
else
{
2014-02-24 11:07:16 +00:00
SendMessageW ( m_hwndToolbar , TB_SETIMAGELIST , 0 , reinterpret_cast < LPARAM > ( ilSmall ) ) ;
2014-02-12 16:48:36 +00:00
}
return S_OK ;
}
HRESULT CMenuToolbarBase : : Close ( )
{
2014-02-24 11:07:16 +00:00
DestroyWindow ( m_hwndToolbar ) ;
if ( m_hwndToolbar ! = m_hwnd )
DestroyWindow ( m_hwnd ) ;
m_hwndToolbar = NULL ;
2014-02-12 16:48:36 +00:00
m_hwnd = NULL ;
return S_OK ;
}
HRESULT CMenuToolbarBase : : CreateToolbar ( HWND hwndParent , DWORD dwFlags )
{
LONG tbStyles = WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN |
2014-02-18 10:26:50 +00:00
TBSTYLE_TOOLTIPS | TBSTYLE_TRANSPARENT | TBSTYLE_REGISTERDROP | TBSTYLE_LIST | TBSTYLE_FLAT | TBSTYLE_CUSTOMERASE |
2014-02-12 16:48:36 +00:00
CCS_NODIVIDER | CCS_NOPARENTALIGN | CCS_NORESIZE | CCS_TOP ;
2014-02-17 11:20:35 +00:00
LONG tbExStyles = TBSTYLE_EX_DOUBLEBUFFER ;
2014-02-12 16:48:36 +00:00
if ( dwFlags & SMINIT_VERTICAL )
{
tbStyles | = CCS_VERT ;
2014-02-18 10:26:50 +00:00
tbExStyles | = TBSTYLE_EX_VERTICAL | WS_EX_TOOLWINDOW ;
2014-02-12 16:48:36 +00:00
}
RECT rc ;
if ( ! : : GetClientRect ( hwndParent , & rc ) | | ( rc . left = = rc . right ) | | ( rc . top = = rc . bottom ) )
{
rc . left = 0 ;
rc . top = 0 ;
rc . right = 1 ;
rc . bottom = 1 ;
}
HWND hwndToolbar = CreateWindowEx (
tbExStyles , TOOLBARCLASSNAMEW , NULL ,
tbStyles , rc . left , rc . top , rc . right - rc . left , rc . bottom - rc . top ,
hwndParent , NULL , _AtlBaseModule . GetModuleInstance ( ) , 0 ) ;
if ( hwndToolbar = = NULL )
return E_FAIL ;
2014-02-24 11:07:16 +00:00
if ( m_usePager )
{
LONG pgStyles = PGS_VERT | WS_CHILD | WS_VISIBLE ;
LONG pgExStyles = 0 ;
HWND hwndPager = CreateWindowEx (
pgExStyles , WC_PAGESCROLLER , NULL ,
pgStyles , rc . left , rc . top , rc . right - rc . left , rc . bottom - rc . top ,
hwndParent , NULL , _AtlBaseModule . GetModuleInstance ( ) , 0 ) ;
2014-02-12 16:48:36 +00:00
2014-02-24 11:07:16 +00:00
: : SetParent ( hwndToolbar , hwndPager ) ;
: : SetParent ( hwndPager , hwndParent ) ;
2014-02-12 16:48:36 +00:00
2014-02-24 11:07:16 +00:00
SendMessage ( hwndPager , PGM_SETCHILD , 0 , reinterpret_cast < LPARAM > ( hwndToolbar ) ) ;
m_hwndToolbar = hwndToolbar ;
m_hwnd = hwndPager ;
}
else
{
: : SetParent ( hwndToolbar , hwndParent ) ;
m_hwndToolbar = hwndToolbar ;
m_hwnd = hwndToolbar ;
}
2014-02-12 16:48:36 +00:00
/* Identify the version of the used Common Controls DLL by sending the size of the TBBUTTON structure */
2014-02-24 11:07:16 +00:00
SendMessageW ( hwndToolbar , TB_BUTTONSTRUCTSIZE , sizeof ( TBBUTTON ) , 0 ) ;
2014-02-12 16:48:36 +00:00
//if (dwFlags & SMINIT_TOPLEVEL)
//{
// /* Hide the placeholders for the button images */
// SendMessageW(m_hwnd, TB_SETIMAGELIST, 0, 0);
//}
//else
2014-02-24 11:07:16 +00:00
int shiml ;
2014-02-12 16:48:36 +00:00
if ( m_menuBand - > UseBigIcons ( ) )
{
2014-02-24 11:07:16 +00:00
shiml = SHIL_LARGE ;
SendMessageW ( hwndToolbar , TB_SETPADDING , 0 , MAKELPARAM ( 0 , 0 ) ) ;
}
else
{
shiml = SHIL_SMALL ;
}
2014-02-23 18:13:43 +00:00
2014-02-24 11:07:16 +00:00
IImageList * piml ;
HRESULT hr = SHGetImageList ( shiml , IID_PPV_ARG ( IImageList , & piml ) ) ;
if ( SUCCEEDED ( hr ) )
{
SendMessageW ( hwndToolbar , TB_SETIMAGELIST , 0 , reinterpret_cast < LPARAM > ( piml ) ) ;
2014-02-12 16:48:36 +00:00
}
else
{
2014-02-24 11:07:16 +00:00
SendMessageW ( hwndToolbar , TB_SETIMAGELIST , 0 , 0 ) ;
}
SetWindowLongPtr ( hwndToolbar , GWLP_USERDATA , reinterpret_cast < LONG_PTR > ( this ) ) ;
m_SubclassOld = ( WNDPROC ) SetWindowLongPtr ( hwndToolbar , GWLP_WNDPROC , reinterpret_cast < LONG_PTR > ( CMenuToolbarBase : : s_SubclassProc ) ) ;
return S_OK ;
}
2014-02-23 18:13:43 +00:00
2014-02-24 11:07:16 +00:00
HRESULT CMenuToolbarBase : : GetIdealSize ( SIZE & size )
{
size . cx = size . cy = 0 ;
if ( m_hwndToolbar & & ! m_hasIdealSize )
{
SendMessageW ( m_hwndToolbar , TB_AUTOSIZE , 0 , 0 ) ;
SendMessageW ( m_hwndToolbar , TB_GETMAXSIZE , 0 , reinterpret_cast < LPARAM > ( & m_idealSize ) ) ;
m_hasIdealSize = TRUE ;
2014-02-12 16:48:36 +00:00
}
2014-02-24 11:07:16 +00:00
size = m_idealSize ;
2014-02-17 15:38:55 +00:00
2014-02-12 16:48:36 +00:00
return S_OK ;
}
2014-02-24 11:07:16 +00:00
HRESULT CMenuToolbarBase : : SetPosSize ( int x , int y , int cx , int cy )
{
if ( m_hwnd ! = m_hwndToolbar )
{
SetWindowPos ( m_hwndToolbar , NULL , x , y , cx , m_idealSize . cy , 0 ) ;
}
SetWindowPos ( m_hwnd , NULL , x , y , cx , cy , 0 ) ;
DWORD btnSize = SendMessage ( m_hwndToolbar , TB_GETBUTTONSIZE , 0 , 0 ) ;
SendMessage ( m_hwndToolbar , TB_SETBUTTONSIZE , 0 , MAKELPARAM ( cx , HIWORD ( btnSize ) ) ) ;
return S_OK ;
}
2014-02-12 16:48:36 +00:00
HRESULT CMenuToolbarBase : : GetWindow ( HWND * phwnd )
{
if ( ! phwnd )
return E_FAIL ;
* phwnd = m_hwnd ;
return S_OK ;
}
2014-02-17 15:38:55 +00:00
LRESULT CALLBACK CMenuToolbarBase : : s_SubclassProc ( HWND hWnd , UINT uMsg , WPARAM wParam , LPARAM lParam )
{
2014-02-18 10:26:50 +00:00
CMenuToolbarBase * pthis = reinterpret_cast < CMenuToolbarBase * > ( GetWindowLongPtr ( hWnd , GWLP_USERDATA ) ) ;
2014-02-17 15:38:55 +00:00
return pthis - > SubclassProc ( hWnd , uMsg , wParam , lParam ) ;
}
LRESULT CMenuToolbarBase : : SubclassProc ( HWND hWnd , UINT uMsg , WPARAM wParam , LPARAM lParam )
{
switch ( uMsg )
{
case WM_TIMER :
if ( wParam = = TIMERID_HOTTRACK )
{
KillTimer ( hWnd , TIMERID_HOTTRACK ) ;
2014-02-23 15:02:02 +00:00
2014-02-24 11:07:16 +00:00
m_menuBand - > _OnPopupSubMenu ( - 1 , NULL , NULL , NULL ) ;
2014-02-23 15:02:02 +00:00
if ( HasSubMenu ( m_hotItem ) = = S_OK )
{
PopupItem ( m_hotItem ) ;
}
2014-02-17 15:38:55 +00:00
}
}
return m_SubclassOld ( hWnd , uMsg , wParam , lParam ) ;
}
HRESULT CMenuToolbarBase : : OnHotItemChange ( const NMTBHOTITEM * hot )
{
if ( hot - > dwFlags & HICF_LEAVING )
{
2014-02-24 11:07:16 +00:00
KillTimer ( m_hwndToolbar , TIMERID_HOTTRACK ) ;
2014-02-20 12:12:42 +00:00
m_hotItem = - 1 ;
2014-02-20 16:18:49 +00:00
m_menuBand - > _OnHotItemChanged ( NULL , - 1 ) ;
m_menuBand - > _MenuItemHotTrack ( MPOS_CHILDTRACKING ) ;
2014-02-17 15:38:55 +00:00
}
else if ( m_hotItem ! = hot - > idNew )
{
2014-02-23 15:02:02 +00:00
DWORD elapsed = 0 ;
SystemParametersInfo ( SPI_GETMENUSHOWDELAY , 0 , & elapsed , 0 ) ;
2014-02-24 11:07:16 +00:00
SetTimer ( m_hwndToolbar , TIMERID_HOTTRACK , elapsed , NULL ) ;
2014-02-17 15:38:55 +00:00
2014-02-20 12:12:42 +00:00
m_hotItem = hot - > idNew ;
2014-02-20 16:18:49 +00:00
m_menuBand - > _OnHotItemChanged ( this , m_hotItem ) ;
m_menuBand - > _MenuItemHotTrack ( MPOS_CHILDTRACKING ) ;
2014-02-20 12:12:42 +00:00
}
2014-02-17 15:38:55 +00:00
return S_OK ;
}
2014-02-24 11:07:16 +00:00
HRESULT CMenuToolbarBase : : PopupSubMenu ( UINT itemId , UINT index , IShellMenu * childShellMenu )
2014-02-17 17:16:55 +00:00
{
2014-02-17 18:38:31 +00:00
IBandSite * pBandSite ;
IDeskBar * pDeskBar ;
2014-02-19 00:20:45 +00:00
HRESULT hr = 0 ;
RECT rc = { 0 } ;
2014-02-17 18:38:31 +00:00
2014-02-24 11:07:16 +00:00
if ( ! SendMessage ( m_hwndToolbar , TB_GETITEMRECT , index , reinterpret_cast < LPARAM > ( & rc ) ) )
2014-02-17 17:16:55 +00:00
return E_FAIL ;
POINT a = { rc . left , rc . top } ;
POINT b = { rc . right , rc . bottom } ;
2014-02-24 11:07:16 +00:00
ClientToScreen ( m_hwndToolbar , & a ) ;
ClientToScreen ( m_hwndToolbar , & b ) ;
2014-02-17 17:16:55 +00:00
2014-02-23 00:15:27 +00:00
POINTL pt = { b . x , a . y } ;
2014-02-17 17:16:55 +00:00
RECTL rcl = { a . x , a . y , b . x , b . y } ; // maybe-TODO: fetch client area of deskbar?
2014-02-19 00:20:45 +00:00
# if USE_SYSTEM_MENUSITE
2014-02-17 17:16:55 +00:00
hr = CoCreateInstance ( CLSID_MenuBandSite ,
NULL ,
CLSCTX_INPROC_SERVER ,
IID_PPV_ARG ( IBandSite , & pBandSite ) ) ;
# else
hr = CMenuSite_Constructor ( IID_PPV_ARG ( IBandSite , & pBandSite ) ) ;
# endif
if ( FAILED ( hr ) )
return hr ;
2014-02-19 12:19:50 +00:00
# if WRAP_MENUSITE
hr = CMenuSite_Wrapper ( pBandSite , IID_PPV_ARG ( IBandSite , & pBandSite ) ) ;
if ( FAILED ( hr ) )
return hr ;
# endif
2014-02-17 17:16:55 +00:00
2014-02-19 00:20:45 +00:00
# if USE_SYSTEM_MENUDESKBAR
2014-02-17 17:16:55 +00:00
hr = CoCreateInstance ( CLSID_MenuDeskBar ,
NULL ,
CLSCTX_INPROC_SERVER ,
IID_PPV_ARG ( IDeskBar , & pDeskBar ) ) ;
# else
hr = CMenuDeskBar_Constructor ( IID_PPV_ARG ( IDeskBar , & pDeskBar ) ) ;
# endif
if ( FAILED ( hr ) )
return hr ;
2014-02-19 12:19:50 +00:00
# if WRAP_MENUDESKBAR
hr = CMenuDeskBar_Wrapper ( pDeskBar , IID_PPV_ARG ( IDeskBar , & pDeskBar ) ) ;
if ( FAILED ( hr ) )
return hr ;
# endif
2014-02-17 17:16:55 +00:00
hr = pDeskBar - > SetClient ( pBandSite ) ;
if ( FAILED ( hr ) )
return hr ;
hr = pBandSite - > AddBand ( childShellMenu ) ;
if ( FAILED ( hr ) )
return hr ;
CComPtr < IMenuPopup > popup ;
hr = pDeskBar - > QueryInterface ( IID_PPV_ARG ( IMenuPopup , & popup ) ) ;
if ( FAILED ( hr ) )
return hr ;
2014-02-24 11:07:16 +00:00
m_menuBand - > _OnPopupSubMenu ( itemId , popup , & pt , & rcl ) ;
2014-02-20 16:18:49 +00:00
2014-02-17 17:16:55 +00:00
return S_OK ;
}
2014-02-18 18:18:08 +00:00
HRESULT CMenuToolbarBase : : PopupSubMenu ( UINT index , HMENU menu )
{
2014-02-19 00:20:45 +00:00
RECT rc = { 0 } ;
2014-02-24 11:07:16 +00:00
if ( ! SendMessage ( m_hwndToolbar , TB_GETITEMRECT , index , reinterpret_cast < LPARAM > ( & rc ) ) )
2014-02-18 18:18:08 +00:00
return E_FAIL ;
POINT b = { rc . right , rc . bottom } ;
2014-02-24 11:07:16 +00:00
ClientToScreen ( m_hwndToolbar , & b ) ;
2014-02-18 18:18:08 +00:00
HMENU popup = GetSubMenu ( menu , index ) ;
2014-02-20 16:18:49 +00:00
m_menuBand - > _TrackSubMenuUsingTrackPopupMenu ( popup , b . x , b . y ) ;
2014-02-18 18:18:08 +00:00
return S_OK ;
}
2014-02-18 10:26:50 +00:00
HRESULT CMenuToolbarBase : : DoContextMenu ( IContextMenu * contextMenu )
{
HRESULT hr ;
HMENU hPopup = CreatePopupMenu ( ) ;
if ( hPopup = = NULL )
return E_FAIL ;
hr = contextMenu - > QueryContextMenu ( hPopup , 0 , 0 , UINT_MAX , CMF_NORMAL ) ;
if ( FAILED ( hr ) )
{
DestroyMenu ( hPopup ) ;
return hr ;
}
DWORD dwPos = GetMessagePos ( ) ;
UINT uCommand = : : TrackPopupMenu ( hPopup , TPM_RETURNCMD , GET_X_LPARAM ( dwPos ) , GET_Y_LPARAM ( dwPos ) , 0 , m_hwnd , NULL ) ;
if ( uCommand = = 0 )
return S_FALSE ;
CMINVOKECOMMANDINFO cmi = { 0 } ;
cmi . cbSize = sizeof ( cmi ) ;
2014-02-24 11:07:16 +00:00
cmi . lpVerb = reinterpret_cast < LPCSTR > ( uCommand ) ;
2014-02-18 10:26:50 +00:00
cmi . hwnd = m_hwnd ;
hr = contextMenu - > InvokeCommand ( & cmi ) ;
DestroyMenu ( hPopup ) ;
return hr ;
}
2014-02-18 13:55:57 +00:00
HRESULT CMenuToolbarBase : : OnCommand ( WPARAM wParam , LPARAM lParam , LRESULT * theResult )
{
2014-02-20 16:18:49 +00:00
theResult = 0 ;
2014-02-24 11:07:16 +00:00
if ( HasSubMenu ( wParam ) = = S_OK )
{
KillTimer ( m_hwndToolbar , TIMERID_HOTTRACK ) ;
PopupItem ( wParam ) ;
return S_FALSE ;
}
2014-02-20 16:18:49 +00:00
return m_menuBand - > _MenuItemHotTrack ( MPOS_EXECUTE ) ;
2014-02-18 13:55:57 +00:00
}
2014-02-20 12:12:42 +00:00
2014-02-20 16:18:49 +00:00
HRESULT CMenuToolbarBase : : ChangeHotItem ( DWORD dwSelectType )
2014-02-20 12:12:42 +00:00
{
2014-02-23 15:02:02 +00:00
int prev = m_hotItem ;
2014-02-20 12:12:42 +00:00
int index = - 1 ;
if ( dwSelectType ! = 0xFFFFFFFF )
{
2014-02-24 11:07:16 +00:00
int count = SendMessage ( m_hwndToolbar , TB_BUTTONCOUNT , 0 , 0 ) ;
2014-02-20 12:12:42 +00:00
if ( m_hotItem > = 0 )
{
TBBUTTONINFO info = { 0 } ;
info . cbSize = sizeof ( TBBUTTONINFO ) ;
info . dwMask = 0 ;
2014-02-24 11:07:16 +00:00
index = SendMessage ( m_hwndToolbar , TB_GETBUTTONINFO , m_hotItem , reinterpret_cast < LPARAM > ( & info ) ) ;
2014-02-20 12:12:42 +00:00
}
if ( dwSelectType = = VK_HOME )
{
index = 0 ;
dwSelectType = VK_DOWN ;
}
else if ( dwSelectType = = VK_END )
{
index = count - 1 ;
dwSelectType = VK_UP ;
}
else if ( index < 0 )
{
if ( dwSelectType = = VK_UP )
{
index = count - 1 ;
}
else if ( dwSelectType = = VK_DOWN )
{
index = 0 ;
}
}
else
{
if ( dwSelectType = = VK_UP )
{
index - - ;
}
else if ( dwSelectType = = VK_DOWN )
{
index + + ;
}
}
TBBUTTON btn = { 0 } ;
while ( index > = 0 & & index < count )
{
2014-02-24 11:07:16 +00:00
DWORD res = SendMessage ( m_hwndToolbar , TB_GETBUTTON , index , reinterpret_cast < LPARAM > ( & btn ) ) ;
2014-02-20 12:12:42 +00:00
if ( ! res )
return E_FAIL ;
if ( btn . dwData )
{
m_hotItem = btn . idCommand ;
2014-02-23 15:02:02 +00:00
if ( prev ! = m_hotItem )
2014-02-20 12:12:42 +00:00
{
2014-02-24 11:07:16 +00:00
SendMessage ( m_hwndToolbar , TB_SETHOTITEM , index , 0 ) ;
2014-02-20 16:18:49 +00:00
return m_menuBand - > _OnHotItemChanged ( this , m_hotItem ) ;
2014-02-20 12:12:42 +00:00
}
return S_OK ;
}
if ( dwSelectType = = VK_UP )
{
index - - ;
}
else if ( dwSelectType = = VK_DOWN )
{
index + + ;
}
}
}
m_hotItem = - 1 ;
2014-02-23 15:02:02 +00:00
if ( prev ! = m_hotItem )
2014-02-20 12:12:42 +00:00
{
2014-02-24 11:07:16 +00:00
SendMessage ( m_hwndToolbar , TB_SETHOTITEM , - 1 , 0 ) ;
2014-02-20 16:18:49 +00:00
m_menuBand - > _OnHotItemChanged ( NULL , - 1 ) ;
2014-02-20 12:12:42 +00:00
}
return S_FALSE ;
}
2014-02-12 16:48:36 +00:00
BOOL
AllocAndGetMenuString ( HMENU hMenu , UINT ItemIDByPosition , WCHAR * * String )
{
int Length ;
Length = GetMenuStringW ( hMenu , ItemIDByPosition , NULL , 0 , MF_BYPOSITION ) ;
if ( ! Length )
return FALSE ;
/* Also allocate space for the terminating NULL character */
+ + Length ;
* String = ( PWSTR ) HeapAlloc ( GetProcessHeap ( ) , 0 , Length * sizeof ( WCHAR ) ) ;
GetMenuStringW ( hMenu , ItemIDByPosition , * String , Length , MF_BYPOSITION ) ;
return TRUE ;
}
CMenuStaticToolbar : : CMenuStaticToolbar ( CMenuBand * menuBand ) :
2014-02-24 11:07:16 +00:00
CMenuToolbarBase ( menuBand , FALSE ) ,
2014-02-12 16:48:36 +00:00
m_hmenu ( NULL )
{
}
HRESULT CMenuStaticToolbar : : GetMenu (
HMENU * phmenu ,
HWND * phwnd ,
DWORD * pdwFlags )
{
* phmenu = m_hmenu ;
* phwnd = NULL ;
* pdwFlags = m_dwMenuFlags ;
return S_OK ;
}
HRESULT CMenuStaticToolbar : : SetMenu (
HMENU hmenu ,
HWND hwnd ,
DWORD dwFlags )
{
m_hmenu = hmenu ;
m_dwMenuFlags = dwFlags ;
return S_OK ;
}
HRESULT CMenuStaticToolbar : : FillToolbar ( )
{
int i ;
int ic = GetMenuItemCount ( m_hmenu ) ;
for ( i = 0 ; i < ic ; i + + )
{
MENUITEMINFOW info ;
TBBUTTON tbb = { 0 } ;
2014-02-16 21:53:21 +00:00
PWSTR MenuString = NULL ;
2014-02-12 16:48:36 +00:00
tbb . fsState = TBSTATE_ENABLED ;
2014-02-16 12:48:41 +00:00
tbb . fsStyle = 0 ;
2014-02-12 16:48:36 +00:00
info . cbSize = sizeof ( info ) ;
info . fMask = MIIM_FTYPE | MIIM_ID ;
GetMenuItemInfoW ( m_hmenu , i , TRUE , & info ) ;
if ( info . fType = = MFT_STRING )
{
if ( ! AllocAndGetMenuString ( m_hmenu , i , & MenuString ) )
return E_OUTOFMEMORY ;
2014-02-17 11:20:35 +00:00
if ( : : GetSubMenu ( m_hmenu , i ) ! = NULL )
2014-02-18 10:26:50 +00:00
tbb . fsStyle | = BTNS_DROPDOWN ;
2014-02-17 15:38:55 +00:00
tbb . iString = ( INT_PTR ) MenuString ;
2014-02-16 21:53:21 +00:00
tbb . idCommand = info . wID ;
2014-02-17 16:41:10 +00:00
2014-02-18 18:18:08 +00:00
SMINFO * sminfo = new SMINFO ( ) ;
sminfo - > dwMask = SMIM_ICON | SMIM_FLAGS ;
2014-02-20 16:18:49 +00:00
if ( SUCCEEDED ( m_menuBand - > _CallCBWithItemId ( info . wID , SMC_GETINFO , 0 , reinterpret_cast < LPARAM > ( sminfo ) ) ) )
2014-02-16 21:53:21 +00:00
{
2014-02-18 18:18:08 +00:00
tbb . iBitmap = sminfo - > iIcon ;
tbb . dwData = reinterpret_cast < DWORD_PTR > ( sminfo ) ;
// FIXME: remove before deleting the toolbar or it will leak
2014-02-16 21:53:21 +00:00
}
2014-02-12 16:48:36 +00:00
}
else
{
tbb . fsStyle | = BTNS_SEP ;
}
2014-02-24 11:07:16 +00:00
SendMessageW ( m_hwndToolbar , TB_ADDBUTTONS , 1 , reinterpret_cast < LPARAM > ( & tbb ) ) ;
2014-02-16 21:53:21 +00:00
if ( MenuString )
HeapFree ( GetProcessHeap ( ) , 0 , MenuString ) ;
2014-02-12 16:48:36 +00:00
}
return S_OK ;
}
2014-02-17 18:38:31 +00:00
HRESULT CMenuStaticToolbar : : OnContextMenu ( NMMOUSE * rclick )
{
CComPtr < IContextMenu > contextMenu ;
2014-02-20 16:18:49 +00:00
HRESULT hr = m_menuBand - > _CallCBWithItemId ( rclick - > dwItemSpec , SMC_GETOBJECT , reinterpret_cast < WPARAM > ( & IID_IContextMenu ) , reinterpret_cast < LPARAM > ( & contextMenu ) ) ;
2014-02-17 18:38:31 +00:00
if ( hr ! = S_OK )
return hr ;
2014-02-18 10:26:50 +00:00
return DoContextMenu ( contextMenu ) ;
2014-02-17 18:38:31 +00:00
}
2014-02-17 15:38:55 +00:00
HRESULT CMenuStaticToolbar : : OnCommand ( WPARAM wParam , LPARAM lParam , LRESULT * theResult )
{
2014-02-21 10:00:00 +00:00
HRESULT hr ;
hr = CMenuToolbarBase : : OnCommand ( wParam , lParam , theResult ) ;
2014-02-18 13:55:57 +00:00
if ( FAILED ( hr ) )
return hr ;
2014-02-24 11:07:16 +00:00
// in case the clicked item has a submenu, we do not need to execute the item
if ( hr = = S_FALSE )
return hr ;
2014-02-21 10:00:00 +00:00
return m_menuBand - > _CallCBWithItemId ( wParam , SMC_EXEC , 0 , 0 ) ;
2014-02-17 15:38:55 +00:00
}
HRESULT CMenuStaticToolbar : : PopupItem ( UINT uItem )
{
2014-02-17 18:38:31 +00:00
TBBUTTONINFO info = { 0 } ;
info . cbSize = sizeof ( TBBUTTONINFO ) ;
info . dwMask = 0 ;
2014-02-24 11:07:16 +00:00
int index = SendMessage ( m_hwndToolbar , TB_GETBUTTONINFO , uItem , reinterpret_cast < LPARAM > ( & info ) ) ;
2014-02-17 18:38:31 +00:00
if ( index < 0 )
return E_FAIL ;
2014-02-20 16:18:49 +00:00
2014-02-18 18:18:08 +00:00
TBBUTTON btn = { 0 } ;
2014-02-24 11:07:16 +00:00
SendMessage ( m_hwndToolbar , TB_GETBUTTON , index , reinterpret_cast < LPARAM > ( & btn ) ) ;
2014-02-17 18:38:31 +00:00
2014-02-18 18:18:08 +00:00
SMINFO * nfo = reinterpret_cast < SMINFO * > ( btn . dwData ) ;
2014-02-19 00:20:45 +00:00
if ( ! nfo )
return E_FAIL ;
2014-02-18 18:18:08 +00:00
if ( nfo - > dwFlags & SMIF_TRACKPOPUP )
{
return PopupSubMenu ( index , m_hmenu ) ;
}
else
{
CComPtr < IShellMenu > shellMenu ;
2014-02-20 16:18:49 +00:00
HRESULT hr = m_menuBand - > _CallCBWithItemId ( uItem , SMC_GETOBJECT , reinterpret_cast < WPARAM > ( & IID_IShellMenu ) , reinterpret_cast < LPARAM > ( & shellMenu ) ) ;
2014-02-18 18:18:08 +00:00
if ( FAILED ( hr ) )
return hr ;
2014-02-24 11:07:16 +00:00
return PopupSubMenu ( uItem , index , shellMenu ) ;
2014-02-18 18:18:08 +00:00
}
2014-02-17 15:38:55 +00:00
}
HRESULT CMenuStaticToolbar : : HasSubMenu ( UINT uItem )
{
TBBUTTONINFO info = { 0 } ;
info . cbSize = sizeof ( TBBUTTONINFO ) ;
info . dwMask = 0 ;
2014-02-24 11:07:16 +00:00
int index = SendMessage ( m_hwndToolbar , TB_GETBUTTONINFO , uItem , reinterpret_cast < LPARAM > ( & info ) ) ;
2014-02-17 15:38:55 +00:00
if ( index < 0 )
return E_FAIL ;
return : : GetSubMenu ( m_hmenu , index ) ? S_OK : S_FALSE ;
}
2014-02-12 16:48:36 +00:00
CMenuSFToolbar : : CMenuSFToolbar ( CMenuBand * menuBand ) :
2014-02-24 11:07:16 +00:00
CMenuToolbarBase ( menuBand , TRUE ) ,
2014-02-12 16:48:36 +00:00
m_shellFolder ( NULL )
{
}
CMenuSFToolbar : : ~ CMenuSFToolbar ( )
{
}
HRESULT CMenuSFToolbar : : FillToolbar ( )
{
HRESULT hr ;
int i = 0 ;
PWSTR MenuString ;
IEnumIDList * eidl ;
2014-02-24 11:07:16 +00:00
m_shellFolder - > EnumObjects ( m_hwndToolbar , SHCONTF_FOLDERS | SHCONTF_NONFOLDERS , & eidl ) ;
2014-02-12 16:48:36 +00:00
2014-02-18 18:18:08 +00:00
LPITEMIDLIST item = static_cast < LPITEMIDLIST > ( CoTaskMemAlloc ( sizeof ( ITEMIDLIST ) ) ) ;
2014-02-12 16:48:36 +00:00
ULONG fetched ;
while ( ( hr = eidl - > Next ( 1 , & item , & fetched ) ) = = S_OK )
{
INT index = 0 ;
INT indexOpen = 0 ;
2014-02-21 10:00:00 +00:00
TBBUTTON tbb = { 0 } ;
tbb . fsState = TBSTATE_ENABLED ;
tbb . fsStyle = 0 ;
2014-02-17 18:38:31 +00:00
CComPtr < IShellItem > psi ;
2014-02-23 16:44:54 +00:00
hr = SHCreateShellItem ( NULL , m_shellFolder , item , & psi ) ;
if ( FAILED ( hr ) )
return hr ;
2014-02-12 16:48:36 +00:00
hr = psi - > GetDisplayName ( SIGDN_NORMALDISPLAY , & MenuString ) ;
if ( FAILED ( hr ) )
return hr ;
index = SHMapPIDLToSystemImageListIndex ( m_shellFolder , item , & indexOpen ) ;
2014-02-17 18:38:31 +00:00
SFGAOF attrs ;
hr = psi - > GetAttributes ( SFGAO_FOLDER , & attrs ) ;
if ( attrs ! = 0 )
{
2014-02-18 10:26:50 +00:00
tbb . fsStyle | = BTNS_DROPDOWN ;
2014-02-17 18:38:31 +00:00
}
2014-02-20 12:12:42 +00:00
tbb . idCommand = + + i ;
2014-02-12 16:48:36 +00:00
tbb . iString = ( INT_PTR ) MenuString ;
tbb . iBitmap = index ;
2014-02-18 18:18:08 +00:00
tbb . dwData = reinterpret_cast < DWORD_PTR > ( ILClone ( item ) ) ;
// FIXME: remove before deleting the toolbar or it will leak
2014-02-12 16:48:36 +00:00
2014-02-24 11:07:16 +00:00
SendMessageW ( m_hwndToolbar , TB_ADDBUTTONS , 1 , reinterpret_cast < LPARAM > ( & tbb ) ) ;
2014-02-12 16:48:36 +00:00
HeapFree ( GetProcessHeap ( ) , 0 , MenuString ) ;
}
CoTaskMemFree ( item ) ;
2014-02-22 22:59:28 +00:00
// If no items were added, show the "empty" placeholder
if ( i = = 0 )
{
TBBUTTON tbb = { 0 } ;
2014-02-23 16:44:54 +00:00
PCWSTR MenuString = L " (Empty) " ;
2014-02-22 22:59:28 +00:00
tbb . fsState = 0 /*TBSTATE_DISABLED*/ ;
tbb . fsStyle = 0 ;
tbb . iString = ( INT_PTR ) MenuString ;
tbb . iBitmap = - 1 ;
2014-02-24 11:07:16 +00:00
SendMessageW ( m_hwndToolbar , TB_ADDBUTTONS , 1 , reinterpret_cast < LPARAM > ( & tbb ) ) ;
2014-02-22 22:59:28 +00:00
return S_OK ;
}
2014-02-12 16:48:36 +00:00
return hr ;
}
HRESULT CMenuSFToolbar : : SetShellFolder ( IShellFolder * psf , LPCITEMIDLIST pidlFolder , HKEY hKey , DWORD dwFlags )
{
m_shellFolder = psf ;
m_idList = pidlFolder ;
m_hKey = hKey ;
m_dwMenuFlags = dwFlags ;
return S_OK ;
}
HRESULT CMenuSFToolbar : : GetShellFolder ( DWORD * pdwFlags , LPITEMIDLIST * ppidl , REFIID riid , void * * ppv )
{
HRESULT hr ;
hr = m_shellFolder - > QueryInterface ( riid , ppv ) ;
if ( FAILED ( hr ) )
return hr ;
if ( pdwFlags )
* pdwFlags = m_dwMenuFlags ;
if ( ppidl )
{
LPITEMIDLIST pidl = NULL ;
if ( m_idList )
{
pidl = ILClone ( m_idList ) ;
if ( ! pidl )
{
( * ( IUnknown * * ) ppv ) - > Release ( ) ;
return E_FAIL ;
}
}
* ppidl = pidl ;
}
return hr ;
}
2014-02-17 18:38:31 +00:00
LPITEMIDLIST CMenuSFToolbar : : GetPidlFromId ( UINT uItem , INT * pIndex )
2014-02-17 11:20:35 +00:00
{
2014-02-17 18:38:31 +00:00
TBBUTTONINFO info = { 0 } ;
info . cbSize = sizeof ( TBBUTTONINFO ) ;
info . dwMask = 0 ;
2014-02-24 11:07:16 +00:00
int index = SendMessage ( m_hwndToolbar , TB_GETBUTTONINFO , uItem , reinterpret_cast < LPARAM > ( & info ) ) ;
2014-02-17 18:38:31 +00:00
if ( index < 0 )
return NULL ;
if ( pIndex )
* pIndex = index ;
TBBUTTON btn = { 0 } ;
2014-02-24 11:07:16 +00:00
if ( ! SendMessage ( m_hwndToolbar , TB_GETBUTTON , index , reinterpret_cast < LPARAM > ( & btn ) ) )
2014-02-17 18:38:31 +00:00
return NULL ;
2014-02-18 18:18:08 +00:00
return reinterpret_cast < LPITEMIDLIST > ( btn . dwData ) ;
2014-02-17 18:38:31 +00:00
}
HRESULT CMenuSFToolbar : : OnContextMenu ( NMMOUSE * rclick )
{
HRESULT hr ;
CComPtr < IContextMenu > contextMenu ;
2014-02-18 10:26:50 +00:00
LPCITEMIDLIST pidl = reinterpret_cast < LPCITEMIDLIST > ( rclick - > dwItemData ) ;
2014-02-17 18:38:31 +00:00
2014-02-24 11:07:16 +00:00
hr = m_shellFolder - > GetUIObjectOf ( m_hwndToolbar , 1 , & pidl , IID_IContextMenu , NULL , reinterpret_cast < VOID * * > ( & contextMenu ) ) ;
2014-02-17 18:38:31 +00:00
if ( hr ! = S_OK )
return hr ;
2014-02-18 10:26:50 +00:00
return DoContextMenu ( contextMenu ) ;
2014-02-17 11:20:35 +00:00
}
2014-02-17 18:38:31 +00:00
HRESULT CMenuSFToolbar : : OnCommand ( WPARAM wParam , LPARAM lParam , LRESULT * theResult )
{
2014-02-21 10:00:00 +00:00
HRESULT hr ;
hr = CMenuToolbarBase : : OnCommand ( wParam , lParam , theResult ) ;
if ( FAILED ( hr ) )
return hr ;
2014-02-20 16:18:49 +00:00
2014-02-24 11:07:16 +00:00
// in case the clicked item has a submenu, we do not need to execute the item
if ( hr = = S_FALSE )
return hr ;
2014-02-21 10:00:00 +00:00
return m_menuBand - > _CallCBWithItemPidl ( GetPidlFromId ( wParam ) , SMC_SFEXEC , 0 , 0 ) ;
2014-02-17 18:38:31 +00:00
}
2014-02-17 15:38:55 +00:00
HRESULT CMenuSFToolbar : : PopupItem ( UINT uItem )
{
2014-02-18 11:05:20 +00:00
HRESULT hr ;
UINT uId ;
UINT uIdAncestor ;
DWORD flags ;
2014-02-18 10:26:50 +00:00
int index ;
2014-02-18 11:05:20 +00:00
CComPtr < IShellMenuCallback > psmc ;
2014-02-17 18:38:31 +00:00
CComPtr < IShellMenu > shellMenu ;
2014-02-20 16:18:49 +00:00
2014-02-18 11:05:20 +00:00
LPITEMIDLIST pidl = GetPidlFromId ( uItem , & index ) ;
if ( ! pidl )
return E_FAIL ;
2014-02-19 00:20:45 +00:00
# if USE_SYSTEM_MENUBAND
2014-02-18 11:05:20 +00:00
hr = CoCreateInstance ( CLSID_MenuBand ,
NULL ,
CLSCTX_INPROC_SERVER ,
2014-02-19 00:20:45 +00:00
IID_PPV_ARG ( IShellMenu , & shellMenu ) ) ;
2014-02-18 11:05:20 +00:00
# else
hr = CMenuBand_Constructor ( IID_PPV_ARG ( IShellMenu , & shellMenu ) ) ;
# endif
if ( FAILED ( hr ) )
return hr ;
2014-02-19 12:19:50 +00:00
# if WRAP_MENUBAND
hr = CMenuBand_Wrapper ( shellMenu , IID_PPV_ARG ( IShellMenu , & shellMenu ) ) ;
if ( FAILED ( hr ) )
return hr ;
# endif
2014-02-18 11:05:20 +00:00
m_menuBand - > GetMenuInfo ( & psmc , & uId , & uIdAncestor , & flags ) ;
2014-02-24 11:07:16 +00:00
// FIXME: not sure what to use as uId/uIdAncestor here
2014-02-18 11:05:20 +00:00
hr = shellMenu - > Initialize ( psmc , 0 , uId , SMINIT_VERTICAL ) ;
if ( FAILED ( hr ) )
return hr ;
CComPtr < IShellFolder > childFolder ;
hr = m_shellFolder - > BindToObject ( pidl , NULL , IID_PPV_ARG ( IShellFolder , & childFolder ) ) ;
if ( FAILED ( hr ) )
return hr ;
hr = shellMenu - > SetShellFolder ( childFolder , NULL , NULL , 0 ) ;
2014-02-17 18:38:31 +00:00
if ( FAILED ( hr ) )
return hr ;
2014-02-24 11:07:16 +00:00
return PopupSubMenu ( uItem , index , shellMenu ) ;
2014-02-17 15:38:55 +00:00
}
HRESULT CMenuSFToolbar : : HasSubMenu ( UINT uItem )
{
2014-02-17 18:38:31 +00:00
HRESULT hr ;
CComPtr < IShellItem > psi ;
2014-02-23 16:44:54 +00:00
hr = SHCreateShellItem ( NULL , m_shellFolder , GetPidlFromId ( uItem ) , & psi ) ;
if ( FAILED ( hr ) )
return S_FALSE ;
2014-02-17 18:38:31 +00:00
SFGAOF attrs ;
hr = psi - > GetAttributes ( SFGAO_FOLDER , & attrs ) ;
2014-02-19 00:20:45 +00:00
if ( FAILED ( hr ) )
return hr ;
2014-02-17 18:38:31 +00:00
return ( attrs ! = 0 ) ? S_OK : S_FALSE ;
2014-02-17 15:38:55 +00:00
}
2014-02-12 16:48:36 +00:00
CMenuBand : : CMenuBand ( ) :
m_staticToolbar ( NULL ) ,
m_SFToolbar ( NULL ) ,
2014-02-23 16:44:54 +00:00
m_site ( NULL ) ,
m_psmc ( NULL ) ,
m_subMenuChild ( NULL ) ,
2014-02-20 12:12:42 +00:00
m_useBigIcons ( FALSE ) ,
m_hotBar ( NULL ) ,
2014-02-24 11:07:16 +00:00
m_hotItem ( - 1 ) ,
m_popupItem ( - 1 )
2014-02-12 16:48:36 +00:00
{
2014-02-19 20:35:50 +00:00
m_focusManager = CMenuFocusManager : : AcquireManager ( ) ;
2014-02-24 11:07:16 +00:00
m_marlett = CreateFont (
0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , DEFAULT_CHARSET ,
OUT_DEFAULT_PRECIS , CLIP_DEFAULT_PRECIS ,
DEFAULT_QUALITY , FF_DONTCARE , L " Marlett " ) ;
2014-02-12 16:48:36 +00:00
}
CMenuBand : : ~ CMenuBand ( )
{
2014-02-19 20:35:50 +00:00
CMenuFocusManager : : ReleaseManager ( m_focusManager ) ;
2014-02-12 16:48:36 +00:00
if ( m_staticToolbar )
delete m_staticToolbar ;
if ( m_SFToolbar )
delete m_SFToolbar ;
2014-02-24 11:07:16 +00:00
DeleteObject ( m_marlett ) ;
2014-02-12 16:48:36 +00:00
}
HRESULT STDMETHODCALLTYPE CMenuBand : : Initialize (
IShellMenuCallback * psmc ,
UINT uId ,
UINT uIdAncestor ,
DWORD dwFlags )
{
2014-02-21 10:00:00 +00:00
if ( m_psmc ! = psmc )
m_psmc = psmc ;
2014-02-12 16:48:36 +00:00
m_uId = uId ;
m_uIdAncestor = uIdAncestor ;
m_dwFlags = dwFlags ;
if ( m_psmc )
{
2014-02-18 18:18:08 +00:00
_CallCB ( SMC_CREATE , 0 , reinterpret_cast < LPARAM > ( & m_UserData ) ) ;
2014-02-12 16:48:36 +00:00
}
return S_OK ;
}
HRESULT STDMETHODCALLTYPE CMenuBand : : GetMenuInfo (
IShellMenuCallback * * ppsmc ,
UINT * puId ,
UINT * puIdAncestor ,
DWORD * pdwFlags )
{
if ( ! pdwFlags ) // maybe?
return E_INVALIDARG ;
if ( ppsmc )
* ppsmc = m_psmc ;
if ( puId )
* puId = m_uId ;
if ( puIdAncestor )
* puIdAncestor = m_uIdAncestor ;
* pdwFlags = m_dwFlags ;
return S_OK ;
}
HRESULT STDMETHODCALLTYPE CMenuBand : : SetMenu (
HMENU hmenu ,
HWND hwnd ,
DWORD dwFlags )
{
if ( m_staticToolbar = = NULL )
{
m_staticToolbar = new CMenuStaticToolbar ( this ) ;
}
m_hmenu = hmenu ;
2014-02-18 18:18:08 +00:00
m_menuOwner ;
2014-02-12 16:48:36 +00:00
2014-02-19 12:19:50 +00:00
HRESULT hr = m_staticToolbar - > SetMenu ( hmenu , hwnd , dwFlags ) ;
if ( FAILED ( hr ) )
return hr ;
2014-02-12 16:48:36 +00:00
if ( m_site )
{
HWND hwndParent ;
2014-02-19 12:19:50 +00:00
hr = m_site - > GetWindow ( & hwndParent ) ;
if ( FAILED ( hr ) )
return hr ;
2014-02-12 16:48:36 +00:00
2014-02-19 12:19:50 +00:00
hr = m_staticToolbar - > CreateToolbar ( hwndParent , m_dwFlags ) ;
if ( FAILED ( hr ) )
return hr ;
2014-02-12 16:48:36 +00:00
2014-02-19 12:19:50 +00:00
hr = m_staticToolbar - > FillToolbar ( ) ;
2014-02-12 16:48:36 +00:00
}
2014-02-19 12:19:50 +00:00
return hr ;
2014-02-12 16:48:36 +00:00
}
HRESULT STDMETHODCALLTYPE CMenuBand : : GetMenu (
HMENU * phmenu ,
HWND * phwnd ,
DWORD * pdwFlags )
{
if ( m_staticToolbar = = NULL )
return E_FAIL ;
return m_staticToolbar - > GetMenu ( phmenu , phwnd , pdwFlags ) ;
}
HRESULT STDMETHODCALLTYPE CMenuBand : : SetSite ( IUnknown * pUnkSite )
{
2014-02-19 12:19:50 +00:00
HWND hwndParent ;
HRESULT hr ;
2014-02-12 16:48:36 +00:00
2014-02-20 16:18:49 +00:00
m_site = NULL ;
2014-02-12 16:48:36 +00:00
if ( pUnkSite = = NULL )
return S_OK ;
hwndParent = NULL ;
2014-02-19 12:19:50 +00:00
hr = pUnkSite - > QueryInterface ( IID_PPV_ARG ( IOleWindow , & m_site ) ) ;
2014-02-20 16:18:49 +00:00
if ( FAILED ( hr ) )
return hr ;
2014-02-19 12:19:50 +00:00
2014-02-20 16:18:49 +00:00
hr = m_site - > GetWindow ( & hwndParent ) ;
if ( FAILED ( hr ) )
return hr ;
2014-02-19 12:19:50 +00:00
2014-02-12 16:48:36 +00:00
if ( ! : : IsWindow ( hwndParent ) )
return E_FAIL ;
if ( m_staticToolbar ! = NULL )
{
2014-02-19 12:19:50 +00:00
hr = m_staticToolbar - > CreateToolbar ( hwndParent , m_dwFlags ) ;
if ( FAILED ( hr ) )
return hr ;
2014-02-12 16:48:36 +00:00
2014-02-19 12:19:50 +00:00
hr = m_staticToolbar - > FillToolbar ( ) ;
if ( FAILED ( hr ) )
return hr ;
2014-02-12 16:48:36 +00:00
}
if ( m_SFToolbar ! = NULL )
{
2014-02-19 12:19:50 +00:00
hr = m_SFToolbar - > CreateToolbar ( hwndParent , m_dwFlags ) ;
if ( FAILED ( hr ) )
return hr ;
2014-02-12 16:48:36 +00:00
2014-02-19 12:19:50 +00:00
hr = m_SFToolbar - > FillToolbar ( ) ;
if ( FAILED ( hr ) )
return hr ;
2014-02-12 16:48:36 +00:00
}
2014-02-21 10:00:00 +00:00
hr = IUnknown_QueryService ( m_site , SID_SMenuPopup , IID_PPV_ARG ( IMenuPopup , & m_subMenuParent ) ) ;
if ( FAILED ( hr ) )
return hr ;
2014-02-19 12:19:50 +00:00
CComPtr < IOleWindow > pTopLevelWindow ;
hr = IUnknown_QueryService ( m_site , SID_STopLevelBrowser , IID_PPV_ARG ( IOleWindow , & pTopLevelWindow ) ) ;
if ( FAILED ( hr ) )
return hr ;
return pTopLevelWindow - > GetWindow ( & m_topLevelWindow ) ;
2014-02-12 16:48:36 +00:00
}
HRESULT STDMETHODCALLTYPE CMenuBand : : GetSite ( REFIID riid , PVOID * ppvSite )
{
if ( m_site = = NULL )
return E_FAIL ;
return m_site - > QueryInterface ( riid , ppvSite ) ;
}
HRESULT STDMETHODCALLTYPE CMenuBand : : GetWindow (
HWND * phwnd )
{
if ( m_SFToolbar ! = NULL )
return m_SFToolbar - > GetWindow ( phwnd ) ;
if ( m_staticToolbar ! = NULL )
return m_staticToolbar - > GetWindow ( phwnd ) ;
return E_FAIL ;
}
HRESULT STDMETHODCALLTYPE CMenuBand : : OnPosRectChangeDB ( RECT * prc )
{
2014-02-24 11:07:16 +00:00
SIZE sizeStatic = { 0 } ;
SIZE sizeShlFld = { 0 } ;
2014-02-19 12:19:50 +00:00
HRESULT hr = S_OK ;
2014-02-12 16:48:36 +00:00
if ( m_staticToolbar ! = NULL )
2014-02-24 11:07:16 +00:00
hr = m_staticToolbar - > GetIdealSize ( sizeStatic ) ;
2014-02-19 12:19:50 +00:00
if ( FAILED ( hr ) )
return hr ;
2014-02-12 16:48:36 +00:00
if ( m_SFToolbar ! = NULL )
2014-02-24 11:07:16 +00:00
hr = m_SFToolbar - > GetIdealSize ( sizeShlFld ) ;
2014-02-19 12:19:50 +00:00
if ( FAILED ( hr ) )
return hr ;
2014-02-12 16:48:36 +00:00
2014-02-24 11:07:16 +00:00
if ( m_staticToolbar = = NULL & & m_SFToolbar = = NULL )
2014-02-12 16:48:36 +00:00
return E_FAIL ;
2014-02-24 11:07:16 +00:00
int sy = min ( prc - > bottom - prc - > top , sizeStatic . cy + sizeShlFld . cy ) ;
2014-02-21 10:00:00 +00:00
2014-02-24 11:07:16 +00:00
int syStatic = sizeStatic . cy ;
2014-02-21 10:00:00 +00:00
int syShlFld = sy - syStatic ;
2014-02-12 16:48:36 +00:00
2014-02-24 11:07:16 +00:00
if ( m_SFToolbar )
2014-02-16 12:48:41 +00:00
{
2014-02-24 11:07:16 +00:00
m_SFToolbar - > SetPosSize (
prc - > left ,
prc - > top ,
prc - > right - prc - > left ,
syShlFld ) ;
2014-02-16 12:48:41 +00:00
}
2014-02-24 11:07:16 +00:00
if ( m_staticToolbar )
2014-02-16 12:48:41 +00:00
{
2014-02-24 11:07:16 +00:00
m_staticToolbar - > SetPosSize (
prc - > left ,
prc - > top + syShlFld ,
prc - > right - prc - > left ,
syStatic ) ;
2014-02-16 12:48:41 +00:00
}
2014-02-12 16:48:36 +00:00
return S_OK ;
}
HRESULT STDMETHODCALLTYPE CMenuBand : : GetBandInfo (
DWORD dwBandID ,
DWORD dwViewMode ,
DESKBANDINFO * pdbi )
{
2014-02-24 11:07:16 +00:00
SIZE sizeStatic = { 0 } ;
SIZE sizeShlFld = { 0 } ;
2014-02-19 12:19:50 +00:00
HRESULT hr = S_OK ;
2014-02-12 16:48:36 +00:00
if ( m_staticToolbar ! = NULL )
2014-02-24 11:07:16 +00:00
hr = m_staticToolbar - > GetIdealSize ( sizeStatic ) ;
2014-02-19 12:19:50 +00:00
if ( FAILED ( hr ) )
return hr ;
2014-02-12 16:48:36 +00:00
if ( m_SFToolbar ! = NULL )
2014-02-24 11:07:16 +00:00
hr = m_SFToolbar - > GetIdealSize ( sizeShlFld ) ;
2014-02-19 12:19:50 +00:00
if ( FAILED ( hr ) )
return hr ;
2014-02-12 16:48:36 +00:00
2014-02-24 11:07:16 +00:00
if ( m_staticToolbar = = NULL & & m_SFToolbar = = NULL )
2014-02-12 16:48:36 +00:00
return E_FAIL ;
2014-02-24 11:07:16 +00:00
pdbi - > ptMaxSize . x = max ( sizeStatic . cx , sizeShlFld . cx ) + 20 ;
pdbi - > ptMaxSize . y = sizeStatic . cy + sizeShlFld . cy ;
2014-02-12 16:48:36 +00:00
return S_OK ;
}
/* IDockingWindow */
HRESULT STDMETHODCALLTYPE CMenuBand : : ShowDW ( BOOL fShow )
{
HRESULT hr = S_OK ;
if ( m_staticToolbar ! = NULL )
hr = m_staticToolbar - > ShowWindow ( fShow ) ;
if ( FAILED ( hr ) )
return hr ;
if ( m_SFToolbar ! = NULL )
hr = m_SFToolbar - > ShowWindow ( fShow ) ;
if ( FAILED ( hr ) )
return hr ;
if ( fShow )
2014-02-19 20:35:50 +00:00
{
hr = _CallCB ( SMC_INITMENU , 0 , 0 ) ;
if ( FAILED ( hr ) )
return hr ;
}
2014-02-12 16:48:36 +00:00
2014-02-19 20:35:50 +00:00
if ( fShow )
hr = m_focusManager - > PushMenu ( this ) ;
else
hr = m_focusManager - > PopMenu ( this ) ;
2014-02-21 10:00:00 +00:00
return S_OK ;
2014-02-12 16:48:36 +00:00
}
HRESULT STDMETHODCALLTYPE CMenuBand : : CloseDW ( DWORD dwReserved )
{
ShowDW ( FALSE ) ;
if ( m_staticToolbar ! = NULL )
return m_staticToolbar - > Close ( ) ;
if ( m_SFToolbar ! = NULL )
return m_SFToolbar - > Close ( ) ;
return S_OK ;
}
HRESULT STDMETHODCALLTYPE CMenuBand : : ResizeBorderDW ( LPCRECT prcBorder , IUnknown * punkToolbarSite , BOOL fReserved )
{
UNIMPLEMENTED ;
return S_OK ;
}
HRESULT STDMETHODCALLTYPE CMenuBand : : ContextSensitiveHelp ( BOOL fEnterMode )
{
UNIMPLEMENTED ;
return S_OK ;
}
HRESULT STDMETHODCALLTYPE CMenuBand : : UIActivateIO ( BOOL fActivate , LPMSG lpMsg )
{
2014-02-19 13:58:28 +00:00
HRESULT hr ;
2014-02-21 10:00:00 +00:00
hr = m_subMenuParent - > SetSubMenu ( this , fActivate ) ;
2014-02-19 13:58:28 +00:00
if ( FAILED ( hr ) )
return hr ;
2014-02-20 12:12:42 +00:00
if ( fActivate )
{
CComPtr < IOleWindow > pTopLevelWindow ;
hr = IUnknown_QueryService ( m_site , SID_SMenuPopup , IID_PPV_ARG ( IOleWindow , & pTopLevelWindow ) ) ;
if ( FAILED ( hr ) )
return hr ;
2014-02-19 13:58:28 +00:00
2014-02-20 12:12:42 +00:00
hr = pTopLevelWindow - > GetWindow ( & m_topLevelWindow ) ;
if ( FAILED ( hr ) )
return hr ;
}
else
{
m_topLevelWindow = NULL ;
}
2014-02-19 13:58:28 +00:00
return S_FALSE ;
2014-02-12 16:48:36 +00:00
}
HRESULT STDMETHODCALLTYPE CMenuBand : : HasFocusIO ( )
{
UNIMPLEMENTED ;
return S_OK ;
}
HRESULT STDMETHODCALLTYPE CMenuBand : : TranslateAcceleratorIO ( LPMSG lpMsg )
{
UNIMPLEMENTED ;
return S_OK ;
}
HRESULT STDMETHODCALLTYPE CMenuBand : : IsDirty ( )
{
UNIMPLEMENTED ;
return S_OK ;
}
HRESULT STDMETHODCALLTYPE CMenuBand : : Load ( IStream * pStm )
{
UNIMPLEMENTED ;
return S_OK ;
}
HRESULT STDMETHODCALLTYPE CMenuBand : : Save ( IStream * pStm , BOOL fClearDirty )
{
UNIMPLEMENTED ;
return S_OK ;
}
HRESULT STDMETHODCALLTYPE CMenuBand : : GetSizeMax ( ULARGE_INTEGER * pcbSize )
{
UNIMPLEMENTED ;
return S_OK ;
}
HRESULT STDMETHODCALLTYPE CMenuBand : : GetClassID ( CLSID * pClassID )
{
UNIMPLEMENTED ;
return S_OK ;
}
HRESULT STDMETHODCALLTYPE CMenuBand : : QueryStatus ( const GUID * pguidCmdGroup , ULONG cCmds , OLECMD prgCmds [ ] , OLECMDTEXT * pCmdText )
{
UNIMPLEMENTED ;
return S_OK ;
}
HRESULT STDMETHODCALLTYPE CMenuBand : : Exec ( const GUID * pguidCmdGroup , DWORD nCmdID , DWORD nCmdexecopt , VARIANT * pvaIn , VARIANT * pvaOut )
{
if ( ! pguidCmdGroup )
return E_FAIL ;
if ( IsEqualGUID ( * pguidCmdGroup , CLSID_MenuBand ) )
{
if ( nCmdID = = 16 ) // set (big) icon size
{
2014-02-23 18:13:43 +00:00
this - > m_useBigIcons = nCmdexecopt = = 2 ;
2014-02-12 16:48:36 +00:00
return S_OK ;
}
else if ( nCmdID = = 19 ) // popup-related
{
return S_FALSE ;
}
}
UNIMPLEMENTED ;
return S_OK ;
}
HRESULT STDMETHODCALLTYPE CMenuBand : : QueryService ( REFGUID guidService , REFIID riid , void * * ppvObject )
{
2014-02-18 13:55:57 +00:00
if ( IsEqualIID ( guidService , SID_SMenuBandChild ) | |
2014-02-20 16:18:49 +00:00
IsEqualIID ( guidService , SID_SMenuBandBottom ) | |
2014-02-18 13:55:57 +00:00
IsEqualIID ( guidService , SID_SMenuBandBottomSelected ) )
2014-02-12 16:48:36 +00:00
return this - > QueryInterface ( riid , ppvObject ) ;
WARN ( " Unknown service requested %s \n " , wine_dbgstr_guid ( & guidService ) ) ;
return E_NOINTERFACE ;
}
HRESULT STDMETHODCALLTYPE CMenuBand : : Popup ( POINTL * ppt , RECTL * prcExclude , MP_POPUPFLAGS dwFlags )
{
UNIMPLEMENTED ;
return S_OK ;
}
HRESULT STDMETHODCALLTYPE CMenuBand : : OnSelect ( DWORD dwSelectType )
{
2014-02-21 10:00:00 +00:00
switch ( dwSelectType )
2014-02-20 16:18:49 +00:00
{
2014-02-21 10:00:00 +00:00
case MPOS_CHILDTRACKING :
// TODO: Cancel timers?
return m_subMenuParent - > OnSelect ( dwSelectType ) ;
case MPOS_SELECTLEFT :
if ( m_subMenuChild )
m_subMenuChild - > OnSelect ( MPOS_CANCELLEVEL ) ;
return m_subMenuParent - > OnSelect ( dwSelectType ) ;
case MPOS_SELECTRIGHT :
if ( m_hotBar & & m_hotItem > = 0 )
2014-02-20 16:18:49 +00:00
{
2014-02-21 10:00:00 +00:00
// TODO: popup the current child if it has subitems, otherwise spread up.
2014-02-20 16:18:49 +00:00
}
2014-02-21 10:00:00 +00:00
return m_subMenuParent - > OnSelect ( dwSelectType ) ;
case MPOS_EXECUTE :
case MPOS_FULLCANCEL :
if ( m_subMenuChild )
m_subMenuChild - > OnSelect ( dwSelectType ) ;
return m_subMenuParent - > OnSelect ( dwSelectType ) ;
case MPOS_CANCELLEVEL :
if ( m_subMenuChild )
m_subMenuChild - > OnSelect ( dwSelectType ) ;
break ;
2014-02-20 16:18:49 +00:00
}
return S_FALSE ;
2014-02-12 16:48:36 +00:00
}
HRESULT STDMETHODCALLTYPE CMenuBand : : SetSubMenu ( IMenuPopup * pmp , BOOL fSet )
{
UNIMPLEMENTED ;
return S_OK ;
}
HRESULT STDMETHODCALLTYPE CMenuBand : : SetClient ( IUnknown * punkClient )
{
UNIMPLEMENTED ;
return S_OK ;
}
HRESULT STDMETHODCALLTYPE CMenuBand : : GetClient ( IUnknown * * ppunkClient )
{
2014-02-22 22:59:28 +00:00
// HACK, so I can test for a submenu in the DeskBar
//UNIMPLEMENTED;
if ( ppunkClient )
{
if ( m_subMenuChild )
* ppunkClient = m_subMenuChild ;
else
* ppunkClient = NULL ;
}
2014-02-12 16:48:36 +00:00
return S_OK ;
}
HRESULT STDMETHODCALLTYPE CMenuBand : : IsMenuMessage ( MSG * pmsg )
{
//UNIMPLEMENTED;
//return S_OK;
return S_FALSE ;
//return E_NOTIMPL;
}
HRESULT STDMETHODCALLTYPE CMenuBand : : TranslateMenuMessage ( MSG * pmsg , LRESULT * plRet )
{
//UNIMPLEMENTED;
return S_FALSE ;
}
HRESULT STDMETHODCALLTYPE CMenuBand : : SetShellFolder ( IShellFolder * psf , LPCITEMIDLIST pidlFolder , HKEY hKey , DWORD dwFlags )
{
if ( m_SFToolbar = = NULL )
{
m_SFToolbar = new CMenuSFToolbar ( this ) ;
}
2014-02-19 12:19:50 +00:00
HRESULT hr = m_SFToolbar - > SetShellFolder ( psf , pidlFolder , hKey , dwFlags ) ;
if ( FAILED ( hr ) )
return hr ;
2014-02-12 16:48:36 +00:00
if ( m_site )
{
HWND hwndParent ;
2014-02-19 12:19:50 +00:00
hr = m_site - > GetWindow ( & hwndParent ) ;
if ( FAILED ( hr ) )
return hr ;
2014-02-12 16:48:36 +00:00
2014-02-19 12:19:50 +00:00
hr = m_SFToolbar - > CreateToolbar ( hwndParent , m_dwFlags ) ;
if ( FAILED ( hr ) )
return hr ;
2014-02-12 16:48:36 +00:00
2014-02-19 12:19:50 +00:00
hr = m_SFToolbar - > FillToolbar ( ) ;
2014-02-12 16:48:36 +00:00
}
2014-02-19 12:19:50 +00:00
return hr ;
2014-02-12 16:48:36 +00:00
}
HRESULT STDMETHODCALLTYPE CMenuBand : : GetShellFolder ( DWORD * pdwFlags , LPITEMIDLIST * ppidl , REFIID riid , void * * ppv )
{
if ( m_SFToolbar )
return m_SFToolbar - > GetShellFolder ( pdwFlags , ppidl , riid , ppv ) ;
return E_FAIL ;
}
HRESULT STDMETHODCALLTYPE CMenuBand : : InvalidateItem ( LPSMDATA psmd , DWORD dwFlags )
{
UNIMPLEMENTED ;
return S_OK ;
}
HRESULT STDMETHODCALLTYPE CMenuBand : : GetState ( LPSMDATA psmd )
{
UNIMPLEMENTED ;
return S_OK ;
}
HRESULT STDMETHODCALLTYPE CMenuBand : : SetMenuToolbar ( IUnknown * punk , DWORD dwFlags )
{
UNIMPLEMENTED ;
return S_OK ;
}
HRESULT STDMETHODCALLTYPE CMenuBand : : OnWinEvent ( HWND hWnd , UINT uMsg , WPARAM wParam , LPARAM lParam , LRESULT * theResult )
{
2014-02-24 11:07:16 +00:00
RECT rc ;
HDC hdc ;
HBRUSH bgBrush ;
HBRUSH hotBrush ;
2014-02-16 12:48:41 +00:00
* theResult = 0 ;
2014-02-17 11:20:35 +00:00
switch ( uMsg )
2014-02-16 12:48:41 +00:00
{
2014-02-17 11:20:35 +00:00
case WM_COMMAND :
2014-02-20 16:18:49 +00:00
if ( m_staticToolbar & & m_staticToolbar - > IsWindowOwner ( hWnd ) = = S_OK )
2014-02-17 11:20:35 +00:00
{
return m_staticToolbar - > OnCommand ( wParam , lParam , theResult ) ;
}
2014-02-20 16:18:49 +00:00
if ( m_SFToolbar & & m_SFToolbar - > IsWindowOwner ( hWnd ) = = S_OK )
2014-02-17 11:20:35 +00:00
{
return m_SFToolbar - > OnCommand ( wParam , lParam , theResult ) ;
}
return S_OK ;
2014-02-17 15:38:55 +00:00
2014-02-17 11:20:35 +00:00
case WM_NOTIFY :
2014-02-18 10:26:50 +00:00
NMHDR * hdr = reinterpret_cast < LPNMHDR > ( lParam ) ;
2014-02-16 12:48:41 +00:00
NMTBCUSTOMDRAW * cdraw ;
2014-02-17 15:38:55 +00:00
NMTBHOTITEM * hot ;
2014-02-17 18:38:31 +00:00
NMMOUSE * rclick ;
2014-02-24 11:07:16 +00:00
NMPGCALCSIZE * csize ;
TBBUTTONINFO btni ;
2014-02-16 12:48:41 +00:00
switch ( hdr - > code )
{
2014-02-24 11:07:16 +00:00
case PGN_CALCSIZE :
csize = reinterpret_cast < LPNMPGCALCSIZE > ( hdr ) ;
if ( m_staticToolbar & & m_staticToolbar - > IsWindowOwner ( hWnd ) = = S_OK )
{
SIZE tbs ;
m_staticToolbar - > GetIdealSize ( tbs ) ;
if ( csize - > dwFlag = = PGF_CALCHEIGHT )
{
csize - > iHeight = tbs . cy ;
}
else if ( csize - > dwFlag = = PGF_CALCWIDTH )
{
csize - > iHeight = tbs . cx ;
}
}
if ( m_SFToolbar & & m_SFToolbar - > IsWindowOwner ( hWnd ) = = S_OK )
{
SIZE tbs ;
m_SFToolbar - > GetIdealSize ( tbs ) ;
if ( csize - > dwFlag = = PGF_CALCHEIGHT )
{
csize - > iHeight = tbs . cy ;
}
else if ( csize - > dwFlag = = PGF_CALCWIDTH )
{
csize - > iHeight = tbs . cx ;
}
}
return S_OK ;
case TBN_DROPDOWN :
if ( m_staticToolbar & & m_staticToolbar - > IsWindowOwner ( hWnd ) = = S_OK )
{
WPARAM wp = reinterpret_cast < LPNMTOOLBAR > ( hdr ) - > iItem ;
return m_staticToolbar - > OnCommand ( wp , 0 , theResult ) ;
}
if ( m_SFToolbar & & m_SFToolbar - > IsWindowOwner ( hWnd ) = = S_OK )
{
WPARAM wp = reinterpret_cast < LPNMTOOLBAR > ( hdr ) - > iItem ;
return m_SFToolbar - > OnCommand ( wp , 0 , theResult ) ;
}
return S_OK ;
2014-02-17 15:38:55 +00:00
case TBN_HOTITEMCHANGE :
2014-02-18 10:26:50 +00:00
hot = reinterpret_cast < LPNMTBHOTITEM > ( hdr ) ;
2014-02-17 15:38:55 +00:00
2014-02-20 16:18:49 +00:00
if ( m_staticToolbar & & m_staticToolbar - > IsWindowOwner ( hWnd ) = = S_OK )
2014-02-17 15:38:55 +00:00
{
return m_staticToolbar - > OnHotItemChange ( hot ) ;
}
2014-02-20 16:18:49 +00:00
if ( m_SFToolbar & & m_SFToolbar - > IsWindowOwner ( hWnd ) = = S_OK )
2014-02-17 15:38:55 +00:00
{
return m_SFToolbar - > OnHotItemChange ( hot ) ;
}
return S_OK ;
2014-02-17 18:38:31 +00:00
case NM_RCLICK :
2014-02-18 10:26:50 +00:00
rclick = reinterpret_cast < LPNMMOUSE > ( hdr ) ;
2014-02-17 18:38:31 +00:00
2014-02-20 16:18:49 +00:00
if ( m_staticToolbar & & m_staticToolbar - > IsWindowOwner ( hWnd ) = = S_OK )
2014-02-17 18:38:31 +00:00
{
return m_staticToolbar - > OnContextMenu ( rclick ) ;
}
2014-02-20 16:18:49 +00:00
if ( m_SFToolbar & & m_SFToolbar - > IsWindowOwner ( hWnd ) = = S_OK )
2014-02-17 18:38:31 +00:00
{
return m_SFToolbar - > OnContextMenu ( rclick ) ;
}
return S_OK ;
2014-02-24 11:07:16 +00:00
2014-02-16 12:48:41 +00:00
case NM_CUSTOMDRAW :
2014-02-18 10:26:50 +00:00
cdraw = reinterpret_cast < LPNMTBCUSTOMDRAW > ( hdr ) ;
2014-02-16 12:48:41 +00:00
switch ( cdraw - > nmcd . dwDrawStage )
{
case CDDS_PREPAINT :
* theResult = CDRF_NOTIFYITEMDRAW ;
return S_OK ;
case CDDS_ITEMPREPAINT :
cdraw - > clrBtnFace = GetSysColor ( COLOR_MENU ) ;
cdraw - > clrBtnHighlight = GetSysColor ( COLOR_MENUHILIGHT ) ;
cdraw - > clrText = GetSysColor ( COLOR_MENUTEXT ) ;
cdraw - > clrTextHighlight = GetSysColor ( COLOR_HIGHLIGHTTEXT ) ;
cdraw - > clrHighlightHotTrack = GetSysColor ( COLOR_HIGHLIGHTTEXT ) ;
2014-02-24 11:07:16 +00:00
bgBrush = GetSysColorBrush ( COLOR_MENU ) ;
hotBrush = GetSysColorBrush ( COLOR_MENUHILIGHT ) ;
2014-02-16 12:48:41 +00:00
2014-02-24 11:07:16 +00:00
rc = cdraw - > nmcd . rc ;
hdc = cdraw - > nmcd . hdc ;
if ( cdraw - > nmcd . uItemState ! = CDIS_DISABLED & &
( ( INT ) cdraw - > nmcd . dwItemSpec = = m_hotItem | |
( m_hotItem < 0 & & ( INT ) cdraw - > nmcd . dwItemSpec = = m_popupItem ) ) )
{
cdraw - > nmcd . uItemState = CDIS_HOT ;
}
2014-02-16 12:48:41 +00:00
switch ( cdraw - > nmcd . uItemState )
{
case CDIS_HOT :
case CDIS_FOCUS :
FillRect ( hdc , & rc , hotBrush ) ;
break ;
default :
FillRect ( hdc , & rc , bgBrush ) ;
break ;
}
2014-02-24 11:07:16 +00:00
* theResult = CDRF_NOTIFYPOSTPAINT | TBCDRF_NOBACKGROUND | TBCDRF_NOEDGES | TBCDRF_NOOFFSET | TBCDRF_NOMARK | 0x00800000 ; // FIXME: the last bit is Vista+, for debugging only
return S_OK ;
case CDDS_ITEMPOSTPAINT :
btni . cbSize = sizeof ( btni ) ;
btni . dwMask = TBIF_STYLE ;
SendMessage ( hWnd , TB_GETBUTTONINFO , cdraw - > nmcd . dwItemSpec , reinterpret_cast < LPARAM > ( & btni ) ) ;
if ( btni . fsStyle & BTNS_DROPDOWN )
{
SelectObject ( cdraw - > nmcd . hdc , m_marlett ) ;
WCHAR text [ ] = L " 8 " ;
SetBkMode ( cdraw - > nmcd . hdc , TRANSPARENT ) ;
DrawTextEx ( cdraw - > nmcd . hdc , text , 1 , & cdraw - > nmcd . rc , DT_NOCLIP | DT_VCENTER | DT_RIGHT | DT_SINGLELINE , NULL ) ;
}
* theResult = TRUE ;
2014-02-16 12:48:41 +00:00
return S_OK ;
}
return S_OK ;
}
return S_OK ;
}
2014-02-17 11:20:35 +00:00
2014-02-16 12:48:41 +00:00
return S_FALSE ;
2014-02-12 16:48:36 +00:00
}
HRESULT STDMETHODCALLTYPE CMenuBand : : IsWindowOwner ( HWND hWnd )
{
2014-02-20 16:18:49 +00:00
if ( m_staticToolbar & & m_staticToolbar - > IsWindowOwner ( hWnd ) = = S_OK )
2014-02-16 12:48:41 +00:00
return S_OK ;
2014-02-20 16:18:49 +00:00
if ( m_SFToolbar & & m_SFToolbar - > IsWindowOwner ( hWnd ) = = S_OK )
2014-02-16 12:48:41 +00:00
return S_OK ;
return S_FALSE ;
2014-02-12 16:48:36 +00:00
}
HRESULT STDMETHODCALLTYPE CMenuBand : : GetSubMenu ( THIS )
{
UNIMPLEMENTED ;
return S_OK ;
}
HRESULT STDMETHODCALLTYPE CMenuBand : : SetToolbar ( THIS )
{
UNIMPLEMENTED ;
return S_OK ;
}
HRESULT STDMETHODCALLTYPE CMenuBand : : SetMinWidth ( THIS )
{
UNIMPLEMENTED ;
return S_OK ;
}
HRESULT STDMETHODCALLTYPE CMenuBand : : SetNoBorder ( THIS )
{
UNIMPLEMENTED ;
return S_OK ;
}
HRESULT STDMETHODCALLTYPE CMenuBand : : SetTheme ( THIS )
{
UNIMPLEMENTED ;
return S_OK ;
}
HRESULT STDMETHODCALLTYPE CMenuBand : : GetTop ( THIS )
{
UNIMPLEMENTED ;
return S_OK ;
}
HRESULT STDMETHODCALLTYPE CMenuBand : : GetBottom ( THIS )
{
UNIMPLEMENTED ;
return S_OK ;
}
HRESULT STDMETHODCALLTYPE CMenuBand : : GetTracked ( THIS )
{
UNIMPLEMENTED ;
return S_OK ;
}
HRESULT STDMETHODCALLTYPE CMenuBand : : GetParentSite ( THIS )
{
UNIMPLEMENTED ;
return S_OK ;
}
HRESULT STDMETHODCALLTYPE CMenuBand : : GetState ( THIS )
{
UNIMPLEMENTED ;
return S_OK ;
}
HRESULT STDMETHODCALLTYPE CMenuBand : : DoDefaultAction ( THIS )
{
UNIMPLEMENTED ;
return S_OK ;
}
HRESULT STDMETHODCALLTYPE CMenuBand : : IsEmpty ( THIS )
{
UNIMPLEMENTED ;
return S_OK ;
}
2014-02-20 16:18:49 +00:00
HRESULT CMenuBand : : _CallCBWithItemId ( UINT id , UINT uMsg , WPARAM wParam , LPARAM lParam )
2014-02-12 16:48:36 +00:00
{
2014-02-18 10:26:50 +00:00
return _CallCB ( uMsg , wParam , lParam , id ) ;
2014-02-17 18:38:31 +00:00
}
2014-02-20 16:18:49 +00:00
HRESULT CMenuBand : : _CallCBWithItemPidl ( LPITEMIDLIST pidl , UINT uMsg , WPARAM wParam , LPARAM lParam )
2014-02-17 18:38:31 +00:00
{
2014-02-18 10:26:50 +00:00
return _CallCB ( uMsg , wParam , lParam , 0 , pidl ) ;
2014-02-12 16:48:36 +00:00
}
2014-02-18 10:26:50 +00:00
HRESULT CMenuBand : : _CallCB ( UINT uMsg , WPARAM wParam , LPARAM lParam , UINT id , LPITEMIDLIST pidl )
2014-02-12 16:48:36 +00:00
{
if ( ! m_psmc )
return S_FALSE ;
HWND hwnd ;
GetWindow ( & hwnd ) ;
SMDATA smData = { 0 } ;
2014-02-18 10:26:50 +00:00
smData . punk = static_cast < IShellMenu2 * > ( this ) ;
smData . uId = id ;
2014-02-12 16:48:36 +00:00
smData . uIdParent = m_uId ;
smData . uIdAncestor = m_uIdAncestor ;
smData . hwnd = hwnd ;
2014-02-18 10:26:50 +00:00
smData . pidlItem = pidl ;
2014-02-12 16:48:36 +00:00
if ( m_staticToolbar )
{
smData . hmenu = m_hmenu ;
}
smData . pvUserData = NULL ;
if ( m_SFToolbar )
m_SFToolbar - > GetShellFolder ( NULL , & smData . pidlFolder , IID_PPV_ARG ( IShellFolder , & smData . psf ) ) ;
HRESULT hr = m_psmc - > CallbackSM ( & smData , uMsg , wParam , lParam ) ;
ILFree ( smData . pidlFolder ) ;
if ( smData . psf )
smData . psf - > Release ( ) ;
return hr ;
}
2014-02-18 18:18:08 +00:00
2014-02-20 16:18:49 +00:00
HRESULT CMenuBand : : _TrackSubMenuUsingTrackPopupMenu ( HMENU popup , INT x , INT y )
2014-02-18 18:18:08 +00:00
{
2014-02-19 00:20:45 +00:00
: : TrackPopupMenu ( popup , 0 , x , y , 0 , m_menuOwner , NULL ) ;
2014-02-18 18:18:08 +00:00
return S_OK ;
}
2014-02-19 20:35:50 +00:00
2014-02-20 16:18:49 +00:00
HRESULT CMenuBand : : _GetTopLevelWindow ( HWND * topLevel )
2014-02-19 20:35:50 +00:00
{
* topLevel = m_topLevelWindow ;
return S_OK ;
2014-02-20 12:12:42 +00:00
}
2014-02-20 16:18:49 +00:00
HRESULT CMenuBand : : _OnHotItemChanged ( CMenuToolbarBase * tb , INT id )
2014-02-20 12:12:42 +00:00
{
if ( m_hotBar & & m_hotBar ! = tb )
2014-02-20 16:18:49 +00:00
m_hotBar - > ChangeHotItem ( - 1 ) ;
2014-02-20 12:12:42 +00:00
m_hotBar = tb ;
m_hotItem = id ;
2014-02-24 11:07:16 +00:00
if ( m_staticToolbar ) m_staticToolbar - > InvalidateDraw ( ) ;
if ( m_SFToolbar ) m_SFToolbar - > InvalidateDraw ( ) ;
2014-02-20 12:12:42 +00:00
return S_OK ;
}
2014-02-20 16:18:49 +00:00
HRESULT CMenuBand : : _MenuItemHotTrack ( DWORD changeType )
2014-02-20 12:12:42 +00:00
{
HRESULT hr ;
2014-02-20 16:18:49 +00:00
if ( changeType = = VK_DOWN )
2014-02-20 12:12:42 +00:00
{
if ( m_SFToolbar & & ( m_hotBar = = m_SFToolbar | | m_hotBar = = NULL ) )
{
2014-02-20 16:18:49 +00:00
hr = m_SFToolbar - > ChangeHotItem ( VK_DOWN ) ;
2014-02-20 12:12:42 +00:00
if ( hr = = S_FALSE )
{
if ( m_staticToolbar )
2014-02-20 16:18:49 +00:00
return m_staticToolbar - > ChangeHotItem ( VK_HOME ) ;
2014-02-20 12:12:42 +00:00
else
2014-02-20 16:18:49 +00:00
return m_SFToolbar - > ChangeHotItem ( VK_HOME ) ;
2014-02-20 12:12:42 +00:00
}
return hr ;
}
else if ( m_staticToolbar & & m_hotBar = = m_staticToolbar )
{
2014-02-20 16:18:49 +00:00
hr = m_staticToolbar - > ChangeHotItem ( VK_DOWN ) ;
2014-02-20 12:12:42 +00:00
if ( hr = = S_FALSE )
{
if ( m_SFToolbar )
2014-02-20 16:18:49 +00:00
return m_SFToolbar - > ChangeHotItem ( VK_HOME ) ;
2014-02-20 12:12:42 +00:00
else
2014-02-20 16:18:49 +00:00
return m_staticToolbar - > ChangeHotItem ( VK_HOME ) ;
2014-02-20 12:12:42 +00:00
}
return hr ;
}
}
2014-02-20 16:18:49 +00:00
else if ( changeType = = VK_UP )
2014-02-20 12:12:42 +00:00
{
if ( m_staticToolbar & & ( m_hotBar = = m_staticToolbar | | m_hotBar = = NULL ) )
{
2014-02-20 16:18:49 +00:00
hr = m_staticToolbar - > ChangeHotItem ( VK_DOWN ) ;
2014-02-20 12:12:42 +00:00
if ( hr = = S_FALSE )
{
if ( m_SFToolbar )
2014-02-20 16:18:49 +00:00
return m_SFToolbar - > ChangeHotItem ( VK_END ) ;
2014-02-20 12:12:42 +00:00
else
2014-02-20 16:18:49 +00:00
return m_staticToolbar - > ChangeHotItem ( VK_END ) ;
2014-02-20 12:12:42 +00:00
}
return hr ;
}
else if ( m_SFToolbar & & m_hotBar = = m_SFToolbar )
{
2014-02-20 16:18:49 +00:00
hr = m_SFToolbar - > ChangeHotItem ( VK_UP ) ;
2014-02-20 12:12:42 +00:00
if ( hr = = S_FALSE )
{
if ( m_staticToolbar )
2014-02-20 16:18:49 +00:00
return m_staticToolbar - > ChangeHotItem ( VK_END ) ;
2014-02-20 12:12:42 +00:00
else
2014-02-20 16:18:49 +00:00
return m_SFToolbar - > ChangeHotItem ( VK_END ) ;
2014-02-20 12:12:42 +00:00
}
return hr ;
}
}
else
{
2014-02-21 10:00:00 +00:00
m_subMenuParent - > OnSelect ( changeType ) ;
2014-02-20 12:12:42 +00:00
}
return S_OK ;
}
2014-02-20 16:18:49 +00:00
2014-02-24 11:07:16 +00:00
HRESULT CMenuBand : : _OnPopupSubMenu ( INT popupItem , IMenuPopup * popup , POINTL * pAt , RECTL * pExclude )
2014-02-20 16:18:49 +00:00
{
2014-02-21 10:00:00 +00:00
if ( m_subMenuChild )
2014-02-20 16:18:49 +00:00
{
2014-02-21 10:00:00 +00:00
HRESULT hr = m_subMenuChild - > OnSelect ( MPOS_CANCELLEVEL ) ;
2014-02-20 16:18:49 +00:00
if ( FAILED ( hr ) )
return hr ;
}
2014-02-24 11:07:16 +00:00
m_popupItem = popupItem ;
2014-02-21 10:00:00 +00:00
m_subMenuChild = popup ;
if ( popup )
2014-02-20 16:18:49 +00:00
{
2014-02-21 10:00:00 +00:00
IUnknown_SetSite ( popup , m_subMenuParent ) ;
2014-02-23 00:15:27 +00:00
popup - > Popup ( pAt , pExclude , MPPF_RIGHT ) ;
2014-02-20 16:18:49 +00:00
}
2014-02-24 11:07:16 +00:00
if ( m_staticToolbar ) m_staticToolbar - > InvalidateDraw ( ) ;
if ( m_SFToolbar ) m_SFToolbar - > InvalidateDraw ( ) ;
2014-02-20 16:18:49 +00:00
return S_OK ;
2014-02-21 10:00:00 +00:00
}