1
0
mirror of https://github.com/valinet/ExplorerPatcher.git synced 2024-11-27 17:00:59 +01:00

Start menu positioning improvements; refactored and explained code

This commit is contained in:
Valentin Radu 2021-11-10 21:33:04 +02:00
parent e4eff89cf1
commit aa0371e0fb
6 changed files with 480 additions and 213 deletions

View File

@ -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.

View File

@ -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"

View File

@ -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;
}

View File

@ -8,6 +8,8 @@
#include <TlHelp32.h>
#include <Psapi.h>
#pragma comment(lib, "Psapi.lib")
#include <roapi.h>
#include <winstring.h>
#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

View File

@ -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)

View File

@ -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