Browse Source

Start menu is displayed on monitor containing the cursor when opened

using the Windows key (v22000.1.0.3).
pull/20/head 22000.1.0.3
Valentin Radu 5 years ago
parent
commit
ec808402e0
  1. 8
      ExplorerPatcher/ExplorerPatcher.rc
  2. 8
      ExplorerPatcherLibrary/ExplorerPatcherLibrary.rc
  3. 317
      ExplorerPatcherLibrary/dllmain.c
  4. 1
      README.md

8
ExplorerPatcher/ExplorerPatcher.rc

@ -51,8 +51,8 @@ END
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 22000,1,0,2 FILEVERSION 22000,1,0,3
PRODUCTVERSION 22000,1,0,2 PRODUCTVERSION 22000,1,0,3
FILEFLAGSMASK 0x3fL FILEFLAGSMASK 0x3fL
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L
@ -69,12 +69,12 @@ BEGIN
BEGIN BEGIN
VALUE "CompanyName", "VALINET Solutions SRL" VALUE "CompanyName", "VALINET Solutions SRL"
VALUE "FileDescription", "ExplorerPatcher Daemon" VALUE "FileDescription", "ExplorerPatcher Daemon"
VALUE "FileVersion", "22000.1.0.2" VALUE "FileVersion", "22000.1.0.3"
VALUE "InternalName", "ExplorerPatcher.exe" VALUE "InternalName", "ExplorerPatcher.exe"
VALUE "LegalCopyright", "Copyright (C) 2006-2021 VALINET Solutions SRL. All rights reserved." VALUE "LegalCopyright", "Copyright (C) 2006-2021 VALINET Solutions SRL. All rights reserved."
VALUE "OriginalFilename", "ExplorerPatcher.exe" VALUE "OriginalFilename", "ExplorerPatcher.exe"
VALUE "ProductName", "ExplorerPatcher" VALUE "ProductName", "ExplorerPatcher"
VALUE "ProductVersion", "22000.1.0.2" VALUE "ProductVersion", "22000.1.0.3"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"

8
ExplorerPatcherLibrary/ExplorerPatcherLibrary.rc

@ -51,8 +51,8 @@ END
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 22000,1,0,2 FILEVERSION 22000,1,0,3
PRODUCTVERSION 22000,1,0,2 PRODUCTVERSION 22000,1,0,3
FILEFLAGSMASK 0x3fL FILEFLAGSMASK 0x3fL
#ifdef _DEBUG #ifdef _DEBUG
FILEFLAGS 0x1L FILEFLAGS 0x1L
@ -69,12 +69,12 @@ BEGIN
BEGIN BEGIN
VALUE "CompanyName", "VALINET Solutions SRL" VALUE "CompanyName", "VALINET Solutions SRL"
VALUE "FileDescription", "ExplorerPatcher Library" VALUE "FileDescription", "ExplorerPatcher Library"
VALUE "FileVersion", "22000.1.0.2" VALUE "FileVersion", "22000.1.0.3"
VALUE "InternalName", "ExplorerPatcherLibrary.dll" VALUE "InternalName", "ExplorerPatcherLibrary.dll"
VALUE "LegalCopyright", "Copyright (C) 2006-2021 VALINET Solutions SRL. All rights reserved." VALUE "LegalCopyright", "Copyright (C) 2006-2021 VALINET Solutions SRL. All rights reserved."
VALUE "OriginalFilename", "ExplorerPatcherLibrary.dll" VALUE "OriginalFilename", "ExplorerPatcherLibrary.dll"
VALUE "ProductName", "WinOverview" VALUE "ProductName", "WinOverview"
VALUE "ProductVersion", "22000.1.0.2" VALUE "ProductVersion", "22000.1.0.3"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"

317
ExplorerPatcherLibrary/dllmain.c

