From a9b77d89fb660802f9e8ee4497e56f5d576ecb42 Mon Sep 17 00:00:00 2001 From: Marek Benc Date: Tue, 27 Aug 2024 20:25:02 +0200 Subject: [PATCH] [USER32_APITEST] Add scrollbar showing/hiding testcase (#7254) Checks CORE-19669, making sure that CS_HREDRAW and CS_VREDRAW are respected when the client area changes due to the scrollbar disappearing or re-appearing. ROSTESTS-397 Co-authored-by: Stanislav Motylkov --- .../rostests/apitests/user32/CMakeLists.txt | 1 + .../apitests/user32/ScrollBarRedraw.c | 727 ++++++++++++++++++ modules/rostests/apitests/user32/testlist.c | 2 + 3 files changed, 730 insertions(+) create mode 100644 modules/rostests/apitests/user32/ScrollBarRedraw.c diff --git a/modules/rostests/apitests/user32/CMakeLists.txt b/modules/rostests/apitests/user32/CMakeLists.txt index 3e696def280..1a3c829dcea 100644 --- a/modules/rostests/apitests/user32/CMakeLists.txt +++ b/modules/rostests/apitests/user32/CMakeLists.txt @@ -41,6 +41,7 @@ list(APPEND SOURCE RedrawWindow.c RegisterClassEx.c RegisterHotKey.c + ScrollBarRedraw.c ScrollBarWndExtra.c ScrollDC.c ScrollWindowEx.c diff --git a/modules/rostests/apitests/user32/ScrollBarRedraw.c b/modules/rostests/apitests/user32/ScrollBarRedraw.c new file mode 100644 index 00000000000..6cecaf50dbb --- /dev/null +++ b/modules/rostests/apitests/user32/ScrollBarRedraw.c @@ -0,0 +1,727 @@ +/* + * PROJECT: ReactOS API tests + * LICENSE: MIT (https://spdx.org/licenses/MIT) + * PURPOSE: Tests window redrawing when scrollbars appear or disappear + * COPYRIGHT: Copyright 2024 Marek Benc + */ + +#include "precomp.h" + +#define TEST_CLASS_NAME L"ScrollBarRedraw" +#define TEST_WINDOW_TITLE L"ScrollBarRedraw" + +static LRESULT CALLBACK WindowProc(HWND Window, UINT Message, WPARAM wParam, LPARAM lParam); + +#define TEST_COLOR_COUNT 16 + +/* Standard Windows 16-Color VGA Color palette. */ +static COLORREF Colors[] = +{ + RGB(0x00, 0x00, 0x00), /* Black */ + RGB(0x00, 0x00, 0x80), /* Dark Blue */ + RGB(0x00, 0x80, 0x00), /* Dark Green */ + RGB(0x00, 0x80, 0x80), /* Dark Cyan */ + RGB(0x80, 0x00, 0x00), /* Dark Red */ + RGB(0x80, 0x00, 0x80), /* Dark Magenta */ + RGB(0x80, 0x80, 0x00), /* Dark Yellow */ + RGB(0xC0, 0xC0, 0xC0), /* Light Gray */ + RGB(0x80, 0x80, 0x80), /* Dark Gray */ + RGB(0x00, 0x00, 0xFF), /* Blue */ + RGB(0x00, 0xFF, 0x00), /* Green */ + RGB(0x00, 0xFF, 0xFF), /* Cyan */ + RGB(0xFF, 0x00, 0x00), /* Red */ + RGB(0xFF, 0x00, 0xFF), /* Magenta */ + RGB(0xFF, 0xFF, 0x00), /* Yellow */ + RGB(0xFF, 0xFF, 0xFF) /* White */ +}; +static HBRUSH ColorBrushes[TEST_COLOR_COUNT] = { 0 }; + +static BOOL HaveHRedraw = FALSE; +static BOOL HaveVRedraw = FALSE; +static BOOL WindowCreatedOk = FALSE; + +typedef enum _FSM_STATE +{ + FSM_STATE_START, + FSM_STATE_VSCR_SHOWN, + FSM_STATE_VSCR_HIDDEN, + FSM_STATE_HSCR_SHOWN, + FSM_STATE_HSCR_HIDDEN, + FSM_STATE_BSCR_SHOWN, + FSM_STATE_BSCR_HIDDEN, + FSM_STATE_WIDTH_SHRUNK, + FSM_STATE_WIDTH_EXPANDED, + FSM_STATE_HEIGHT_SHRUNK, + FSM_STATE_HEIGHT_EXPANDED, + FSM_STATE_BOTH_SHRUNK, + FSM_STATE_BOTH_EXPANDED, + FSM_STATE_END +} FSM_STATE; + +#define FSM_STEP_PERIOD_MS 250 + +static UINT_PTR FsmTimer = 0; +static UINT CurrentColor = 0; +static FSM_STATE FsmState = FSM_STATE_START; + +static int ClientWidth = 0; +static int ClientHeight = 0; + +static int OrigWidth = 0; +static int OrigHeight = 0; +static int SmallWidth = 0; +static int SmallHeight = 0; + +static void ColorsCleanup(void) +{ + UINT Iter; + + for (Iter = 0; Iter < _countof(ColorBrushes); Iter++) + { + if (ColorBrushes[Iter] != NULL) + { + DeleteObject(ColorBrushes[Iter]); + ColorBrushes[Iter] = NULL; + } + } +} + +static BOOL ColorsInit(void) +{ + UINT Iter; + + assert(_countof(Colors) == _countof(ColorBrushes)); + + for (Iter = 0; Iter < _countof(ColorBrushes); Iter++) + { + ColorBrushes[Iter] = CreateSolidBrush(Colors[Iter]); + if (ColorBrushes[Iter] == NULL) + { + ColorsCleanup(); + return FALSE; + } + } + + return TRUE; +} + +static void RunTestWindow(PCWSTR ClassName, PCWSTR WindowTitle, UINT ClassStyle) +{ + WNDCLASSW Class = { 0 }; + HWND Window; + MSG Message; + HINSTANCE hInst; + + CurrentColor = 0; + hInst = GetModuleHandleW(NULL); + + Class.style = ClassStyle; + Class.lpfnWndProc = WindowProc; + Class.cbClsExtra = 0; + Class.cbWndExtra = 0; + Class.hInstance = hInst; + Class.hIcon = LoadIcon(NULL, IDI_APPLICATION); + Class.hCursor = LoadCursor(NULL, IDC_ARROW); + Class.hbrBackground = ColorBrushes[CurrentColor]; + Class.lpszMenuName = NULL; + Class.lpszClassName = ClassName; + + if (!RegisterClassW(&Class)) + { + skip("Failed to register window class '%ls', code: %ld\n", + ClassName, GetLastError()); + return; + } + + Window = CreateWindowW(ClassName, + WindowTitle, + WS_OVERLAPPEDWINDOW | WS_VSCROLL | WS_HSCROLL, + CW_USEDEFAULT, + CW_USEDEFAULT, + CW_USEDEFAULT, + CW_USEDEFAULT, + NULL, + NULL, + hInst, + NULL); + if (Window == NULL) + { + skip("Failed to create window of class '%ls', code: %ld\n", + ClassName, GetLastError()); + return; + } + + ShowWindow(Window, SW_SHOWNORMAL); + UpdateWindow(Window); + + while (GetMessageW(&Message, NULL, 0, 0)) + { + TranslateMessage(&Message); + DispatchMessageW(&Message); + } +} + +START_TEST(ScrollBarRedraw) +{ + if (!ColorsInit()) + { + skip("Failed to initialize colors and solid color brushes\n"); + return; + } + + trace("Running test without specifying either CS_HREDRAW or CS_HREDRAW\n"); + HaveHRedraw = FALSE; + HaveVRedraw = FALSE; + RunTestWindow(TEST_CLASS_NAME L"NoRedraw", + TEST_WINDOW_TITLE L" (No Redraw Flags)", + 0); + + trace("Running test with CS_HREDRAW\n"); + HaveHRedraw = TRUE; + HaveVRedraw = FALSE; + RunTestWindow(TEST_CLASS_NAME L"HRedraw", + TEST_WINDOW_TITLE L" (CS_HREDRAW)", + CS_HREDRAW); + + trace("Running test with CS_VREDRAW\n"); + HaveHRedraw = FALSE; + HaveVRedraw = TRUE; + RunTestWindow(TEST_CLASS_NAME L"VRedraw", + TEST_WINDOW_TITLE L" (CS_VREDRAW)", + CS_VREDRAW); + + trace("Running test with both CS_HREDRAW and CS_VREDRAW\n"); + HaveHRedraw = TRUE; + HaveVRedraw = TRUE; + RunTestWindow(TEST_CLASS_NAME L"HRedrawVRedraw", + TEST_WINDOW_TITLE L" (CS_HREDRAW | CS_VREDRAW)", + CS_HREDRAW | CS_VREDRAW); + + trace("Test complete\n"); + ColorsCleanup(); +} + +static void HideVertScrollBar(HWND Window) +{ + SCROLLINFO ScrollInfo; + + ScrollInfo.cbSize = sizeof(ScrollInfo); + ScrollInfo.fMask = SIF_RANGE | SIF_PAGE | SIF_POS; + ScrollInfo.nPage = ClientHeight; + + ScrollInfo.nMin = 0; + ScrollInfo.nMax = ClientHeight - 1; + ScrollInfo.nPos = 0; + + SetScrollInfo(Window, SB_VERT, &ScrollInfo, TRUE); +} + +static void ShowVertScrollBar(HWND Window) +{ + SCROLLINFO ScrollInfo; + + ScrollInfo.cbSize = sizeof(ScrollInfo); + ScrollInfo.fMask = SIF_RANGE | SIF_PAGE | SIF_POS; + ScrollInfo.nPage = ClientHeight; + + ScrollInfo.nMin = 0; + ScrollInfo.nMax = (3 * ClientHeight) - 1; + ScrollInfo.nPos = 0; + + SetScrollInfo(Window, SB_VERT, &ScrollInfo, TRUE); +} + +static void HideHorzScrollBar(HWND Window) +{ + SCROLLINFO ScrollInfo; + + ScrollInfo.cbSize = sizeof(ScrollInfo); + ScrollInfo.fMask = SIF_RANGE | SIF_PAGE | SIF_POS; + ScrollInfo.nPage = ClientWidth; + + ScrollInfo.nMin = 0; + ScrollInfo.nMax = ClientWidth - 1; + ScrollInfo.nPos = 0; + + SetScrollInfo(Window, SB_HORZ, &ScrollInfo, TRUE); +} + +static void ShowHorzScrollBar(HWND Window) +{ + SCROLLINFO ScrollInfo; + + ScrollInfo.cbSize = sizeof(ScrollInfo); + ScrollInfo.fMask = SIF_RANGE | SIF_PAGE | SIF_POS; + ScrollInfo.nPage = ClientWidth; + + ScrollInfo.nMin = 0; + ScrollInfo.nMax = (3 * ClientWidth) - 1; + ScrollInfo.nPos = 0; + + SetScrollInfo(Window, SB_HORZ, &ScrollInfo, TRUE); +} + +static int FsmStep(HWND Window) +{ + static COLORREF PrevColor = CLR_INVALID; + COLORREF Color = CLR_INVALID; + HDC hdc = NULL; + + if (FsmState != FSM_STATE_END) + { + hdc = GetDC(Window); + if (hdc == NULL) + { + skip("Failed to get device context\n"); + + FsmState = FSM_STATE_END; + DestroyWindow(Window); + + return 0; + } + Color = GetPixel(hdc, ClientWidth / 4, ClientHeight / 4); + + ReleaseDC(Window, hdc); + hdc = NULL; + + if (Color == CLR_INVALID) + { + skip("Failed to get window color\n"); + + FsmState = FSM_STATE_END; + DestroyWindow(Window); + + return 0; + } + } + + trace("FsmState: %d, Color: 0x%.8lX\n", FsmState, Color); + + switch (FsmState) + { + case FSM_STATE_START: + ShowVertScrollBar(Window); + FsmState = FSM_STATE_VSCR_SHOWN; + break; + + case FSM_STATE_VSCR_SHOWN: + if (HaveHRedraw) + { + ok(Color != PrevColor, + "CS_HREDRAW specified, but appearence of vertical scroll bar" + " didn't trigger redraw, PrevColor: 0x%.8lX, Color: 0x%.8lX\n", + PrevColor, Color); + } + else + { + ok(Color == PrevColor, + "CS_HREDRAW not specified, but appearence of vertical scroll bar" + " triggered unneccessary redraw, PrevColor: 0x%.8lX, Color: 0x%.8lX\n", + PrevColor, Color); + } + + HideVertScrollBar(Window); + FsmState = FSM_STATE_VSCR_HIDDEN; + break; + + case FSM_STATE_VSCR_HIDDEN: + if (HaveHRedraw) + { + ok(Color != PrevColor, + "CS_HREDRAW specified, but disappearence of vertical scroll bar" + " didn't trigger redraw, PrevColor: 0x%.8lX, Color: 0x%.8lX\n", + PrevColor, Color); + } + else + { + ok(Color == PrevColor, + "CS_HREDRAW not specified, but disappearence of vertical scroll bar" + " triggered unneccessary redraw, PrevColor: 0x%.8lX, Color: 0x%.8lX\n", + PrevColor, Color); + } + + ShowHorzScrollBar(Window); + FsmState = FSM_STATE_HSCR_SHOWN; + break; + + case FSM_STATE_HSCR_SHOWN: + if (HaveVRedraw) + { + ok(Color != PrevColor, + "CS_VREDRAW specified, but appearence of horizontal scroll bar" + " didn't trigger redraw, PrevColor: 0x%.8lX, Color: 0x%.8lX\n", + PrevColor, Color); + } + else + { + ok(Color == PrevColor, + "CS_VREDRAW not specified, but appearence of horizontal scroll bar" + " triggered unneccessary redraw, PrevColor: 0x%.8lX, Color: 0x%.8lX\n", + PrevColor, Color); + } + + HideHorzScrollBar(Window); + FsmState = FSM_STATE_HSCR_HIDDEN; + break; + + case FSM_STATE_HSCR_HIDDEN: + if (HaveVRedraw) + { + ok(Color != PrevColor, + "CS_VREDRAW specified, but disappearence of horizontal scroll bar" + " didn't trigger redraw, PrevColor: 0x%.8lX, Color: 0x%.8lX\n", + PrevColor, Color); + } + else + { + ok(Color == PrevColor, + "CS_VREDRAW not specified, but disappearence of horizontal scroll bar" + " triggered unneccessary redraw, PrevColor: 0x%.8lX, Color: 0x%.8lX\n", + PrevColor, Color); + } + + ShowVertScrollBar(Window); + ShowHorzScrollBar(Window); + + FsmState = FSM_STATE_BSCR_SHOWN; + break; + + case FSM_STATE_BSCR_SHOWN: + if (HaveHRedraw || HaveVRedraw) + { + ok(Color != PrevColor, + "CS_HREDRAW or CS_VREDRAW specified, but appearence of both scroll bars" + " didn't trigger redraw, PrevColor: 0x%.8lX, Color: 0x%.8lX\n", + PrevColor, Color); + } + else + { + ok(Color == PrevColor, + "Neither CS_HREDRAW nor CS_VREDRAW specified, but appearence" + " of both scroll bars triggered unneccessary redraw," + " PrevColor: 0x%.8lX, Color: 0x%.8lX\n", + PrevColor, Color); + } + + HideVertScrollBar(Window); + HideHorzScrollBar(Window); + + FsmState = FSM_STATE_BSCR_HIDDEN; + break; + + case FSM_STATE_BSCR_HIDDEN: + if (HaveHRedraw || HaveVRedraw) + { + ok(Color != PrevColor, + "CS_HREDRAW or CS_VREDRAW specified, but disappearence of both scroll bars" + " didn't trigger redraw, PrevColor: 0x%.8lX, Color: 0x%.8lX\n", + PrevColor, Color); + } + else + { + ok(Color == PrevColor, + "Neither CS_HREDRAW nor CS_VREDRAW specified, but disappearence" + " of both scroll bars triggered unneccessary redraw," + " PrevColor: 0x%.8lX, Color: 0x%.8lX\n", + PrevColor, Color); + } + + SetWindowPos(Window, HWND_TOPMOST, 0, 0, SmallWidth, OrigHeight, SWP_NOMOVE); + FsmState = FSM_STATE_WIDTH_SHRUNK; + break; + + case FSM_STATE_WIDTH_SHRUNK: + if (HaveHRedraw) + { + ok(Color != PrevColor, + "CS_HREDRAW specified, but horizontal window shrinkage" + " didn't trigger redraw, PrevColor: 0x%.8lX, Color: 0x%.8lX\n", + PrevColor, Color); + } + else + { + ok(Color == PrevColor, + "CS_HREDRAW not specified, but horizontal window shrinkage" + " triggered unneccessary redraw, PrevColor: 0x%.8lX, Color: 0x%.8lX\n", + PrevColor, Color); + } + + SetWindowPos(Window, HWND_TOPMOST, 0, 0, OrigWidth, OrigHeight, SWP_NOMOVE); + FsmState = FSM_STATE_WIDTH_EXPANDED; + break; + + case FSM_STATE_WIDTH_EXPANDED: + if (HaveHRedraw) + { + ok(Color != PrevColor, + "CS_HREDRAW specified, but horizontal window expansion" + " didn't trigger redraw, PrevColor: 0x%.8lX, Color: 0x%.8lX\n", + PrevColor, Color); + } + else + { + ok(Color == PrevColor, + "CS_HREDRAW not specified, but horizontal window expansion" + " triggered unneccessary redraw, PrevColor: 0x%.8lX, Color: 0x%.8lX\n", + PrevColor, Color); + } + + SetWindowPos(Window, HWND_TOPMOST, 0, 0, OrigWidth, SmallHeight, SWP_NOMOVE); + FsmState = FSM_STATE_HEIGHT_SHRUNK; + break; + + case FSM_STATE_HEIGHT_SHRUNK: + if (HaveVRedraw) + { + ok(Color != PrevColor, + "CS_VREDRAW specified, but vertical window shrinkage" + " didn't trigger redraw, PrevColor: 0x%.8lX, Color: 0x%.8lX\n", + PrevColor, Color); + } + else + { + ok(Color == PrevColor, + "CS_VREDRAW not specified, but vertical window shrinkage" + " triggered unneccessary redraw, PrevColor: 0x%.8lX, Color: 0x%.8lX\n", + PrevColor, Color); + } + + SetWindowPos(Window, HWND_TOPMOST, 0, 0, OrigWidth, OrigHeight, SWP_NOMOVE); + FsmState = FSM_STATE_HEIGHT_EXPANDED; + break; + + case FSM_STATE_HEIGHT_EXPANDED: + if (HaveVRedraw) + { + ok(Color != PrevColor, + "CS_VREDRAW specified, but vertical window expansion" + " didn't trigger redraw, PrevColor: 0x%.8lX, Color: 0x%.8lX\n", + PrevColor, Color); + } + else + { + ok(Color == PrevColor, + "CS_VREDRAW not specified, but vertical window expansion" + " triggered unneccessary redraw, PrevColor: 0x%.8lX, Color: 0x%.8lX\n", + PrevColor, Color); + } + + SetWindowPos(Window, HWND_TOPMOST, 0, 0, SmallWidth, SmallHeight, SWP_NOMOVE); + + FsmState = FSM_STATE_BOTH_SHRUNK; + break; + + case FSM_STATE_BOTH_SHRUNK: + if (HaveHRedraw || HaveVRedraw) + { + ok(Color != PrevColor, + "CS_HREDRAW or CS_VREDRAW specified, but combined" + " vertical/horizontal shrinkage didn't trigger redraw," + " PrevColor: 0x%.8lX, Color: 0x%.8lX\n", + PrevColor, Color); + } + else + { + ok(Color == PrevColor, + "Neither CS_HREDRAW nor CS_VREDRAW specified, but combined" + " vertical/horizontal shrinkage triggered unneccessary redraw," + " PrevColor: 0x%.8lX, Color: 0x%.8lX\n", + PrevColor, Color); + } + + SetWindowPos(Window, HWND_TOPMOST, 0, 0, OrigWidth, OrigHeight, SWP_NOMOVE); + + FsmState = FSM_STATE_BOTH_EXPANDED; + break; + + case FSM_STATE_BOTH_EXPANDED: + if (HaveHRedraw || HaveVRedraw) + { + ok(Color != PrevColor, + "CS_HREDRAW or CS_VREDRAW specified, but combined" + " vertical/horizontal expansion didn't trigger redraw," + " PrevColor: 0x%.8lX, Color: 0x%.8lX\n", + PrevColor, Color); + } + else + { + ok(Color == PrevColor, + "Neither CS_HREDRAW nor CS_VREDRAW specified, but combined" + " vertical/horizontal expansion triggered unneccessary redraw," + " PrevColor: 0x%.8lX, Color: 0x%.8lX\n", + PrevColor, Color); + } + + FsmState = FSM_STATE_END; + DestroyWindow(Window); + break; + + case FSM_STATE_END: + break; + } + + PrevColor = Color; + return 0; +} + +static int OnPaint(HWND Window) +{ + HRGN Region; + HDC hdc; + PAINTSTRUCT ps; + + hdc = BeginPaint(Window, &ps); + if (hdc == NULL) + { + skip("Failed to get device context\n"); + DestroyWindow(Window); + return 0; + } + + Region = CreateRectRgn(ps.rcPaint.left, + ps.rcPaint.top, + ps.rcPaint.right, + ps.rcPaint.bottom); + if (Region == NULL) + { + skip("Failed to create drawing region\n"); + EndPaint(Window, &ps); + DestroyWindow(Window); + return 0; + } + + if (!FillRgn(hdc, Region, ColorBrushes[CurrentColor])) + { + skip("Failed to paint the window\n"); + DeleteObject(Region); + EndPaint(Window, &ps); + DestroyWindow(Window); + return 0; + } + + DeleteObject(Region); + EndPaint(Window, &ps); + + return 0; +} + +static LRESULT CALLBACK WindowProc(HWND Window, UINT Message, WPARAM wParam, LPARAM lParam) +{ + switch (Message) + { + case WM_CREATE: + { + RECT Rect; + WindowCreatedOk = FALSE; + + /* It's important for the test that the entire Window is visible. */ + if (!SetWindowPos(Window, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE)) + { + skip("Failed to set window as top-most, code: %ld\n", GetLastError()); + return -1; + } + + if (!GetClientRect(Window, &Rect)) + { + skip("Failed to retrieve client area dimensions, code: %ld\n", GetLastError()); + return -1; + } + ClientWidth = Rect.right; + ClientHeight = Rect.bottom; + + if (!GetWindowRect(Window, &Rect)) + { + skip("Failed to retrieve window dimensions, code: %ld\n", GetLastError()); + return -1; + } + OrigWidth = Rect.right - Rect.left; + OrigHeight = Rect.bottom - Rect.top; + + SmallWidth = max((OrigWidth * 3) / 4, 1); + SmallHeight = max((OrigHeight * 3) / 4, 1); + OrigWidth = max(OrigWidth, SmallWidth + 1); + OrigHeight = max(OrigHeight, SmallHeight + 1); + + trace("OrigWidth: %d, OrigHeight: %d, SmallWidth: %d, SmallHeight: %d\n", + OrigWidth, OrigHeight, SmallWidth, SmallHeight); + + HideVertScrollBar(Window); + HideHorzScrollBar(Window); + + FsmState = FSM_STATE_START; + FsmTimer = 0; + WindowCreatedOk = TRUE; + return 0; + } + + case WM_PAINT: + if (FsmTimer == 0 && WindowCreatedOk) + { + FsmTimer = SetTimer(Window, 1, FSM_STEP_PERIOD_MS, NULL); + if (FsmTimer == 0) + { + skip("Failed to initialize FSM timer, code: %ld\n", GetLastError()); + WindowCreatedOk = FALSE; + DestroyWindow(Window); + return 0; + } + } + return OnPaint(Window); + + case WM_SIZE: + { + int NewWidth = LOWORD(lParam); + int NewHeight = HIWORD(lParam); + + if (NewWidth != 0 && NewHeight != 0 && + (NewWidth != ClientWidth || NewHeight != ClientHeight)) + { + CurrentColor = (CurrentColor + 1) % TEST_COLOR_COUNT; + SetClassLongPtrW(Window, + GCLP_HBRBACKGROUND, + (LONG_PTR)ColorBrushes[CurrentColor]); + + trace("New window size: %d x %d, new color: 0x%.8lX\n", + NewWidth, NewHeight, Colors[CurrentColor]); + + ClientWidth = NewWidth; + ClientHeight = NewHeight; + } + return 0; + } + + case WM_ERASEBKGND: + /* We use WM_PAINT instead, since WM_ERASEBKGND is issued before WM_SIZE. */ + return 1; + + case WM_TIMER: + if (wParam != 0 && wParam == FsmTimer) + { + return FsmStep(Window); + } + break; + + case WM_NCDESTROY: + if (FsmTimer != 0) + { + KillTimer(Window, FsmTimer); + FsmTimer = 0; + + if (FsmState != FSM_STATE_END) + { + skip("Window closed before test concluded, FsmState: %d, FSM_STATE_END: %d.\n", + FsmState, FSM_STATE_END); + } + } + else if (WindowCreatedOk) + { + skip("Window closed before test began.\n"); + } + return 0; + + case WM_DESTROY: + PostQuitMessage(0); + return 0; + } + return DefWindowProcW(Window, Message, wParam, lParam); +} diff --git a/modules/rostests/apitests/user32/testlist.c b/modules/rostests/apitests/user32/testlist.c index 5186c71c5d1..f8508301df0 100644 --- a/modules/rostests/apitests/user32/testlist.c +++ b/modules/rostests/apitests/user32/testlist.c @@ -42,6 +42,7 @@ extern void func_RealGetWindowClass(void); extern void func_RedrawWindow(void); extern void func_RegisterHotKey(void); extern void func_RegisterClassEx(void); +extern void func_ScrollBarRedraw(void); extern void func_ScrollBarWndExtra(void); extern void func_ScrollDC(void); extern void func_ScrollWindowEx(void); @@ -104,6 +105,7 @@ const struct test winetest_testlist[] = { "RedrawWindow", func_RedrawWindow }, { "RegisterHotKey", func_RegisterHotKey }, { "RegisterClassEx", func_RegisterClassEx }, + { "ScrollBarRedraw", func_ScrollBarRedraw }, { "ScrollBarWndExtra", func_ScrollBarWndExtra }, { "ScrollDC", func_ScrollDC }, { "ScrollWindowEx", func_ScrollWindowEx },