Index: rostests/apitests/CMakeLists.txt =================================================================== --- rostests/apitests/CMakeLists.txt (revision 75031) +++ rostests/apitests/CMakeLists.txt (working copy) @@ -8,6 +8,7 @@ add_subdirectory(com) add_subdirectory(comctl32) add_subdirectory(crt) +add_subdirectory(ctrlscroll) add_subdirectory(dbghelp) add_subdirectory(dciman32) add_subdirectory(dnsapi) Index: rostests/apitests/ctrlscroll/CMakeLists.txt =================================================================== --- rostests/apitests/ctrlscroll/CMakeLists.txt (nonexistent) +++ rostests/apitests/ctrlscroll/CMakeLists.txt (working copy) @@ -0,0 +1,5 @@ +add_executable(ctrlscroll_apitest testlist.c ctrlscroll.c ctrlscroll.rc) +target_link_libraries(ctrlscroll_apitest wine) +set_module_type(ctrlscroll_apitest win32cui) +add_importlibs(ctrlscroll_apitest uxtheme comctl32 user32 gdi32 msvcrt kernel32) +add_rostests_file(TARGET ctrlscroll_apitest) Index: rostests/apitests/ctrlscroll/ctrlscroll.c =================================================================== --- rostests/apitests/ctrlscroll/ctrlscroll.c (nonexistent) +++ rostests/apitests/ctrlscroll/ctrlscroll.c (working copy) @@ -0,0 +1,481 @@ +/* + * PROJECT: ReactOS api tests + * LICENSE: GPL - See COPYING in the top level directory + * PURPOSE: Test for scrolling of dialog controls + * PROGRAMMERS: Katayama Hirofumi MZ + */ + +#include "wine/test.h" +#include +#include +#include +#include +#include + +#define FIRST_WAIT 200 +#define INPUT_WAIT 50 + +#define MAX_LINES 28 +#define MAX_COLUMNS 80 + +#define EF_ARROWLEFT 1 +#define EF_ARROWUP 2 +#define EF_ARROWRIGHT 3 +#define EF_ARROWDOWN 4 +#define EF_SCROLLLEFT 5 +#define EF_SCROLLUP 6 +#define EF_SCROLLRIGHT 7 +#define EF_SCROLLDOWN 8 + +#define MAX_TARGETS 10 + +static HWND s_ahTargets[MAX_TARGETS] = { NULL }; + +static POINT GetLeftArrowPt(HWND hwnd) +{ + POINT pt; + RECT rc; + GetWindowRect(hwnd, &rc); + + pt.x = rc.left + GetSystemMetrics(SM_CXHSCROLL) / 2; + pt.y = rc.bottom - GetSystemMetrics(SM_CYHSCROLL) / 2; + return pt; +} + +static POINT GetRightArrowPt(HWND hwnd) +{ + POINT pt; + RECT rc; + GetWindowRect(hwnd, &rc); + + pt.x = rc.right - GetSystemMetrics(SM_CXHSCROLL) / 2; + pt.y = rc.bottom - GetSystemMetrics(SM_CYHSCROLL) / 2; + + if (GetWindowStyle(hwnd) & WS_VSCROLL) + { + pt.x -= GetSystemMetrics(SM_CXVSCROLL); + } + return pt; +} + +static POINT GetUpArrowPt(HWND hwnd) +{ + POINT pt; + RECT rc; + GetWindowRect(hwnd, &rc); + + pt.x = rc.right - GetSystemMetrics(SM_CXVSCROLL) / 2; + pt.y = rc.top + GetSystemMetrics(SM_CYVSCROLL) / 2; + return pt; +} + +static POINT GetDownArrowPt(HWND hwnd) +{ + POINT pt; + RECT rc; + GetWindowRect(hwnd, &rc); + + pt.x = rc.right - GetSystemMetrics(SM_CXVSCROLL) / 2; + pt.y = rc.bottom - GetSystemMetrics(SM_CYVSCROLL) / 2; + + if (GetWindowStyle(hwnd) & WS_HSCROLL) + { + pt.y -= GetSystemMetrics(SM_CYHSCROLL); + } + return pt; +} + +typedef struct ENTRY +{ + INT EntryNumber; + INT TargetNumber; + INT EF_; + INT Repeat; +} ENTRY; + +#define TARGET_EDIT 0 +#define TARGET_LISTBOX 1 +#define TARGET_LISTVIEW 2 +#define TARGET_HSCROLLBAR 3 +#define TARGET_VSCROLLBAR 4 +#define TARGET_TREEVIEW 5 + +static const ENTRY s_Entries[] = +{ + /* EDIT */ + { 0, TARGET_EDIT, EF_ARROWRIGHT, 10 }, + { 1, TARGET_EDIT, EF_ARROWLEFT, 10 }, + { 2, TARGET_EDIT, EF_ARROWDOWN, 10 }, + { 3, TARGET_EDIT, EF_ARROWUP, 10 }, + { 4, TARGET_EDIT, EF_SCROLLRIGHT, 10 }, + { 5, TARGET_EDIT, EF_SCROLLLEFT, 10 }, + { 6, TARGET_EDIT, EF_SCROLLDOWN, 10 }, + { 7, TARGET_EDIT, EF_SCROLLUP, 10 }, + /* LISTBOX */ + { 8, TARGET_LISTBOX, EF_ARROWDOWN, 10 }, + { 9, TARGET_LISTBOX, EF_ARROWUP, 10 }, + { 10, TARGET_LISTBOX, EF_SCROLLDOWN, 10 }, + { 11, TARGET_LISTBOX, EF_SCROLLUP, 10 }, + /* ListView */ + { 12, TARGET_LISTVIEW, EF_ARROWRIGHT, 10 }, + { 13, TARGET_LISTVIEW, EF_ARROWLEFT, 10 }, + { 14, TARGET_LISTVIEW, EF_ARROWDOWN, 10 }, + { 15, TARGET_LISTVIEW, EF_ARROWUP, 10 }, + { 16, TARGET_LISTVIEW, EF_SCROLLRIGHT, 10 }, + { 17, TARGET_LISTVIEW, EF_SCROLLLEFT, 10 }, + { 18, TARGET_LISTVIEW, EF_SCROLLDOWN, 10 }, + { 19, TARGET_LISTVIEW, EF_SCROLLUP, 10 }, + /* HSCROLLBAR: Skip */ + /* VSCROLLBAR: Skip */ + /* TreeView */ + { 20, TARGET_TREEVIEW, EF_ARROWRIGHT, 10 }, + { 21, TARGET_TREEVIEW, EF_ARROWLEFT, 10 }, + { 22, TARGET_TREEVIEW, EF_ARROWDOWN, 10 }, + { 23, TARGET_TREEVIEW, EF_ARROWUP, 10 }, + { 24, TARGET_TREEVIEW, EF_SCROLLRIGHT, 10 }, + { 25, TARGET_TREEVIEW, EF_SCROLLLEFT, 10 }, + { 26, TARGET_TREEVIEW, EF_SCROLLDOWN, 10 }, + { 27, TARGET_TREEVIEW, EF_SCROLLUP, 10 }, +}; + +static void NCLeftClick(HWND hwnd, HWND hCtrl, POINT pt, INT HitTest) +{ + POINT pt2 = pt; + ScreenToClient(hCtrl, &pt2); + PostMessage(hCtrl, WM_NCLBUTTONDOWN, HitTest, MAKELPARAM(pt.x, pt.y)); + PostMessage(hCtrl, WM_LBUTTONDOWN, MK_LBUTTON, MAKELPARAM(pt2.x, pt2.y)); + PostMessage(hCtrl, WM_LBUTTONUP, 0, MAKELPARAM(pt2.x, pt2.y)); + PostMessage(hCtrl, WM_NCLBUTTONUP, HitTest, MAKELPARAM(pt.x, pt.y)); +} + +static void DoEntry(HWND hwnd, INT EntryNumber, const ENTRY *pEntry) +{ + INT i; + INT nPos, nTrackPos; + POINT pt; + SCROLLINFO si; + MSG msg; + HWND hCtrl = s_ahTargets[pEntry->TargetNumber]; + + si.cbSize = sizeof(si); + si.fMask = SIF_ALL | SIF_TRACKPOS; + + ok(hCtrl != NULL, "#%d\n", EntryNumber); + switch (pEntry->EF_) + { + case EF_ARROWLEFT: + GetScrollInfo(hCtrl, SB_HORZ, &si); + nPos = si.nPos; + nTrackPos = si.nTrackPos; + pt = GetLeftArrowPt(hCtrl); + for (i = 0; i < pEntry->Repeat; ++i) + { + SetCursorPos(pt.x, pt.y); + NCLeftClick(hwnd, hCtrl, pt, HTHSCROLL); + + while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) + { + DispatchMessage(&msg); + TranslateMessage(&msg); + } + Sleep(INPUT_WAIT); + + si.fMask = SIF_ALL | SIF_TRACKPOS; + GetScrollInfo(hCtrl, SB_HORZ, &si); + ok(nPos > si.nPos, "#%d: %d, %d\n", EntryNumber, nPos, si.nPos); + ok(nTrackPos > si.nTrackPos, "#%d: %d, %d\n", EntryNumber, nTrackPos, si.nTrackPos); + + nPos = si.nPos; + nTrackPos = si.nTrackPos; + } + break; + case EF_ARROWUP: + GetScrollInfo(hCtrl, SB_VERT, &si); + nPos = si.nPos; + nTrackPos = si.nTrackPos; + pt = GetUpArrowPt(hCtrl); + for (i = 0; i < pEntry->Repeat; ++i) + { + SetCursorPos(pt.x, pt.y); + NCLeftClick(hwnd, hCtrl, pt, HTVSCROLL); + + while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) + { + DispatchMessage(&msg); + TranslateMessage(&msg); + } + Sleep(INPUT_WAIT); + + si.fMask = SIF_ALL | SIF_TRACKPOS; + GetScrollInfo(hCtrl, SB_VERT, &si); + ok(nPos > si.nPos, "#%d: %d, %d\n", EntryNumber, nPos, si.nPos); + ok(nTrackPos > si.nTrackPos, "#%d: %d, %d\n", EntryNumber, nTrackPos, si.nTrackPos); + + nPos = si.nPos; + nTrackPos = si.nTrackPos; + } + break; + case EF_ARROWRIGHT: + GetScrollInfo(hCtrl, SB_HORZ, &si); + nPos = si.nPos; + nTrackPos = si.nTrackPos; + pt = GetRightArrowPt(hCtrl); + for (i = 0; i < pEntry->Repeat; ++i) + { + SetCursorPos(pt.x, pt.y); + NCLeftClick(hwnd, hCtrl, pt, HTHSCROLL); + + while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) + { + DispatchMessage(&msg); + TranslateMessage(&msg); + } + Sleep(INPUT_WAIT); + + si.fMask = SIF_ALL | SIF_TRACKPOS; + GetScrollInfo(hCtrl, SB_HORZ, &si); + ok(nPos < si.nPos, "#%d: %d, %d\n", EntryNumber, nPos, si.nPos); + ok(nTrackPos < si.nTrackPos, "#%d: %d, %d\n", EntryNumber, nTrackPos, si.nTrackPos); + + nPos = si.nPos; + nTrackPos = si.nTrackPos; + } + break; + case EF_ARROWDOWN: + GetScrollInfo(hCtrl, SB_VERT, &si); + nPos = si.nPos; + nTrackPos = si.nTrackPos; + pt = GetDownArrowPt(hCtrl); + for (i = 0; i < pEntry->Repeat; ++i) + { + SetCursorPos(pt.x, pt.y); + NCLeftClick(hwnd, hCtrl, pt, HTVSCROLL); + + while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) + { + DispatchMessage(&msg); + TranslateMessage(&msg); + } + Sleep(INPUT_WAIT); + + si.fMask = SIF_ALL | SIF_TRACKPOS; + GetScrollInfo(hCtrl, SB_VERT, &si); + ok(nPos < si.nPos, "#%d: %d, %d\n", EntryNumber, nPos, si.nPos); + ok(nTrackPos < si.nTrackPos, "#%d: %d, %d\n", EntryNumber, nTrackPos, si.nTrackPos); + + nPos = si.nPos; + nTrackPos = si.nTrackPos; + } + break; + case EF_SCROLLLEFT: + GetScrollInfo(hCtrl, SB_HORZ, &si); + nPos = si.nPos; + nTrackPos = si.nTrackPos; + for (i = 0; i < pEntry->Repeat; ++i) + { + SendMessage(hCtrl, WM_HSCROLL, MAKEWPARAM(SB_LINELEFT, 0), 0); + Sleep(INPUT_WAIT); + + si.fMask = SIF_ALL | SIF_TRACKPOS; + GetScrollInfo(hCtrl, SB_HORZ, &si); + ok(nPos > si.nPos, "#%d: %d, %d\n", EntryNumber, nPos, si.nPos); + ok(nTrackPos > si.nTrackPos, "#%d: %d, %d\n", EntryNumber, nTrackPos, si.nTrackPos); + + nPos = si.nPos; + nTrackPos = si.nTrackPos; + } + break; + case EF_SCROLLUP: + GetScrollInfo(hCtrl, SB_VERT, &si); + nPos = si.nPos; + nTrackPos = si.nTrackPos; + for (i = 0; i < pEntry->Repeat; ++i) + { + SendMessage(hCtrl, WM_VSCROLL, MAKEWPARAM(SB_LINEUP, 0), 0); + Sleep(INPUT_WAIT); + + si.fMask = SIF_ALL | SIF_TRACKPOS; + GetScrollInfo(hCtrl, SB_VERT, &si); + ok(nPos > si.nPos, "#%d: %d, %d\n", EntryNumber, nPos, si.nPos); + ok(nTrackPos > si.nTrackPos, "#%d: %d, %d\n", EntryNumber, nTrackPos, si.nTrackPos); + + nPos = si.nPos; + nTrackPos = si.nTrackPos; + } + break; + case EF_SCROLLRIGHT: + GetScrollInfo(hCtrl, SB_HORZ, &si); + nPos = si.nPos; + nTrackPos = si.nTrackPos; + for (i = 0; i < pEntry->Repeat; ++i) + { + SendMessage(hCtrl, WM_HSCROLL, MAKEWPARAM(SB_LINERIGHT, 0), 0); + Sleep(INPUT_WAIT); + + si.fMask = SIF_ALL | SIF_TRACKPOS; + GetScrollInfo(hCtrl, SB_HORZ, &si); + ok(nPos < si.nPos, "#%d: %d, %d\n", EntryNumber, nPos, si.nPos); + ok(nTrackPos < si.nTrackPos, "#%d: %d, %d\n", EntryNumber, nTrackPos, si.nTrackPos); + + nPos = si.nPos; + nTrackPos = si.nTrackPos; + } + break; + case EF_SCROLLDOWN: + GetScrollInfo(hCtrl, SB_VERT, &si); + nPos = si.nPos; + nTrackPos = si.nTrackPos; + for (i = 0; i < pEntry->Repeat; ++i) + { + SendMessage(hCtrl, WM_VSCROLL, MAKEWPARAM(SB_LINEDOWN, 0), 0); + Sleep(INPUT_WAIT); + + si.fMask = SIF_ALL | SIF_TRACKPOS; + GetScrollInfo(hCtrl, SB_VERT, &si); + ok(nPos < si.nPos, "#%d: %d, %d\n", EntryNumber, nPos, si.nPos); + ok(nTrackPos < si.nTrackPos, "#%d: %d, %d\n", EntryNumber, nTrackPos, si.nTrackPos); + + nPos = si.nPos; + nTrackPos = si.nTrackPos; + } + break; + } +} + +static BOOL OnInitDialog(HWND hwnd, HWND hwndFocus, LPARAM lParam) +{ + INT i, n; + TCHAR buf[MAX_LINES * (MAX_COLUMNS + 7) + 1], buf2[32]; + + // EDIT + buf[0] = 0; + for (i = 0; i < MAX_LINES; ++i) + { + for (n = 0; n < MAX_COLUMNS; ++n) + { + wsprintf(buf2, TEXT("%d"), ((n + i) % 10)); + lstrcat(buf, buf2); + } + lstrcat(buf, TEXT("---\r\n")); + lstrcat(buf, TEXT("\r\n")); + } + SetDlgItemText(hwnd, edt1, buf); + + // ListBox + for (i = 0; i < MAX_LINES; ++i) + { + wsprintf(buf, "item #%d: ", i); + for (n = 0; n < MAX_COLUMNS - 7; ++n) + { + wsprintf(buf2, TEXT("%d"), i % 10); + lstrcat(buf, buf2); + } + ListBox_AddString(GetDlgItem(hwnd, lst1), buf); + } + + // ListView + { + LV_COLUMN column; + ZeroMemory(&column, sizeof(column)); + column.mask = LVCF_TEXT | LVCF_WIDTH | LVCF_SUBITEM; + column.pszText = TEXT("Column"); + column.cx = 400; + column.iSubItem = 0; + ListView_InsertColumn(GetDlgItem(hwnd, ctl1), 0, &column); + for (i = 0; i < MAX_LINES; ++i) + { + LV_ITEM item; + ZeroMemory(&item, sizeof(item)); + wsprintf(buf, "item #%d: ", i); + for (n = 0; n < MAX_COLUMNS - 7; ++n) + { + wsprintf(buf2, TEXT("%d"), i % 10); + lstrcat(buf, buf2); + } + item.mask = LVIF_TEXT; + item.iItem = i; + item.pszText = buf; + ListView_InsertItem(GetDlgItem(hwnd, ctl1), &item); + } + } + + // HSCROLLBAR: skip + // VSCROLLBAR: skip + + // TreeView + { + TV_INSERTSTRUCT is; + for (i = 0; i < MAX_LINES; ++i) + { + ZeroMemory(&is, sizeof(is)); + wsprintf(buf, "item #%d: ", i); + for (n = 0; n < MAX_COLUMNS - 7; ++n) + { + wsprintf(buf2, TEXT("%d"), i % 10); + lstrcat(buf, buf2); + } + is.hParent = NULL; + is.hInsertAfter = TVI_LAST; + is.item.mask = TVIF_TEXT; + is.item.pszText = buf; + TreeView_InsertItem(GetDlgItem(hwnd, 1000), &is); + } + } + + i = 0; + s_ahTargets[i++] = GetDlgItem(hwnd, edt1); + s_ahTargets[i++] = GetDlgItem(hwnd, lst1); + s_ahTargets[i++] = GetDlgItem(hwnd, ctl1); + s_ahTargets[i++] = GetDlgItem(hwnd, scr1); + s_ahTargets[i++] = GetDlgItem(hwnd, scr2); + s_ahTargets[i++] = GetDlgItem(hwnd, 1000); + + SetTimer(hwnd, 999, FIRST_WAIT, NULL); + return FALSE; +} + +static void OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify) +{ + UINT i; + switch (id) + { + case 666: + for (i = 0; i < _countof(s_Entries); ++i) + { + DoEntry(hwnd, s_Entries[i].EntryNumber, &s_Entries[i]); + } + PostMessage(hwnd, WM_COMMAND, IDOK, 0); + break; + case IDOK: + EndDialog(hwnd, IDOK); + break; + case IDCANCEL: + EndDialog(hwnd, IDCANCEL); + break; + } +} + +static void OnTimer(HWND hwnd, UINT id) +{ + KillTimer(hwnd, id); + PostMessage(hwnd, WM_COMMAND, 666, 0); +} + +static INT_PTR CALLBACK +DialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + switch (uMsg) + { + HANDLE_MSG(hwnd, WM_INITDIALOG, OnInitDialog); + HANDLE_MSG(hwnd, WM_COMMAND, OnCommand); + HANDLE_MSG(hwnd, WM_TIMER, OnTimer); + } + return 0; +} + +START_TEST(scroll) +{ + InitCommonControls(); + + DialogBox(GetModuleHandle(NULL), MAKEINTRESOURCE(1), NULL, DialogProc); +} Index: rostests/apitests/ctrlscroll/ctrlscroll.rc =================================================================== --- rostests/apitests/ctrlscroll/ctrlscroll.rc (nonexistent) +++ rostests/apitests/ctrlscroll/ctrlscroll.rc (working copy) @@ -0,0 +1,28 @@ +/* + * PROJECT: ReactOS api tests + * LICENSE: GPL - See COPYING in the top level directory + * PURPOSE: Test for scrolling of dialog controls + * PROGRAMMERS: Katayama Hirofumi MZ + */ +#include +#include +#include +#include + +LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL + +#include + +1 DIALOG 0, 0, 297, 207 +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "ctrlscroll_apitest" +FONT 9, "MS Shell Dlg" +{ + CONTROL "", edt1, "EDIT", ES_LEFT | ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_VSCROLL | WS_HSCROLL | WS_TABSTOP, 7, 9, 99, 63 + CONTROL "", lst1, "LISTBOX", WS_VSCROLL | WS_BORDER | LBS_HASSTRINGS | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 7, 89, 74, 99 + CONTROL "", ctl1, "SysListView32", LVS_REPORT | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_VSCROLL | WS_TABSTOP, 90, 88, 72, 99 + CONTROL "", scr1, "SCROLLBAR", SBS_HORZ | WS_CHILD | WS_VISIBLE, 141, 19, 119, 13 + CONTROL "", scr2, "SCROLLBAR", SBS_VERT | WS_CHILD | WS_VISIBLE, 275, 21, 11, 106 + CONTROL "", 1000, "SysTreeView32", WS_CHILD | WS_VISIBLE | WS_BORDER | WS_VSCROLL | WS_HSCROLL | WS_TABSTOP, 168, 52, 100, 135 + CONTROL "OK", IDOK, "BUTTON", BS_DEFPUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 151, 192, 60, 14 +} Index: rostests/apitests/ctrlscroll/testlist.c =================================================================== --- rostests/apitests/ctrlscroll/testlist.c (nonexistent) +++ rostests/apitests/ctrlscroll/testlist.c (working copy) @@ -0,0 +1,16 @@ +/* + * PROJECT: ReactOS api tests + * LICENSE: GPL - See COPYING in the top level directory + * PURPOSE: Test for scrolling of dialog controls + * PROGRAMMERS: Katayama Hirofumi MZ + */ +#define STANDALONE +#include + +extern void func_scroll(void); + +const struct test winetest_testlist[] = +{ + { "scroll", func_scroll }, + { 0, 0 } +};