Skip to content

Commit ec80840

Browse files
committed
Start menu is displayed on monitor containing the cursor when opened
using the Windows key (v22000.1.0.3).
1 parent 4a65e22 commit ec80840

File tree

4 files changed

+326
-8
lines changed

4 files changed

+326
-8
lines changed

ExplorerPatcher/ExplorerPatcher.rc

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,8 @@ END
5151
//
5252

5353
VS_VERSION_INFO VERSIONINFO
54-
FILEVERSION 22000,1,0,2
55-
PRODUCTVERSION 22000,1,0,2
54+
FILEVERSION 22000,1,0,3
55+
PRODUCTVERSION 22000,1,0,3
5656
FILEFLAGSMASK 0x3fL
5757
#ifdef _DEBUG
5858
FILEFLAGS 0x1L
@@ -69,12 +69,12 @@ BEGIN
6969
BEGIN
7070
VALUE "CompanyName", "VALINET Solutions SRL"
7171
VALUE "FileDescription", "ExplorerPatcher Daemon"
72-
VALUE "FileVersion", "22000.1.0.2"
72+
VALUE "FileVersion", "22000.1.0.3"
7373
VALUE "InternalName", "ExplorerPatcher.exe"
7474
VALUE "LegalCopyright", "Copyright (C) 2006-2021 VALINET Solutions SRL. All rights reserved."
7575
VALUE "OriginalFilename", "ExplorerPatcher.exe"
7676
VALUE "ProductName", "ExplorerPatcher"
77-
VALUE "ProductVersion", "22000.1.0.2"
77+
VALUE "ProductVersion", "22000.1.0.3"
7878
END
7979
END
8080
BLOCK "VarFileInfo"

ExplorerPatcherLibrary/ExplorerPatcherLibrary.rc

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,8 @@ END
5151
//
5252

5353
VS_VERSION_INFO VERSIONINFO
54-
FILEVERSION 22000,1,0,2
55-
PRODUCTVERSION 22000,1,0,2
54+
FILEVERSION 22000,1,0,3
55+
PRODUCTVERSION 22000,1,0,3
5656
FILEFLAGSMASK 0x3fL
5757
#ifdef _DEBUG
5858
FILEFLAGS 0x1L
@@ -69,12 +69,12 @@ BEGIN
6969
BEGIN
7070
VALUE "CompanyName", "VALINET Solutions SRL"
7171
VALUE "FileDescription", "ExplorerPatcher Library"
72-
VALUE "FileVersion", "22000.1.0.2"
72+
VALUE "FileVersion", "22000.1.0.3"
7373
VALUE "InternalName", "ExplorerPatcherLibrary.dll"
7474
VALUE "LegalCopyright", "Copyright (C) 2006-2021 VALINET Solutions SRL. All rights reserved."
7575
VALUE "OriginalFilename", "ExplorerPatcherLibrary.dll"
7676
VALUE "ProductName", "WinOverview"
77-
VALUE "ProductVersion", "22000.1.0.2"
77+
VALUE "ProductVersion", "22000.1.0.3"
7878
END
7979
END
8080
BLOCK "VarFileInfo"

ExplorerPatcherLibrary/dllmain.c

Lines changed: 317 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#pragma comment(lib, "Shlwapi.lib")
99
#include <dwmapi.h>
1010
#pragma comment(lib, "Dwmapi.lib")
11+
#include <windowsx.h>
1112

