8
8
#pragma comment(lib, "Shlwapi.lib")
9
9
#include <dwmapi.h>
10
10
#pragma comment(lib, "Dwmapi.lib")
11
+ #include <windowsx.h>
11
12
12
13
#define DEBUG
13
14
#undef DEBUG
@@ -116,6 +117,137 @@ static BOOL(*IsDesktopInputContextFunc)(
116
117
117
118
118
119
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
+
119
251
120
252
HANDLE hThread ;
121
253
@@ -435,6 +567,180 @@ HRESULT CImmersiveHotkeyNotification_OnMessageHook(
435
567
);
436
568
}
437
569
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
+
438
744
__declspec(dllexport ) DWORD WINAPI main (
439
745
_In_ LPVOID lpParameter
440
746
)
@@ -460,6 +766,17 @@ __declspec(dllexport) DWORD WINAPI main(
460
766
461
767
462
768
769
+ CreateThread (
770
+ 0 ,
771
+ 0 ,
772
+ OpenStartOnCurentMonitorThread ,
773
+ 0 ,
774
+ 0 ,
775
+ 0
776
+ );
777
+
778
+
779
+
463
780
HANDLE hUser32 = GetModuleHandle (L"user32.dll" );
464
781
465
782
if (hUser32 ) CreateWindowInBand = GetProcAddress (hUser32 , "CreateWindowInBand" );
0 commit comments