[SHELL32_APITEST] Enhance SHAppBarMessage testcase (#8149)

SHAppBarMessage testcase has to
cover the auto-hide feature. Make the
testcase more stable.
JIRA issue: CORE-7237
Add more tests.
This commit is contained in:
Katayama Hirofumi MZ 2025-06-25 08:48:30 +09:00 committed by GitHub
parent b254ea8274
commit aaed9f77d9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -2,7 +2,7 @@
* PROJECT: ReactOS api tests
* LICENSE: LGPL-2.0-or-later (https://spdx.org/licenses/LGPL-2.0-or-later)
* PURPOSE: Test for SHAppBarMessage
* COPYRIGHT: Copyright 2020 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
* COPYRIGHT: Copyright 2020-2025 Katayama Hirofumi MZ (katayama.hirofumi.mz@gmail.com)
*/
#include "shelltest.h"
@ -18,6 +18,7 @@
#define IDT_AUTOUNHIDE 2
#define ID_ACTION 100
#define ID_QUIT 999
#define APPBAR_CALLBACK (WM_USER + 100)
@ -25,8 +26,13 @@
#define LEFT_UP() mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 0, 0);
#define MOVE(x, y) SetCursorPos((x), (y))
#define INTERVAL 250
#define LONG_INTERVAL 2500
static const TCHAR s_szName[] = TEXT("AppBarSample");
static RECT s_rcPrimaryMonitor;
static RECT s_rcWorkArea;
static RECT s_rcTaskBar;
static HWND s_hwnd1 = NULL;
static HWND s_hwnd2 = NULL;
@ -145,9 +151,7 @@ public:
{
}
virtual ~Window()
{
}
virtual ~Window() { }
static BOOL DoRegisterClass(HINSTANCE hInstance)
{
@ -176,17 +180,6 @@ public:
return hwnd;
}
static INT DoMainLoop()
{
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (INT)msg.wParam;
}
static Window *GetAppbarData(HWND hwnd)
{
return (Window *)GetWindowLongPtr(hwnd, GWLP_USERDATA);
@ -257,6 +250,7 @@ protected:
POINT m_ptDragOn;
RECT m_rcAppBar;
RECT m_rcDrag;
BOOL m_bGotFullScreen;
void OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)
{
@ -276,6 +270,12 @@ protected:
return;
}
CloseHandle(hThread);
break;
case ID_QUIT:
DestroyWindow(s_hwnd1);
DestroyWindow(s_hwnd2);
PostQuitMessage(0);
break;
}
}
@ -318,6 +318,7 @@ protected:
break;
case ABN_FULLSCREENAPP:
m_bGotFullScreen = TRUE;
if (lParam)
{
s_hwndZOrder = GetWindow(hwnd, GW_HWNDPREV);
@ -334,8 +335,7 @@ protected:
case ABN_POSCHANGED:
{
APPBARDATA abd = { sizeof(abd) };
abd.hWnd = hwnd;
APPBARDATA abd = { sizeof(abd), hwnd };
AppBar_PosChanged(&abd);
}
break;
@ -344,23 +344,36 @@ protected:
BOOL AppBar_Register(HWND hwnd)
{
APPBARDATA abd = { sizeof(abd) };
abd.hWnd = hwnd;
abd.uCallbackMessage = APPBAR_CALLBACK;
APPBARDATA abd = { sizeof(abd), hwnd, APPBAR_CALLBACK };
m_fAppBarRegd = (BOOL)SHAppBarMessage(ABM_NEW, &abd);
return m_fAppBarRegd;
}
BOOL AppBar_UnRegister(HWND hwnd)
{
APPBARDATA abd = { sizeof(abd) };
abd.hWnd = hwnd;
APPBARDATA abd = { sizeof(abd), hwnd };
m_fAppBarRegd = !SHAppBarMessage(ABM_REMOVE, &abd);
return !m_fAppBarRegd;
}
BOOL AppBar_GetTaskBarPos(HWND hwnd, PRECT prc)
{
APPBARDATA abd = { sizeof(abd), hwnd };
if (!SHAppBarMessage(ABM_GETTASKBARPOS, &abd))
return FALSE;
*prc = abd.rc;
return TRUE;
}
HWND AppBar_GetAutoHideBar(HWND hwnd, UINT uSide)
{
APPBARDATA abd = { sizeof(abd), hwnd };
abd.uEdge = uSide;
return (HWND)SHAppBarMessage(ABM_GETAUTOHIDEBAR, &abd);
}
BOOL AppBar_SetAutoHide(HWND hwnd, BOOL fHide)
{
if (fHide)
@ -371,8 +384,7 @@ protected:
BOOL AppBar_AutoHide(HWND hwnd)
{
APPBARDATA abd = { sizeof(abd) };
abd.hWnd = hwnd;
APPBARDATA abd = { sizeof(abd), hwnd };
abd.uEdge = m_uSide;
HWND hwndAutoHide = (HWND)SHAppBarMessage(ABM_GETAUTOHIDEBAR, &abd);
@ -418,8 +430,7 @@ protected:
BOOL AppBar_NoAutoHide(HWND hwnd)
{
APPBARDATA abd = { sizeof(abd) };
abd.hWnd = hwnd;
APPBARDATA abd = { sizeof(abd), hwnd };
abd.uEdge = m_uSide;
HWND hwndAutoHide = (HWND)SHAppBarMessage(ABM_GETAUTOHIDEBAR, &abd);
if (hwndAutoHide != hwnd)
@ -468,8 +479,7 @@ protected:
break;
}
APPBARDATA abd = { sizeof(abd) };
abd.hWnd = hwnd;
APPBARDATA abd = { sizeof(abd), hwnd };
AppBar_QuerySetPos(uSide, &rc, &abd, TRUE);
if (fAutoHide)
@ -546,8 +556,7 @@ protected:
{
if (m_fAppBarRegd)
{
APPBARDATA abd = { sizeof(abd) };
abd.hWnd = hwnd;
APPBARDATA abd = { sizeof(abd), hwnd };
RECT rc;
GetWindowRect(hwnd, &rc);
@ -557,8 +566,7 @@ protected:
void AppBar_QueryPos(HWND hwnd, LPRECT lprc)
{
APPBARDATA abd = { sizeof(abd) };
abd.hWnd = hwnd;
APPBARDATA abd = { sizeof(abd), hwnd };
abd.rc = *lprc;
abd.uEdge = m_uSide;
@ -688,8 +696,7 @@ protected:
void OnActivate(HWND hwnd, UINT state, HWND hwndActDeact, BOOL fMinimized)
{
APPBARDATA abd = { sizeof(abd) };
abd.hWnd = hwnd;
APPBARDATA abd = { sizeof(abd), hwnd };
SHAppBarMessage(ABM_ACTIVATE, &abd);
switch (state)
@ -708,8 +715,7 @@ protected:
void OnWindowPosChanged(HWND hwnd, const LPWINDOWPOS lpwpos)
{
APPBARDATA abd = { sizeof(abd) };
abd.hWnd = hwnd;
APPBARDATA abd = { sizeof(abd), hwnd };
SHAppBarMessage(ABM_WINDOWPOSCHANGED, &abd);
FORWARD_WM_WINDOWPOSCHANGED(hwnd, lpwpos, DefWindowProc);
@ -731,13 +737,9 @@ protected:
m_rcAppBar = rcWindow;
if (m_uSide == ABE_TOP || m_uSide == ABE_BOTTOM)
{
m_cyHeight = m_cySave = rcWindow.bottom - rcWindow.top;
}
else
{
m_cxWidth = m_cxSave = rcWindow.right - rcWindow.left;
}
}
InvalidateRect(hwnd, NULL, TRUE);
@ -956,8 +958,7 @@ protected:
}
else
{
APPBARDATA abd = { sizeof(abd) };
abd.hWnd = hwnd;
APPBARDATA abd = { sizeof(abd), hwnd };
AppBar_QuerySetPos(m_uSide, &m_rcDrag, &abd, FALSE);
}
}
@ -970,16 +971,36 @@ protected:
SystemParametersInfoW(SPI_GETWORKAREA, 0, prc, 0);
}
void Quit()
{
PostMessage(s_hwnd1, WM_COMMAND, ID_QUIT, 0);
PostMessage(s_hwnd2, WM_COMMAND, ID_QUIT, 0);
}
public:
void DoAction()
{
#define INTERVAL 250
trace("DoAction\n");
TEST_Main();
TEST_Dragging();
TEST_AutoHide();
TEST_FullScreen();
Quit();
}
void TEST_Main()
{
trace("TEST_Main\n");
Sleep(INTERVAL);
POINT pt;
RECT rc1, rc2, rcWork;
DWORD dwTID = GetWindowThreadProcessId(s_hwnd1, NULL);
trace("DoAction\n");
Sleep(INTERVAL);
BOOL ret = AppBar_GetTaskBarPos(s_hwnd1, &rc1);
ok_int(ret, TRUE);
ok_int(EqualRect(&rc1, &s_rcTaskBar), TRUE);
GetWindowRect(s_hwnd1, &rc1);
GetWindowRect(s_hwnd2, &rc2);
@ -997,7 +1018,7 @@ public:
ok_long(rcWork.right, s_rcWorkArea.right);
ok_long(rcWork.bottom, s_rcWorkArea.bottom);
PostMessageW(s_hwnd1, WM_CLOSE, 0, 0);
Sleep(INTERVAL);
Sleep(LONG_INTERVAL);
GetWindowRect(s_hwnd2, &rc2);
GetWorkArea(&rcWork);
@ -1072,44 +1093,126 @@ public:
ok_long(rcWork.right, s_rcWorkArea.right);
ok_long(rcWork.bottom, s_rcWorkArea.bottom);
Sleep(INTERVAL);
}
GetWindowRect(s_hwnd2, &rc2);
pt.x = (rc2.left + rc2.right) / 2;
pt.y = (rc2.top + rc2.bottom) / 2;
void TEST_Dragging()
{
trace("TEST_Dragging\n");
RECT rc, rcWork;
POINT pt;
GetWindowRect(s_hwnd2, &rc);
pt.x = (rc.left + rc.right) / 2;
pt.y = (rc.top + rc.bottom) / 2;
MOVE(pt.x, pt.y);
LEFT_DOWN();
MOVE(pt.x + 64, pt.y + 64);
Sleep(INTERVAL);
pt.x = s_rcWorkArea.right - 80;
pt.x = (s_rcWorkArea.left + s_rcWorkArea.right) / 2;
pt.y = s_rcWorkArea.top;
MOVE(pt.x, pt.y);
Sleep(INTERVAL);
pt.x = s_rcWorkArea.right - 1;
pt.y = (s_rcWorkArea.top + s_rcWorkArea.bottom) / 2;
MOVE(pt.x, pt.y);
LEFT_UP();
Sleep(INTERVAL);
Sleep(LONG_INTERVAL);
GetWindowRect(s_hwnd2, &rc2);
GetWindowRect(s_hwnd2, &rc);
GetWorkArea(&rcWork);
ok_long(rc2.left, s_rcWorkArea.right - 30);
ok_long(rc2.top, s_rcWorkArea.top);
ok_long(rc2.right, s_rcWorkArea.right);
ok_long(rc.left, s_rcWorkArea.right - 30);
ok_long(rc.top, s_rcWorkArea.top);
ok_long(rc.right, s_rcWorkArea.right);
ok_long(rcWork.left, s_rcWorkArea.left);
ok_long(rcWork.top, s_rcWorkArea.top);
ok_long(rcWork.right, s_rcWorkArea.right - 30);
ok_long(rcWork.bottom, s_rcWorkArea.bottom);
Sleep(INTERVAL);
}
SendMessage(s_hwnd2, WM_CLOSE, 0, 0);
Sleep(INTERVAL);
void TEST_AutoHide()
{
trace("TEST_AutoHide\n");
GetWorkArea(&rcWork);
ok_long(rcWork.left, s_rcWorkArea.left);
ok_long(rcWork.top, s_rcWorkArea.top);
ok_long(rcWork.right, s_rcWorkArea.right);
ok_long(rcWork.bottom, s_rcWorkArea.bottom);
RECT rc;
PostMessageW(s_hwnd2, WM_QUIT, 0, 0);
PostThreadMessage(dwTID, WM_QUIT, 0, 0);
#undef INTERVAL
m_cxWidth = 80;
m_cyHeight = 40;
AppBar_SetSide(s_hwnd2, ABE_TOP);
AppBar_AutoHide(s_hwnd2);
HWND hwndRet = AppBar_GetAutoHideBar(s_hwnd2, ABE_TOP);
ok_ptr(hwndRet, s_hwnd2);
Sleep(LONG_INTERVAL);
GetWindowRect(s_hwnd2, &rc);
ok_long(rc.left, s_rcWorkArea.left);
ok_long(rc.top, s_rcWorkArea.top);
ok_long(rc.right, s_rcWorkArea.right);
ok_long(rc.bottom, s_rcWorkArea.top + 2);
MOVE((s_rcWorkArea.left + s_rcWorkArea.right) / 2, s_rcWorkArea.top);
LEFT_DOWN();
LEFT_UP();
Sleep(LONG_INTERVAL);
GetWindowRect(s_hwnd2, &rc);
ok_long(rc.left, s_rcWorkArea.left);
ok_long(rc.top, s_rcWorkArea.top);
ok_long(rc.right, s_rcWorkArea.right);
ok_long(rc.bottom, s_rcWorkArea.top + 40);
MOVE((s_rcWorkArea.left + s_rcWorkArea.right) / 2, s_rcWorkArea.bottom - 1);
LEFT_DOWN();
LEFT_UP();
Sleep(LONG_INTERVAL);
GetWindowRect(s_hwnd2, &rc);
ok_long(rc.left, s_rcWorkArea.left);
ok_long(rc.top, s_rcWorkArea.top);
ok_long(rc.right, s_rcWorkArea.right);
ok_long(rc.bottom, s_rcWorkArea.top + 2);
SetForegroundWindow(s_hwnd2);
Sleep(LONG_INTERVAL);
GetWindowRect(s_hwnd2, &rc);
ok_long(rc.left, s_rcWorkArea.left);
ok_long(rc.top, s_rcWorkArea.top);
ok_long(rc.right, s_rcWorkArea.right);
ok_long(rc.bottom, s_rcWorkArea.top + 40);
AppBar_SetSide(s_hwnd2, ABE_RIGHT);
AppBar_AutoHide(s_hwnd2);
SetForegroundWindow(s_hwnd2);
hwndRet = AppBar_GetAutoHideBar(s_hwnd2, ABE_RIGHT);
ok_ptr(hwndRet, s_hwnd2);
GetWindowRect(s_hwnd2, &rc);
ok_long(rc.left, s_rcWorkArea.right - 2);
ok_long(rc.top, s_rcWorkArea.top);
ok_long(rc.right, s_rcWorkArea.right);
ok_long(rc.bottom, s_rcWorkArea.bottom);
MOVE(s_rcWorkArea.left, (s_rcWorkArea.top + s_rcWorkArea.bottom) / 2);
Sleep(LONG_INTERVAL);
GetWindowRect(s_hwnd2, &rc);
ok_long(rc.left, s_rcWorkArea.right - 2);
ok_long(rc.top, s_rcWorkArea.top);
ok_long(rc.right, s_rcWorkArea.right);
ok_long(rc.bottom, s_rcWorkArea.bottom);
}
void TEST_FullScreen()
{
trace("TEST_FullScreen\n");
RECT rc = s_rcPrimaryMonitor;
m_bGotFullScreen = FALSE;
MoveWindow(s_hwnd2, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, TRUE);
Sleep(LONG_INTERVAL);
ok_int(m_bGotFullScreen, TRUE);
MoveWindow(s_hwnd2, rc.left, rc.top, 100, 100, TRUE);
}
static DWORD WINAPI ActionThreadFunc(LPVOID args)
@ -1124,6 +1227,39 @@ START_TEST(SHAppBarMessage)
{
HINSTANCE hInstance = GetModuleHandle(NULL);
// Check Taskbar
HWND hTrayWnd = FindWindowW(L"Shell_TrayWnd", NULL);
if (!IsWindowVisible(hTrayWnd))
{
skip("Taskbar not found\n");
return;
}
// Taskbar
RECT rc;
GetWindowRect(hTrayWnd, &rc);
s_rcTaskBar = rc;
trace("s_rcTaskBar: %ld, %ld, %ld, %ld\n", rc.left, rc.top, rc.right, rc.bottom);
// Work area
SystemParametersInfo(SPI_GETWORKAREA, 0, &rc, FALSE);
s_rcWorkArea = rc;
trace("s_rcWorkArea: %ld, %ld, %ld, %ld\n", rc.left, rc.top, rc.right, rc.bottom);
// Primary monitor
SetRect(&rc, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
s_rcPrimaryMonitor = rc;
trace("s_rcPrimaryMonitor: %ld, %ld, %ld, %ld\n", rc.left, rc.top, rc.right, rc.bottom);
if (s_rcTaskBar.left > s_rcPrimaryMonitor.left ||
s_rcTaskBar.right < s_rcPrimaryMonitor.right ||
s_rcTaskBar.bottom < s_rcPrimaryMonitor.bottom)
{
// Taskbar must be bottom in this testcase
skip("Taskbar was not bottom\n");
return;
}
if (!Window::DoRegisterClass(hInstance))
{
skip("Window::DoRegisterClass failed\n");
@ -1137,10 +1273,6 @@ START_TEST(SHAppBarMessage)
return;
}
SystemParametersInfo(SPI_GETWORKAREA, 0, &s_rcWorkArea, FALSE);
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);
if (!hwnd1)
@ -1162,5 +1294,11 @@ START_TEST(SHAppBarMessage)
PostMessageW(hwnd1, WM_COMMAND, ID_ACTION, 0);
Window::DoMainLoop();
// message loop
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}