diff --git a/CHANGELOG.md b/CHANGELOG.md index df936ed..0301381 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,20 @@ This document includes the same release notes as in the [Releases](https://github.com/valinet/ExplorerPatcher/releases) section on GitHub. +## 22000.318.35 + +Tested on build 22000.318. + +#### Feature enhancements + +* Start menu position can now be changed without needing to restart File Explorer + +#### Fixes + +* Improved reliability of Start menu positioning when the monitor topology changes and at startup +* Start menu injection returns error codes from the remote process in the debug console +* Other Start menu quality of life improvements + ## 22000.318.34 Tested on build 22000.318. diff --git a/ExplorerPatcher/ExplorerPatcher.rc b/ExplorerPatcher/ExplorerPatcher.rc index 4531c93..1306fa1 100644 --- a/ExplorerPatcher/ExplorerPatcher.rc +++ b/ExplorerPatcher/ExplorerPatcher.rc @@ -51,8 +51,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 22000,318,34,1 - PRODUCTVERSION 22000,318,34,1 + FILEVERSION 22000,318,35,0 + PRODUCTVERSION 22000,318,35,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -69,12 +69,12 @@ BEGIN BEGIN VALUE "CompanyName", "VALINET Solutions SRL" VALUE "FileDescription", "ExplorerPatcher" - VALUE "FileVersion", "22000.318.34.1" + VALUE "FileVersion", "22000.318.35.0" VALUE "InternalName", "ExplorerPatcher.dll" VALUE "LegalCopyright", "Copyright (C) 2006-2021 VALINET Solutions SRL. All rights reserved." VALUE "OriginalFilename", "ExplorerPatcher.dll" VALUE "ProductName", "ExplorerPatcher" - VALUE "ProductVersion", "22000.318.34.1" + VALUE "ProductVersion", "22000.318.35.0" END END BLOCK "VarFileInfo" diff --git a/ExplorerPatcher/StartMenu.c b/ExplorerPatcher/StartMenu.c index 1030482..9a530d0 100644 --- a/ExplorerPatcher/StartMenu.c +++ b/ExplorerPatcher/StartMenu.c @@ -448,3 +448,254 @@ DWORD WINAPI HookStartMenu(HookStartMenuParams* params) CloseHandle(hProcess); } } + +static HRESULT STDMETHODCALLTYPE WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented(void* instanceof_WindowsUdk_UI_Shell_ITaskbarSettings) +{ + return E_NOTIMPL; +} + +static ULONG STDMETHODCALLTYPE WindowsUdk_UI_Shell_ITaskbarSettings_AddRefRelease(void* instanceof_WindowsUdk_UI_Shell_ITaskbarSettings) +{ + return 1; +} + +static HRESULT STDMETHODCALLTYPE WindowsUdk_UI_Shell_ITaskbarSettings_GetAlignment_Left( + void* instanceof_WindowsUdk_UI_Shell_ITaskbarSettings, + DWORD* pAlignment +) +{ + *pAlignment = 0; + return 0; +} + +static HRESULT STDMETHODCALLTYPE WindowsUdk_UI_Shell_ITaskbarSettings_GetAlignment_Center( + void* instanceof_WindowsUdk_UI_Shell_ITaskbarSettings, + DWORD* pAlignment +) +{ + *pAlignment = 1; + return 0; +} + +static HRESULT STDMETHODCALLTYPE WindowsUdk_UI_Shell_ITaskbarSettings_GetLocation_Left( + void* instanceof_WindowsUdk_UI_Shell_ITaskbarSettings, + DWORD* pLocation +) +{ + *pLocation = 0; + return 0; +} + +static HRESULT STDMETHODCALLTYPE WindowsUdk_UI_Shell_ITaskbarSettings_GetLocation_Center( + void* instanceof_WindowsUdk_UI_Shell_ITaskbarSettings, + DWORD* pLocation +) +{ + *pLocation = 1; + return 0; +} + +static HRESULT STDMETHODCALLTYPE WindowsUdk_UI_Shell_ITaskbarSettings_GetSearchMode( + void* instanceof_WindowsUdk_UI_Shell_ITaskbarSettings, + DWORD* pSearchMode +) +{ + *pSearchMode = 1; + return 0; +} + +static void* instanceof_WindowsUdk_UI_Shell_ITaskbarSettingsVtbl[41] = { // : IInspectableVtbl + WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, + WindowsUdk_UI_Shell_ITaskbarSettings_AddRefRelease, + WindowsUdk_UI_Shell_ITaskbarSettings_AddRefRelease, + WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, + WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, + WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, + WindowsUdk_UI_Shell_ITaskbarSettings_GetAlignment_Left, + WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, + WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, + WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, + WindowsUdk_UI_Shell_ITaskbarSettings_GetLocation_Left, + WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, + WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, + WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, + WindowsUdk_UI_Shell_ITaskbarSettings_GetSearchMode, + WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, + WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, + WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, + WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, + WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, + WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, + WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, + WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, + WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, + WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, + WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, + WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, + WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, + WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, + WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, + WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, + WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, + WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, + WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, + WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, + WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, + WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, + WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, + WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, + WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented, + WindowsUdk_UI_Shell_ITaskbarSettings_NotImplemented +}; +typedef struct instanceof_WindowsUdk_UI_Shell_ITaskbarSettings // : IInspectable +{ + void* lpVtbl; +} WindowsUdk_UI_Shell_ITaskbarSettings; +static const WindowsUdk_UI_Shell_ITaskbarSettings instanceof_WindowsUdk_UI_Shell_ITaskbarSettings = { instanceof_WindowsUdk_UI_Shell_ITaskbarSettingsVtbl }; + +BOOL NeedsRo_PositionStartMenuForMonitor( + HMONITOR hMonitor, + HDC unused1, + LPRECT unused2, + StartMenuPositioningData* data +) +{ + // For this to have any chance to succeed, the Windows Runtime has to be + // already initialized on the calling thread, concurrency model RO_INIT_MULTITHREADED + + HRESULT hr = S_OK; + HSTRING_HEADER hstringHeader_of_WindowsUdk_UI_Shell_TaskbarLayout; + HSTRING hstring_of_WindowsUdk_UI_Shell_TaskbarLayout = NULL; + WindowsUdk_UI_Shell_TaskbarLayoutStatics* pTaskbarLayoutFactory = NULL; + IInspectable* pTaskbarLayout = NULL; + WindowsUdk_UI_Shell_TaskbarLayoutManager* pTaskbarLayoutManager = NULL; + + if (SUCCEEDED(hr)) + { + hr = WindowsCreateStringReference( + L"WindowsUdk.UI.Shell.TaskbarLayout", + 33, + &hstringHeader_of_WindowsUdk_UI_Shell_TaskbarLayout, + &hstring_of_WindowsUdk_UI_Shell_TaskbarLayout + ); + } + if (SUCCEEDED(hr)) + { + hr = RoGetActivationFactory( + hstring_of_WindowsUdk_UI_Shell_TaskbarLayout, + &IID_WindowsUdk_UI_Shell_TaskbarLayoutStatics, + &pTaskbarLayoutFactory + ); + } + if (SUCCEEDED(hr)) + { + //hr = (*(HRESULT(**)(INT64, INT64*))(*(INT64*)pTaskbarLayoutFactory + 48))(pTaskbarLayoutFactory, &v12); + hr = pTaskbarLayoutFactory->lpVtbl->get_Current(pTaskbarLayoutFactory, &pTaskbarLayout); + } + if (SUCCEEDED(hr)) + { + /*hr = (**(HRESULT(***)(INT64, GUID*, INT64*))v12)( + v12, + &IID_WindowsUdk_UI_Shell_ITaskbarLayoutManager, + (INT64*)&v13 + );*/ + hr = pTaskbarLayout->lpVtbl->QueryInterface( + pTaskbarLayout, + &IID_WindowsUdk_UI_Shell_ITaskbarLayoutManager, + &pTaskbarLayoutManager + ); + } + if (SUCCEEDED(hr)) + { + //hr = (*(HRESULT(**)(INT64, HMONITOR, INT64(***)(), INT64))(*v13 + 48 + (sizeof(uintptr_t) * data->operation)))(v13, hMonitor, &p, 0); + + // Filling a vtable for a winrt::WindowsUdk::UI::Shell::ITaskbarSettings interface + // some info about it can be found in method: + // > WindowsUdk::UI::Shell::Bamo::TaskbarLayoutBamoPrincipal::SetSettings + // from windowsudk.shellcommon.dll + // useful refrences: https://blog.magnusmontin.net/2017/12/30/minimal-uwp-wrl-xaml-app/ + // registry: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsRuntime\ActivatableClassId\WindowsUdk.UI.Shell.TaskbarLayout + if (data->location) + { + instanceof_WindowsUdk_UI_Shell_ITaskbarSettingsVtbl[6] = WindowsUdk_UI_Shell_ITaskbarSettings_GetAlignment_Center; + instanceof_WindowsUdk_UI_Shell_ITaskbarSettingsVtbl[10] = WindowsUdk_UI_Shell_ITaskbarSettings_GetLocation_Center; + } + else + { + instanceof_WindowsUdk_UI_Shell_ITaskbarSettingsVtbl[6] = WindowsUdk_UI_Shell_ITaskbarSettings_GetAlignment_Left; + instanceof_WindowsUdk_UI_Shell_ITaskbarSettingsVtbl[10] = WindowsUdk_UI_Shell_ITaskbarSettings_GetLocation_Left; + } + instanceof_WindowsUdk_UI_Shell_ITaskbarSettingsVtbl[14] = WindowsUdk_UI_Shell_ITaskbarSettings_GetSearchMode; + + if (data->operation == STARTMENU_POSITIONING_OPERATION_ADD) + { + hr = pTaskbarLayoutManager->lpVtbl->ReportMonitorAdded( + pTaskbarLayoutManager, + hMonitor, + &instanceof_WindowsUdk_UI_Shell_ITaskbarSettings, + NULL + ); + data->pMonitorList[InterlockedIncrement(data->pMonitorCount) - 1] = hMonitor; + printf("[Positioning] Added settings for monitor %p : %d\n", hMonitor, data->location); + } + else if (data->operation == STARTMENU_POSITIONING_OPERATION_CHANGE) + { + hr = pTaskbarLayoutManager->lpVtbl->ReportSettingsForMonitor( + pTaskbarLayoutManager, + hMonitor, + &instanceof_WindowsUdk_UI_Shell_ITaskbarSettings + ); + printf("[Positioning] Changed settings for monitor: %p : %d\n", hMonitor, data->location); + } + else if (data->operation == STARTMENU_POSITIONING_OPERATION_REMOVE) + { + hr = pTaskbarLayoutManager->lpVtbl->ReportMonitorRemoved( + pTaskbarLayoutManager, + hMonitor + ); + printf("[Positioning] Removed settings for monitor: %p\n", hMonitor); + } + } + if (pTaskbarLayoutManager) + { + pTaskbarLayoutManager->lpVtbl->Release(pTaskbarLayoutManager); + pTaskbarLayoutManager = NULL; + } + if (pTaskbarLayout) + { + pTaskbarLayout->lpVtbl->Release(pTaskbarLayout); + pTaskbarLayout = NULL; + } + if (pTaskbarLayoutFactory) + { + pTaskbarLayoutFactory->lpVtbl->Release(pTaskbarLayoutFactory); + pTaskbarLayoutFactory = NULL; + } + if (hstring_of_WindowsUdk_UI_Shell_TaskbarLayout) + { + WindowsDeleteString(hstring_of_WindowsUdk_UI_Shell_TaskbarLayout); + hstring_of_WindowsUdk_UI_Shell_TaskbarLayout = NULL; + } + + return TRUE; +} + +DWORD GetStartMenuPosition(FARPROC SHRegGetValueFromHKCUHKLMFunc) +{ + DWORD dwSize = sizeof(DWORD); + + DWORD dwTaskbarAl = 0; + if (!SHRegGetValueFromHKCUHKLMFunc || SHRegGetValueFromHKCUHKLMFunc( + TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced"), + TEXT("TaskbarAl"), + SRRF_RT_REG_DWORD, + NULL, + &dwTaskbarAl, + (LPDWORD)(&dwSize) + ) != ERROR_SUCCESS) + { + dwTaskbarAl = 0; + } + + return dwTaskbarAl; +} \ No newline at end of file diff --git a/ExplorerPatcher/StartMenu.h b/ExplorerPatcher/StartMenu.h index 7c937ee..5825136 100644 --- a/ExplorerPatcher/StartMenu.h +++ b/ExplorerPatcher/StartMenu.h @@ -8,6 +8,8 @@ #include #include #pragma comment(lib, "Psapi.lib") +#include +#include #pragma comment(lib, "ntdll.lib") EXTERN_C NTSYSAPI PIMAGE_NT_HEADERS NTAPI RtlImageNtHeader(PVOID); @@ -236,4 +238,143 @@ typedef struct _HookStartMenuParams FARPROC proc; } HookStartMenuParams; DWORD WINAPI HookStartMenu(HookStartMenuParams* params); + +typedef interface WindowsUdk_UI_Shell_TaskbarLayoutStatics WindowsUdk_UI_Shell_TaskbarLayoutStatics; +typedef interface WindowsUdk_UI_Shell_TaskbarLayoutManager WindowsUdk_UI_Shell_TaskbarLayoutManager; + +DEFINE_GUID(IID_WindowsUdk_UI_Shell_TaskbarLayoutStatics, + 0x4472FE8B, + 0xF3B1, 0x5CC9, 0x81, 0xc1, + 0x76, 0xf8, 0xc3, 0x38, 0x8a, 0xab +); + +typedef struct WindowsUdk_UI_Shell_TaskbarLayoutStaticsVtbl // : IInspectableVtbl +{ + BEGIN_INTERFACE + + HRESULT(STDMETHODCALLTYPE* QueryInterface)( + __RPC__in WindowsUdk_UI_Shell_TaskbarLayoutStatics* This, + /* [in] */ __RPC__in REFIID riid, + /* [annotation][iid_is][out] */ + _COM_Outptr_ void** ppvObject); + + ULONG(STDMETHODCALLTYPE* AddRef)( + __RPC__in WindowsUdk_UI_Shell_TaskbarLayoutStatics* This); + + ULONG(STDMETHODCALLTYPE* Release)( + __RPC__in WindowsUdk_UI_Shell_TaskbarLayoutStatics* This); + + HRESULT(STDMETHODCALLTYPE* GetIids)( + __RPC__in WindowsUdk_UI_Shell_TaskbarLayoutStatics* This, + /* [out] */ __RPC__out ULONG* iidCount, + /* [size_is][size_is][out] */ __RPC__deref_out_ecount_full_opt(*iidCount) IID** iids); + + HRESULT(STDMETHODCALLTYPE* GetRuntimeClassName)( + __RPC__in WindowsUdk_UI_Shell_TaskbarLayoutStatics* This, + /* [out] */ __RPC__deref_out_opt HSTRING* className); + + HRESULT(STDMETHODCALLTYPE* GetTrustLevel)( + __RPC__in WindowsUdk_UI_Shell_TaskbarLayoutStatics* This, + /* [out] */ __RPC__out TrustLevel* trustLevel); + + HRESULT(STDMETHODCALLTYPE* get_Current)( + __RPC__in WindowsUdk_UI_Shell_TaskbarLayoutStatics* This, + /* [out] */ __RPC__out void** _instanceof_winrt_WindowsUdk_UI_Shell_implementation_TaskbarLayout); + + END_INTERFACE +} WindowsUdk_UI_Shell_TaskbarLayoutStaticsVtbl; + +interface WindowsUdk_UI_Shell_TaskbarLayoutStatics // : IInspectable +{ + CONST_VTBL struct WindowsUdk_UI_Shell_TaskbarLayoutStaticsVtbl* lpVtbl; +}; + +DEFINE_GUID(IID_WindowsUdk_UI_Shell_ITaskbarLayoutManager, + 0x4FB10D7C4, + 0x4F7F, 0x5DE5, 0xA5, 0x28, + 0x7e, 0xfe, 0xf4, 0x18, 0xaa, 0x48 +); + +typedef struct WindowsUdk_UI_Shell_TaskbarLayoutManagerVtbl // : IInspectableVtbl +{ + BEGIN_INTERFACE + + HRESULT(STDMETHODCALLTYPE* QueryInterface)( + __RPC__in WindowsUdk_UI_Shell_TaskbarLayoutManager* This, + /* [in] */ __RPC__in REFIID riid, + /* [annotation][iid_is][out] */ + _COM_Outptr_ void** ppvObject); + + ULONG(STDMETHODCALLTYPE* AddRef)( + __RPC__in WindowsUdk_UI_Shell_TaskbarLayoutManager* This); + + ULONG(STDMETHODCALLTYPE* Release)( + __RPC__in WindowsUdk_UI_Shell_TaskbarLayoutManager* This); + + HRESULT(STDMETHODCALLTYPE* GetIids)( + __RPC__in WindowsUdk_UI_Shell_TaskbarLayoutManager* This, + /* [out] */ __RPC__out ULONG* iidCount, + /* [size_is][size_is][out] */ __RPC__deref_out_ecount_full_opt(*iidCount) IID** iids); + + HRESULT(STDMETHODCALLTYPE* GetRuntimeClassName)( + __RPC__in WindowsUdk_UI_Shell_TaskbarLayoutManager* This, + /* [out] */ __RPC__deref_out_opt HSTRING* className); + + HRESULT(STDMETHODCALLTYPE* GetTrustLevel)( + __RPC__in WindowsUdk_UI_Shell_TaskbarLayoutManager* This, + /* [out] */ __RPC__out TrustLevel* trustLevel); + + HRESULT(STDMETHODCALLTYPE* ReportMonitorAdded)( + __RPC__in WindowsUdk_UI_Shell_TaskbarLayoutManager* This, + __RPC__in HMONITOR hMonitor, + __RPC__in void* _instance_of_winrt_WindowsUdk_UI_Shell_ITaskbarSettings, + __RPC__in LPRECT _unknown_lpGeometry); + + HRESULT(STDMETHODCALLTYPE* ReportMonitorRemoved)( + __RPC__in WindowsUdk_UI_Shell_TaskbarLayoutManager* This, + __RPC__in HMONITOR hMonitor); + + HRESULT(STDMETHODCALLTYPE* ReportMonitorChanged)( + __RPC__in WindowsUdk_UI_Shell_TaskbarLayoutManager* This, + __RPC__in HMONITOR hMonitor, + __RPC__in LPRECT _unknown_lpGeometry); + + HRESULT(STDMETHODCALLTYPE* ReportSettingsForMonitor)( + __RPC__in WindowsUdk_UI_Shell_TaskbarLayoutManager* This, + __RPC__in HMONITOR hMonitor, + __RPC__in void* _instance_of_winrt_WindowsUdk_UI_Shell_ITaskbarSettings); + + HRESULT(STDMETHODCALLTYPE* ReportShellViewButtonBounds)( + __RPC__in WindowsUdk_UI_Shell_TaskbarLayoutManager* This, + __RPC__in HMONITOR hMonitor, + __RPC__in void* _instanceof_winrt_WindowsUdk_UI_Shell_Bamo_ShellViewButtonBounds); + + END_INTERFACE +} WindowsUdk_UI_Shell_TaskbarLayoutManagerVtbl; + +interface WindowsUdk_UI_Shell_TaskbarLayoutManager // : IInspectable +{ + CONST_VTBL struct WindowsUdk_UI_Shell_TaskbarLayoutManagerVtbl* lpVtbl; +}; + +typedef struct _StartMenuPositioningData +{ + DWORD location; + DWORD operation; + DWORD* pMonitorCount; + HMONITOR* pMonitorList; +} StartMenuPositioningData; + +#define STARTMENU_POSITIONING_OPERATION_ADD 0 +#define STARTMENU_POSITIONING_OPERATION_REMOVE 1 +#define STARTMENU_POSITIONING_OPERATION_CHANGE 3 + +BOOL NeedsRo_PositionStartMenuForMonitor( + HMONITOR hMonitor, + HDC unused1, + LPRECT unused2, + StartMenuPositioningData* data +); + +DWORD GetStartMenuPosition(FARPROC SHRegGetValueFromHKCUHKLMFunc); #endif diff --git a/ExplorerPatcher/dllmain.c b/ExplorerPatcher/dllmain.c index ba031ab..303ee73 100644 --- a/ExplorerPatcher/dllmain.c +++ b/ExplorerPatcher/dllmain.c @@ -68,6 +68,7 @@ DWORD bHookStartMenu = TRUE; DWORD bNoMenuAccelerator = FALSE; DWORD bTaskbarMonitorOverride = 0; DWORD dwIMEStyle = 0; +DWORD dwTaskbarAl = 0; HMODULE hModule = NULL; HANDLE hSettingsMonitorThread = NULL; HANDLE hDelayedInjectionThread = NULL; @@ -77,6 +78,8 @@ HANDLE hExitSettingsMonitor = NULL; HANDLE hSwsSettingsChanged = NULL; HANDLE hSwsOpacityMaybeChanged = NULL; BYTE* lpShouldDisplayCCButton = NULL; +HMONITOR hMonitorList[30]; +DWORD dwMonitorCount = 0; int Code = 0; @@ -855,6 +858,55 @@ finalize: #pragma endregion +#pragma region "Show Start in correct location according to TaskbarAl" +#ifdef _WIN64 +void UpdateStartMenuPositioning(LPARAM loIsShouldInitializeArray_hiIsShouldRoInitialize) +{ + BOOL bShouldInitialize = LOWORD(loIsShouldInitializeArray_hiIsShouldRoInitialize); + BOOL bShouldRoInitialize = HIWORD(loIsShouldInitializeArray_hiIsShouldRoInitialize); + + DWORD dwPosCurrent = GetStartMenuPosition(SHRegGetValueFromHKCUHKLMFunc); + if (bShouldInitialize || InterlockedAdd(&dwTaskbarAl, 0) != dwPosCurrent) + { + HRESULT hr = S_OK; + if (bShouldRoInitialize) + { + hr = RoInitialize(RO_INIT_MULTITHREADED); + } + if (SUCCEEDED(hr)) + { + InterlockedExchange(&dwTaskbarAl, dwPosCurrent); + StartMenuPositioningData spd; + spd.pMonitorCount = &dwMonitorCount; + spd.pMonitorList = hMonitorList; + spd.location = dwPosCurrent; + if (bShouldInitialize) + { + spd.operation = STARTMENU_POSITIONING_OPERATION_REMOVE; + unsigned int k = InterlockedAdd(&dwMonitorCount, 0); + for (unsigned int i = 0; i < k; ++i) + { + NeedsRo_PositionStartMenuForMonitor(hMonitorList[i], NULL, NULL, &spd); + } + InterlockedExchange(&dwMonitorCount, 0); + spd.operation = STARTMENU_POSITIONING_OPERATION_ADD; + } + else + { + spd.operation = STARTMENU_POSITIONING_OPERATION_CHANGE; + } + EnumDisplayMonitors(NULL, NULL, NeedsRo_PositionStartMenuForMonitor, &spd); + if (bShouldRoInitialize) + { + RoUninitialize(); + } + } + } +} +#endif +#pragma endregion + + #pragma region "Shell_TrayWnd subclass" #ifdef _WIN64 INT64 Shell_TrayWndSubclassProc( @@ -883,6 +935,10 @@ INT64 Shell_TrayWndSubclassProc( } return lRes; } + else if (uMsg == WM_DISPLAYCHANGE) + { + UpdateStartMenuPositioning(MAKELPARAM(TRUE, FALSE)); + } return DefSubclassProc(hWnd, uMsg, wParam, lParam); } #endif @@ -1894,189 +1950,13 @@ INT64 winrt_Windows_Internal_Shell_implementation_MeetAndChatManager_OnMessageHo #pragma endregion -#pragma region "Show Start in correct location according to TaskbarAl" +#pragma region "Enable old taskbar" #ifdef _WIN64 DEFINE_GUID(GUID_18C02F2E_2754_5A20_8BD5_0B34CE79DA2B, 0x18C02F2E, 0x2754, 0x5A20, 0x8b, 0xd5, 0x0b, 0x34, 0xce, 0x79, 0xda, 0x2b ); - -DEFINE_GUID(_uuidof_WindowsUdk_UI_Shell_TaskbarLayout_Factory, - 0x4472FE8B, - 0xF3B1, 0x5CC9, 0x81, 0xc1, - 0x76, 0xf8, 0xc3, 0x38, 0x8a, 0xab -); -DEFINE_GUID(_uuidof_v13, - 0x4FB10D7C4, - 0x4F7F, 0x5DE5, 0xA5, 0x28, - 0x7e, 0xfe, 0xf4, 0x18, 0xaa, 0x48 -); -BOOL PositionStartMenuForMonitor( - HMONITOR hMonitor, - HDC unused1, - LPRECT unused2, - DWORD location) -{ - HRESULT hr = S_OK; - HSTRING_HEADER hstringHeader; - HSTRING string = NULL; - void* factory = NULL; - INT64 v12 = NULL; - INT64* v13 = NULL; - - if (SUCCEEDED(hr)) - { - hr = RoInitialize(RO_INIT_MULTITHREADED); - } - if (SUCCEEDED(hr)) - { - hr = WindowsCreateStringReference( - L"WindowsUdk.UI.Shell.TaskbarLayout", - 33, - &hstringHeader, - &string - ); - } - if (SUCCEEDED(hr)) - { - hr = RoGetActivationFactory( - string, - &_uuidof_WindowsUdk_UI_Shell_TaskbarLayout_Factory, - &factory - ); - } - if (SUCCEEDED(hr)) - { - hr = (*(HRESULT(**)(INT64, INT64*))(*(INT64*)factory + 48))(factory, &v12); - } - if (SUCCEEDED(hr)) - { - hr = (**(HRESULT(***)(INT64, GUID*, INT64*))v12)(v12, &_uuidof_v13, (INT64*)&v13); // QueryInterface - } - if (SUCCEEDED(hr)) - { - void** p = malloc(41 * sizeof(void*)); - for (unsigned int i = 0; i < 41; ++i) - { - if (i == 1 || i == 2) - { - p[i] = nimpl3; - } - else if (i == 6 || i == 10) - { - if (location) - { - p[i] = nimpl4_1; - } - else - { - p[i] = nimpl4_0; - } - } - else if (i == 14) - { - p[i] = nimpl4_1; - } - else - { - p[i] = nimpl; - } - } - hr = (*(HRESULT(**)(INT64, HMONITOR, INT64(***)(), INT64))(*v13 + 48))(v13, hMonitor, &p, 0); - free(p); - } - if (SUCCEEDED(hr)) - { - (*(void(**)(INT64*))(*v13 + 16))(v13); // Release - (*(void(**)(INT64))(*(INT64*)v12 + 16))(v12); // Release - (*(void(**)(INT64))(*(INT64*)factory + 16))(factory); // Release - WindowsDeleteString(string); - RoUninitialize(); - } - return TRUE; -} - -void PositionStartMenu(INT64 unused, DWORD location) -{ - HWND hWnd = NULL; - - do - { - hWnd = FindWindowEx( - NULL, - hWnd, - L"Shell_SecondaryTrayWnd", - NULL - ); - PositionStartMenuForMonitor(MonitorFromWindow(hWnd, MONITOR_DEFAULTTOPRIMARY), NULL, NULL, location); - } while (hWnd); - if (!hWnd) - { - hWnd = FindWindowEx( - NULL, - NULL, - L"Shell_TrayWnd", - NULL - ); - PositionStartMenuForMonitor(MonitorFromWindow(hWnd, MONITOR_DEFAULTTOPRIMARY), NULL, NULL, location); - } -} - -DWORD PositionStartMenuTimeout(INT64 timeout) -{ - Sleep(timeout); - printf("Started \"Position Start menu\" thread.\n"); - EnumDisplayMonitors(NULL, NULL, PositionStartMenuForMonitor, GetStartMenuPosition()); - printf("Ended \"Position Start menu\" thread.\n"); -} - -DWORD GetStartMenuPosition() -{ - DWORD dwSize = sizeof(DWORD); - - DWORD dwTaskbarAl = 0; - if (!SHRegGetValueFromHKCUHKLMFunc || SHRegGetValueFromHKCUHKLMFunc( - TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced"), - TEXT("TaskbarAl"), - SRRF_RT_REG_DWORD, - NULL, - &dwTaskbarAl, - (LPDWORD)(&dwSize) - ) != ERROR_SUCCESS) - { - dwTaskbarAl = 0; - } - - return dwTaskbarAl; -} - -INT64 PositionStartMenuOnMonitorTopologyChangeSubclass( - _In_ HWND hWnd, - _In_ UINT uMsg, - _In_ WPARAM wParam, - _In_ LPARAM lParam, - UINT_PTR uIdSubclass, - DWORD_PTR dwRefData -) -{ - if (uMsg == WM_DISPLAYCHANGE) - { - CreateThread(0, 0, PositionStartMenuTimeout, 1000, 0, 0); - } - return DefSubclassProc( - hWnd, - uMsg, - wParam, - lParam - ); -} -#endif -#pragma endregion - - -#pragma region "Enable old taskbar" -#ifdef _WIN64 HRESULT explorer_RoGetActivationFactoryHook(HSTRING activatableClassId, GUID* iid, void** factory) { PCWSTR StringRawBuffer = WindowsGetStringRawBuffer(activatableClassId, 0); @@ -2382,6 +2262,7 @@ INT64 ShowDesktopSubclassProc( DWORD SignalShellReady(DWORD wait) { printf("Started \"Signal shell ready\" thread.\n"); + UpdateStartMenuPositioning(MAKELPARAM(TRUE, TRUE)); while (!wait && TRUE) { @@ -2403,34 +2284,7 @@ DWORD SignalShellReady(DWORD wait) { if (IsWindowVisible(hWnd)) { - /* - SetWindowSubclass( - hWnd, - PositionStartMenuOnMonitorTopologyChangeSubclass, - PositionStartMenuOnMonitorTopologyChangeSubclass, - 0 - ); - SettingsChangeParameters* params = calloc(1, sizeof(SettingsChangeParameters)); - params->isStartMenuExperienceHost = FALSE; - params->TaskbarAlChangedCallback = PositionStartMenu; - params->TaskbarAlChangedCallbackData = 0; - CreateThread( - 0, - 0, - MonitorSettingsChanges, - params, - 0, - 0 - ); - */ - EnumDisplayMonitors(NULL, NULL, PositionStartMenuForMonitor, GetStartMenuPosition()); - /*printf("hook show desktop\n"); - void* ShellTrayWndProcFuncT = GetWindowLongPtrW(hWnd, GWLP_WNDPROC); - if (ShellTrayWndProcHook != ShellTrayWndProcFuncT) - { - ShellTrayWndProcFunc = ShellTrayWndProcFuncT; - SetWindowLongPtrW(hWnd, GWLP_WNDPROC, ShellTrayWndProcHook); - }*/ + // UpdateStartMenuPositioning(MAKELPARAM(TRUE, TRUE)); break; } } @@ -2447,7 +2301,7 @@ DWORD SignalShellReady(DWORD wait) Sleep(wait); } - HANDLE hEvent = CreateEvent(0, 0, 0, L"ShellDesktopSwitchEvent"); + HANDLE hEvent = CreateEventW(0, 0, 0, L"ShellDesktopSwitchEvent"); if (hEvent) { printf(">>> Signal shell ready.\n"); @@ -4092,7 +3946,7 @@ __declspec(dllexport) DWORD WINAPI main( hSwsOpacityMaybeChanged = CreateEventW(NULL, FALSE, FALSE, NULL); } - settings = calloc(9, sizeof(Setting)); + settings = calloc(10, sizeof(Setting)); settings[0].callback = LoadSettings; settings[0].data = bIsExplorer; settings[0].hEvent = NULL; @@ -4156,9 +4010,16 @@ __declspec(dllexport) DWORD WINAPI main( wcscpy_s(settings[8].name, MAX_PATH, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer"); settings[8].origin = HKEY_CURRENT_USER; + settings[9].callback = UpdateStartMenuPositioning; + settings[9].data = MAKELPARAM(FALSE, TRUE); + settings[9].hEvent = NULL; + settings[9].hKey = NULL; + wcscpy_s(settings[9].name, MAX_PATH, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Advanced"); + settings[9].origin = HKEY_CURRENT_USER; + settingsParams = calloc(1, sizeof(SettingsChangeParameters)); settingsParams->settings = settings; - settingsParams->size = bIsExplorer ? 9 : 1; + settingsParams->size = bIsExplorer ? 10 : 1; hExitSettingsMonitor = CreateEventW(NULL, FALSE, FALSE, NULL); settingsParams->hExitEvent = hExitSettingsMonitor; if (!hSettingsMonitorThread) diff --git a/ExplorerPatcher/settings.reg b/ExplorerPatcher/settings.reg index 38282c5..d093f5e 100644 --- a/ExplorerPatcher/settings.reg +++ b/ExplorerPatcher/settings.reg @@ -138,7 +138,7 @@ ;b Open Start in All apps by default "MakeAllAppsDefault"=dword:00000000 [HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced] -;c 2 Location on screen * +;c 2 Location on screen ;x 0 Left ;x 1 Center (default) "TaskbarAl"=dword:00000001