diff --git a/base/shell/explorer/appbar.cpp b/base/shell/explorer/appbar.cpp index 964bd60ec2b..52e87208b56 100644 --- a/base/shell/explorer/appbar.cpp +++ b/base/shell/explorer/appbar.cpp @@ -130,7 +130,7 @@ void CAppBarManager::OnAppBarQueryPos(_Inout_ PAPPBAR_COMMAND pData) return; } - PAPPBARDATA3264 pOutput = AppBar_LockOutput(pData); + PAPPBARDATAINTEROP pOutput = AppBar_LockOutput(pData); if (!pOutput) { ERR("!pOutput: %d\n", pData->dwProcessId); @@ -187,7 +187,7 @@ void CAppBarManager::OnAppBarSetPos(_Inout_ PAPPBAR_COMMAND pData) OnAppBarQueryPos(pData); - PAPPBARDATA3264 pOutput = AppBar_LockOutput(pData); + PAPPBARDATAINTEROP pOutput = AppBar_LockOutput(pData); if (!pOutput) return; @@ -425,6 +425,31 @@ CAppBarManager::RecomputeWorkArea( return WORKAREA_SAME_AS_MONITOR; } +BOOL CALLBACK +CAppBarManager::MonitorEnumProc( + _In_ HMONITOR hMonitor, + _In_ HDC hDC, + _In_ LPRECT prc, + _Inout_ LPARAM lParam) +{ + CAppBarManager *pThis = (CAppBarManager *)lParam; + UNREFERENCED_PARAMETER(hDC); + + RECT rcWorkArea; + if (pThis->RecomputeWorkArea(prc, hMonitor, &rcWorkArea) != WORKAREA_IS_NOT_MONITOR) + return TRUE; + + HWND hwndDesktop = pThis->GetDesktopWnd(); + ::SystemParametersInfoW(SPI_SETWORKAREA, 0, &rcWorkArea, hwndDesktop ? SPIF_SENDCHANGE : 0); + pThis->RedrawDesktop(hwndDesktop, &rcWorkArea); + return TRUE; +} + +void CAppBarManager::RecomputeAllWorkareas() +{ + ::EnumDisplayMonitors(NULL, NULL, CAppBarManager::MonitorEnumProc, (LPARAM)this); +} + PAPPBAR_COMMAND CAppBarManager::GetAppBarMessage(_Inout_ PCOPYDATASTRUCT pCopyData) { diff --git a/base/shell/explorer/appbar.h b/base/shell/explorer/appbar.h index c5b873365de..e0894b18dbb 100644 --- a/base/shell/explorer/appbar.h +++ b/base/shell/explorer/appbar.h @@ -15,14 +15,14 @@ typedef struct tagAPPBAR RECT rc; } APPBAR, *PAPPBAR; -static inline PAPPBARDATA3264 +static inline PAPPBARDATAINTEROP AppBar_LockOutput(_In_ PAPPBAR_COMMAND pData) { - return (PAPPBARDATA3264)SHLockShared(UlongToHandle(pData->hOutput32), pData->dwProcessId); + return (PAPPBARDATAINTEROP)SHLockShared((HANDLE)pData->hOutput, pData->dwProcessId); } static inline VOID -AppBar_UnLockOutput(_Out_ PAPPBARDATA3264 pOutput) +AppBar_UnLockOutput(_Out_ PAPPBARDATAINTEROP pOutput) { SHUnlockShared(pOutput); } @@ -77,6 +77,7 @@ protected: _In_ const RECT *prcTray, _In_ HMONITOR hMonitor, _Out_ PRECT prcWorkArea); + void RecomputeAllWorkareas(); void StuckAppChange( _In_opt_ HWND hwndTarget, @@ -93,4 +94,11 @@ protected: virtual INT GetPosition() const = 0; virtual const RECT* GetTrayRect() = 0; virtual HWND GetDesktopWnd() const = 0; + + static BOOL CALLBACK + MonitorEnumProc( + _In_ HMONITOR hMonitor, + _In_ HDC hDC, + _In_ LPRECT prc, + _Inout_ LPARAM lParam); }; diff --git a/base/shell/explorer/traywnd.cpp b/base/shell/explorer/traywnd.cpp index 85f7ae62816..5976227501f 100644 --- a/base/shell/explorer/traywnd.cpp +++ b/base/shell/explorer/traywnd.cpp @@ -2492,6 +2492,9 @@ ChangePos: LRESULT OnDisplayChange(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { + /* Refresh workareas */ + RecomputeAllWorkareas(); + /* Load the saved tray window settings */ RegLoadSettings(); diff --git a/dll/win32/shell32/appbar.c b/dll/win32/shell32/appbar.c index eef28ded2bb..daffdc712f6 100644 --- a/dll/win32/shell32/appbar.c +++ b/dll/win32/shell32/appbar.c @@ -19,7 +19,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(appbar); -static UINT32 +static HANDLE AppBar_CopyIn( _In_ const VOID *pvSrc, _In_ SIZE_T dwSize, @@ -38,17 +38,16 @@ AppBar_CopyIn( CopyMemory(pvDest, pvSrc, dwSize); SHUnlockShared(pvDest); - return HandleToUlong(hMem); + return hMem; } static BOOL AppBar_CopyOut( - _In_ UINT32 hOutput32, + _In_ HANDLE hOutput, _Out_ PVOID pvDest, _In_ SIZE_T cbDest, _In_ DWORD dwProcessId) { - HANDLE hOutput = UlongToHandle(hOutput32); PVOID pvSrc = SHLockShared(hOutput, dwProcessId); if (pvSrc) { @@ -86,7 +85,7 @@ SHAppBarMessage( cmd.abd.rc = pData->rc; cmd.abd.lParam64 = pData->lParam; cmd.dwMessage = dwMessage; - cmd.hOutput32 = 0; + cmd.hOutput = (APPBAR_OUTPUT)NULL; cmd.dwProcessId = GetCurrentProcessId(); /* Make output data if necessary */ @@ -95,8 +94,8 @@ SHAppBarMessage( case ABM_QUERYPOS: case ABM_SETPOS: case ABM_GETTASKBARPOS: - cmd.hOutput32 = AppBar_CopyIn(&cmd.abd, sizeof(cmd.abd), cmd.dwProcessId); - if (!cmd.hOutput32) + cmd.hOutput = (APPBAR_OUTPUT)AppBar_CopyIn(&cmd.abd, sizeof(cmd.abd), cmd.dwProcessId); + if (!cmd.hOutput) { ERR("AppBar_CopyIn: %d\n", dwMessage); return FALSE; @@ -111,9 +110,9 @@ SHAppBarMessage( UINT_PTR ret = SendMessageW(hTrayWnd, WM_COPYDATA, (WPARAM)pData->hWnd, (LPARAM)©Data); /* Copy back output data */ - if (cmd.hOutput32) + if (cmd.hOutput) { - if (!AppBar_CopyOut(cmd.hOutput32, &cmd.abd, sizeof(cmd.abd), cmd.dwProcessId)) + if (!AppBar_CopyOut((HANDLE)cmd.hOutput, &cmd.abd, sizeof(cmd.abd), cmd.dwProcessId)) { ERR("AppBar_CopyOut: %d\n", dwMessage); return FALSE; diff --git a/modules/rostests/apitests/shell32/SHAppBarMessage.cpp b/modules/rostests/apitests/shell32/SHAppBarMessage.cpp index 26d7246ee65..54a78ec194e 100644 --- a/modules/rostests/apitests/shell32/SHAppBarMessage.cpp +++ b/modules/rostests/apitests/shell32/SHAppBarMessage.cpp @@ -10,9 +10,6 @@ #include #include -#define NDEBUG -#include - /* Based on https://github.com/katahiromz/AppBarSample */ //#define VERBOSE @@ -469,9 +466,6 @@ protected: case ABE_RIGHT: rc.left = rc.right - m_cxWidth; break; - default: - ASSERT(FALSE); - break; } APPBARDATA abd = { sizeof(abd) }; @@ -688,7 +682,7 @@ protected: AppBar_Register(hwnd); AppBar_SetSide(hwnd, ABE_TOP); - DPRINT1("OnCreate(%p) done\n", hwnd); + trace("OnCreate(%p) done\n", hwnd); return TRUE; } @@ -984,7 +978,7 @@ public: RECT rc1, rc2, rcWork; DWORD dwTID = GetWindowThreadProcessId(s_hwnd1, NULL); - DPRINT1("DoAction\n"); + trace("DoAction\n"); Sleep(INTERVAL); GetWindowRect(s_hwnd1, &rc1); @@ -1136,7 +1130,7 @@ START_TEST(SHAppBarMessage) return; } - DPRINT1("SM_CMONITORS: %d\n", GetSystemMetrics(SM_CMONITORS)); + trace("SM_CMONITORS: %d\n", GetSystemMetrics(SM_CMONITORS)); if (GetSystemMetrics(SM_CMONITORS) != 1) { skip("Multi-monitor not supported yet\n"); @@ -1144,8 +1138,8 @@ START_TEST(SHAppBarMessage) } SystemParametersInfo(SPI_GETWORKAREA, 0, &s_rcWorkArea, FALSE); - DPRINT1("s_rcWorkArea: %d, %d, %d, %d\n", - s_rcWorkArea.left, s_rcWorkArea.top, s_rcWorkArea.right, s_rcWorkArea.bottom); + trace("s_rcWorkArea: %ld, %ld, %ld, %ld\n", + s_rcWorkArea.left, s_rcWorkArea.top, s_rcWorkArea.right, s_rcWorkArea.bottom); HWND hwnd1 = Window::DoCreateMainWnd(hInstance, TEXT("Test1"), 80, 80, WS_POPUP | WS_THICKFRAME | WS_CLIPCHILDREN); diff --git a/sdk/include/reactos/undocshell.h b/sdk/include/reactos/undocshell.h index e19f0705be5..945892b71aa 100644 --- a/sdk/include/reactos/undocshell.h +++ b/sdk/include/reactos/undocshell.h @@ -1222,32 +1222,44 @@ typedef struct SFVM_CUSTOMVIEWINFO_DATA #include +#if defined(_WIN64) || defined(BUILD_WOW6432) + typedef UINT64 APPBAR_OUTPUT; +#else + typedef HANDLE APPBAR_OUTPUT; +#endif + /* * Private structures for internal AppBar messaging. * These structures can be sent from 32-bit shell32 to 64-bit Explorer. * See also: https://learn.microsoft.com/en-us/windows/win32/winprog64/interprocess-communication * > ... only the lower 32 bits are significant, so it is safe to truncate the handle + * See also: https://learn.microsoft.com/en-us/windows/win32/api/handleapi/nf-handleapi-duplicatehandle + * > DuplicateHandle can be used to duplicate a handle between a 32-bit process and a 64-bit process. */ #include -typedef struct tagAPPBARDATA3264 +typedef struct tagAPPBARDATAINTEROP { - DWORD cbSize; /* == sizeof(APPBARDATA3264) */ + DWORD cbSize; /* == sizeof(APPBARDATAINTEROP) */ UINT32 hWnd32; UINT uCallbackMessage; UINT uEdge; RECT rc; LONGLONG lParam64; -} APPBARDATA3264, *PAPPBARDATA3264; +} APPBARDATAINTEROP, *PAPPBARDATAINTEROP; typedef struct tagAPPBAR_COMMAND { - APPBARDATA3264 abd; + APPBARDATAINTEROP abd; DWORD dwMessage; - UINT32 hOutput32; /* For shlwapi!SHAllocShared */ + APPBAR_OUTPUT hOutput; /* For shlwapi!SHAllocShared */ DWORD dwProcessId; } APPBAR_COMMAND, *PAPPBAR_COMMAND; #include +#if defined(_WIN64) || defined(BUILD_WOW6432) +C_ASSERT(sizeof(APPBAR_COMMAND) == 0x40); +#else C_ASSERT(sizeof(APPBAR_COMMAND) == 0x38); +#endif #ifdef __cplusplus } /* extern "C" */