1213
#define DEBUG
1314
#undef DEBUG
@@ -116,6 +117,137 @@ static BOOL(*IsDesktopInputContextFunc)(
116117

117118

118119

120+
DEFINE_GUID(CLSID_ImmersiveShell,
121+
0xc2f03a33,
122+
0x21f5, 0x47fa, 0xb4, 0xbb,
123+
0x15, 0x63, 0x62, 0xa2, 0xf2, 0x39
124+
);
125+
126+
DEFINE_GUID(SID_IImmersiveMonitorService,
127+
0x47094e3a,
128+
0x0cf2, 0x430f, 0x80, 0x6f,
129+
0xcf, 0x9e, 0x4f, 0x0f, 0x12, 0xdd
130+
);
131+
132+
DEFINE_GUID(IID_IImmersiveMonitorService,
133+
0x4d4c1e64,
134+
0xe410, 0x4faa, 0xba, 0xfa,
135+
0x59, 0xca, 0x06, 0x9b, 0xfe, 0xc2
136+
);
137+
138+
DEFINE_GUID(SID_ImmersiveLauncher,
139+
0x6f86e01c,
140+
0xc649, 0x4d61, 0xbe, 0x23,
141+
0xf1, 0x32, 0x2d, 0xde, 0xca, 0x9d
142+
);
143+
144+
DEFINE_GUID(IID_IImmersiveLauncher10RS,
145+
0xd8d60399,
146+
0xa0f1, 0xf987, 0x55, 0x51,
147+
0x32, 0x1f, 0xd1, 0xb4, 0x98, 0x64
148+
);
149+
150+
typedef interface IImmersiveMonitorService IImmersiveMonitorService;
151+
152+
typedef struct IImmersiveMonitorServiceVtbl
153+
{
154+
BEGIN_INTERFACE
155+
156+
HRESULT(STDMETHODCALLTYPE* QueryInterface)(
157+
IImmersiveMonitorService* This,
158+
/* [in] */ REFIID riid,
159+
/* [annotation][iid_is][out] */
160+
_COM_Outptr_ void** ppvObject);
161+
162+
ULONG(STDMETHODCALLTYPE* AddRef)(
163+
IImmersiveMonitorService* This);
164+
165+
ULONG(STDMETHODCALLTYPE* Release)(
166+
IImmersiveMonitorService* This);
167+
168+
HRESULT(STDMETHODCALLTYPE* method3)(
169+
IImmersiveMonitorService* This);
170+
171+
HRESULT(STDMETHODCALLTYPE* method4)(
172+
IImmersiveMonitorService* This);
173+
174+
HRESULT(STDMETHODCALLTYPE* method5)(
175+
IImmersiveMonitorService* This);
176+
177+
HRESULT(STDMETHODCALLTYPE* GetFromHandle)(
178+
IImmersiveMonitorService* This,
179+
/* [in] */ HMONITOR hMonitor,
180+
_COM_Outptr_ IUnknown** ppvObject);
181+
182+
END_INTERFACE
183+
} IImmersiveMonitorServiceVtbl;
184+
185+
interface IImmersiveMonitorService
186+
{
187+
CONST_VTBL struct IImmersiveMonitorServiceVtbl* lpVtbl;
188+
};
189+
190+
191+
typedef interface IImmersiveLauncher10RS IImmersiveLauncher10RS;
192+
193+
typedef struct IImmersiveLauncher10RSVtbl
194+
{
195+
BEGIN_INTERFACE
196+
197+
HRESULT(STDMETHODCALLTYPE* QueryInterface)(
198+
IImmersiveLauncher10RS* This,
199+
/* [in] */ REFIID riid,
200+
/* [annotation][iid_is][out] */
201+
_COM_Outptr_ void** ppvObject);
202+
203+
ULONG(STDMETHODCALLTYPE* AddRef)(
204+
IImmersiveLauncher10RS* This);
205+
206+
ULONG(STDMETHODCALLTYPE* Release)(
207+
IImmersiveLauncher10RS* This);
208+
209+
HRESULT(STDMETHODCALLTYPE* ShowStartView)(
210+
IImmersiveLauncher10RS* This,
211+
/* [in] */ int method,
212+
/* [in] */ int flags);
213+
214+
HRESULT(STDMETHODCALLTYPE* Dismiss)(
215+
IImmersiveLauncher10RS* This);
216+
217+
HRESULT(STDMETHODCALLTYPE* method5)(
218+
IImmersiveLauncher10RS* This);
219+
220+
HRESULT(STDMETHODCALLTYPE* method6)(
221+
IImmersiveLauncher10RS* This);
222+
223+
HRESULT(STDMETHODCALLTYPE* IsVisible)(
224+
IImmersiveLauncher10RS* This,
225+
/* [in] */ BOOL* ret);
226+
227+
HRESULT(STDMETHODCALLTYPE* method8)(
228+
IImmersiveLauncher10RS* This);
229+
230+
HRESULT(STDMETHODCALLTYPE* method9)(
231+
IImmersiveLauncher10RS* This);
232+
233+
HRESULT(STDMETHODCALLTYPE* ConnectToMonitor)(
234+
IImmersiveLauncher10RS* This,
235+
/* [in] */ IUnknown* monitor);
236+
237+
HRESULT(STDMETHODCALLTYPE* GetMonitor)(
238+
IImmersiveLauncher10RS* This,
239+
/* [in] */ IUnknown** monitor);
240+
241+
END_INTERFACE
242+
} IImmersiveLauncher10RSVtbl;
243+
244+
interface IImmersiveLauncher10RS
245+
{
246+
CONST_VTBL struct IImmersiveLauncher10RSVtbl* lpVtbl;
247+
};
248+
249+
250+
119251

120252
HANDLE hThread;
121253

@@ -435,6 +567,180 @@ HRESULT CImmersiveHotkeyNotification_OnMessageHook(
435567
);
436568
}
437569

