7 changed files with 463 additions and 130 deletions
@ -1,62 +1,247 @@ |
|||||||
#include "TaskbarCenter.h" |
#include "TaskbarCenter.h" |
||||||
|
|
||||||
HANDLE hEvent; |
extern DWORD dwOldTaskbarAl; |
||||||
|
extern DWORD dwMMOldTaskbarAl; |
||||||
|
extern wchar_t* EP_TASKBAR_LENGTH_PROP_NAME; |
||||||
|
#define EP_TASKBAR_LENGTH_TOO_SMALL 20 |
||||||
|
|
||||||
HRESULT TaskbarCenter_Center() |
inline BOOL TaskbarCenter_IsTaskbarHorizontal(HWND hWnd) |
||||||
{ |
{ |
||||||
HRESULT hr = S_OK; |
__int64 v1; |
||||||
HWND hWnd = FindWindowExW(NULL, NULL, L"Shell_TrayWnd", NULL); |
__int64 result; |
||||||
|
v1 = *((__int64*)GetWindowLongPtrW(hWnd, 0) + 13); |
||||||
while (hWnd) |
result = 1i64; |
||||||
{ |
if (v1) |
||||||
if (SUCCEEDED(hr)) |
return (*(__int64(__fastcall**)(__int64))(*(__int64*)v1 + 96))(v1); |
||||||
{ |
return result; |
||||||
/*hr = AccessibleObjectFromWindow(
|
} |
||||||
|
|
||||||
);*/ |
|
||||||
} |
|
||||||
|
|
||||||
hWnd = NULL; |
inline BOOL TaskbarCenter_ShouldCenter(DWORD dwSetting) |
||||||
} |
{ |
||||||
|
return (dwSetting & 0b001); |
||||||
|
} |
||||||
|
|
||||||
|
inline BOOL TaskbarCenter_ShouldStartBeCentered(DWORD dwSetting) |
||||||
|
{ |
||||||
|
return (dwSetting & 0b010); |
||||||
} |
} |
||||||
|
|
||||||
BOOL TaskbarCenter_Notify() |
inline BOOL TaskbarCenter_ShouldLeftAlignWhenSpaceConstrained(DWORD dwSetting) |
||||||
{ |
{ |
||||||
if (hEvent) |
return (dwSetting & 0b100); |
||||||
{ |
|
||||||
SetEvent(hEvent); |
|
||||||
return TRUE; |
|
||||||
} |
|
||||||
return FALSE; |
|
||||||
} |
} |
||||||
|
|
||||||
BOOL GetClientRectHook(HWND hWnd, LPRECT lpRect) |
HRESULT TaskbarCenter_Center(HWND hWnd, RECT rc, BOOL bIsTaskbarHorizontal) |
||||||
{ |
{ |
||||||
wchar_t wszClassName[100]; |
HRESULT hr = S_OK; |
||||||
ZeroMemory(wszClassName, 100); |
VARIANT vtChild[10]; |
||||||
GetClassNameW(hWnd, wszClassName, 100); |
VARIANT vt; |
||||||
if (!wcscmp(wszClassName, L"MSTaskListWClass")) |
long k = 0, kk = 0; |
||||||
|
|
||||||
|
IAccessible* pAccessible = NULL; |
||||||
|
AccessibleObjectFromWindow(hWnd, 0, &IID_IAccessible, &pAccessible); |
||||||
|
if (pAccessible) |
||||||
|
{ |
||||||
|
pAccessible->lpVtbl->get_accChildCount(pAccessible, &kk); |
||||||
|
if (kk <= 10) |
||||||
|
{ |
||||||
|
AccessibleChildren(pAccessible, 0, kk, vtChild, &k); |
||||||
|
for (int i = 0; i < k; ++i) |
||||||
|
{ |
||||||
|
if (vtChild[i].vt == VT_DISPATCH) |
||||||
{ |
{ |
||||||
TaskbarCenter_Center(); |
IDispatch* pDisp = vtChild[i].ppdispVal; |
||||||
|
IAccessible* pChild = NULL; |
||||||
|
pDisp->lpVtbl->QueryInterface(pDisp, &IID_IAccessible, &pChild); |
||||||
|
if (pChild) |
||||||
|
{ |
||||||
|
vt.vt = VT_I4; |
||||||
|
vt.lVal = CHILDID_SELF; |
||||||
|
pChild->lpVtbl->get_accRole(pChild, vt, &vt); |
||||||
|
if (vt.lVal == ROLE_SYSTEM_TOOLBAR) |
||||||
|
{ |
||||||
|
IAccessible* pLast = NULL; |
||||||
|
kk = 0; |
||||||
|
pChild->lpVtbl->get_accChildCount(pChild, &kk); |
||||||
|
if (kk <= 1) |
||||||
|
{ |
||||||
|
SetPropW(hWnd, EP_TASKBAR_LENGTH_PROP_NAME, -1); |
||||||
} |
} |
||||||
return GetClientRect(hWnd, lpRect); |
else if (kk >= 2) |
||||||
|
{ |
||||||
|
vt.vt = VT_I4; |
||||||
|
vt.lVal = kk - 1; |
||||||
|
long x = 0, y = 0, w = 0, h = 0, d = 0; |
||||||
|
pChild->lpVtbl->accLocation(pChild, &x, &y, &w, &h, vt); |
||||||
|
if (bIsTaskbarHorizontal ? (x == -1 || w < EP_TASKBAR_LENGTH_TOO_SMALL) : (y == -1 || h < EP_TASKBAR_LENGTH_TOO_SMALL)) |
||||||
|
{ |
||||||
|
hr = E_FAIL; |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
if (kk >= 3) |
||||||
|
{ |
||||||
|
d = (bIsTaskbarHorizontal ? ((x - rc.left) + w) : ((y - rc.top) + h)); |
||||||
|
vt.vt = VT_I4; |
||||||
|
vt.lVal = 1; |
||||||
|
x = 0, y = 0, w = 0, h = 0; |
||||||
|
pChild->lpVtbl->accLocation(pChild, &x, &y, &w, &h, vt); |
||||||
|
if (bIsTaskbarHorizontal ? w == 0 : h == 0) |
||||||
|
{ |
||||||
|
vt.vt = VT_I4; |
||||||
|
vt.lVal = 2; |
||||||
|
x = 0, y = 0, w = 0, h = 0; |
||||||
|
pChild->lpVtbl->accLocation(pChild, &x, &y, &w, &h, vt); |
||||||
|
} |
||||||
|
if (bIsTaskbarHorizontal ? (x == -1 || w < EP_TASKBAR_LENGTH_TOO_SMALL) : (y == -1 || h < EP_TASKBAR_LENGTH_TOO_SMALL)) |
||||||
|
{ |
||||||
|
hr == E_FAIL; |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
SetPropW(hWnd, EP_TASKBAR_LENGTH_PROP_NAME, (bIsTaskbarHorizontal ? (d - (x - rc.left)) : (d - (y - rc.top)))); |
||||||
|
} |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
SetPropW(hWnd, EP_TASKBAR_LENGTH_PROP_NAME, bIsTaskbarHorizontal ? w : h); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
pChild->lpVtbl->Release(pChild); |
||||||
|
} |
||||||
|
pDisp->lpVtbl->Release(pDisp); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
pAccessible->lpVtbl->Release(pAccessible); |
||||||
|
} |
||||||
|
return hr; |
||||||
} |
} |
||||||
|
|
||||||
HRESULT TaskbarCenter_Initialize(HMODULE hExplorer) |
BOOL TaskbarCenter_GetClientRectHook(HWND hWnd, LPRECT lpRect) |
||||||
{ |
{ |
||||||
if (!(hEvent = CreateEventW(NULL, TRUE, FALSE, TASKBAR_CHANGED_NOTIFICATION))) |
BOOL bWasCalled = FALSE; |
||||||
|
HWND hWndStart = NULL; |
||||||
|
RECT rcStart; |
||||||
|
SetRect(&rcStart, 0, 0, 0, 0); |
||||||
|
if (GetClassWord(hWnd, GCW_ATOM) == RegisterWindowMessageW(L"MSTaskListWClass")) |
||||||
|
{ |
||||||
|
BOOL bIsPrimaryTaskbar = GetClassWord(GetParent(hWnd), GCW_ATOM) == RegisterWindowMessageW(L"MSTaskSwWClass"); |
||||||
|
DWORD dwSetting = (bIsPrimaryTaskbar ? dwOldTaskbarAl : dwMMOldTaskbarAl); |
||||||
|
HWND hWndTaskbar = NULL; |
||||||
|
if (bIsPrimaryTaskbar) |
||||||
{ |
{ |
||||||
return E_NOTIMPL; |
hWndTaskbar = GetParent(GetParent(GetParent(hWnd))); |
||||||
} |
} |
||||||
if (FindWindowExW(NULL, NULL, L"Shell_TrayWnd", NULL)) |
else |
||||||
{ |
{ |
||||||
return E_NOTIMPL; |
hWndTaskbar = GetParent(GetParent(hWnd)); |
||||||
} |
} |
||||||
// This is one of the methods called by explorer!CTaskListWnd::_RecomputeLayout
|
hWndStart = FindWindowExW(hWndTaskbar, NULL, L"Start", NULL); |
||||||
if (!VnPatchDelayIAT(hExplorer, "ext-ms-win-rtcore-ntuser-window-ext-l1-1-0.dll", "GetClientRect", GetClientRectHook)) |
BOOL bIsTaskbarHorizontal = TaskbarCenter_IsTaskbarHorizontal(hWnd); |
||||||
|
if (TaskbarCenter_ShouldCenter(dwSetting)) |
||||||
{ |
{ |
||||||
return E_NOTIMPL; |
if (TaskbarCenter_ShouldStartBeCentered(dwSetting) && hWndStart) |
||||||
|
{ |
||||||
|
GetClientRect(hWndStart, &rcStart); |
||||||
} |
} |
||||||
return S_OK; |
RECT rc; |
||||||
|
GetWindowRect(hWnd, &rc); |
||||||
|
MONITORINFO mi; |
||||||
|
ZeroMemory(&mi, sizeof(MONITORINFO)); |
||||||
|
mi.cbSize = sizeof(MONITORINFO); |
||||||
|
GetMonitorInfoW(MonitorFromWindow(hWnd, MONITOR_DEFAULTTOPRIMARY), &mi); |
||||||
|
DWORD dwLength = 0; |
||||||
|
TaskbarCenter_Center(hWnd, mi.rcMonitor, bIsTaskbarHorizontal); |
||||||
|
if (dwLength = GetPropW(hWnd, EP_TASKBAR_LENGTH_PROP_NAME)) |
||||||
|
{ |
||||||
|
if (dwLength == -1) |
||||||
|
{ |
||||||
|
if (TaskbarCenter_ShouldStartBeCentered(dwSetting) && hWndStart) |
||||||
|
{ |
||||||
|
if (bIsTaskbarHorizontal) |
||||||
|
{ |
||||||
|
SetWindowPos(hWndStart, NULL, ((mi.rcMonitor.right - mi.rcMonitor.left) - (rcStart.right - rcStart.left)) / 2, rcStart.top, 0, 0, SWP_NOSIZE | SWP_FRAMECHANGED | SWP_ASYNCWINDOWPOS); |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
SetWindowPos(hWndStart, NULL, rcStart.left, ((mi.rcMonitor.bottom - mi.rcMonitor.top) - (rcStart.bottom - rcStart.top)) / 2, 0, 0, SWP_NOSIZE | SWP_FRAMECHANGED | SWP_ASYNCWINDOWPOS); |
||||||
|
} |
||||||
|
if (!bIsPrimaryTaskbar) InvalidateRect(hWndStart, NULL, TRUE); |
||||||
|
} |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
if (TaskbarCenter_ShouldStartBeCentered(dwSetting) && hWndStart) |
||||||
|
{ |
||||||
|
dwLength += (bIsTaskbarHorizontal ? (rcStart.right - rcStart.left) : (rcStart.bottom - rcStart.top)); |
||||||
|
} |
||||||
|
bWasCalled = GetClientRect(hWnd, lpRect); |
||||||
|
long res = 0; |
||||||
|
if (bIsTaskbarHorizontal) |
||||||
|
{ |
||||||
|
res = ((mi.rcMonitor.right - mi.rcMonitor.left) - dwLength) / 2 - (!TaskbarCenter_ShouldStartBeCentered(dwSetting) ? (rc.left - mi.rcMonitor.left) : 0); |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
res = ((mi.rcMonitor.bottom - mi.rcMonitor.top) - dwLength) / 2 - (!TaskbarCenter_ShouldStartBeCentered(dwSetting) ? (rc.top - mi.rcMonitor.top) : 0); |
||||||
|
} |
||||||
|
if (res + dwLength + 5 - (TaskbarCenter_ShouldStartBeCentered(dwSetting) ? (bIsTaskbarHorizontal ? (rc.left - mi.rcMonitor.left) : (rc.top - mi.rcMonitor.top)) : 0) < (bIsTaskbarHorizontal ? lpRect->right : lpRect->bottom)) |
||||||
|
{ |
||||||
|
if (bIsTaskbarHorizontal) |
||||||
|
{ |
||||||
|
lpRect->left = res; |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
lpRect->top = res; |
||||||
|
} |
||||||
|
if (TaskbarCenter_ShouldLeftAlignWhenSpaceConstrained(dwSetting) || !bIsTaskbarHorizontal) |
||||||
|
{ |
||||||
|
if (bIsTaskbarHorizontal) |
||||||
|
{ |
||||||
|
lpRect->right = (TaskbarCenter_ShouldStartBeCentered(dwSetting) ? (rc.left - mi.rcMonitor.left) : 0) + 10 + lpRect->right; |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
lpRect->bottom = (TaskbarCenter_ShouldStartBeCentered(dwSetting) ? (rc.top - mi.rcMonitor.top) : 0) + 10 + lpRect->bottom; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
if (TaskbarCenter_ShouldStartBeCentered(dwSetting) && hWndStart) |
||||||
|
{ |
||||||
|
if (bIsTaskbarHorizontal) |
||||||
|
{ |
||||||
|
SetWindowPos(hWndStart, NULL, (rc.left - mi.rcMonitor.left) + lpRect->left - (rcStart.right - rcStart.left), rcStart.top, 0, 0, SWP_NOSIZE | SWP_FRAMECHANGED | SWP_ASYNCWINDOWPOS); |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
SetWindowPos(hWndStart, NULL, rcStart.left, (rc.top - mi.rcMonitor.top) + lpRect->top - (rcStart.bottom - rcStart.top), 0, 0, SWP_NOSIZE | SWP_FRAMECHANGED | SWP_ASYNCWINDOWPOS); |
||||||
|
} |
||||||
|
if (!bIsPrimaryTaskbar) InvalidateRect(hWndStart, NULL, TRUE); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
else |
||||||
|
{ |
||||||
|
if (GetPropW(hWnd, EP_TASKBAR_LENGTH_PROP_NAME)) |
||||||
|
{ |
||||||
|
RemovePropW(hWnd, EP_TASKBAR_LENGTH_PROP_NAME); |
||||||
|
} |
||||||
|
} |
||||||
|
if ((!TaskbarCenter_ShouldCenter(dwSetting) || !TaskbarCenter_ShouldStartBeCentered(dwSetting)) && hWndStart) |
||||||
|
{ |
||||||
|
GetWindowRect(hWndStart, &rcStart); |
||||||
|
if (rcStart.left != 0 || rcStart.top != 0) |
||||||
|
{ |
||||||
|
SetWindowPos(hWndStart, NULL, 0, 0, 0, 0, SWP_NOSIZE | SWP_FRAMECHANGED | SWP_ASYNCWINDOWPOS); |
||||||
|
if (!bIsPrimaryTaskbar) InvalidateRect(hWndStart, NULL, TRUE); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
if (bWasCalled) return bWasCalled; |
||||||
|
return GetClientRect(hWnd, lpRect); |
||||||
} |
} |
||||||
Loading…
Reference in new issue