[EXPLORER][SHELL32][SHELL32_APITEST][SDK] AppBar Part 2 (#7946)

Follow-up of #7778.
JIRA issue: CORE-7237
- Rename APPBARDATA3264 structure
  as APPBARDATAINTEROP.
- Fix structures for WoW64.
- Use trace instead of DPRINT1.
- Add CAppBarManager::
  RecomputeAllWorkareas function.
- Fix WM_DISPLAYCHANGE handling
  to re-compute the work areas.
This commit is contained in:
Katayama Hirofumi MZ 2025-05-05 12:48:02 +09:00 committed by GitHub
parent 24c2e4433b
commit 7073bdfead
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 71 additions and 30 deletions

View file

@ -130,7 +130,7 @@ void CAppBarManager::OnAppBarQueryPos(_Inout_ PAPPBAR_COMMAND pData)
return; return;
} }
PAPPBARDATA3264 pOutput = AppBar_LockOutput(pData); PAPPBARDATAINTEROP pOutput = AppBar_LockOutput(pData);
if (!pOutput) if (!pOutput)
{ {
ERR("!pOutput: %d\n", pData->dwProcessId); ERR("!pOutput: %d\n", pData->dwProcessId);
@ -187,7 +187,7 @@ void CAppBarManager::OnAppBarSetPos(_Inout_ PAPPBAR_COMMAND pData)
OnAppBarQueryPos(pData); OnAppBarQueryPos(pData);
PAPPBARDATA3264 pOutput = AppBar_LockOutput(pData); PAPPBARDATAINTEROP pOutput = AppBar_LockOutput(pData);
if (!pOutput) if (!pOutput)
return; return;
@ -425,6 +425,31 @@ CAppBarManager::RecomputeWorkArea(
return WORKAREA_SAME_AS_MONITOR; 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 PAPPBAR_COMMAND
CAppBarManager::GetAppBarMessage(_Inout_ PCOPYDATASTRUCT pCopyData) CAppBarManager::GetAppBarMessage(_Inout_ PCOPYDATASTRUCT pCopyData)
{ {

View file

@ -15,14 +15,14 @@ typedef struct tagAPPBAR
RECT rc; RECT rc;
} APPBAR, *PAPPBAR; } APPBAR, *PAPPBAR;
static inline PAPPBARDATA3264 static inline PAPPBARDATAINTEROP
AppBar_LockOutput(_In_ PAPPBAR_COMMAND pData) 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 static inline VOID
AppBar_UnLockOutput(_Out_ PAPPBARDATA3264 pOutput) AppBar_UnLockOutput(_Out_ PAPPBARDATAINTEROP pOutput)
{ {
SHUnlockShared(pOutput); SHUnlockShared(pOutput);
} }
@ -77,6 +77,7 @@ protected:
_In_ const RECT *prcTray, _In_ const RECT *prcTray,
_In_ HMONITOR hMonitor, _In_ HMONITOR hMonitor,
_Out_ PRECT prcWorkArea); _Out_ PRECT prcWorkArea);
void RecomputeAllWorkareas();
void StuckAppChange( void StuckAppChange(
_In_opt_ HWND hwndTarget, _In_opt_ HWND hwndTarget,
@ -93,4 +94,11 @@ protected:
virtual INT GetPosition() const = 0; virtual INT GetPosition() const = 0;
virtual const RECT* GetTrayRect() = 0; virtual const RECT* GetTrayRect() = 0;
virtual HWND GetDesktopWnd() const = 0; virtual HWND GetDesktopWnd() const = 0;
static BOOL CALLBACK
MonitorEnumProc(
_In_ HMONITOR hMonitor,
_In_ HDC hDC,
_In_ LPRECT prc,
_Inout_ LPARAM lParam);
}; };

View file

@ -2492,6 +2492,9 @@ ChangePos:
LRESULT OnDisplayChange(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) LRESULT OnDisplayChange(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{ {
/* Refresh workareas */
RecomputeAllWorkareas();
/* Load the saved tray window settings */ /* Load the saved tray window settings */
RegLoadSettings(); RegLoadSettings();

View file

@ -19,7 +19,7 @@
WINE_DEFAULT_DEBUG_CHANNEL(appbar); WINE_DEFAULT_DEBUG_CHANNEL(appbar);
static UINT32 static HANDLE
AppBar_CopyIn( AppBar_CopyIn(
_In_ const VOID *pvSrc, _In_ const VOID *pvSrc,
_In_ SIZE_T dwSize, _In_ SIZE_T dwSize,
@ -38,17 +38,16 @@ AppBar_CopyIn(
CopyMemory(pvDest, pvSrc, dwSize); CopyMemory(pvDest, pvSrc, dwSize);
SHUnlockShared(pvDest); SHUnlockShared(pvDest);
return HandleToUlong(hMem); return hMem;
} }
static BOOL static BOOL
AppBar_CopyOut( AppBar_CopyOut(
_In_ UINT32 hOutput32, _In_ HANDLE hOutput,
_Out_ PVOID pvDest, _Out_ PVOID pvDest,
_In_ SIZE_T cbDest, _In_ SIZE_T cbDest,
_In_ DWORD dwProcessId) _In_ DWORD dwProcessId)
{ {
HANDLE hOutput = UlongToHandle(hOutput32);
PVOID pvSrc = SHLockShared(hOutput, dwProcessId); PVOID pvSrc = SHLockShared(hOutput, dwProcessId);
if (pvSrc) if (pvSrc)
{ {
@ -86,7 +85,7 @@ SHAppBarMessage(
cmd.abd.rc = pData->rc; cmd.abd.rc = pData->rc;
cmd.abd.lParam64 = pData->lParam; cmd.abd.lParam64 = pData->lParam;
cmd.dwMessage = dwMessage; cmd.dwMessage = dwMessage;
cmd.hOutput32 = 0; cmd.hOutput = (APPBAR_OUTPUT)NULL;
cmd.dwProcessId = GetCurrentProcessId(); cmd.dwProcessId = GetCurrentProcessId();
/* Make output data if necessary */ /* Make output data if necessary */
@ -95,8 +94,8 @@ SHAppBarMessage(
case ABM_QUERYPOS: case ABM_QUERYPOS:
case ABM_SETPOS: case ABM_SETPOS:
case ABM_GETTASKBARPOS: case ABM_GETTASKBARPOS:
cmd.hOutput32 = AppBar_CopyIn(&cmd.abd, sizeof(cmd.abd), cmd.dwProcessId); cmd.hOutput = (APPBAR_OUTPUT)AppBar_CopyIn(&cmd.abd, sizeof(cmd.abd), cmd.dwProcessId);
if (!cmd.hOutput32) if (!cmd.hOutput)
{ {
ERR("AppBar_CopyIn: %d\n", dwMessage); ERR("AppBar_CopyIn: %d\n", dwMessage);
return FALSE; return FALSE;
@ -111,9 +110,9 @@ SHAppBarMessage(
UINT_PTR ret = SendMessageW(hTrayWnd, WM_COPYDATA, (WPARAM)pData->hWnd, (LPARAM)&copyData); UINT_PTR ret = SendMessageW(hTrayWnd, WM_COPYDATA, (WPARAM)pData->hWnd, (LPARAM)&copyData);
/* Copy back output 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); ERR("AppBar_CopyOut: %d\n", dwMessage);
return FALSE; return FALSE;

View file

@ -10,9 +10,6 @@
#include <shlwapi.h> #include <shlwapi.h>
#include <stdio.h> #include <stdio.h>
#define NDEBUG
#include <debug.h>
/* Based on https://github.com/katahiromz/AppBarSample */ /* Based on https://github.com/katahiromz/AppBarSample */
//#define VERBOSE //#define VERBOSE
@ -469,9 +466,6 @@ protected:
case ABE_RIGHT: case ABE_RIGHT:
rc.left = rc.right - m_cxWidth; rc.left = rc.right - m_cxWidth;
break; break;
default:
ASSERT(FALSE);
break;
} }
APPBARDATA abd = { sizeof(abd) }; APPBARDATA abd = { sizeof(abd) };
@ -688,7 +682,7 @@ protected:
AppBar_Register(hwnd); AppBar_Register(hwnd);
AppBar_SetSide(hwnd, ABE_TOP); AppBar_SetSide(hwnd, ABE_TOP);
DPRINT1("OnCreate(%p) done\n", hwnd); trace("OnCreate(%p) done\n", hwnd);
return TRUE; return TRUE;
} }
@ -984,7 +978,7 @@ public:
RECT rc1, rc2, rcWork; RECT rc1, rc2, rcWork;
DWORD dwTID = GetWindowThreadProcessId(s_hwnd1, NULL); DWORD dwTID = GetWindowThreadProcessId(s_hwnd1, NULL);
DPRINT1("DoAction\n"); trace("DoAction\n");
Sleep(INTERVAL); Sleep(INTERVAL);
GetWindowRect(s_hwnd1, &rc1); GetWindowRect(s_hwnd1, &rc1);
@ -1136,7 +1130,7 @@ START_TEST(SHAppBarMessage)
return; return;
} }
DPRINT1("SM_CMONITORS: %d\n", GetSystemMetrics(SM_CMONITORS)); trace("SM_CMONITORS: %d\n", GetSystemMetrics(SM_CMONITORS));
if (GetSystemMetrics(SM_CMONITORS) != 1) if (GetSystemMetrics(SM_CMONITORS) != 1)
{ {
skip("Multi-monitor not supported yet\n"); skip("Multi-monitor not supported yet\n");
@ -1144,8 +1138,8 @@ START_TEST(SHAppBarMessage)
} }
SystemParametersInfo(SPI_GETWORKAREA, 0, &s_rcWorkArea, FALSE); SystemParametersInfo(SPI_GETWORKAREA, 0, &s_rcWorkArea, FALSE);
DPRINT1("s_rcWorkArea: %d, %d, %d, %d\n", trace("s_rcWorkArea: %ld, %ld, %ld, %ld\n",
s_rcWorkArea.left, s_rcWorkArea.top, s_rcWorkArea.right, s_rcWorkArea.bottom); s_rcWorkArea.left, s_rcWorkArea.top, s_rcWorkArea.right, s_rcWorkArea.bottom);
HWND hwnd1 = Window::DoCreateMainWnd(hInstance, TEXT("Test1"), 80, 80, HWND hwnd1 = Window::DoCreateMainWnd(hInstance, TEXT("Test1"), 80, 80,
WS_POPUP | WS_THICKFRAME | WS_CLIPCHILDREN); WS_POPUP | WS_THICKFRAME | WS_CLIPCHILDREN);

View file

@ -1222,32 +1222,44 @@ typedef struct SFVM_CUSTOMVIEWINFO_DATA
#include <poppack.h> #include <poppack.h>
#if defined(_WIN64) || defined(BUILD_WOW6432)
typedef UINT64 APPBAR_OUTPUT;
#else
typedef HANDLE APPBAR_OUTPUT;
#endif
/* /*
* Private structures for internal AppBar messaging. * Private structures for internal AppBar messaging.
* These structures can be sent from 32-bit shell32 to 64-bit Explorer. * 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 * 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 * > ... 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 <pshpack8.h> #include <pshpack8.h>
typedef struct tagAPPBARDATA3264 typedef struct tagAPPBARDATAINTEROP
{ {
DWORD cbSize; /* == sizeof(APPBARDATA3264) */ DWORD cbSize; /* == sizeof(APPBARDATAINTEROP) */
UINT32 hWnd32; UINT32 hWnd32;
UINT uCallbackMessage; UINT uCallbackMessage;
UINT uEdge; UINT uEdge;
RECT rc; RECT rc;
LONGLONG lParam64; LONGLONG lParam64;
} APPBARDATA3264, *PAPPBARDATA3264; } APPBARDATAINTEROP, *PAPPBARDATAINTEROP;
typedef struct tagAPPBAR_COMMAND typedef struct tagAPPBAR_COMMAND
{ {
APPBARDATA3264 abd; APPBARDATAINTEROP abd;
DWORD dwMessage; DWORD dwMessage;
UINT32 hOutput32; /* For shlwapi!SHAllocShared */ APPBAR_OUTPUT hOutput; /* For shlwapi!SHAllocShared */
DWORD dwProcessId; DWORD dwProcessId;
} APPBAR_COMMAND, *PAPPBAR_COMMAND; } APPBAR_COMMAND, *PAPPBAR_COMMAND;
#include <poppack.h> #include <poppack.h>
#if defined(_WIN64) || defined(BUILD_WOW6432)
C_ASSERT(sizeof(APPBAR_COMMAND) == 0x40);
#else
C_ASSERT(sizeof(APPBAR_COMMAND) == 0x38); C_ASSERT(sizeof(APPBAR_COMMAND) == 0x38);
#endif
#ifdef __cplusplus #ifdef __cplusplus
} /* extern "C" */ } /* extern "C" */