570+
// Slightly tweaked version of function available in Open Shell
571+
// (Open-Shell-Menu\Src\StartMenu\StartMenuHelper\StartMenuHelper.cpp)
572+
LRESULT CALLBACK HookProgManThread(int code, WPARAM wParam, LPARAM lParam)
573+
{
574+
if (code == HC_ACTION && wParam)
575+
{
576+
MSG* msg = (MSG*)lParam;
577+
if (msg->message == WM_SYSCOMMAND && (msg->wParam & 0xFFF0) == SC_TASKLIST)
578+
{
579+
BOOL bShouldCheckHKLM = FALSE;
580+
HKEY hKey;
581+
if (RegOpenKeyEx(
582+
HKEY_CURRENT_USER,
583+
TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\StartPage"),
584+
0,
585+
KEY_READ,
586+
&hKey
587+
) != ERROR_SUCCESS)
588+
{
589+
bShouldCheckHKLM = TRUE;
590+
}
591+
DWORD dwStatus = 0;
592+
DWORD dwSize = sizeof(DWORD);
593+
if (RegGetValue(
594+
hKey,
595+
NULL,
596+
TEXT("MonitorOverride"),
597+
RRF_RT_REG_DWORD,
598+
NULL,
599+
&dwStatus,
600+
(LPDWORD)(&dwSize)
601+
) != ERROR_SUCCESS)
602+
{
603+
bShouldCheckHKLM = TRUE;
604+
}
605+
RegCloseKey(hKey);
606+
if (bShouldCheckHKLM)
607+
{
608+
if (RegOpenKeyEx(
609+
HKEY_LOCAL_MACHINE,
610+
TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\StartPage"),
611+
0,
612+
KEY_READ,
613+
&hKey
614+
) != ERROR_SUCCESS)
615+
{
616+
goto finish;
617+
}
618+
dwStatus = 0;
619+
dwSize = sizeof(DWORD);
620+
if (RegGetValue(
621+
hKey,
622+
NULL,
623+
TEXT("MonitorOverride"),
624+
RRF_RT_REG_DWORD,
625+
NULL,
626+
&dwStatus,
627+
(LPDWORD)(&dwSize)
628+
) != ERROR_SUCCESS)
629+
{
630+
goto finish;
631+
}
632+
RegCloseKey(hKey);
633+
}
634+
if (dwStatus == 1)
635+
{
636+
goto finish;
637+
}
638+
639+
DWORD pts = GetMessagePos();
640+
POINT pt;
641+
pt.x = GET_X_LPARAM(pts);
642+
pt.y = GET_Y_LPARAM(pts);
643+
HMONITOR monitor = MonitorFromPoint(
644+
pt,
645+
MONITOR_DEFAULTTONULL
646+
);
647+
648+
HRESULT hr = S_OK;
649+
IUnknown* pImmersiveShell;
650+
hr = CoCreateInstance(
651+
&CLSID_ImmersiveShell,
652+
NULL,
653+
CLSCTX_INPROC_SERVER,
654+
&IID_IServiceProvider,
655+
&pImmersiveShell
656+
);
657+
if (SUCCEEDED(hr))
658+
{
659+
IImmersiveMonitorService* pMonitorService = NULL;
660+
IUnknown_QueryService(
661+
pImmersiveShell,
662+
&SID_IImmersiveMonitorService,
663+
&IID_IImmersiveMonitorService,
664+
&pMonitorService
665+
);
666+
if (pMonitorService)
667+
{
668+
IUnknown* pMonitor = NULL;
669+
pMonitorService->lpVtbl->GetFromHandle(
670+
pMonitorService,
671+
monitor,
672+
&pMonitor
673+
);
674+
IImmersiveLauncher10RS* pLauncher = NULL;
675+
IUnknown_QueryService(
676+
pImmersiveShell,
677+
&SID_ImmersiveLauncher,
678+
&IID_IImmersiveLauncher10RS,
679+
&pLauncher
680+
);
681+
if (pLauncher)
682+
{
683+
BOOL bIsVisible = FALSE;
684+
pLauncher->lpVtbl->IsVisible(pLauncher, &bIsVisible);
685+
if (SUCCEEDED(hr))
686+
{
687+
if (!bIsVisible)
688+
{
689+
if (pMonitor)
690+
{
691+
pLauncher->lpVtbl->ConnectToMonitor(pLauncher, pMonitor);
692+
}
693+
pLauncher->lpVtbl->ShowStartView(pLauncher, 11, 0);
694+
}
695+
else
696+
{
697+
pLauncher->lpVtbl->Dismiss(pLauncher);
698+
}
699+
}
700+
pLauncher->lpVtbl->Release(pLauncher);
701+
}
702+
if (pMonitor)
703+
{
704+
pMonitor->lpVtbl->Release(pMonitor);
705+
}
706+
pMonitorService->lpVtbl->Release(pMonitorService);
707+
}
708+
pImmersiveShell->lpVtbl->Release(pImmersiveShell);
709+
}
710+
711+
msg->message = WM_NULL;
712+
}
713+
}
714+
finish:
715+
return CallNextHookEx(NULL, code, wParam, lParam);
716+
}
717+
718+
DWORD OpenStartOnCurentMonitorThread(LPVOID unused)
719+
{
720+
HWND g_ProgWin = FindWindowEx(
721+
NULL,
722+
NULL,
723+
L"Progman",
724+
NULL
725+
);
726+
DWORD progThread = GetWindowThreadProcessId(
727+
g_ProgWin,
728+
NULL
729+
);
730+
HHOOK g_ProgHook = SetWindowsHookEx(
731+
WH_GETMESSAGE,
732+
HookProgManThread,
733+
NULL,
734+
progThread
735+
);
736+
MSG msg = { 0 };
737+
while (GetMessage(&msg, NULL, 0, 0))
738+
{
739+
TranslateMessage(&msg);
740+
DispatchMessage(&msg);
741+
}
742+
}
743+
438744
__declspec(dllexport) DWORD WINAPI main(
439745
_In_ LPVOID lpParameter
440746
)
@@ -460,6 +766,17 @@ __declspec(dllexport) DWORD WINAPI main(
460766

461767

462768

769+
CreateThread(
770+
0,
771+
0,
772+
OpenStartOnCurentMonitorThread,
773+
0,
774+
0,
775+
0
776+
);
777+
778+
779+
463780
HANDLE hUser32 = GetModuleHandle(L"user32.dll");
464781

465782
if (hUser32) CreateWindowInBand = GetProcAddress(hUser32, "CreateWindowInBand");

0 commit comments

Comments
 (0)