@ -8,6 +8,7 @@
#pragma comment(lib, "Shlwapi.lib") #pragma comment(lib, "Shlwapi.lib")
#include <dwmapi.h> #include <dwmapi.h>
#pragma comment(lib, "Dwmapi.lib") #pragma comment(lib, "Dwmapi.lib")
#include <windowsx.h>
#define DEBUG #define DEBUG
#undef DEBUG #undef DEBUG
@ -116,6 +117,137 @@ static BOOL(*IsDesktopInputContextFunc)(
DEFINE_GUID(CLSID_ImmersiveShell,
0xc2f03a33,
0x21f5, 0x47fa, 0xb4, 0xbb,
0x15, 0x63, 0x62, 0xa2, 0xf2, 0x39
);
DEFINE_GUID(SID_IImmersiveMonitorService,
0x47094e3a,
0x0cf2, 0x430f, 0x80, 0x6f,
0xcf, 0x9e, 0x4f, 0x0f, 0x12, 0xdd
);
DEFINE_GUID(IID_IImmersiveMonitorService,
0x4d4c1e64,
0xe410, 0x4faa, 0xba, 0xfa,
0x59, 0xca, 0x06, 0x9b, 0xfe, 0xc2
);
DEFINE_GUID(SID_ImmersiveLauncher,
0x6f86e01c,
0xc649, 0x4d61, 0xbe, 0x23,
0xf1, 0x32, 0x2d, 0xde, 0xca, 0x9d
);
DEFINE_GUID(IID_IImmersiveLauncher10RS,
0xd8d60399,
0xa0f1, 0xf987, 0x55, 0x51,
0x32, 0x1f, 0xd1, 0xb4, 0x98, 0x64
);
typedef interface IImmersiveMonitorService IImmersiveMonitorService;
typedef struct IImmersiveMonitorServiceVtbl
{
BEGIN_INTERFACE
HRESULT(STDMETHODCALLTYPE* QueryInterface)(
IImmersiveMonitorService* This,
/* [in] */ REFIID riid,
/* [annotation][iid_is][out] */
_COM_Outptr_ void** ppvObject);
ULONG(STDMETHODCALLTYPE* AddRef)(
IImmersiveMonitorService* This);
ULONG(STDMETHODCALLTYPE* Release)(
IImmersiveMonitorService* This);
HRESULT(STDMETHODCALLTYPE* method3)(
IImmersiveMonitorService* This);
HRESULT(STDMETHODCALLTYPE* method4)(
IImmersiveMonitorService* This);
HRESULT(STDMETHODCALLTYPE* method5)(
IImmersiveMonitorService* This);
HRESULT(STDMETHODCALLTYPE* GetFromHandle)(
IImmersiveMonitorService* This,
/* [in] */ HMONITOR hMonitor,
_COM_Outptr_ IUnknown** ppvObject);
END_INTERFACE
} IImmersiveMonitorServiceVtbl;
interface IImmersiveMonitorService
{
CONST_VTBL struct IImmersiveMonitorServiceVtbl* lpVtbl;
};
typedef interface IImmersiveLauncher10RS IImmersiveLauncher10RS;
typedef struct IImmersiveLauncher10RSVtbl
{
BEGIN_INTERFACE
HRESULT(STDMETHODCALLTYPE* QueryInterface)(
IImmersiveLauncher10RS* This,
/* [in] */ REFIID riid,
/* [annotation][iid_is][out] */
_COM_Outptr_ void** ppvObject);
ULONG(STDMETHODCALLTYPE* AddRef)(
IImmersiveLauncher10RS* This);
ULONG(STDMETHODCALLTYPE* Release)(
IImmersiveLauncher10RS* This);
HRESULT(STDMETHODCALLTYPE* ShowStartView)(
IImmersiveLauncher10RS* This,
/* [in] */ int method,
/* [in] */ int flags);
HRESULT(STDMETHODCALLTYPE* Dismiss)(
IImmersiveLauncher10RS* This);
HRESULT(STDMETHODCALLTYPE* method5)(
IImmersiveLauncher10RS* This);
HRESULT(STDMETHODCALLTYPE* method6)(
IImmersiveLauncher10RS* This);
HRESULT(STDMETHODCALLTYPE* IsVisible)(
IImmersiveLauncher10RS* This,
/* [in] */ BOOL* ret);
HRESULT(STDMETHODCALLTYPE* method8)(
IImmersiveLauncher10RS* This);
HRESULT(STDMETHODCALLTYPE* method9)(
IImmersiveLauncher10RS* This);
HRESULT(STDMETHODCALLTYPE* ConnectToMonitor)(
IImmersiveLauncher10RS* This,
/* [in] */ IUnknown* monitor);
HRESULT(STDMETHODCALLTYPE* GetMonitor)(
IImmersiveLauncher10RS* This,
/* [in] */ IUnknown** monitor);
END_INTERFACE
} IImmersiveLauncher10RSVtbl;
interface IImmersiveLauncher10RS
{
CONST_VTBL struct IImmersiveLauncher10RSVtbl* lpVtbl;
};
HANDLE hThread; HANDLE hThread;
@ -435,6 +567,180 @@ HRESULT CImmersiveHotkeyNotification_OnMessageHook(
); );
} }
// Slightly tweaked version of function available in Open Shell
// (Open-Shell-Menu\Src\StartMenu\StartMenuHelper\StartMenuHelper.cpp)
LRESULT CALLBACK HookProgManThread(int code, WPARAM wParam, LPARAM lParam)
{
if (code == HC_ACTION && wParam)
{
MSG* msg = (MSG*)lParam;
if (msg->message == WM_SYSCOMMAND && (msg->wParam & 0xFFF0) == SC_TASKLIST)
{
BOOL bShouldCheckHKLM = FALSE;
HKEY hKey;
if (RegOpenKeyEx(
HKEY_CURRENT_USER,
TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\StartPage"),
0,
KEY_READ,
&hKey
) != ERROR_SUCCESS)
{
bShouldCheckHKLM = TRUE;
}
DWORD dwStatus = 0;
DWORD dwSize = sizeof(DWORD);
if (RegGetValue(
hKey,
NULL,
TEXT("MonitorOverride"),
RRF_RT_REG_DWORD,
NULL,
&dwStatus,
(LPDWORD)(&dwSize)
) != ERROR_SUCCESS)
{
bShouldCheckHKLM = TRUE;
}
RegCloseKey(hKey);
if (bShouldCheckHKLM)
{
if (RegOpenKeyEx(
HKEY_LOCAL_MACHINE,
TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\StartPage"),
0,
KEY_READ,
&hKey
) != ERROR_SUCCESS)
{
goto finish;
}
dwStatus = 0;
dwSize = sizeof(DWORD);
if (RegGetValue(
hKey,
NULL,
TEXT("MonitorOverride"),
RRF_RT_REG_DWORD,
NULL,
&dwStatus,
(LPDWORD)(&dwSize)
) != ERROR_SUCCESS)
{
goto finish;
}
RegCloseKey(hKey);
}
if (dwStatus == 1)
{
goto finish;
}
DWORD pts = GetMessagePos();
POINT pt;
pt.x = GET_X_LPARAM(pts);
pt.y = GET_Y_LPARAM(pts);
HMONITOR monitor = MonitorFromPoint(
pt,
MONITOR_DEFAULTTONULL
);
HRESULT hr = S_OK;
IUnknown* pImmersiveShell;
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)
{
IUnknown* pMonitor = NULL;
pMonitorService->lpVtbl->GetFromHandle(
pMonitorService,
monitor,
&pMonitor
);
IImmersiveLauncher10RS* pLauncher = NULL;
IUnknown_QueryService(
pImmersiveShell,
&SID_ImmersiveLauncher,
&IID_IImmersiveLauncher10RS,
&pLauncher
);
if (pLauncher)
{
BOOL bIsVisible = FALSE;
pLauncher->lpVtbl->IsVisible(pLauncher, &bIsVisible);
if (SUCCEEDED(hr))
{
if (!bIsVisible)
{
if (pMonitor)
{
pLauncher->lpVtbl->ConnectToMonitor(pLauncher, pMonitor);
}
pLauncher->lpVtbl->ShowStartView(pLauncher, 11, 0);
}
else
{
pLauncher->lpVtbl->Dismiss(pLauncher);
}
}
pLauncher->lpVtbl->Release(pLauncher);
}
if (pMonitor)
{
pMonitor->lpVtbl->Release(pMonitor);
}
pMonitorService->lpVtbl->Release(pMonitorService);
}
pImmersiveShell->lpVtbl->Release(pImmersiveShell);
}
msg->message = WM_NULL;
}
}
finish:
return CallNextHookEx(NULL, code, wParam, lParam);
}
DWORD OpenStartOnCurentMonitorThread(LPVOID unused)
{
HWND g_ProgWin = FindWindowEx(
NULL,
NULL,
L"Progman",
NULL
);
DWORD progThread = GetWindowThreadProcessId(
g_ProgWin,
NULL
);
HHOOK g_ProgHook = SetWindowsHookEx(
WH_GETMESSAGE,
HookProgManThread,
NULL,
progThread
);
MSG msg = { 0 };
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
__declspec(dllexport) DWORD WINAPI main( __declspec(dllexport) DWORD WINAPI main(
_In_ LPVOID lpParameter _In_ LPVOID lpParameter
) )
@ -460,6 +766,17 @@ __declspec(dllexport) DWORD WINAPI main(
CreateThread(
0,
0,
OpenStartOnCurentMonitorThread,
0,
0,
0
);
HANDLE hUser32 = GetModuleHandle(L"user32.dll"); HANDLE hUser32 = GetModuleHandle(L"user32.dll");
if (hUser32) CreateWindowInBand = GetProcAddress(hUser32, "CreateWindowInBand"); if (hUser32) CreateWindowInBand = GetProcAddress(hUser32, "CreateWindowInBand");

1
README.md

@ -3,6 +3,7 @@ Explorer Patcher is a patcher that enables various stuff in Explorer. For the mo
* allows using the old taskbar in Windows 11 without the side effects of UndockingDisabled and with fully working search, modern apps showing properly, screen snip still working etc * allows using the old taskbar in Windows 11 without the side effects of UndockingDisabled and with fully working search, modern apps showing properly, screen snip still working etc
* enables the power user menu (Win+X) when using the classic taskbar in Windows 11 * enables the power user menu (Win+X) when using the classic taskbar in Windows 11
* shows the Start menu on the monitor containing the cursor when invoked with the Windows key
This has been tested only on Windows 11 build 22000.1. It probably does not work on other builds due to different offsets in explorer.exe and its libraries. Once this matures, a solution will be offered for dynamically determining the necessary offsets. As it stands, the application is more in a proof of concept phase. This has been tested only on Windows 11 build 22000.1. It probably does not work on other builds due to different offsets in explorer.exe and its libraries. Once this matures, a solution will be offered for dynamically determining the necessary offsets. As it stands, the application is more in a proof of concept phase.

Loading…
Cancel
Save