diff --git a/ExplorerPatcher/StartMenu.h b/ExplorerPatcher/StartMenu.h index ec6a105..7506796 100644 --- a/ExplorerPatcher/StartMenu.h +++ b/ExplorerPatcher/StartMenu.h @@ -55,13 +55,13 @@ typedef struct IImmersiveMonitorServiceVtbl ULONG(STDMETHODCALLTYPE* Release)( IImmersiveMonitorService* This); - HRESULT(STDMETHODCALLTYPE* method3)( + HRESULT(STDMETHODCALLTYPE* GetCount)( IImmersiveMonitorService* This); - HRESULT(STDMETHODCALLTYPE* method4)( + HRESULT(STDMETHODCALLTYPE* GetConnectedCount)( IImmersiveMonitorService* This); - HRESULT(STDMETHODCALLTYPE* method5)( + HRESULT(STDMETHODCALLTYPE* GetAt)( IImmersiveMonitorService* This); HRESULT(STDMETHODCALLTYPE* GetFromHandle)( @@ -69,10 +69,10 @@ typedef struct IImmersiveMonitorServiceVtbl /* [in] */ HMONITOR hMonitor, _COM_Outptr_ IUnknown** ppvObject); - HRESULT(STDMETHODCALLTYPE* method6)( + HRESULT(STDMETHODCALLTYPE* GetFromIdentity)( IImmersiveMonitorService* This); - HRESULT(STDMETHODCALLTYPE* method7)( + HRESULT(STDMETHODCALLTYPE* GetImmersiveProxyMonitor)( IImmersiveMonitorService* This); HRESULT(STDMETHODCALLTYPE* QueryService)( @@ -83,7 +83,7 @@ typedef struct IImmersiveMonitorServiceVtbl void** ppvObject ); - HRESULT(STDMETHODCALLTYPE* method9)( + HRESULT(STDMETHODCALLTYPE* QueryServiceByIdentity)( IImmersiveMonitorService* This); HRESULT(STDMETHODCALLTYPE* QueryServiceFromWindow)( @@ -94,6 +94,14 @@ typedef struct IImmersiveMonitorServiceVtbl void** ppvObject ); + HRESULT(STDMETHODCALLTYPE* QueryServiceFromPoint)( + IImmersiveMonitorService* This, + POINT pt, + GUID* a3, + GUID* a4, + void** ppvObject + ); + END_INTERFACE } IImmersiveMonitorServiceVtbl; @@ -160,6 +168,42 @@ interface IImmersiveLauncher10RS CONST_VTBL struct IImmersiveLauncher10RSVtbl* lpVtbl; }; +DEFINE_GUID(IID_ILauncherTipContextMenu, + 0xb8c1db5f, + 0xcbb3, 0x48bc, 0xaf, 0xd9, + 0xce, 0x6b, 0x88, 0x0c, 0x79, 0xed +); + +typedef interface ILauncherTipContextMenu ILauncherTipContextMenu; + +typedef struct ILauncherTipContextMenuVtbl +{ + BEGIN_INTERFACE + + HRESULT(STDMETHODCALLTYPE* QueryInterface)( + ILauncherTipContextMenu* This, + /* [in] */ REFIID riid, + /* [annotation][iid_is][out] */ + _COM_Outptr_ void** ppvObject); + + ULONG(STDMETHODCALLTYPE* AddRef)( + ILauncherTipContextMenu* This); + + ULONG(STDMETHODCALLTYPE* Release)( + ILauncherTipContextMenu* This); + + HRESULT(STDMETHODCALLTYPE* ShowLauncherTipContextMenu)( + ILauncherTipContextMenu* This, + /* [in] */ POINT* pt); + + END_INTERFACE +} ILauncherTipContextMenuVtbl; + +interface ILauncherTipContextMenu +{ + CONST_VTBL struct ILauncherTipContextMenuVtbl* lpVtbl; +}; + void OpenStartOnMonitor(HMONITOR monitor); // Slightly tweaked version of function available in Open Shell diff --git a/ExplorerPatcher/dllmain.c b/ExplorerPatcher/dllmain.c index f13ab7c..0ce899c 100644 --- a/ExplorerPatcher/dllmain.c +++ b/ExplorerPatcher/dllmain.c @@ -1223,12 +1223,51 @@ LRESULT explorer_SendMessageW(HWND hWndx, UINT uMsg, WPARAM wParam, LPARAM lPara if (hWnd) { POINT pt = GetDefaultWinXPosition(FALSE, NULL, NULL, TRUE); - PostMessage( - hWnd, - WM_CONTEXTMENU, - hWnd, - MAKELPARAM(pt.x, pt.y) + // Finally implemented a variation of + // https://github.com/valinet/ExplorerPatcher/issues/3 + // inspired by how the real Start button activates this menu + // (CPearl::_GetLauncherTipContextMenu) + // This also works when auto hide taskbar is on (#63) + HRESULT hr = S_OK; + IUnknown* pImmersiveShell = NULL; + hr = CoCreateInstance( + &CLSID_ImmersiveShell, + NULL, + CLSCTX_INPROC_SERVER, + &IID_IServiceProvider, + &pImmersiveShell ); + if (SUCCEEDED(hr)) + { + IImmersiveMonitorService* pMonitorService = NULL; + IUnknown_QueryService( + pImmersiveShell, + &SID_IImmersiveMonitorService, + &IID_IImmersiveMonitorService, + &pMonitorService + ); + if (pMonitorService) + { + ILauncherTipContextMenu* pMenu = NULL; + pMonitorService->lpVtbl->QueryServiceFromWindow( + pMonitorService, + hWnd, + &IID_ILauncherTipContextMenu, + &IID_ILauncherTipContextMenu, + &pMenu + ); + if (pMenu) + { + pMenu->lpVtbl->ShowLauncherTipContextMenu( + pMenu, + &pt + ); + pMenu->lpVtbl->Release(pMenu); + } + pMonitorService->lpVtbl->Release(pMonitorService); + } + pImmersiveShell->lpVtbl->Release(pImmersiveShell); + } } } }