mirror of
https://github.com/reactos/reactos.git
synced 2025-08-02 00:43:11 +00:00
Autosyncing with Wine HEAD
svn path=/trunk/; revision=30937
This commit is contained in:
parent
5be02c6da0
commit
58ffb98f70
29 changed files with 9726 additions and 435 deletions
BIN
rostests/winetests/comctl32/bmp128x15.bmp
Normal file
BIN
rostests/winetests/comctl32/bmp128x15.bmp
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.1 KiB |
BIN
rostests/winetests/comctl32/bmp80x15.bmp
Normal file
BIN
rostests/winetests/comctl32/bmp80x15.bmp
Normal file
Binary file not shown.
After Width: | Height: | Size: 718 B |
|
@ -82,108 +82,108 @@ static void test_comboboxex(void) {
|
|||
out_of_range_item[] = {'O','u','t',' ','o','f',' ','R','a','n','g','e',' ','I','t','e','m',0};
|
||||
|
||||
/* Allocate space for result */
|
||||
textBuffer = malloc(MAX_CHARS);
|
||||
textBuffer = HeapAlloc(GetProcessHeap(), 0, MAX_CHARS);
|
||||
|
||||
/* Basic comboboxex test */
|
||||
myHwnd = createComboEx(WS_BORDER | WS_VISIBLE | WS_CHILD | CBS_DROPDOWN);
|
||||
|
||||
/* Add items onto the end of the combobox */
|
||||
res = addItem(myHwnd, -1, first_item);
|
||||
ok(res == 0, "Adding simple item failed (%ld)\n", res);
|
||||
ok(res == 0, "Adding simple item failed (%d)\n", res);
|
||||
res = addItem(myHwnd, -1, second_item);
|
||||
ok(res == 1, "Adding simple item failed (%ld)\n", res);
|
||||
ok(res == 1, "Adding simple item failed (%d)\n", res);
|
||||
res = addItem(myHwnd, 2, third_item);
|
||||
ok(res == 2, "Adding simple item failed (%ld)\n", res);
|
||||
ok(res == 2, "Adding simple item failed (%d)\n", res);
|
||||
res = addItem(myHwnd, 1, middle_item);
|
||||
ok(res == 1, "Inserting simple item failed (%ld)\n", res);
|
||||
ok(res == 1, "Inserting simple item failed (%d)\n", res);
|
||||
|
||||
/* Add an item completely out of range */
|
||||
res = addItem(myHwnd, 99, out_of_range_item);
|
||||
ok(res == -1, "Adding using out of range index worked unexpectedly (%ld)\n", res);
|
||||
ok(res == -1, "Adding using out of range index worked unexpectedly (%d)\n", res);
|
||||
res = addItem(myHwnd, 5, out_of_range_item);
|
||||
ok(res == -1, "Adding using out of range index worked unexpectedly (%ld)\n", res);
|
||||
ok(res == -1, "Adding using out of range index worked unexpectedly (%d)\n", res);
|
||||
/* Removed: Causes traps on Windows XP
|
||||
res = addItem(myHwnd, -2, "Out Of Range Item");
|
||||
ok(res == -1, "Adding out of range worked unexpectedly (%ld)\n", res);
|
||||
*/
|
||||
|
||||
/* Get an item completely out of range */
|
||||
res = getItem(myHwnd, 99, &cbexItem);
|
||||
ok(res == 0, "Getting item using out of range index worked unexpectedly (%ld, %s)\n", res, cbexItem.pszText);
|
||||
res = getItem(myHwnd, 4, &cbexItem);
|
||||
ok(res == 0, "Getting item using out of range index worked unexpectedly (%ld, %s)\n", res, cbexItem.pszText);
|
||||
res = getItem(myHwnd, -2, &cbexItem);
|
||||
ok(res == 0, "Getting item using out of range index worked unexpectedly (%ld, %s)\n", res, cbexItem.pszText);
|
||||
/* Get an item completely out of range */
|
||||
res = getItem(myHwnd, 99, &cbexItem);
|
||||
ok(res == 0, "Getting item using out of range index worked unexpectedly (%d, %s)\n", res, cbexItem.pszText);
|
||||
res = getItem(myHwnd, 4, &cbexItem);
|
||||
ok(res == 0, "Getting item using out of range index worked unexpectedly (%d, %s)\n", res, cbexItem.pszText);
|
||||
res = getItem(myHwnd, -2, &cbexItem);
|
||||
ok(res == 0, "Getting item using out of range index worked unexpectedly (%d, %s)\n", res, cbexItem.pszText);
|
||||
|
||||
/* Get an item in range */
|
||||
res = getItem(myHwnd, 0, &cbexItem);
|
||||
ok(res != 0, "Getting item using valid index failed unexpectedly (%ld)\n", res);
|
||||
/* Get an item in range */
|
||||
res = getItem(myHwnd, 0, &cbexItem);
|
||||
ok(res != 0, "Getting item using valid index failed unexpectedly (%d)\n", res);
|
||||
ok(strcmp(first_item, cbexItem.pszText) == 0, "Getting item returned wrong string (%s)\n", cbexItem.pszText);
|
||||
|
||||
res = getItem(myHwnd, 1, &cbexItem);
|
||||
ok(res != 0, "Getting item using valid index failed unexpectedly (%ld)\n", res);
|
||||
res = getItem(myHwnd, 1, &cbexItem);
|
||||
ok(res != 0, "Getting item using valid index failed unexpectedly (%d)\n", res);
|
||||
ok(strcmp(middle_item, cbexItem.pszText) == 0, "Getting item returned wrong string (%s)\n", cbexItem.pszText);
|
||||
|
||||
res = getItem(myHwnd, 2, &cbexItem);
|
||||
ok(res != 0, "Getting item using valid index failed unexpectedly (%ld)\n", res);
|
||||
res = getItem(myHwnd, 2, &cbexItem);
|
||||
ok(res != 0, "Getting item using valid index failed unexpectedly (%d)\n", res);
|
||||
ok(strcmp(second_item, cbexItem.pszText) == 0, "Getting item returned wrong string (%s)\n", cbexItem.pszText);
|
||||
|
||||
res = getItem(myHwnd, 3, &cbexItem);
|
||||
ok(res != 0, "Getting item using valid index failed unexpectedly (%ld)\n", res);
|
||||
res = getItem(myHwnd, 3, &cbexItem);
|
||||
ok(res != 0, "Getting item using valid index failed unexpectedly (%d)\n", res);
|
||||
ok(strcmp(third_item, cbexItem.pszText) == 0, "Getting item returned wrong string (%s)\n", cbexItem.pszText);
|
||||
|
||||
/* Set an item completely out of range */
|
||||
res = setItem(myHwnd, 99, replacement_item);
|
||||
ok(res == 0, "Setting item using out of range index worked unexpectedly (%ld)\n", res);
|
||||
res = setItem(myHwnd, 4, replacement_item);
|
||||
ok(res == 0, "Setting item using out of range index worked unexpectedly (%ld)\n", res);
|
||||
res = setItem(myHwnd, -2, replacement_item);
|
||||
ok(res == 0, "Setting item using out of range index worked unexpectedly (%ld)\n", res);
|
||||
/* Set an item completely out of range */
|
||||
res = setItem(myHwnd, 99, replacement_item);
|
||||
ok(res == 0, "Setting item using out of range index worked unexpectedly (%d)\n", res);
|
||||
res = setItem(myHwnd, 4, replacement_item);
|
||||
ok(res == 0, "Setting item using out of range index worked unexpectedly (%d)\n", res);
|
||||
res = setItem(myHwnd, -2, replacement_item);
|
||||
ok(res == 0, "Setting item using out of range index worked unexpectedly (%d)\n", res);
|
||||
|
||||
/* Set an item in range */
|
||||
/* Set an item in range */
|
||||
res = setItem(myHwnd, 0, replacement_item);
|
||||
ok(res != 0, "Setting first item failed (%ld)\n", res);
|
||||
ok(res != 0, "Setting first item failed (%d)\n", res);
|
||||
res = setItem(myHwnd, 3, replacement_item);
|
||||
ok(res != 0, "Setting last item failed (%ld)\n", res);
|
||||
ok(res != 0, "Setting last item failed (%d)\n", res);
|
||||
|
||||
/* Remove items completely out of range (4 items in control at this point) */
|
||||
res = delItem(myHwnd, -1);
|
||||
ok(res == CB_ERR, "Deleting using out of range index worked unexpectedly (%ld)\n", res);
|
||||
ok(res == CB_ERR, "Deleting using out of range index worked unexpectedly (%d)\n", res);
|
||||
res = delItem(myHwnd, 4);
|
||||
ok(res == CB_ERR, "Deleting using out of range index worked unexpectedly (%ld)\n", res);
|
||||
ok(res == CB_ERR, "Deleting using out of range index worked unexpectedly (%d)\n", res);
|
||||
|
||||
/* Remove items in range (4 items in control at this point) */
|
||||
res = delItem(myHwnd, 3);
|
||||
ok(res == 3, "Deleting using out of range index failed (%ld)\n", res);
|
||||
ok(res == 3, "Deleting using out of range index failed (%d)\n", res);
|
||||
res = delItem(myHwnd, 0);
|
||||
ok(res == 2, "Deleting using out of range index failed (%ld)\n", res);
|
||||
ok(res == 2, "Deleting using out of range index failed (%d)\n", res);
|
||||
res = delItem(myHwnd, 0);
|
||||
ok(res == 1, "Deleting using out of range index failed (%ld)\n", res);
|
||||
ok(res == 1, "Deleting using out of range index failed (%d)\n", res);
|
||||
res = delItem(myHwnd, 0);
|
||||
ok(res == 0, "Deleting using out of range index failed (%ld)\n", res);
|
||||
ok(res == 0, "Deleting using out of range index failed (%d)\n", res);
|
||||
|
||||
/* Remove from an empty box */
|
||||
res = delItem(myHwnd, 0);
|
||||
ok(res == CB_ERR, "Deleting using out of range index worked unexpectedly (%ld)\n", res);
|
||||
ok(res == CB_ERR, "Deleting using out of range index worked unexpectedly (%d)\n", res);
|
||||
|
||||
|
||||
/* Cleanup */
|
||||
free(textBuffer);
|
||||
HeapFree(GetProcessHeap(), 0, textBuffer);
|
||||
|
||||
}
|
||||
|
||||
LRESULT CALLBACK ComboExTestWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
static LRESULT CALLBACK ComboExTestWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch(msg) {
|
||||
|
||||
case WM_DESTROY:
|
||||
PostQuitMessage(0);
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
return DefWindowProcA(hWnd, msg, wParam, lParam);
|
||||
}
|
||||
|
||||
|
||||
return 0L;
|
||||
}
|
||||
|
||||
|
@ -200,14 +200,14 @@ static void init(void) {
|
|||
wc.cbWndExtra = 0;
|
||||
wc.hInstance = GetModuleHandleA(NULL);
|
||||
wc.hIcon = NULL;
|
||||
wc.hCursor = LoadCursorA(NULL, MAKEINTRESOURCEA(IDC_ARROW));
|
||||
wc.hCursor = LoadCursorA(NULL, IDC_ARROW);
|
||||
wc.hbrBackground = GetSysColorBrush(COLOR_WINDOW);
|
||||
wc.lpszMenuName = NULL;
|
||||
wc.lpszClassName = ComboExTestClass;
|
||||
wc.lpfnWndProc = ComboExTestWndProc;
|
||||
RegisterClassA(&wc);
|
||||
|
||||
hComboExParentWnd = CreateWindowExA(0, ComboExTestClass, "ComboEx test", WS_OVERLAPPEDWINDOW,
|
||||
hComboExParentWnd = CreateWindowExA(0, ComboExTestClass, "ComboEx test", WS_OVERLAPPEDWINDOW,
|
||||
CW_USEDEFAULT, CW_USEDEFAULT, 680, 260, NULL, NULL, GetModuleHandleA(NULL), 0);
|
||||
assert(hComboExParentWnd != NULL);
|
||||
|
||||
|
@ -218,13 +218,13 @@ static void init(void) {
|
|||
static void cleanup(void)
|
||||
{
|
||||
MSG msg;
|
||||
|
||||
|
||||
PostMessageA(hComboExParentWnd, WM_CLOSE, 0, 0);
|
||||
while (GetMessageA(&msg,0,0,0)) {
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessageA(&msg);
|
||||
}
|
||||
|
||||
|
||||
UnregisterClassA(ComboExTestClass, GetModuleHandleA(NULL));
|
||||
}
|
||||
|
||||
|
|
|
@ -1,29 +1,39 @@
|
|||
<module name="comctl32_winetest" type="win32cui" installbase="bin" installname="comctl32_winetest.exe" allowwarnings="true">
|
||||
<include base="comctl32_winetest">.</include>
|
||||
<define name="__USE_W32API" />
|
||||
<library>shlwapi</library>
|
||||
<library>ole32</library>
|
||||
<library>comctl32</library>
|
||||
<library>ntdll</library>
|
||||
<library>gdi32</library>
|
||||
<library>user32</library>
|
||||
<library>kernel32</library>
|
||||
<library>advapi32</library>
|
||||
<file>comboex.c</file>
|
||||
<file>dpa.c</file>
|
||||
<file>header.c</file>
|
||||
<file>imagelist.c</file>
|
||||
<file>listview.c</file>
|
||||
<file>monthcal.c</file>
|
||||
<file>mru.c</file>
|
||||
<file>progress.c</file>
|
||||
<file>propsheet.c</file>
|
||||
<file>subclass.c</file>
|
||||
<file>tab.c</file>
|
||||
<file>testlist.c</file>
|
||||
<file>toolbar.c</file>
|
||||
<file>tooltips.c</file>
|
||||
<file>treeview.c</file>
|
||||
<file>updown.c</file>
|
||||
<file>propsheet.rc</file>
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE module SYSTEM "../../../tools/rbuild/project.dtd">
|
||||
<module name="comctl32_winetest" type="win32cui" installbase="bin" installname="comctl32_winetest.exe" allowwarnings="true" entrypoint="0">
|
||||
<include base="comctl32_winetest">.</include>
|
||||
<define name="WINVER">0x600</define>
|
||||
<define name="_WIN32_WINNT">0x600</define>
|
||||
<library>wine</library>
|
||||
<library>comctl32</library>
|
||||
<library>ole32</library>
|
||||
<library>shlwapi</library>
|
||||
<library>user32</library>
|
||||
<library>gdi32</library>
|
||||
<library>advapi32</library>
|
||||
<library>kernel32</library>
|
||||
<library>ntdll</library>
|
||||
<file>comboex.c</file>
|
||||
<file>datetime.c</file>
|
||||
<file>dpa.c</file>
|
||||
<file>header.c</file>
|
||||
<file>imagelist.c</file>
|
||||
<file>listview.c</file>
|
||||
<file>misc.c</file>
|
||||
<file>monthcal.c</file>
|
||||
<file>mru.c</file>
|
||||
<file>msg.c</file>
|
||||
<file>progress.c</file>
|
||||
<file>propsheet.c</file>
|
||||
<file>rebar.c</file>
|
||||
<file>status.c</file>
|
||||
<file>subclass.c</file>
|
||||
<file>tab.c</file>
|
||||
<file>toolbar.c</file>
|
||||
<file>tooltips.c</file>
|
||||
<file>trackbar.c</file>
|
||||
<file>treeview.c</file>
|
||||
<file>updown.c</file>
|
||||
<file>rsrc.rc</file>
|
||||
<file>testlist.c</file>
|
||||
</module>
|
||||
|
|
24
rostests/winetests/comctl32/comctl32_ros.diff
Normal file
24
rostests/winetests/comctl32/comctl32_ros.diff
Normal file
|
@ -0,0 +1,24 @@
|
|||
Index: dpa.c
|
||||
===================================================================
|
||||
--- dpa.c (revision 25766)
|
||||
+++ dpa.c (working copy)
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
+#include "wingdi.h"
|
||||
#include "winuser.h"
|
||||
#include "commctrl.h"
|
||||
#include "objidl.h"
|
||||
Index: monthcal.c
|
||||
===================================================================
|
||||
--- monthcal.c (revision 25766)
|
||||
+++ monthcal.c (working copy)
|
||||
@@ -23,6 +23,7 @@
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
+#include "wingdi.h"
|
||||
#include "winuser.h"
|
||||
|
||||
#include "commctrl.h"
|
571
rostests/winetests/comctl32/datetime.c
Normal file
571
rostests/winetests/comctl32/datetime.c
Normal file
|
@ -0,0 +1,571 @@
|
|||
/* Unit test suite for datetime control.
|
||||
*
|
||||
* Copyright 2007 Kanit Therdsteerasukdi
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <windows.h>
|
||||
#include <commctrl.h>
|
||||
|
||||
#include "wine/test.h"
|
||||
#include "msg.h"
|
||||
|
||||
#define expect(EXPECTED, GOT) ok((GOT)==(EXPECTED), "Expected %d, got %ld\n", (EXPECTED), (GOT))
|
||||
|
||||
#define expect_unsuccess(EXPECTED, GOT) ok((GOT)==(EXPECTED), "Expected %d(unsuccessful), got %ld(successful)\n", (EXPECTED), (GOT))
|
||||
|
||||
#define NUM_MSG_SEQUENCES 1
|
||||
#define DATETIME_SEQ_INDEX 0
|
||||
|
||||
static struct msg_sequence *sequences[NUM_MSG_SEQUENCES];
|
||||
|
||||
static const struct message test_dtm_set_format_seq[] = {
|
||||
{ DTM_SETFORMATA, sent|wparam|lparam, 0x00000000, 0x00000000 },
|
||||
{ DTM_SETFORMATA, sent|wparam, 0x00000000 },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message test_dtm_set_and_get_mccolor_seq[] = {
|
||||
{ DTM_SETMCCOLOR, sent|wparam|lparam, 0x00000000, 0x00000000 },
|
||||
{ DTM_SETMCCOLOR, sent|wparam|lparam, 0x00000000, 0x00ffffff },
|
||||
{ DTM_SETMCCOLOR, sent|wparam|lparam, 0x00000000, 0x00dcb464 },
|
||||
{ DTM_GETMCCOLOR, sent|wparam|lparam, 0x00000000, 0x00000000 },
|
||||
{ DTM_SETMCCOLOR, sent|wparam|lparam, 0x00000004, 0x00000000 },
|
||||
{ DTM_SETMCCOLOR, sent|wparam|lparam, 0x00000004, 0x00ffffff },
|
||||
{ DTM_SETMCCOLOR, sent|wparam|lparam, 0x00000004, 0x00dcb464 },
|
||||
{ DTM_GETMCCOLOR, sent|wparam|lparam, 0x00000004, 0x00000000 },
|
||||
{ DTM_SETMCCOLOR, sent|wparam|lparam, 0x00000001, 0x00000000 },
|
||||
{ DTM_SETMCCOLOR, sent|wparam|lparam, 0x00000001, 0x00ffffff },
|
||||
{ DTM_SETMCCOLOR, sent|wparam|lparam, 0x00000001, 0x00dcb464 },
|
||||
{ DTM_GETMCCOLOR, sent|wparam|lparam, 0x00000001, 0x00000000 },
|
||||
{ DTM_SETMCCOLOR, sent|wparam|lparam, 0x00000002, 0x00000000 },
|
||||
{ DTM_SETMCCOLOR, sent|wparam|lparam, 0x00000002, 0x00ffffff },
|
||||
{ DTM_SETMCCOLOR, sent|wparam|lparam, 0x00000002, 0x00dcb464 },
|
||||
{ DTM_GETMCCOLOR, sent|wparam|lparam, 0x00000002, 0x00000000 },
|
||||
{ DTM_SETMCCOLOR, sent|wparam|lparam, 0x00000003, 0x00000000 },
|
||||
{ DTM_SETMCCOLOR, sent|wparam|lparam, 0x00000003, 0x00ffffff },
|
||||
{ DTM_SETMCCOLOR, sent|wparam|lparam, 0x00000003, 0x00dcb464 },
|
||||
{ DTM_GETMCCOLOR, sent|wparam|lparam, 0x00000003, 0x00000000 },
|
||||
{ DTM_SETMCCOLOR, sent|wparam|lparam, 0x00000005, 0x00000000 },
|
||||
{ DTM_SETMCCOLOR, sent|wparam|lparam, 0x00000005, 0x00ffffff },
|
||||
{ DTM_SETMCCOLOR, sent|wparam|lparam, 0x00000005, 0x00dcb464 },
|
||||
{ DTM_GETMCCOLOR, sent|wparam|lparam, 0x00000005, 0x00000000 },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message test_dtm_set_and_get_mcfont_seq[] = {
|
||||
{ DTM_SETMCFONT, sent|lparam, 0, 0x00000001 },
|
||||
{ DTM_GETMCFONT, sent|wparam|lparam, 0x00000000, 0x00000000 },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message test_dtm_get_monthcal_seq[] = {
|
||||
{ DTM_GETMONTHCAL, sent|wparam|lparam, 0x00000000, 0x00000000 },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message test_dtm_set_and_get_range_seq[] = {
|
||||
{ DTM_SETRANGE, sent|wparam, 0x00000001 },
|
||||
{ DTM_GETRANGE, sent|wparam, 0x00000000 },
|
||||
{ DTM_SETRANGE, sent|wparam, 0x00000002 },
|
||||
{ DTM_SETRANGE, sent|wparam, 0x00000002 },
|
||||
{ DTM_GETRANGE, sent|wparam, 0x00000000},
|
||||
{ DTM_SETRANGE, sent|wparam, 0x00000001 },
|
||||
{ DTM_SETRANGE, sent|wparam, 0x00000003 },
|
||||
{ DTM_SETRANGE, sent|wparam, 0x00000003 },
|
||||
{ DTM_GETRANGE, sent|wparam, 0x00000000 },
|
||||
{ DTM_SETRANGE, sent|wparam, 0x00000003 },
|
||||
{ DTM_GETRANGE, sent|wparam, 0x00000000 },
|
||||
{ DTM_SETRANGE, sent|wparam, 0x00000003 },
|
||||
{ DTM_GETRANGE, sent|wparam, 0x00000000 },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message test_dtm_set_range_swap_min_max_seq[] = {
|
||||
{ DTM_SETSYSTEMTIME, sent|wparam, 0x00000000 },
|
||||
{ DTM_GETSYSTEMTIME, sent|wparam, 0x00000000 },
|
||||
{ DTM_SETRANGE, sent|wparam, 0x00000003 },
|
||||
{ DTM_GETRANGE, sent|wparam, 0x00000000 },
|
||||
{ DTM_SETSYSTEMTIME, sent|wparam, 0x00000000 },
|
||||
{ DTM_GETSYSTEMTIME, sent|wparam, 0x00000000 },
|
||||
{ DTM_SETRANGE, sent|wparam, 0x00000003 },
|
||||
{ DTM_GETRANGE, sent|wparam, 0x00000000 },
|
||||
{ DTM_SETRANGE, sent|wparam, 0x00000003 },
|
||||
{ DTM_GETRANGE, sent|wparam, 0x00000000 },
|
||||
{ DTM_SETRANGE, sent|wparam, 0x00000003 },
|
||||
{ DTM_GETRANGE, sent|wparam, 0x00000000 },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message test_dtm_set_and_get_system_time_seq[] = {
|
||||
{ DTM_SETSYSTEMTIME, sent|wparam, 0x00000001 },
|
||||
{ WM_DESTROY, sent|wparam|lparam, 0x00000000, 0x00000000 },
|
||||
{ WM_NCDESTROY, sent|wparam|lparam, 0x00000000, 0x00000000 },
|
||||
{ DTM_SETSYSTEMTIME, sent|wparam, 0x00000001 },
|
||||
{ DTM_GETSYSTEMTIME, sent|wparam, 0x00000000 },
|
||||
{ DTM_SETSYSTEMTIME, sent|wparam, 0x00000000 },
|
||||
{ DTM_SETSYSTEMTIME, sent|wparam, 0x00000000 },
|
||||
{ DTM_SETSYSTEMTIME, sent|wparam, 0x00000000 },
|
||||
{ DTM_GETSYSTEMTIME, sent|wparam, 0x00000000 },
|
||||
{ DTM_SETSYSTEMTIME, sent|wparam, 0x00000000 },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message destroy_window_seq[] = {
|
||||
{ WM_DESTROY, sent|wparam|lparam, 0x00000000, 0x00000000 },
|
||||
{ WM_NCDESTROY, sent|wparam|lparam, 0x00000000, 0x00000000 },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
struct subclass_info
|
||||
{
|
||||
WNDPROC oldproc;
|
||||
};
|
||||
|
||||
static LRESULT WINAPI datetime_subclass_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
struct subclass_info *info = (struct subclass_info *)GetWindowLongPtrA(hwnd, GWLP_USERDATA);
|
||||
static long defwndproc_counter = 0;
|
||||
LRESULT ret;
|
||||
struct message msg;
|
||||
|
||||
trace("datetime: %p, %04x, %08lx, %08lx\n", hwnd, message, wParam, lParam);
|
||||
|
||||
msg.message = message;
|
||||
msg.flags = sent|wparam|lparam;
|
||||
if (defwndproc_counter) msg.flags |= defwinproc;
|
||||
msg.wParam = wParam;
|
||||
msg.lParam = lParam;
|
||||
add_message(sequences, DATETIME_SEQ_INDEX, &msg);
|
||||
|
||||
defwndproc_counter++;
|
||||
ret = CallWindowProcA(info->oldproc, hwnd, message, wParam, lParam);
|
||||
defwndproc_counter--;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static HWND create_datetime_control(DWORD style, DWORD exstyle)
|
||||
{
|
||||
struct subclass_info *info;
|
||||
HWND hWndDateTime = NULL;
|
||||
|
||||
info = HeapAlloc(GetProcessHeap(), 0, sizeof(struct subclass_info));
|
||||
if (!info)
|
||||
return NULL;
|
||||
|
||||
hWndDateTime = CreateWindowEx(0,
|
||||
DATETIMEPICK_CLASS,
|
||||
NULL,
|
||||
style,
|
||||
0,50,300,120,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
if (!hWndDateTime) {
|
||||
HeapFree(GetProcessHeap(), 0, info);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
info->oldproc = (WNDPROC)SetWindowLongPtrA(hWndDateTime, GWLP_WNDPROC,
|
||||
(LONG_PTR)datetime_subclass_proc);
|
||||
SetWindowLongPtrA(hWndDateTime, GWLP_USERDATA, (LONG_PTR)info);
|
||||
|
||||
return hWndDateTime;
|
||||
}
|
||||
|
||||
static void test_dtm_set_format(HWND hWndDateTime)
|
||||
{
|
||||
LRESULT r;
|
||||
|
||||
r = SendMessage(hWndDateTime, DTM_SETFORMAT, 0, (LPARAM)NULL);
|
||||
expect(1, r);
|
||||
|
||||
r = SendMessage(hWndDateTime, DTM_SETFORMAT, 0,
|
||||
(LPARAM)"'Today is: 'hh':'m':'s dddd MMM dd', 'yyyy");
|
||||
expect(1, r);
|
||||
|
||||
ok_sequence(sequences, DATETIME_SEQ_INDEX, test_dtm_set_format_seq, "test_dtm_set_format", FALSE);
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
}
|
||||
|
||||
static void test_mccolor_types(HWND hWndDateTime, int mccolor_type, const char* mccolor_name)
|
||||
{
|
||||
LRESULT r;
|
||||
COLORREF theColor, prevColor;
|
||||
|
||||
theColor=RGB(0,0,0);
|
||||
r = SendMessage(hWndDateTime, DTM_SETMCCOLOR, mccolor_type, theColor);
|
||||
ok(r != -1, "%s: Set RGB(0,0,0): Expected COLORREF of previous value, got %ld\n", mccolor_name, r);
|
||||
prevColor=theColor;
|
||||
theColor=RGB(255,255,255);
|
||||
r = SendMessage(hWndDateTime, DTM_SETMCCOLOR, mccolor_type, theColor);
|
||||
ok(r==prevColor, "%s: Set RGB(255,255,255): Expected COLORREF of previous value, got %ld\n", mccolor_name, r);
|
||||
prevColor=theColor;
|
||||
theColor=RGB(100,180,220);
|
||||
r = SendMessage(hWndDateTime, DTM_SETMCCOLOR, mccolor_type, theColor);
|
||||
ok(r==prevColor, "%s: Set RGB(100,180,220): Expected COLORREF of previous value, got %ld\n", mccolor_name, r);
|
||||
r = SendMessage(hWndDateTime, DTM_GETMCCOLOR, mccolor_type, 0);
|
||||
ok(r==theColor, "%s: GETMCCOLOR: Expected %d, got %ld\n", mccolor_name, theColor, r);
|
||||
}
|
||||
|
||||
static void test_dtm_set_and_get_mccolor(HWND hWndDateTime)
|
||||
{
|
||||
test_mccolor_types(hWndDateTime, MCSC_BACKGROUND, "MCSC_BACKGROUND");
|
||||
test_mccolor_types(hWndDateTime, MCSC_MONTHBK, "MCSC_MONTHBK");
|
||||
test_mccolor_types(hWndDateTime, MCSC_TEXT, "MCSC_TEXT");
|
||||
test_mccolor_types(hWndDateTime, MCSC_TITLEBK, "MCSC_TITLEBK");
|
||||
test_mccolor_types(hWndDateTime, MCSC_TITLETEXT, "MCSC_TITLETEXT");
|
||||
test_mccolor_types(hWndDateTime, MCSC_TRAILINGTEXT, "MCSC_TRAILINGTEXT");
|
||||
|
||||
ok_sequence(sequences, DATETIME_SEQ_INDEX, test_dtm_set_and_get_mccolor_seq, "test_dtm_set_and_get_mccolor", FALSE);
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
}
|
||||
|
||||
static void test_dtm_set_and_get_mcfont(HWND hWndDateTime)
|
||||
{
|
||||
HFONT hFontOrig, hFontNew;
|
||||
|
||||
hFontOrig = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
|
||||
SendMessage(hWndDateTime, DTM_SETMCFONT, (WPARAM)hFontOrig, TRUE);
|
||||
hFontNew = (HFONT)SendMessage(hWndDateTime, DTM_GETMCFONT, 0, 0);
|
||||
ok(hFontOrig == hFontNew, "Expected hFontOrig==hFontNew, hFontOrig=%p, hFontNew=%p\n", hFontOrig, hFontNew);
|
||||
|
||||
ok_sequence(sequences, DATETIME_SEQ_INDEX, test_dtm_set_and_get_mcfont_seq, "test_dtm_set_and_get_mcfont", FALSE);
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
}
|
||||
|
||||
static void test_dtm_get_monthcal(HWND hWndDateTime)
|
||||
{
|
||||
LRESULT r;
|
||||
|
||||
todo_wine {
|
||||
r = SendMessage(hWndDateTime, DTM_GETMONTHCAL, 0, 0);
|
||||
ok(r == (LPARAM)NULL, "Expected NULL(no child month calendar control), got %ld\n", r);
|
||||
}
|
||||
|
||||
ok_sequence(sequences, DATETIME_SEQ_INDEX, test_dtm_get_monthcal_seq, "test_dtm_get_monthcal", FALSE);
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
}
|
||||
|
||||
static void fill_systime_struct(SYSTEMTIME *st, int year, int month, int dayofweek, int day, int hour, int minute, int second, int milliseconds)
|
||||
{
|
||||
st->wYear = year;
|
||||
st->wMonth = month;
|
||||
st->wDayOfWeek = dayofweek;
|
||||
st->wDay = day;
|
||||
st->wHour = hour;
|
||||
st->wMinute = minute;
|
||||
st->wSecond = second;
|
||||
st->wMilliseconds = milliseconds;
|
||||
}
|
||||
|
||||
static LPARAM compare_systime_date(SYSTEMTIME *st1, SYSTEMTIME *st2)
|
||||
{
|
||||
return (st1->wYear == st2->wYear)
|
||||
&& (st1->wMonth == st2->wMonth)
|
||||
&& (st1->wDayOfWeek == st2->wDayOfWeek)
|
||||
&& (st1->wDay == st2->wDay);
|
||||
}
|
||||
|
||||
static LPARAM compare_systime_time(SYSTEMTIME *st1, SYSTEMTIME *st2)
|
||||
{
|
||||
return (st1->wHour == st2->wHour)
|
||||
&& (st1->wMinute == st2->wMinute)
|
||||
&& (st1->wSecond == st2->wSecond)
|
||||
&& (st1->wMilliseconds == st2->wMilliseconds);
|
||||
}
|
||||
|
||||
static LPARAM compare_systime(SYSTEMTIME *st1, SYSTEMTIME *st2)
|
||||
{
|
||||
if(!compare_systime_date(st1, st2))
|
||||
return 0;
|
||||
|
||||
return compare_systime_time(st1, st2);
|
||||
}
|
||||
|
||||
#define expect_systime(ST1, ST2) ok(compare_systime((ST1), (ST2))==1, "ST1 != ST2\n")
|
||||
#define expect_systime_date(ST1, ST2) ok(compare_systime_date((ST1), (ST2))==1, "ST1.date != ST2.date\n")
|
||||
#define expect_systime_time(ST1, ST2) ok(compare_systime_time((ST1), (ST2))==1, "ST1.time != ST2.time\n")
|
||||
|
||||
static void test_dtm_set_and_get_range(HWND hWndDateTime)
|
||||
{
|
||||
LRESULT r;
|
||||
SYSTEMTIME st[2];
|
||||
SYSTEMTIME getSt[2];
|
||||
|
||||
/* initialize st[0] to lowest possible value */
|
||||
fill_systime_struct(&st[0], 1601, 1, 0, 1, 0, 0, 0, 0);
|
||||
/* intialize st[1] to all invalid numbers */
|
||||
fill_systime_struct(&st[1], 0, 0, 7, 0, 24, 60, 60, 1000);
|
||||
|
||||
r = SendMessage(hWndDateTime, DTM_SETRANGE, GDTR_MIN, (LPARAM)st);
|
||||
expect(1, r);
|
||||
r = SendMessage(hWndDateTime, DTM_GETRANGE, 0, (LPARAM)getSt);
|
||||
ok(r == GDTR_MIN, "Expected %x, not %x(GDTR_MAX) or %x(GDTR_MIN | GDTR_MAX), got %lx\n", GDTR_MIN, GDTR_MAX, GDTR_MIN | GDTR_MAX, r);
|
||||
expect_systime(&st[0], &getSt[0]);
|
||||
|
||||
r = SendMessage(hWndDateTime, DTM_SETRANGE, GDTR_MAX, (LPARAM)st);
|
||||
expect_unsuccess(0, r);
|
||||
|
||||
/* set st[0] to all invalid numbers */
|
||||
fill_systime_struct(&st[0], 0, 0, 7, 0, 24, 60, 60, 1000);
|
||||
/* set st[1] to highest possible value */
|
||||
fill_systime_struct(&st[1], 30827, 12, 6, 31, 23, 59, 59, 999);
|
||||
|
||||
r = SendMessage(hWndDateTime, DTM_SETRANGE, GDTR_MAX, (LPARAM)st);
|
||||
expect(1, r);
|
||||
r = SendMessage(hWndDateTime, DTM_GETRANGE, 0, (LPARAM)getSt);
|
||||
todo_wine {
|
||||
ok(r == GDTR_MAX, "Expected %x, not %x(GDTR_MIN) or %x(GDTR_MIN | GDTR_MAX), got %lx\n", GDTR_MAX, GDTR_MIN, GDTR_MIN | GDTR_MAX, r);
|
||||
}
|
||||
expect_systime(&st[1], &getSt[1]);
|
||||
|
||||
r = SendMessage(hWndDateTime, DTM_SETRANGE, GDTR_MIN, (LPARAM)st);
|
||||
expect_unsuccess(0, r);
|
||||
r = SendMessage(hWndDateTime, DTM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st);
|
||||
expect_unsuccess(0, r);
|
||||
|
||||
/* set st[0] to highest possible value */
|
||||
fill_systime_struct(&st[0], 30827, 12, 6, 31, 23, 59, 59, 999);
|
||||
|
||||
r = SendMessage(hWndDateTime, DTM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st);
|
||||
expect(1, r);
|
||||
r = SendMessage(hWndDateTime, DTM_GETRANGE, 0, (LPARAM)getSt);
|
||||
ok(r == (GDTR_MIN | GDTR_MAX), "Expected %x, not %x(GDTR_MIN) or %x(GDTR_MAX), got %lx\n", (GDTR_MIN | GDTR_MAX), GDTR_MIN, GDTR_MAX, r);
|
||||
expect_systime(&st[0], &getSt[0]);
|
||||
expect_systime(&st[1], &getSt[1]);
|
||||
|
||||
/* initialize st[0] to lowest possible value */
|
||||
fill_systime_struct(&st[0], 1601, 1, 0, 1, 0, 0, 0, 0);
|
||||
/* set st[1] to highest possible value */
|
||||
fill_systime_struct(&st[1], 30827, 12, 6, 31, 23, 59, 59, 999);
|
||||
|
||||
r = SendMessage(hWndDateTime, DTM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st);
|
||||
expect(1, r);
|
||||
r = SendMessage(hWndDateTime, DTM_GETRANGE, 0, (LPARAM)getSt);
|
||||
ok(r == (GDTR_MIN | GDTR_MAX), "Expected %x, not %x(GDTR_MIN) or %x(GDTR_MAX), got %lx\n", (GDTR_MIN | GDTR_MAX), GDTR_MIN, GDTR_MAX, r);
|
||||
expect_systime(&st[0], &getSt[0]);
|
||||
expect_systime(&st[1], &getSt[1]);
|
||||
|
||||
/* set st[0] to value higher than minimum */
|
||||
fill_systime_struct(&st[0], 1980, 1, 3, 23, 14, 34, 37, 465);
|
||||
/* set st[1] to value lower than maximum */
|
||||
fill_systime_struct(&st[1], 2007, 3, 2, 31, 23, 59, 59, 999);
|
||||
|
||||
r = SendMessage(hWndDateTime, DTM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st);
|
||||
expect(1, r);
|
||||
r = SendMessage(hWndDateTime, DTM_GETRANGE, 0, (LPARAM)getSt);
|
||||
ok(r == (GDTR_MIN | GDTR_MAX), "Expected %x, not %x(GDTR_MIN) or %x(GDTR_MAX), got %lx\n", (GDTR_MIN | GDTR_MAX), GDTR_MIN, GDTR_MAX, r);
|
||||
expect_systime(&st[0], &getSt[0]);
|
||||
expect_systime(&st[1], &getSt[1]);
|
||||
|
||||
ok_sequence(sequences, DATETIME_SEQ_INDEX, test_dtm_set_and_get_range_seq, "test_dtm_set_and_get_range", FALSE);
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
}
|
||||
|
||||
/* when max<min for DTM_SETRANGE, Windows seems to swap the min and max values,
|
||||
although that's undocumented. However, it doesn't seem to be implemented
|
||||
correctly, causing some strange side effects */
|
||||
static void test_dtm_set_range_swap_min_max(HWND hWndDateTime)
|
||||
{
|
||||
LRESULT r;
|
||||
SYSTEMTIME st[2];
|
||||
SYSTEMTIME getSt[2];
|
||||
SYSTEMTIME origSt;
|
||||
|
||||
fill_systime_struct(&st[0], 2007, 2, 4, 15, 2, 2, 2, 2);
|
||||
|
||||
r = SendMessage(hWndDateTime, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st[0]);
|
||||
expect(1, r);
|
||||
r = SendMessage(hWndDateTime, DTM_GETSYSTEMTIME, 0, (LPARAM)&origSt);
|
||||
ok(r == GDT_VALID, "Expected %d, not %d(GDT_NONE) or %d(GDT_ERROR), got %ld\n", GDT_VALID, GDT_NONE, GDT_ERROR, r);
|
||||
expect_systime(&st[0], &origSt);
|
||||
|
||||
/* set st[0] to value higher than st[1] */
|
||||
fill_systime_struct(&st[0], 2007, 3, 2, 31, 23, 59, 59, 999);
|
||||
fill_systime_struct(&st[1], 1980, 1, 3, 23, 14, 34, 37, 465);
|
||||
|
||||
/* since min>max, min and max values should be swapped by DTM_SETRANGE
|
||||
automatically */
|
||||
r = SendMessage(hWndDateTime, DTM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st);
|
||||
expect(1, r);
|
||||
r = SendMessage(hWndDateTime, DTM_GETRANGE, 0, (LPARAM)getSt);
|
||||
ok(r == (GDTR_MIN | GDTR_MAX), "Expected %x, not %x(GDTR_MIN) or %x(GDTR_MAX), got %lx\n", (GDTR_MIN | GDTR_MAX), GDTR_MIN, GDTR_MAX, r);
|
||||
todo_wine {
|
||||
expect_systime(&st[0], &getSt[0]);
|
||||
}
|
||||
todo_wine {
|
||||
expect_systime(&st[1], &getSt[1]);
|
||||
}
|
||||
|
||||
fill_systime_struct(&st[0], 1980, 1, 3, 23, 14, 34, 37, 465);
|
||||
|
||||
r = SendMessage(hWndDateTime, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st[0]);
|
||||
expect(1, r);
|
||||
r = SendMessage(hWndDateTime, DTM_GETSYSTEMTIME, 0, (LPARAM)&getSt[0]);
|
||||
ok(r == GDT_VALID, "Expected %d, not %d(GDT_NONE) or %d(GDT_ERROR), got %ld\n", GDT_VALID, GDT_NONE, GDT_ERROR, r);
|
||||
/* the time part seems to not change after swapping the min and max values
|
||||
and doing DTM_SETSYSTEMTIME */
|
||||
expect_systime_date(&st[0], &getSt[0]);
|
||||
todo_wine {
|
||||
expect_systime_time(&origSt, &getSt[0]);
|
||||
}
|
||||
|
||||
/* set st[0] to value higher than minimum */
|
||||
fill_systime_struct(&st[0], 1980, 1, 3, 23, 14, 34, 37, 465);
|
||||
/* set st[1] to value lower than maximum */
|
||||
fill_systime_struct(&st[1], 2007, 3, 2, 31, 23, 59, 59, 999);
|
||||
|
||||
r = SendMessage(hWndDateTime, DTM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st);
|
||||
expect(1, r);
|
||||
/* for some reason after we swapped the min and max values before,
|
||||
whenever we do a DTM_SETRANGE, the DTM_GETRANGE will return the values
|
||||
swapped*/
|
||||
r = SendMessage(hWndDateTime, DTM_GETRANGE, 0, (LPARAM)getSt);
|
||||
ok(r == (GDTR_MIN | GDTR_MAX), "Expected %x, not %x(GDTR_MIN) or %x(GDTR_MAX), got %lx\n", (GDTR_MIN | GDTR_MAX), GDTR_MIN, GDTR_MAX, r);
|
||||
todo_wine {
|
||||
expect_systime(&st[0], &getSt[1]);
|
||||
}
|
||||
todo_wine {
|
||||
expect_systime(&st[1], &getSt[0]);
|
||||
}
|
||||
|
||||
/* set st[0] to value higher than st[1] */
|
||||
fill_systime_struct(&st[0], 2007, 3, 2, 31, 23, 59, 59, 999);
|
||||
fill_systime_struct(&st[1], 1980, 1, 3, 23, 14, 34, 37, 465);
|
||||
|
||||
/* set min>max again, so that the return values of DTM_GETRANGE are no
|
||||
longer swapped the next time we do a DTM SETRANGE and DTM_GETRANGE*/
|
||||
r = SendMessage(hWndDateTime, DTM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st);
|
||||
expect(1, r);
|
||||
r = SendMessage(hWndDateTime, DTM_GETRANGE, 0, (LPARAM)getSt);
|
||||
ok(r == (GDTR_MIN | GDTR_MAX), "Expected %x, not %x(GDTR_MIN) or %x(GDTR_MAX), got %lx\n", (GDTR_MIN | GDTR_MAX), GDTR_MIN, GDTR_MAX, r);
|
||||
expect_systime(&st[0], &getSt[1]);
|
||||
expect_systime(&st[1], &getSt[0]);
|
||||
|
||||
/* initialize st[0] to lowest possible value */
|
||||
fill_systime_struct(&st[0], 1601, 1, 0, 1, 0, 0, 0, 0);
|
||||
/* set st[1] to highest possible value */
|
||||
fill_systime_struct(&st[1], 30827, 12, 6, 31, 23, 59, 59, 999);
|
||||
|
||||
r = SendMessage(hWndDateTime, DTM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st);
|
||||
expect(1, r);
|
||||
r = SendMessage(hWndDateTime, DTM_GETRANGE, 0, (LPARAM)getSt);
|
||||
ok(r == (GDTR_MIN | GDTR_MAX), "Expected %x, not %x(GDTR_MIN) or %x(GDTR_MAX), got %lx\n", (GDTR_MIN | GDTR_MAX), GDTR_MIN, GDTR_MAX, r);
|
||||
expect_systime(&st[0], &getSt[0]);
|
||||
expect_systime(&st[1], &getSt[1]);
|
||||
|
||||
ok_sequence(sequences, DATETIME_SEQ_INDEX, test_dtm_set_range_swap_min_max_seq, "test_dtm_set_range_swap_min_max", FALSE);
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
}
|
||||
|
||||
static void test_dtm_set_and_get_system_time(HWND hWndDateTime)
|
||||
{
|
||||
LRESULT r;
|
||||
SYSTEMTIME st;
|
||||
SYSTEMTIME getSt;
|
||||
HWND hWndDateTime_test_gdt_none;
|
||||
|
||||
hWndDateTime_test_gdt_none = create_datetime_control(0, 0);
|
||||
|
||||
ok(hWndDateTime_test_gdt_none!=NULL, "Expected non NULL, got %p\n", hWndDateTime_test_gdt_none);
|
||||
if(hWndDateTime_test_gdt_none) {
|
||||
r = SendMessage(hWndDateTime_test_gdt_none, DTM_SETSYSTEMTIME, GDT_NONE, (LPARAM)&st);
|
||||
expect(0, r);
|
||||
}
|
||||
else {
|
||||
skip("hWndDateTime_test_gdt_none is NULL\n");
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
DestroyWindow(hWndDateTime_test_gdt_none);
|
||||
|
||||
r = SendMessage(hWndDateTime, DTM_SETSYSTEMTIME, GDT_NONE, (LPARAM)&st);
|
||||
expect(1, r);
|
||||
r = SendMessage(hWndDateTime, DTM_GETSYSTEMTIME, 0, (LPARAM)&getSt);
|
||||
ok(r == GDT_NONE, "Expected %d, not %d(GDT_VALID) or %d(GDT_ERROR), got %ld\n", GDT_NONE, GDT_VALID, GDT_ERROR, r);
|
||||
|
||||
/* set st to lowest possible value */
|
||||
fill_systime_struct(&st, 1601, 1, 0, 1, 0, 0, 0, 0);
|
||||
|
||||
r = SendMessage(hWndDateTime, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st);
|
||||
expect(1, r);
|
||||
|
||||
/* set st to highest possible value */
|
||||
fill_systime_struct(&st, 30827, 12, 6, 31, 23, 59, 59, 999);
|
||||
|
||||
r = SendMessage(hWndDateTime, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st);
|
||||
expect(1, r);
|
||||
|
||||
/* set st to value between min and max */
|
||||
fill_systime_struct(&st, 1980, 1, 3, 23, 14, 34, 37, 465);
|
||||
|
||||
r = SendMessage(hWndDateTime, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st);
|
||||
expect(1, r);
|
||||
r = SendMessage(hWndDateTime, DTM_GETSYSTEMTIME, 0, (LPARAM)&getSt);
|
||||
ok(r == GDT_VALID, "Expected %d, not %d(GDT_NONE) or %d(GDT_ERROR), got %ld\n", GDT_VALID, GDT_NONE, GDT_ERROR, r);
|
||||
expect_systime(&st, &getSt);
|
||||
|
||||
/* set st to invalid value */
|
||||
fill_systime_struct(&st, 0, 0, 7, 0, 24, 60, 60, 1000);
|
||||
|
||||
r = SendMessage(hWndDateTime, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st);
|
||||
expect_unsuccess(0, r);
|
||||
|
||||
ok_sequence(sequences, DATETIME_SEQ_INDEX, test_dtm_set_and_get_system_time_seq, "test_dtm_set_and_get_system_time", FALSE);
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
}
|
||||
|
||||
static void test_datetime_control(void)
|
||||
{
|
||||
HWND hWndDateTime;
|
||||
|
||||
hWndDateTime = create_datetime_control(DTS_SHOWNONE, 0);
|
||||
|
||||
ok(hWndDateTime != NULL, "Expected non NULL, got %p\n", hWndDateTime);
|
||||
if(hWndDateTime!=NULL) {
|
||||
test_dtm_set_format(hWndDateTime);
|
||||
test_dtm_set_and_get_mccolor(hWndDateTime);
|
||||
test_dtm_set_and_get_mcfont(hWndDateTime);
|
||||
test_dtm_get_monthcal(hWndDateTime);
|
||||
test_dtm_set_and_get_range(hWndDateTime);
|
||||
test_dtm_set_range_swap_min_max(hWndDateTime);
|
||||
test_dtm_set_and_get_system_time(hWndDateTime);
|
||||
}
|
||||
else {
|
||||
skip("hWndDateTime is NULL\n");
|
||||
}
|
||||
|
||||
DestroyWindow(hWndDateTime);
|
||||
ok_sequence(sequences, DATETIME_SEQ_INDEX, destroy_window_seq, "test_dtm_set_and_get_system_time", TRUE);
|
||||
}
|
||||
|
||||
START_TEST(datetime)
|
||||
{
|
||||
INITCOMMONCONTROLSEX icex;
|
||||
|
||||
icex.dwSize = sizeof(icex);
|
||||
icex.dwICC = ICC_DATE_CLASSES;
|
||||
InitCommonControlsEx(&icex);
|
||||
init_msg_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
|
||||
test_datetime_control();
|
||||
}
|
|
@ -23,7 +23,10 @@
|
|||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "windows.h"
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "wingdi.h"
|
||||
#include "winuser.h"
|
||||
#include "commctrl.h"
|
||||
#include "objidl.h"
|
||||
|
||||
|
@ -49,7 +52,7 @@ static PVOID (WINAPI *pDPA_DeleteAllPtrs)(const HDPA);
|
|||
static PVOID (WINAPI *pDPA_DeletePtr)(const HDPA,INT);
|
||||
static BOOL (WINAPI *pDPA_Destroy)(const HDPA);
|
||||
static VOID (WINAPI *pDPA_DestroyCallback)(HDPA,PFNDPAENUMCALLBACK,PVOID);
|
||||
static VOID (WINAPI *pDPA_EnumCallback)(HDPA,PFNDPAENUMCALLBACK,PVOID);
|
||||
static VOID (WINAPI *pDPA_EnumCallback)(HDPA,PFNDPAENUMCALLBACK,PVOID);
|
||||
static INT (WINAPI *pDPA_GetPtr)(const HDPA,INT);
|
||||
static INT (WINAPI *pDPA_GetPtrIndex)(const HDPA,PVOID);
|
||||
static BOOL (WINAPI *pDPA_Grow)(HDPA,INT);
|
||||
|
@ -63,7 +66,7 @@ static BOOL (WINAPI *pDPA_Sort)(const HDPA,PFNDPACOMPARE,LPARAM);
|
|||
|
||||
#define COMCTL32_GET_PROC(func, ord) \
|
||||
((p ## func = (PVOID)GetProcAddress(hcomctl32,(LPCSTR)ord)) ? 1 \
|
||||
: (trace( #func " not exported\n"), 0))
|
||||
: (trace( #func " not exported\n"), 0))
|
||||
|
||||
static BOOL InitFunctionPtrs(HMODULE hcomctl32)
|
||||
{
|
||||
|
@ -112,7 +115,7 @@ static PVOID CALLBACK CB_MergeInsertSrc(UINT op, PVOID p1, PVOID p2, LPARAM lp)
|
|||
{
|
||||
ok(lp == 0xdeadbeef, "lp=%ld\n", lp);
|
||||
return p1;
|
||||
}
|
||||
}
|
||||
|
||||
static PVOID CALLBACK CB_MergeDeleteOddSrc(UINT op, PVOID p1, PVOID p2, LPARAM lp)
|
||||
{
|
||||
|
@ -123,7 +126,7 @@ static PVOID CALLBACK CB_MergeDeleteOddSrc(UINT op, PVOID p1, PVOID p2, LPARAM l
|
|||
static INT nEnum;
|
||||
|
||||
static INT CALLBACK CB_EnumFirstThree(PVOID pItem, PVOID lp)
|
||||
{
|
||||
{
|
||||
INT i;
|
||||
|
||||
i = pDPA_GetPtrIndex(lp, pItem);
|
||||
|
@ -136,12 +139,12 @@ static INT CALLBACK CB_EnumFirstThree(PVOID pItem, PVOID lp)
|
|||
static HRESULT CALLBACK CB_Save(LPITEMDATA pInfo, IStream *pStm, LPARAM lp)
|
||||
{
|
||||
HRESULT hRes;
|
||||
|
||||
|
||||
ok(lp == 0xdeadbeef, "lp=%ld\n", lp);
|
||||
hRes = IStream_Write(pStm, &pInfo->iPos, sizeof(INT), NULL);
|
||||
ok(hRes == S_OK, "hRes=0x%lx\n", hRes);
|
||||
ok(hRes == S_OK, "hRes=0x%x\n", hRes);
|
||||
hRes = IStream_Write(pStm, &pInfo->pvData, sizeof(PVOID), NULL);
|
||||
ok(hRes == S_OK, "hRes=0x%lx\n", hRes);
|
||||
ok(hRes == S_OK, "hRes=0x%x\n", hRes);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -149,14 +152,14 @@ static HRESULT CALLBACK CB_Load(LPITEMDATA pInfo, IStream *pStm, LPARAM lp)
|
|||
{
|
||||
HRESULT hRes;
|
||||
INT iOldPos;
|
||||
|
||||
|
||||
iOldPos = pInfo->iPos;
|
||||
ok(lp == 0xdeadbeef, "lp=%ld\n", lp);
|
||||
hRes = IStream_Read(pStm, &pInfo->iPos, sizeof(INT), NULL);
|
||||
ok(hRes == S_OK, "hRes=0x%lx\n", hRes);
|
||||
ok(hRes == S_OK, "hRes=0x%x\n", hRes);
|
||||
ok(pInfo->iPos == iOldPos, "iPos=%d iOldPos=%d\n", pInfo->iPos, iOldPos);
|
||||
hRes = IStream_Read(pStm, &pInfo->pvData, sizeof(PVOID), NULL);
|
||||
ok(hRes == S_OK, "hRes=0x%lx\n", hRes);
|
||||
ok(hRes == S_OK, "hRes=0x%x\n", hRes);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -171,23 +174,23 @@ static BOOL CheckDPA(HDPA dpa, DWORD dwIn, PDWORD pdwOut)
|
|||
if(!ulItem) break;
|
||||
dwOut = dwOut << 4 | (ulItem & 0xf);
|
||||
}
|
||||
|
||||
|
||||
*pdwOut = dwOut;
|
||||
|
||||
if(dwOut != dwIn)
|
||||
{
|
||||
pDPA_DeleteAllPtrs(dpa);
|
||||
|
||||
|
||||
do
|
||||
{
|
||||
pDPA_InsertPtr(dpa, 0, (PVOID)(dwIn & 0xf));
|
||||
dwIn >>= 4;
|
||||
}
|
||||
while(dwIn);
|
||||
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -200,16 +203,17 @@ static void test_dpa(void)
|
|||
PVOID p;
|
||||
DWORD dw, dw2, dw3;
|
||||
HRESULT hRes;
|
||||
|
||||
BOOL rc;
|
||||
|
||||
GetSystemInfo(&si);
|
||||
hHeap = HeapCreate(0, 1, 2);
|
||||
ok(hHeap != NULL, "error=%ld\n", GetLastError());
|
||||
ok(hHeap != NULL, "error=%d\n", GetLastError());
|
||||
dpa3 = pDPA_CreateEx(0, hHeap);
|
||||
ok(dpa3 != NULL, "\n");
|
||||
ret = pDPA_Grow(dpa3, si.dwPageSize + 1);
|
||||
todo_wine ok(!ret && GetLastError() == ERROR_NOT_ENOUGH_MEMORY,
|
||||
"ret=%d error=%ld\n", ret, GetLastError());
|
||||
|
||||
todo_wine ok(!ret && GetLastError() == ERROR_NOT_ENOUGH_MEMORY,
|
||||
"ret=%d error=%d\n", ret, GetLastError());
|
||||
|
||||
dpa = pDPA_Create(0);
|
||||
ok(dpa != NULL, "\n");
|
||||
|
||||
|
@ -217,8 +221,9 @@ static void test_dpa(void)
|
|||
ok(pDPA_SetPtr(dpa, 1, (PVOID)6), "\n");
|
||||
/* Fill the greated gap */
|
||||
ok(pDPA_SetPtr(dpa, 0, (PVOID)5), "\n");
|
||||
ok(CheckDPA(dpa, 0x56, &dw), "dw=0x%lx\n", dw);
|
||||
|
||||
rc=CheckDPA(dpa, 0x56, &dw);
|
||||
ok(rc, "dw=0x%x\n", dw);
|
||||
|
||||
/* Prepend item */
|
||||
ret = pDPA_InsertPtr(dpa, 1, (PVOID)1);
|
||||
ok(ret == 1, "ret=%d\n", ret);
|
||||
|
@ -228,11 +233,12 @@ static void test_dpa(void)
|
|||
/* Append item using out of bound index */
|
||||
ret = pDPA_InsertPtr(dpa, 5, (PVOID)2);
|
||||
ok(ret == 4, "ret=%d\n", ret);
|
||||
/* Append item using DPA_APPEND */
|
||||
/* Append item using DPA_APPEND */
|
||||
ret = pDPA_InsertPtr(dpa, DPA_APPEND, (PVOID)4);
|
||||
ok(ret == 5, "ret=%d\n", ret);
|
||||
|
||||
ok(CheckDPA(dpa, 0x516324, &dw), "dw=0x%lx\n", dw);
|
||||
rc=CheckDPA(dpa, 0x516324, &dw);
|
||||
ok(rc, "dw=0x%x\n", dw);
|
||||
|
||||
for(i = 1; i <= 6; i++)
|
||||
{
|
||||
|
@ -245,24 +251,29 @@ static void test_dpa(void)
|
|||
|
||||
/* Sort DPA */
|
||||
ok(pDPA_Sort(dpa, CB_CmpGT, 0xdeadbeef), "\n");
|
||||
ok(CheckDPA(dpa, 0x654321, &dw), "dw=0x%lx\n", dw);
|
||||
|
||||
rc=CheckDPA(dpa, 0x654321, &dw);
|
||||
ok(rc, "dw=0x%x\n", dw);
|
||||
|
||||
/* Clone into a new DPA */
|
||||
dpa2 = pDPA_Clone(dpa, NULL);
|
||||
ok(dpa2 != NULL, "\n");
|
||||
/* The old data should have been preserved */
|
||||
ok(CheckDPA(dpa2, 0x654321, &dw2), "dw=0x%lx\n", dw2);
|
||||
rc=CheckDPA(dpa2, 0x654321, &dw2);
|
||||
ok(rc, "dw=0x%x\n", dw2);
|
||||
ok(pDPA_Sort(dpa, CB_CmpLT, 0xdeadbeef), "\n");
|
||||
|
||||
|
||||
/* Test if the DPA itself was really copied */
|
||||
ok(CheckDPA(dpa, 0x123456, &dw), "dw=0x%lx\n", dw );
|
||||
ok(CheckDPA(dpa2, 0x654321, &dw2), "dw2=0x%lx\n", dw2);
|
||||
rc=CheckDPA(dpa, 0x123456, &dw);
|
||||
ok(rc, "dw=0x%x\n", dw );
|
||||
rc=CheckDPA(dpa2, 0x654321, &dw2);
|
||||
ok(rc, "dw2=0x%x\n", dw2);
|
||||
|
||||
/* Clone into an old DPA */
|
||||
p = NULL; SetLastError(ERROR_SUCCESS);
|
||||
p = pDPA_Clone(dpa, dpa3);
|
||||
ok(p == dpa3, "p=%p\n", p);
|
||||
ok(CheckDPA(dpa3, 0x123456, &dw3), "dw3=0x%lx\n", dw3);
|
||||
rc=CheckDPA(dpa3, 0x123456, &dw3);
|
||||
ok(rc, "dw3=0x%x\n", dw3);
|
||||
|
||||
for(i = 1; i <= 6; i++)
|
||||
{
|
||||
|
@ -281,11 +292,11 @@ static void test_dpa(void)
|
|||
j = pDPA_Search(dpa, (PVOID)i, i+1, CB_CmpLT, 0xdeadbeef, DPAS_SORTED);
|
||||
todo_wine ok(j+1 == i, "j=%d i=%d\n", j, i);
|
||||
}
|
||||
|
||||
|
||||
/* Try to get the index of a nonexistent item */
|
||||
i = pDPA_GetPtrIndex(dpa, (PVOID)7);
|
||||
ok(i == DPA_ERR, "i=%d\n", i);
|
||||
|
||||
|
||||
/* Try to delete out of bound indexes */
|
||||
p = pDPA_DeletePtr(dpa, -1);
|
||||
ok(p == NULL, "p=%p\n", p);
|
||||
|
@ -295,10 +306,11 @@ static void test_dpa(void)
|
|||
/* Delete the third item */
|
||||
p = pDPA_DeletePtr(dpa, 2);
|
||||
ok(p == (PVOID)3, "p=%p\n", p);
|
||||
ok(CheckDPA(dpa, 0x12456, &dw), "dw=0x%lx\n", dw);
|
||||
rc=CheckDPA(dpa, 0x12456, &dw);
|
||||
ok(rc, "dw=0x%x\n", dw);
|
||||
|
||||
/* Check where to re-insert the deleted item */
|
||||
i = pDPA_Search(dpa, (PVOID)3, 0,
|
||||
i = pDPA_Search(dpa, (PVOID)3, 0,
|
||||
CB_CmpLT, 0xdeadbeef, DPAS_SORTED|DPAS_INSERTAFTER);
|
||||
ok(i == 2, "i=%d\n", i);
|
||||
/* DPAS_INSERTBEFORE works just like DPAS_INSERTAFTER */
|
||||
|
@ -313,8 +325,9 @@ static void test_dpa(void)
|
|||
/* Re-insert the item */
|
||||
ret = pDPA_InsertPtr(dpa, 2, (PVOID)3);
|
||||
ok(ret == 2, "ret=%d i=%d\n", ret, 2);
|
||||
ok(CheckDPA(dpa, 0x123456, &dw), "dw=0x%lx\n", dw);
|
||||
|
||||
rc=CheckDPA(dpa, 0x123456, &dw);
|
||||
ok(rc, "dw=0x%x\n", dw);
|
||||
|
||||
/* When doing a binary search while claiming reverse order all indexes
|
||||
* should be bogus */
|
||||
for(i = 0; i < 6; i++)
|
||||
|
@ -330,39 +343,49 @@ static void test_dpa(void)
|
|||
p = pDPA_DeletePtr(dpa, 1);
|
||||
p = pDPA_DeletePtr(dpa, 2);
|
||||
p = pDPA_DeletePtr(dpa, 3);
|
||||
ok(CheckDPA(dpa, 0x135, &dw), "dw=0x%lx\n", dw);
|
||||
|
||||
rc=CheckDPA(dpa, 0x135, &dw);
|
||||
ok(rc, "dw=0x%x\n", dw);
|
||||
|
||||
/* Delete all odd entries from dpa2 */
|
||||
pDPA_Merge(dpa2, dpa, DPAM_DELETE,
|
||||
pDPA_Merge(dpa2, dpa, DPAM_DELETE,
|
||||
CB_CmpLT, CB_MergeDeleteOddSrc, 0xdeadbeef);
|
||||
todo_wine ok(CheckDPA(dpa2, 0x246, &dw2), "dw=0x%lx\n", dw2);
|
||||
|
||||
todo_wine
|
||||
{
|
||||
rc=CheckDPA(dpa2, 0x246, &dw2);
|
||||
ok(rc, "dw=0x%x\n", dw2);
|
||||
}
|
||||
|
||||
/* Merge dpa3 into dpa2 and dpa */
|
||||
pDPA_Merge(dpa, dpa3, DPAM_INSERT|DPAM_NOSORT,
|
||||
pDPA_Merge(dpa, dpa3, DPAM_INSERT|DPAM_NOSORT,
|
||||
CB_CmpLT, CB_MergeInsertSrc, 0xdeadbeef);
|
||||
pDPA_Merge(dpa2, dpa3, DPAM_INSERT|DPAM_NOSORT,
|
||||
pDPA_Merge(dpa2, dpa3, DPAM_INSERT|DPAM_NOSORT,
|
||||
CB_CmpLT, CB_MergeInsertSrc, 0xdeadbeef);
|
||||
|
||||
ok(CheckDPA(dpa, 0x123456, &dw ), "dw=0x%lx\n", dw);
|
||||
ok(CheckDPA(dpa2, 0x123456, &dw2), "dw2=0x%lx\n", dw2);
|
||||
ok(CheckDPA(dpa3, 0x123456, &dw3), "dw3=0x%lx\n", dw3);
|
||||
|
||||
rc=CheckDPA(dpa, 0x123456, &dw);
|
||||
ok(rc, "dw=0x%x\n", dw);
|
||||
rc=CheckDPA(dpa2, 0x123456, &dw2);
|
||||
ok(rc, "dw2=0x%x\n", dw2);
|
||||
rc=CheckDPA(dpa3, 0x123456, &dw3);
|
||||
ok(rc, "dw3=0x%x\n", dw3);
|
||||
}
|
||||
|
||||
if(pDPA_EnumCallback)
|
||||
{
|
||||
nEnum = 0;
|
||||
pDPA_EnumCallback(dpa2, CB_EnumFirstThree, (PVOID)dpa2);
|
||||
ok(CheckDPA(dpa2, 0x777456, &dw2), "dw=0x%lx\n", dw2);
|
||||
rc=CheckDPA(dpa2, 0x777456, &dw2);
|
||||
ok(rc, "dw=0x%x\n", dw2);
|
||||
ok(nEnum == 3, "nEnum=%d\n", nEnum);
|
||||
}
|
||||
|
||||
|
||||
/* Setting item with huge index should work */
|
||||
ok(pDPA_SetPtr(dpa2, 0x12345, (PVOID)0xdeadbeef), "\n");
|
||||
ret = pDPA_GetPtrIndex(dpa2, (PVOID)0xdeadbeef);
|
||||
ok(ret == 0x12345, "ret=%d\n", ret);
|
||||
|
||||
|
||||
pDPA_DeleteAllPtrs(dpa2);
|
||||
ok(CheckDPA(dpa2, 0, &dw2), "dw2=0x%lx\n", dw2);
|
||||
rc=CheckDPA(dpa2, 0, &dw2);
|
||||
ok(rc, "dw2=0x%x\n", dw2);
|
||||
pDPA_Destroy(dpa2);
|
||||
|
||||
if(pDPA_DestroyCallback)
|
||||
|
@ -388,31 +411,34 @@ static void test_dpa(void)
|
|||
|
||||
dwMode = STGM_DIRECT|STGM_CREATE|STGM_READWRITE|STGM_SHARE_EXCLUSIVE;
|
||||
hRes = StgCreateDocfile(NULL, dwMode|STGM_DELETEONRELEASE, 0, &pStg);
|
||||
ok(hRes == S_OK, "hRes=0x%lx\n", hRes);
|
||||
ok(hRes == S_OK, "hRes=0x%x\n", hRes);
|
||||
|
||||
hRes = IStorage_CreateStream(pStg, szStg, dwMode, 0, 0, &pStm);
|
||||
ok(hRes == S_OK, "hRes=0x%lx\n", hRes);
|
||||
ok(hRes == S_OK, "hRes=0x%x\n", hRes);
|
||||
|
||||
hRes = pDPA_SaveStream(dpa, CB_Save, pStm, 0xdeadbeef);
|
||||
todo_wine ok(hRes == S_OK, "hRes=0x%lx\n", hRes);
|
||||
todo_wine ok(hRes == S_OK, "hRes=0x%x\n", hRes);
|
||||
pDPA_Destroy(dpa);
|
||||
|
||||
|
||||
hRes = IStream_Seek(pStm, liZero, STREAM_SEEK_SET, NULL);
|
||||
ok(hRes == S_OK, "hRes=0x%lx\n", hRes);
|
||||
ok(hRes == S_OK, "hRes=0x%x\n", hRes);
|
||||
hRes = pDPA_LoadStream(&dpa, CB_Load, pStm, 0xdeadbeef);
|
||||
todo_wine ok(hRes == S_OK, "hRes=0x%lx\n", hRes);
|
||||
todo_wine ok(CheckDPA(dpa, 0x123456, &dw), "dw=0x%lx\n", dw);
|
||||
pDPA_Destroy(dpa);
|
||||
todo_wine
|
||||
{
|
||||
ok(hRes == S_OK, "hRes=0x%x\n", hRes);
|
||||
rc=CheckDPA(dpa, 0x123456, &dw);
|
||||
ok(rc, "dw=0x%x\n", dw);
|
||||
}
|
||||
|
||||
ret = IStream_Release(pStm);
|
||||
ok(!ret, "ret=%d\n", ret);
|
||||
|
||||
|
||||
ret = IStorage_Release(pStg);
|
||||
ok(!ret, "ret=%d\n", ret);
|
||||
|
||||
CoUninitialize();
|
||||
}
|
||||
else ok(0, "hResult: %ld\n", hRes);
|
||||
else ok(0, "hResult: %d\n", hRes);
|
||||
|
||||
skip_stream_tests:
|
||||
pDPA_Destroy(dpa);
|
||||
|
@ -424,12 +450,6 @@ START_TEST(dpa)
|
|||
|
||||
hcomctl32 = GetModuleHandleA("comctl32.dll");
|
||||
|
||||
if(!hcomctl32)
|
||||
{
|
||||
ok(0, "error=%ld\n", GetLastError());
|
||||
return;
|
||||
}
|
||||
|
||||
if(InitFunctionPtrs(hcomctl32))
|
||||
test_dpa();
|
||||
else
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,7 +1,9 @@
|
|||
/* Unit test suite for imagelist control.
|
||||
/*
|
||||
* Unit test suite for imagelist control.
|
||||
*
|
||||
* Copyright 2004 Michael Stefaniuc
|
||||
* Copyright 2002 Mike McCormack for CodeWeavers
|
||||
* Copyright 2007 Dmitry Timoshkov
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -18,10 +20,19 @@
|
|||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <windows.h>
|
||||
#include <commctrl.h>
|
||||
#define COBJMACROS
|
||||
#define CONST_VTABLE
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "wingdi.h"
|
||||
#include "winuser.h"
|
||||
#include "objbase.h"
|
||||
#include "commctrl.h" /* must be included after objbase.h to get ImageList_Write */
|
||||
|
||||
#include "wine/test.h"
|
||||
|
||||
|
@ -35,6 +46,24 @@
|
|||
#define REDRAW(hwnd)
|
||||
#endif
|
||||
|
||||
#define IMAGELIST_MAGIC (('L' << 8) | 'I')
|
||||
|
||||
#include "pshpack2.h"
|
||||
/* Header used by ImageList_Read() and ImageList_Write() */
|
||||
typedef struct _ILHEAD
|
||||
{
|
||||
USHORT usMagic;
|
||||
USHORT usVersion;
|
||||
WORD cCurImage;
|
||||
WORD cMaxImage;
|
||||
WORD cGrow;
|
||||
WORD cx;
|
||||
WORD cy;
|
||||
COLORREF bkcolor;
|
||||
WORD flags;
|
||||
SHORT ovls[4];
|
||||
} ILHEAD;
|
||||
#include "poppack.h"
|
||||
|
||||
static BOOL (WINAPI *pImageList_DrawIndirect)(IMAGELISTDRAWPARAMS*) = NULL;
|
||||
|
||||
|
@ -264,7 +293,7 @@ static void testHotspot (void)
|
|||
/* check new hotspot, it should be the same like the old one */
|
||||
himlNew = ImageList_GetDragImage(NULL, &ppt);
|
||||
ok(ppt.x == dx1 && ppt.y == dy1,
|
||||
"Expected drag hotspot [%d,%d] got [%ld,%ld]\n",
|
||||
"Expected drag hotspot [%d,%d] got [%d,%d]\n",
|
||||
dx1, dy1, ppt.x, ppt.y);
|
||||
/* check size of new dragged image */
|
||||
ImageList_GetIconSize(himlNew, &newx, &newy);
|
||||
|
@ -283,6 +312,8 @@ static void testHotspot (void)
|
|||
#undef SIZEX2
|
||||
#undef SIZEY2
|
||||
#undef HOTSPOTS_MAX
|
||||
ImageList_Destroy(himl2);
|
||||
ImageList_Destroy(himl1);
|
||||
DestroyWindow(hwnd);
|
||||
}
|
||||
|
||||
|
@ -327,13 +358,20 @@ static BOOL DoTest1(void)
|
|||
/* remove one extra */
|
||||
ok(!ImageList_Remove(himl,0),"removed nonexistent icon\n");
|
||||
|
||||
/* check SetImageCount/GetImageCount */
|
||||
ok(ImageList_SetImageCount(himl, 3), "couldn't increase image count\n");
|
||||
ok(ImageList_GetImageCount(himl) == 3, "invalid image count after increase\n");
|
||||
ok(ImageList_SetImageCount(himl, 1), "couldn't decrease image count\n");
|
||||
ok(ImageList_GetImageCount(himl) == 1, "invalid image count after decrease to 1\n");
|
||||
ok(ImageList_SetImageCount(himl, 0), "couldn't decrease image count\n");
|
||||
ok(ImageList_GetImageCount(himl) == 0, "invalid image count after decrease to 0\n");
|
||||
|
||||
/* destroy it */
|
||||
ok(ImageList_Destroy(himl),"destroy imagelist failed\n");
|
||||
|
||||
/* icons should be deleted by the imagelist */
|
||||
ok(!DeleteObject(hicon1),"icon 1 wasn't deleted\n");
|
||||
ok(!DeleteObject(hicon2),"icon 2 wasn't deleted\n");
|
||||
ok(!DeleteObject(hicon3),"icon 3 wasn't deleted\n");
|
||||
ok(DestroyIcon(hicon1),"icon 1 wasn't deleted\n");
|
||||
ok(DestroyIcon(hicon2),"icon 2 wasn't deleted\n");
|
||||
ok(DestroyIcon(hicon3),"icon 3 wasn't deleted\n");
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -366,10 +404,9 @@ static BOOL DoTest2(void)
|
|||
/* destroy it */
|
||||
ok(ImageList_Destroy(himl),"destroy imagelist failed\n");
|
||||
|
||||
/* icons should be deleted by the imagelist */
|
||||
ok(!DeleteObject(hicon1),"icon 1 wasn't deleted\n");
|
||||
ok(!DeleteObject(hicon2),"icon 2 wasn't deleted\n");
|
||||
ok(!DeleteObject(hicon3),"icon 3 wasn't deleted\n");
|
||||
ok(DestroyIcon(hicon1),"icon 1 wasn't deleted\n");
|
||||
ok(DestroyIcon(hicon2),"icon 2 wasn't deleted\n");
|
||||
ok(DestroyIcon(hicon3),"icon 3 wasn't deleted\n");
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
@ -541,10 +578,395 @@ static void testMerge(void)
|
|||
|
||||
ImageList_Destroy(himl1);
|
||||
ImageList_Destroy(himl2);
|
||||
DeleteObject(hicon1);
|
||||
DestroyIcon(hicon1);
|
||||
DestroyWindow(hwnd);
|
||||
}
|
||||
|
||||
/*********************** imagelist storage test ***************************/
|
||||
|
||||
#define BMP_CX 48
|
||||
|
||||
struct my_IStream
|
||||
{
|
||||
IStream is;
|
||||
char *iml_data; /* written imagelist data */
|
||||
ULONG iml_data_size;
|
||||
};
|
||||
|
||||
static HRESULT STDMETHODCALLTYPE Test_Stream_QueryInterface(
|
||||
IStream* This,
|
||||
REFIID riid,
|
||||
void** ppvObject)
|
||||
{
|
||||
assert(0);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static ULONG STDMETHODCALLTYPE Test_Stream_AddRef(
|
||||
IStream* This)
|
||||
{
|
||||
assert(0);
|
||||
return 2;
|
||||
}
|
||||
|
||||
static ULONG STDMETHODCALLTYPE Test_Stream_Release(
|
||||
IStream* This)
|
||||
{
|
||||
assert(0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static HRESULT STDMETHODCALLTYPE Test_Stream_Read(
|
||||
IStream* This,
|
||||
void* pv,
|
||||
ULONG cb,
|
||||
ULONG* pcbRead)
|
||||
{
|
||||
assert(0);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static BOOL allocate_storage(struct my_IStream *my_is, ULONG add)
|
||||
{
|
||||
my_is->iml_data_size += add;
|
||||
|
||||
if (!my_is->iml_data)
|
||||
my_is->iml_data = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, my_is->iml_data_size);
|
||||
else
|
||||
my_is->iml_data = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, my_is->iml_data, my_is->iml_data_size);
|
||||
|
||||
return my_is->iml_data ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
static HRESULT STDMETHODCALLTYPE Test_Stream_Write(
|
||||
IStream* This,
|
||||
const void* pv,
|
||||
ULONG cb,
|
||||
ULONG* pcbWritten)
|
||||
{
|
||||
struct my_IStream *my_is = (struct my_IStream *)This;
|
||||
ULONG current_iml_data_size = my_is->iml_data_size;
|
||||
|
||||
if (!allocate_storage(my_is, cb)) return E_FAIL;
|
||||
|
||||
memcpy(my_is->iml_data + current_iml_data_size, pv, cb);
|
||||
if (pcbWritten) *pcbWritten = cb;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT STDMETHODCALLTYPE Test_Stream_Seek(
|
||||
IStream* This,
|
||||
LARGE_INTEGER dlibMove,
|
||||
DWORD dwOrigin,
|
||||
ULARGE_INTEGER* plibNewPosition)
|
||||
{
|
||||
assert(0);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT STDMETHODCALLTYPE Test_Stream_SetSize(
|
||||
IStream* This,
|
||||
ULARGE_INTEGER libNewSize)
|
||||
{
|
||||
assert(0);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT STDMETHODCALLTYPE Test_Stream_CopyTo(
|
||||
IStream* This,
|
||||
IStream* pstm,
|
||||
ULARGE_INTEGER cb,
|
||||
ULARGE_INTEGER* pcbRead,
|
||||
ULARGE_INTEGER* pcbWritten)
|
||||
{
|
||||
assert(0);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT STDMETHODCALLTYPE Test_Stream_Commit(
|
||||
IStream* This,
|
||||
DWORD grfCommitFlags)
|
||||
{
|
||||
assert(0);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT STDMETHODCALLTYPE Test_Stream_Revert(
|
||||
IStream* This)
|
||||
{
|
||||
assert(0);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT STDMETHODCALLTYPE Test_Stream_LockRegion(
|
||||
IStream* This,
|
||||
ULARGE_INTEGER libOffset,
|
||||
ULARGE_INTEGER cb,
|
||||
DWORD dwLockType)
|
||||
{
|
||||
assert(0);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT STDMETHODCALLTYPE Test_Stream_UnlockRegion(
|
||||
IStream* This,
|
||||
ULARGE_INTEGER libOffset,
|
||||
ULARGE_INTEGER cb,
|
||||
DWORD dwLockType)
|
||||
{
|
||||
assert(0);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT STDMETHODCALLTYPE Test_Stream_Stat(
|
||||
IStream* This,
|
||||
STATSTG* pstatstg,
|
||||
DWORD grfStatFlag)
|
||||
{
|
||||
assert(0);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static HRESULT STDMETHODCALLTYPE Test_Stream_Clone(
|
||||
IStream* This,
|
||||
IStream** ppstm)
|
||||
{
|
||||
assert(0);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
static const IStreamVtbl Test_Stream_Vtbl =
|
||||
{
|
||||
Test_Stream_QueryInterface,
|
||||
Test_Stream_AddRef,
|
||||
Test_Stream_Release,
|
||||
Test_Stream_Read,
|
||||
Test_Stream_Write,
|
||||
Test_Stream_Seek,
|
||||
Test_Stream_SetSize,
|
||||
Test_Stream_CopyTo,
|
||||
Test_Stream_Commit,
|
||||
Test_Stream_Revert,
|
||||
Test_Stream_LockRegion,
|
||||
Test_Stream_UnlockRegion,
|
||||
Test_Stream_Stat,
|
||||
Test_Stream_Clone
|
||||
};
|
||||
|
||||
static struct my_IStream Test_Stream = { { &Test_Stream_Vtbl }, 0, 0 };
|
||||
|
||||
static INT DIB_GetWidthBytes( int width, int bpp )
|
||||
{
|
||||
int words;
|
||||
|
||||
switch (bpp)
|
||||
{
|
||||
case 1: words = (width + 31) / 32; break;
|
||||
case 4: words = (width + 7) / 8; break;
|
||||
case 8: words = (width + 3) / 4; break;
|
||||
case 15:
|
||||
case 16: words = (width + 1) / 2; break;
|
||||
case 24: words = (width * 3 + 3)/4; break;
|
||||
case 32: words = width; break;
|
||||
|
||||
default:
|
||||
words=0;
|
||||
trace("Unknown depth %d, please report.\n", bpp );
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
return 4 * words;
|
||||
}
|
||||
|
||||
static void check_bitmap_data(const char *bm_data, ULONG bm_data_size,
|
||||
INT width, INT height, INT bpp,
|
||||
const char *comment)
|
||||
{
|
||||
const BITMAPFILEHEADER *bmfh = (const BITMAPFILEHEADER *)bm_data;
|
||||
const BITMAPINFOHEADER *bmih = (const BITMAPINFOHEADER *)(bm_data + sizeof(*bmfh));
|
||||
ULONG hdr_size, image_size;
|
||||
|
||||
hdr_size = sizeof(*bmfh) + sizeof(*bmih);
|
||||
if (bmih->biBitCount <= 8) hdr_size += (1 << bpp) * sizeof(RGBQUAD);
|
||||
|
||||
ok(bmfh->bfType == (('M' << 8) | 'B'), "wrong bfType 0x%02x\n", bmfh->bfType);
|
||||
ok(bmfh->bfSize == hdr_size, "wrong bfSize 0x%02x\n", bmfh->bfSize);
|
||||
ok(bmfh->bfReserved1 == 0, "wrong bfReserved1 0x%02x\n", bmfh->bfReserved1);
|
||||
ok(bmfh->bfReserved2 == 0, "wrong bfReserved2 0x%02x\n", bmfh->bfReserved2);
|
||||
ok(bmfh->bfOffBits == hdr_size, "wrong bfOffBits 0x%02x\n", bmfh->bfOffBits);
|
||||
|
||||
ok(bmih->biSize == sizeof(*bmih), "wrong biSize %d\n", bmih->biSize);
|
||||
ok(bmih->biWidth == width, "wrong biWidth %d (expected %d)\n", bmih->biWidth, width);
|
||||
ok(bmih->biHeight == height, "wrong biHeight %d (expected %d)\n", bmih->biHeight, height);
|
||||
ok(bmih->biPlanes == 1, "wrong biPlanes %d\n", bmih->biPlanes);
|
||||
ok(bmih->biBitCount == bpp, "wrong biBitCount %d\n", bmih->biBitCount);
|
||||
|
||||
image_size = DIB_GetWidthBytes(bmih->biWidth, bmih->biBitCount) * bmih->biHeight;
|
||||
ok(bmih->biSizeImage == image_size, "wrong biSizeImage %u\n", bmih->biSizeImage);
|
||||
#if 0
|
||||
{
|
||||
char fname[256];
|
||||
FILE *f;
|
||||
sprintf(fname, "bmp_%s.bmp", comment);
|
||||
f = fopen(fname, "wb");
|
||||
fwrite(bm_data, 1, bm_data_size, f);
|
||||
fclose(f);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static void check_ilhead_data(const char *ilh_data, INT cx, INT cy, INT cur, INT max)
|
||||
{
|
||||
ILHEAD *ilh = (ILHEAD *)ilh_data;
|
||||
|
||||
ok(ilh->usMagic == IMAGELIST_MAGIC, "wrong usMagic %4x (expected %02x)\n", ilh->usMagic, IMAGELIST_MAGIC);
|
||||
ok(ilh->usVersion == 0x101, "wrong usVersion %x (expected 0x101)\n", ilh->usVersion);
|
||||
ok(ilh->cCurImage == cur, "wrong cCurImage %d (expected %d)\n", ilh->cCurImage, cur);
|
||||
ok(ilh->cMaxImage == max, "wrong cMaxImage %d (expected %d)\n", ilh->cMaxImage, max);
|
||||
ok(ilh->cGrow == 4, "wrong cGrow %d (expected 4)\n", ilh->cGrow);
|
||||
ok(ilh->cx == cx, "wrong cx %d (expected %d)\n", ilh->cx, cx);
|
||||
ok(ilh->cy == cy, "wrong cy %d (expected %d)\n", ilh->cy, cy);
|
||||
ok(ilh->bkcolor == CLR_NONE, "wrong bkcolor %x\n", ilh->bkcolor);
|
||||
ok(ilh->flags == ILC_COLOR24, "wrong flags %04x\n", ilh->flags);
|
||||
ok(ilh->ovls[0] == -1, "wrong ovls[0] %04x\n", ilh->ovls[0]);
|
||||
ok(ilh->ovls[1] == -1, "wrong ovls[1] %04x\n", ilh->ovls[1]);
|
||||
ok(ilh->ovls[2] == -1, "wrong ovls[2] %04x\n", ilh->ovls[2]);
|
||||
ok(ilh->ovls[3] == -1, "wrong ovls[3] %04x\n", ilh->ovls[3]);
|
||||
}
|
||||
|
||||
static HBITMAP create_bitmap(INT cx, INT cy, COLORREF color, const char *comment)
|
||||
{
|
||||
HDC hdc;
|
||||
char bmibuf[sizeof(BITMAPINFO) + 256 * sizeof(RGBQUAD)];
|
||||
BITMAPINFO *bmi = (BITMAPINFO *)bmibuf;
|
||||
HBITMAP hbmp, hbmp_old;
|
||||
HBRUSH hbrush;
|
||||
RECT rc = { 0, 0, cx, cy };
|
||||
|
||||
hdc = CreateCompatibleDC(0);
|
||||
|
||||
memset(bmi, 0, sizeof(*bmi));
|
||||
bmi->bmiHeader.biSize = sizeof(bmi->bmiHeader);
|
||||
bmi->bmiHeader.biHeight = cx;
|
||||
bmi->bmiHeader.biWidth = cy;
|
||||
bmi->bmiHeader.biBitCount = 24;
|
||||
bmi->bmiHeader.biPlanes = 1;
|
||||
bmi->bmiHeader.biCompression = BI_RGB;
|
||||
hbmp = CreateDIBSection(hdc, bmi, DIB_RGB_COLORS, NULL, NULL, 0);
|
||||
|
||||
hbmp_old = SelectObject(hdc, hbmp);
|
||||
|
||||
hbrush = CreateSolidBrush(color);
|
||||
FillRect(hdc, &rc, hbrush);
|
||||
DeleteObject(hbrush);
|
||||
|
||||
DrawText(hdc, comment, -1, &rc, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
|
||||
|
||||
SelectObject(hdc, hbmp_old);
|
||||
DeleteDC(hdc);
|
||||
|
||||
return hbmp;
|
||||
}
|
||||
|
||||
static void image_list_init(HIMAGELIST himl)
|
||||
{
|
||||
HBITMAP hbm;
|
||||
char comment[16];
|
||||
INT n = 1;
|
||||
|
||||
#define add_bitmap(grey) \
|
||||
sprintf(comment, "%d", n++); \
|
||||
hbm = create_bitmap(BMP_CX, BMP_CX, RGB((grey),(grey),(grey)), comment); \
|
||||
ImageList_Add(himl, hbm, NULL);
|
||||
|
||||
add_bitmap(255); add_bitmap(170); add_bitmap(85); add_bitmap(0);
|
||||
add_bitmap(0); add_bitmap(85); add_bitmap(170); add_bitmap(255);
|
||||
add_bitmap(255); add_bitmap(170); add_bitmap(85); add_bitmap(0);
|
||||
add_bitmap(0); add_bitmap(85); add_bitmap(170); add_bitmap(255);
|
||||
add_bitmap(255); add_bitmap(170); add_bitmap(85); add_bitmap(0);
|
||||
add_bitmap(0); add_bitmap(85); add_bitmap(170); add_bitmap(255);
|
||||
#undef add_bitmap
|
||||
}
|
||||
|
||||
#define iml_clear_stream_data() \
|
||||
HeapFree(GetProcessHeap(), 0, Test_Stream.iml_data); \
|
||||
Test_Stream.iml_data = NULL; \
|
||||
Test_Stream.iml_data_size = 0;
|
||||
|
||||
static void check_iml_data(HIMAGELIST himl, INT cx, INT cy, INT cur, INT max,
|
||||
INT width, INT height, INT bpp, const char *comment)
|
||||
{
|
||||
INT ret, cxx, cyy;
|
||||
|
||||
ret = ImageList_GetImageCount(himl);
|
||||
ok(ret == cur, "expected cur %d got %d\n", cur, ret);
|
||||
|
||||
ret = ImageList_GetIconSize(himl, &cxx, &cyy);
|
||||
ok(ret, "ImageList_GetIconSize failed\n");
|
||||
ok(cxx == cx, "wrong cx %d (expected %d)\n", cxx, cx);
|
||||
ok(cyy == cy, "wrong cy %d (expected %d)\n", cyy, cy);
|
||||
|
||||
iml_clear_stream_data();
|
||||
ret = ImageList_Write(himl, &Test_Stream.is);
|
||||
ok(ret, "ImageList_Write failed\n");
|
||||
|
||||
ok(Test_Stream.iml_data != 0, "ImageList_Write didn't write any data\n");
|
||||
ok(Test_Stream.iml_data_size > sizeof(ILHEAD), "ImageList_Write wrote not enough data\n");
|
||||
|
||||
check_ilhead_data(Test_Stream.iml_data, cx, cy, cur, max);
|
||||
check_bitmap_data(Test_Stream.iml_data + sizeof(ILHEAD),
|
||||
Test_Stream.iml_data_size - sizeof(ILHEAD),
|
||||
width, height, bpp, comment);
|
||||
}
|
||||
|
||||
static void test_imagelist_storage(void)
|
||||
{
|
||||
HIMAGELIST himl;
|
||||
BOOL ret;
|
||||
|
||||
himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR24, 1, 1);
|
||||
ok(himl != 0, "ImageList_Create failed\n");
|
||||
|
||||
check_iml_data(himl, BMP_CX, BMP_CX, 0, 2, BMP_CX * 4, BMP_CX * 1, 24, "empty");
|
||||
|
||||
image_list_init(himl);
|
||||
check_iml_data(himl, BMP_CX, BMP_CX, 24, 27, BMP_CX * 4, BMP_CX * 7, 24, "orig");
|
||||
|
||||
ret = ImageList_Remove(himl, 4);
|
||||
ok(ret, "ImageList_Remove failed\n");
|
||||
check_iml_data(himl, BMP_CX, BMP_CX, 23, 27, BMP_CX * 4, BMP_CX * 7, 24, "1");
|
||||
|
||||
ret = ImageList_Remove(himl, 5);
|
||||
ok(ret, "ImageList_Remove failed\n");
|
||||
check_iml_data(himl, BMP_CX, BMP_CX, 22, 27, BMP_CX * 4, BMP_CX * 7, 24, "2");
|
||||
|
||||
ret = ImageList_Remove(himl, 6);
|
||||
ok(ret, "ImageList_Remove failed\n");
|
||||
check_iml_data(himl, BMP_CX, BMP_CX, 21, 27, BMP_CX * 4, BMP_CX * 7, 24, "3");
|
||||
|
||||
ret = ImageList_Remove(himl, 7);
|
||||
ok(ret, "ImageList_Remove failed\n");
|
||||
check_iml_data(himl, BMP_CX, BMP_CX, 20, 27, BMP_CX * 4, BMP_CX * 7, 24, "4");
|
||||
|
||||
ret = ImageList_Remove(himl, -2);
|
||||
ok(!ret, "ImageList_Remove(-2) should fail\n");
|
||||
check_iml_data(himl, BMP_CX, BMP_CX, 20, 27, BMP_CX * 4, BMP_CX * 7, 24, "5");
|
||||
|
||||
ret = ImageList_Remove(himl, 20);
|
||||
ok(!ret, "ImageList_Remove(20) should fail\n");
|
||||
check_iml_data(himl, BMP_CX, BMP_CX, 20, 27, BMP_CX * 4, BMP_CX * 7, 24, "6");
|
||||
|
||||
ret = ImageList_Remove(himl, -1);
|
||||
ok(ret, "ImageList_Remove(-1) failed\n");
|
||||
check_iml_data(himl, BMP_CX, BMP_CX, 0, 4, BMP_CX * 4, BMP_CX * 1, 24, "7");
|
||||
|
||||
ret = ImageList_Destroy(himl);
|
||||
ok(ret, "ImageList_Destroy failed\n");
|
||||
|
||||
iml_clear_stream_data();
|
||||
}
|
||||
|
||||
START_TEST(imagelist)
|
||||
{
|
||||
desktopDC=GetDC(NULL);
|
||||
|
@ -557,4 +979,5 @@ START_TEST(imagelist)
|
|||
DoTest2();
|
||||
DoTest3();
|
||||
testMerge();
|
||||
test_imagelist_storage();
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
* ListView tests
|
||||
*
|
||||
* Copyright 2006 Mike McCormack for CodeWeavers
|
||||
* Copyright 2007 George Gov
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -23,10 +24,318 @@
|
|||
#include <commctrl.h>
|
||||
|
||||
#include "wine/test.h"
|
||||
#include "msg.h"
|
||||
|
||||
#define PARENT_SEQ_INDEX 0
|
||||
#define LISTVIEW_SEQ_INDEX 1
|
||||
#define NUM_MSG_SEQUENCES 2
|
||||
|
||||
#define LISTVIEW_ID 0
|
||||
#define HEADER_ID 1
|
||||
|
||||
#define expect(expected, got) ok(got == expected, "Expected %d, got %d\n", expected, got)
|
||||
#define expect2(expected1, expected2, got1, got2) ok(expected1 == got1 && expected2 == got2, \
|
||||
"expected (%d,%d), got (%d,%d)\n", expected1, expected2, got1, got2)
|
||||
|
||||
HWND hwndparent;
|
||||
|
||||
static struct msg_sequence *sequences[NUM_MSG_SEQUENCES];
|
||||
|
||||
static const struct message create_parent_wnd_seq[] = {
|
||||
{ WM_GETMINMAXINFO, sent },
|
||||
{ WM_NCCREATE, sent },
|
||||
{ WM_NCCALCSIZE, sent|wparam, 0 },
|
||||
{ WM_CREATE, sent },
|
||||
{ WM_SHOWWINDOW, sent|wparam, 1 },
|
||||
{ WM_WINDOWPOSCHANGING, sent|wparam, 0 },
|
||||
{ WM_WINDOWPOSCHANGING, sent|wparam, 0 },
|
||||
{ WM_ACTIVATEAPP, sent|wparam, 1 },
|
||||
{ WM_NCACTIVATE, sent|wparam, 1 },
|
||||
{ WM_ACTIVATE, sent|wparam, 1 },
|
||||
{ WM_IME_SETCONTEXT, sent|wparam|defwinproc|optional, 1 },
|
||||
{ WM_IME_NOTIFY, sent|defwinproc|optional },
|
||||
{ WM_SETFOCUS, sent|wparam|defwinproc, 0 },
|
||||
/* Win9x adds SWP_NOZORDER below */
|
||||
{ WM_WINDOWPOSCHANGED, sent, /*|wparam, SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE|SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE*/ },
|
||||
{ WM_NCCALCSIZE, sent|wparam|optional, 1 },
|
||||
{ WM_SIZE, sent },
|
||||
{ WM_MOVE, sent },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message redraw_listview_seq[] = {
|
||||
{ WM_PAINT, sent|id, 0, 0, LISTVIEW_ID },
|
||||
{ WM_PAINT, sent|id, 0, 0, HEADER_ID },
|
||||
{ WM_NCPAINT, sent|id|defwinproc, 0, 0, HEADER_ID },
|
||||
{ WM_ERASEBKGND, sent|id|defwinproc, 0, 0, HEADER_ID },
|
||||
{ WM_NOTIFY, sent|id|defwinproc, 0, 0, LISTVIEW_ID },
|
||||
{ WM_NCPAINT, sent|id|defwinproc, 0, 0, LISTVIEW_ID },
|
||||
{ WM_ERASEBKGND, sent|id|defwinproc, 0, 0, LISTVIEW_ID },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message listview_icon_spacing_seq[] = {
|
||||
{ LVM_SETICONSPACING, sent|lparam, 0, (LPARAM) MAKELONG(20, 30) },
|
||||
{ LVM_SETICONSPACING, sent|lparam, 0, (LPARAM) MAKELONG(25, 35) },
|
||||
{ LVM_SETICONSPACING, sent|lparam, 0, (LPARAM) MAKELONG(-1, -1) },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message listview_color_seq[] = {
|
||||
{ LVM_SETBKCOLOR, sent|lparam, 0, RGB(0,0,0) },
|
||||
{ LVM_GETBKCOLOR, sent },
|
||||
{ LVM_SETTEXTCOLOR, sent|lparam, 0, RGB(0,0,0) },
|
||||
{ LVM_GETTEXTCOLOR, sent },
|
||||
{ LVM_SETTEXTBKCOLOR, sent|lparam, 0, RGB(0,0,0) },
|
||||
{ LVM_GETTEXTBKCOLOR, sent },
|
||||
|
||||
{ LVM_SETBKCOLOR, sent|lparam, 0, RGB(100,50,200) },
|
||||
{ LVM_GETBKCOLOR, sent },
|
||||
{ LVM_SETTEXTCOLOR, sent|lparam, 0, RGB(100,50,200) },
|
||||
{ LVM_GETTEXTCOLOR, sent },
|
||||
{ LVM_SETTEXTBKCOLOR, sent|lparam, 0, RGB(100,50,200) },
|
||||
{ LVM_GETTEXTBKCOLOR, sent },
|
||||
|
||||
{ LVM_SETBKCOLOR, sent|lparam, 0, CLR_NONE },
|
||||
{ LVM_GETBKCOLOR, sent },
|
||||
{ LVM_SETTEXTCOLOR, sent|lparam, 0, CLR_NONE },
|
||||
{ LVM_GETTEXTCOLOR, sent },
|
||||
{ LVM_SETTEXTBKCOLOR, sent|lparam, 0, CLR_NONE },
|
||||
{ LVM_GETTEXTBKCOLOR, sent },
|
||||
|
||||
{ LVM_SETBKCOLOR, sent|lparam, 0, RGB(255,255,255) },
|
||||
{ LVM_GETBKCOLOR, sent },
|
||||
{ LVM_SETTEXTCOLOR, sent|lparam, 0, RGB(255,255,255) },
|
||||
{ LVM_GETTEXTCOLOR, sent },
|
||||
{ LVM_SETTEXTBKCOLOR, sent|lparam, 0, RGB(255,255,255) },
|
||||
{ LVM_GETTEXTBKCOLOR, sent },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message listview_item_count_seq[] = {
|
||||
{ LVM_GETITEMCOUNT, sent },
|
||||
{ LVM_INSERTITEM, sent },
|
||||
{ LVM_INSERTITEM, sent },
|
||||
{ LVM_INSERTITEM, sent },
|
||||
{ LVM_GETITEMCOUNT, sent },
|
||||
{ LVM_DELETEITEM, sent|wparam, 2 },
|
||||
{ LVM_GETITEMCOUNT, sent },
|
||||
{ LVM_DELETEALLITEMS, sent },
|
||||
{ LVM_GETITEMCOUNT, sent },
|
||||
{ LVM_INSERTITEM, sent },
|
||||
{ LVM_INSERTITEM, sent },
|
||||
{ LVM_GETITEMCOUNT, sent },
|
||||
{ LVM_INSERTITEM, sent },
|
||||
{ LVM_GETITEMCOUNT, sent },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message listview_itempos_seq[] = {
|
||||
{ LVM_INSERTITEM, sent },
|
||||
{ LVM_INSERTITEM, sent },
|
||||
{ LVM_INSERTITEM, sent },
|
||||
{ LVM_SETITEMPOSITION, sent|wparam|lparam, 1, MAKELPARAM(10,5) },
|
||||
{ LVM_GETITEMPOSITION, sent|wparam, 1 },
|
||||
{ LVM_SETITEMPOSITION, sent|wparam|lparam, 2, MAKELPARAM(0,0) },
|
||||
{ LVM_GETITEMPOSITION, sent|wparam, 2 },
|
||||
{ LVM_SETITEMPOSITION, sent|wparam|lparam, 0, MAKELPARAM(20,20) },
|
||||
{ LVM_GETITEMPOSITION, sent|wparam, 0 },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
struct subclass_info
|
||||
{
|
||||
WNDPROC oldproc;
|
||||
};
|
||||
|
||||
static LRESULT WINAPI parent_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
static long defwndproc_counter = 0;
|
||||
LRESULT ret;
|
||||
struct message msg;
|
||||
|
||||
/* do not log painting messages */
|
||||
if (message != WM_PAINT &&
|
||||
message != WM_ERASEBKGND &&
|
||||
message != WM_NCPAINT &&
|
||||
message != WM_NCHITTEST &&
|
||||
message != WM_GETTEXT &&
|
||||
message != WM_GETICON &&
|
||||
message != WM_DEVICECHANGE)
|
||||
{
|
||||
trace("parent: %p, %04x, %08lx, %08lx\n", hwnd, message, wParam, lParam);
|
||||
|
||||
msg.message = message;
|
||||
msg.flags = sent|wparam|lparam;
|
||||
if (defwndproc_counter) msg.flags |= defwinproc;
|
||||
msg.wParam = wParam;
|
||||
msg.lParam = lParam;
|
||||
add_message(sequences, PARENT_SEQ_INDEX, &msg);
|
||||
}
|
||||
|
||||
defwndproc_counter++;
|
||||
ret = DefWindowProcA(hwnd, message, wParam, lParam);
|
||||
defwndproc_counter--;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL register_parent_wnd_class(void)
|
||||
{
|
||||
WNDCLASSA cls;
|
||||
|
||||
cls.style = 0;
|
||||
cls.lpfnWndProc = parent_wnd_proc;
|
||||
cls.cbClsExtra = 0;
|
||||
cls.cbWndExtra = 0;
|
||||
cls.hInstance = GetModuleHandleA(NULL);
|
||||
cls.hIcon = 0;
|
||||
cls.hCursor = LoadCursorA(0, (LPSTR)IDC_ARROW);
|
||||
cls.hbrBackground = GetStockObject(WHITE_BRUSH);
|
||||
cls.lpszMenuName = NULL;
|
||||
cls.lpszClassName = "Listview test parent class";
|
||||
return RegisterClassA(&cls);
|
||||
}
|
||||
|
||||
static HWND create_parent_window(void)
|
||||
{
|
||||
if (!register_parent_wnd_class())
|
||||
return NULL;
|
||||
|
||||
return CreateWindowEx(0, "Listview test parent class",
|
||||
"Listview test parent window",
|
||||
WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX |
|
||||
WS_MAXIMIZEBOX | WS_VISIBLE,
|
||||
0, 0, 100, 100,
|
||||
GetDesktopWindow(), NULL, GetModuleHandleA(NULL), NULL);
|
||||
}
|
||||
|
||||
static LRESULT WINAPI listview_subclass_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
struct subclass_info *info = (struct subclass_info *)GetWindowLongPtrA(hwnd, GWLP_USERDATA);
|
||||
static long defwndproc_counter = 0;
|
||||
LRESULT ret;
|
||||
struct message msg;
|
||||
|
||||
trace("listview: %p, %04x, %08lx, %08lx\n", hwnd, message, wParam, lParam);
|
||||
|
||||
msg.message = message;
|
||||
msg.flags = sent|wparam|lparam;
|
||||
if (defwndproc_counter) msg.flags |= defwinproc;
|
||||
msg.wParam = wParam;
|
||||
msg.lParam = lParam;
|
||||
msg.id = LISTVIEW_ID;
|
||||
add_message(sequences, LISTVIEW_SEQ_INDEX, &msg);
|
||||
|
||||
defwndproc_counter++;
|
||||
ret = CallWindowProcA(info->oldproc, hwnd, message, wParam, lParam);
|
||||
defwndproc_counter--;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static HWND create_listview_control(void)
|
||||
{
|
||||
struct subclass_info *info;
|
||||
HWND hwnd;
|
||||
RECT rect;
|
||||
|
||||
info = HeapAlloc(GetProcessHeap(), 0, sizeof(struct subclass_info));
|
||||
if (!info)
|
||||
return NULL;
|
||||
|
||||
GetClientRect(hwndparent, &rect);
|
||||
hwnd = CreateWindowExA(0, WC_LISTVIEW, "foo",
|
||||
WS_CHILD | WS_BORDER | WS_VISIBLE | LVS_REPORT,
|
||||
0, 0, rect.right, rect.bottom,
|
||||
hwndparent, NULL, GetModuleHandleA(NULL), NULL);
|
||||
ok(hwnd != NULL, "gle=%d\n", GetLastError());
|
||||
|
||||
if (!hwnd)
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, info);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
info->oldproc = (WNDPROC)SetWindowLongPtrA(hwnd, GWLP_WNDPROC,
|
||||
(LONG_PTR)listview_subclass_proc);
|
||||
SetWindowLongPtrA(hwnd, GWLP_USERDATA, (LONG_PTR)info);
|
||||
|
||||
return hwnd;
|
||||
}
|
||||
|
||||
static HWND create_custom_listview_control(DWORD style)
|
||||
{
|
||||
struct subclass_info *info;
|
||||
HWND hwnd;
|
||||
RECT rect;
|
||||
|
||||
info = HeapAlloc(GetProcessHeap(), 0, sizeof(struct subclass_info));
|
||||
if (!info)
|
||||
return NULL;
|
||||
|
||||
GetClientRect(hwndparent, &rect);
|
||||
hwnd = CreateWindowExA(0, WC_LISTVIEW, "foo",
|
||||
WS_CHILD | WS_BORDER | WS_VISIBLE | style,
|
||||
0, 0, rect.right, rect.bottom,
|
||||
hwndparent, NULL, GetModuleHandleA(NULL), NULL);
|
||||
ok(hwnd != NULL, "gle=%d\n", GetLastError());
|
||||
|
||||
if (!hwnd)
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, info);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
info->oldproc = (WNDPROC)SetWindowLongPtrA(hwnd, GWLP_WNDPROC,
|
||||
(LONG_PTR)listview_subclass_proc);
|
||||
SetWindowLongPtrA(hwnd, GWLP_USERDATA, (LONG_PTR)info);
|
||||
|
||||
return hwnd;
|
||||
}
|
||||
|
||||
static LRESULT WINAPI header_subclass_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
struct subclass_info *info = (struct subclass_info *)GetWindowLongPtrA(hwnd, GWLP_USERDATA);
|
||||
static long defwndproc_counter = 0;
|
||||
LRESULT ret;
|
||||
struct message msg;
|
||||
|
||||
trace("header: %p, %04x, %08lx, %08lx\n", hwnd, message, wParam, lParam);
|
||||
|
||||
msg.message = message;
|
||||
msg.flags = sent|wparam|lparam;
|
||||
if (defwndproc_counter) msg.flags |= defwinproc;
|
||||
msg.wParam = wParam;
|
||||
msg.lParam = lParam;
|
||||
msg.id = HEADER_ID;
|
||||
add_message(sequences, LISTVIEW_SEQ_INDEX, &msg);
|
||||
|
||||
defwndproc_counter++;
|
||||
ret = CallWindowProcA(info->oldproc, hwnd, message, wParam, lParam);
|
||||
defwndproc_counter--;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static HWND subclass_header(HWND hwndListview)
|
||||
{
|
||||
struct subclass_info *info;
|
||||
HWND hwnd;
|
||||
|
||||
info = HeapAlloc(GetProcessHeap(), 0, sizeof(struct subclass_info));
|
||||
if (!info)
|
||||
return NULL;
|
||||
|
||||
hwnd = ListView_GetHeader(hwndListview);
|
||||
info->oldproc = (WNDPROC)SetWindowLongPtrA(hwnd, GWLP_WNDPROC,
|
||||
(LONG_PTR)header_subclass_proc);
|
||||
SetWindowLongPtrA(hwnd, GWLP_USERDATA, (LONG_PTR)info);
|
||||
|
||||
return hwnd;
|
||||
}
|
||||
|
||||
static void test_images(void)
|
||||
{
|
||||
HWND hwnd, hwndparent = 0;
|
||||
HWND hwnd;
|
||||
DWORD r;
|
||||
LVITEM item;
|
||||
HIMAGELIST himl;
|
||||
|
@ -43,7 +352,7 @@ static void test_images(void)
|
|||
r = ImageList_Add(himl, hbmp, 0);
|
||||
ok(r == 0, "should be zero\n");
|
||||
|
||||
hwnd = CreateWindowEx(0, "SysListView32", "foo", LVS_OWNERDRAWFIXED,
|
||||
hwnd = CreateWindowEx(0, "SysListView32", "foo", LVS_OWNERDRAWFIXED,
|
||||
10, 10, 100, 200, hwndparent, NULL, NULL, NULL);
|
||||
ok(hwnd != NULL, "failed to create listview window\n");
|
||||
|
||||
|
@ -63,6 +372,7 @@ static void test_images(void)
|
|||
item.iItem = 0;
|
||||
item.iSubItem = 1;
|
||||
item.iImage = 0;
|
||||
item.pszText = 0;
|
||||
r = SendMessage(hwnd, LVM_INSERTITEM, 0, (LPARAM) &item);
|
||||
ok(r == -1, "should fail\n");
|
||||
|
||||
|
@ -94,14 +404,14 @@ static void test_images(void)
|
|||
|
||||
static void test_checkboxes(void)
|
||||
{
|
||||
HWND hwnd, hwndparent = 0;
|
||||
HWND hwnd;
|
||||
LVITEMA item;
|
||||
DWORD r;
|
||||
static CHAR text[] = "Text",
|
||||
text2[] = "Text2",
|
||||
text3[] = "Text3";
|
||||
|
||||
hwnd = CreateWindowEx(0, "SysListView32", "foo", LVS_REPORT,
|
||||
hwnd = CreateWindowEx(0, "SysListView32", "foo", LVS_REPORT,
|
||||
10, 10, 100, 200, hwndparent, NULL, NULL, NULL);
|
||||
ok(hwnd != NULL, "failed to create listview window\n");
|
||||
|
||||
|
@ -113,7 +423,7 @@ static void test_checkboxes(void)
|
|||
item.iSubItem = 0;
|
||||
item.pszText = text;
|
||||
r = SendMessage(hwnd, LVM_INSERTITEMA, 0, (LPARAM) &item);
|
||||
ok(r == 0, "ret %ld\n", r);
|
||||
ok(r == 0, "ret %d\n", r);
|
||||
|
||||
item.iItem = 0;
|
||||
item.mask = LVIF_STATE;
|
||||
|
@ -129,7 +439,7 @@ static void test_checkboxes(void)
|
|||
item.iSubItem = 0;
|
||||
item.pszText = text;
|
||||
r = SendMessage(hwnd, LVM_INSERTITEMA, 0, (LPARAM) &item);
|
||||
ok(r == 1, "ret %ld\n", r);
|
||||
ok(r == 1, "ret %d\n", r);
|
||||
|
||||
item.iItem = 1;
|
||||
item.mask = LVIF_STATE;
|
||||
|
@ -147,13 +457,13 @@ static void test_checkboxes(void)
|
|||
r = SendMessage(hwnd, LVM_GETITEMA, 0, (LPARAM) &item);
|
||||
ok(item.state == 0x1ccc, "state %x\n", item.state);
|
||||
|
||||
/* Now add an item without specifying a state and check that it's state goes to 0x1000 */
|
||||
/* Now add an item without specifying a state and check that its state goes to 0x1000 */
|
||||
item.iItem = 2;
|
||||
item.mask = LVIF_TEXT;
|
||||
item.state = 0;
|
||||
item.pszText = text2;
|
||||
r = SendMessage(hwnd, LVM_INSERTITEMA, 0, (LPARAM) &item);
|
||||
ok(r == 2, "ret %ld\n", r);
|
||||
ok(r == 2, "ret %d\n", r);
|
||||
|
||||
item.iItem = 2;
|
||||
item.mask = LVIF_STATE;
|
||||
|
@ -161,14 +471,14 @@ static void test_checkboxes(void)
|
|||
r = SendMessage(hwnd, LVM_GETITEMA, 0, (LPARAM) &item);
|
||||
ok(item.state == 0x1000, "state %x\n", item.state);
|
||||
|
||||
/* Add a further item this time specifying a state and still it's state goes to 0x1000 */
|
||||
/* Add a further item this time specifying a state and still its state goes to 0x1000 */
|
||||
item.iItem = 3;
|
||||
item.mask = LVIF_TEXT | LVIF_STATE;
|
||||
item.stateMask = 0xffff;
|
||||
item.state = 0x2aaa;
|
||||
item.pszText = text3;
|
||||
r = SendMessage(hwnd, LVM_INSERTITEMA, 0, (LPARAM) &item);
|
||||
ok(r == 3, "ret %ld\n", r);
|
||||
ok(r == 3, "ret %d\n", r);
|
||||
|
||||
item.iItem = 3;
|
||||
item.mask = LVIF_STATE;
|
||||
|
@ -189,9 +499,19 @@ static void test_checkboxes(void)
|
|||
r = SendMessage(hwnd, LVM_GETITEMA, 0, (LPARAM) &item);
|
||||
ok(item.state == 0x2aaa, "state %x\n", item.state);
|
||||
|
||||
/* Check that only the bits we asked for are returned,
|
||||
* and that all the others are set to zero
|
||||
*/
|
||||
item.iItem = 3;
|
||||
item.mask = LVIF_STATE;
|
||||
item.stateMask = 0xf000;
|
||||
item.state = 0xffff;
|
||||
r = SendMessage(hwnd, LVM_GETITEMA, 0, (LPARAM) &item);
|
||||
ok(item.state == 0x2000, "state %x\n", item.state);
|
||||
|
||||
/* Set the style again and check that doesn't change an item's state */
|
||||
r = SendMessage(hwnd, LVM_SETEXTENDEDLISTVIEWSTYLE, LVS_EX_CHECKBOXES, LVS_EX_CHECKBOXES);
|
||||
ok(r == LVS_EX_CHECKBOXES, "ret %lx\n", r);
|
||||
ok(r == LVS_EX_CHECKBOXES, "ret %x\n", r);
|
||||
|
||||
item.iItem = 3;
|
||||
item.mask = LVIF_STATE;
|
||||
|
@ -201,7 +521,7 @@ static void test_checkboxes(void)
|
|||
|
||||
/* Unsetting the checkbox extended style doesn't change an item's state */
|
||||
r = SendMessage(hwnd, LVM_SETEXTENDEDLISTVIEWSTYLE, LVS_EX_CHECKBOXES, 0);
|
||||
ok(r == LVS_EX_CHECKBOXES, "ret %lx\n", r);
|
||||
ok(r == LVS_EX_CHECKBOXES, "ret %x\n", r);
|
||||
|
||||
item.iItem = 3;
|
||||
item.mask = LVIF_STATE;
|
||||
|
@ -211,7 +531,7 @@ static void test_checkboxes(void)
|
|||
|
||||
/* Now setting the style again will change an item's state */
|
||||
r = SendMessage(hwnd, LVM_SETEXTENDEDLISTVIEWSTYLE, LVS_EX_CHECKBOXES, LVS_EX_CHECKBOXES);
|
||||
ok(r == 0, "ret %lx\n", r);
|
||||
ok(r == 0, "ret %x\n", r);
|
||||
|
||||
item.iItem = 3;
|
||||
item.mask = LVIF_STATE;
|
||||
|
@ -222,6 +542,502 @@ static void test_checkboxes(void)
|
|||
DestroyWindow(hwnd);
|
||||
}
|
||||
|
||||
static void insert_column(HWND hwnd, int idx)
|
||||
{
|
||||
LVCOLUMN column;
|
||||
DWORD rc;
|
||||
|
||||
memset(&column, 0xaa, sizeof(column));
|
||||
column.mask = LVCF_SUBITEM;
|
||||
column.iSubItem = idx;
|
||||
|
||||
rc = ListView_InsertColumn(hwnd, idx, &column);
|
||||
expect(idx, rc);
|
||||
}
|
||||
|
||||
static void insert_item(HWND hwnd, int idx)
|
||||
{
|
||||
static CHAR text[] = "foo";
|
||||
|
||||
LVITEMA item;
|
||||
DWORD rc;
|
||||
|
||||
memset(&item, 0xaa, sizeof (item));
|
||||
item.mask = LVIF_TEXT;
|
||||
item.iItem = idx;
|
||||
item.iSubItem = 0;
|
||||
item.pszText = text;
|
||||
|
||||
rc = ListView_InsertItem(hwnd, &item);
|
||||
expect(idx, rc);
|
||||
}
|
||||
|
||||
static void test_items(void)
|
||||
{
|
||||
const LPARAM lparamTest = 0x42;
|
||||
HWND hwnd;
|
||||
LVITEMA item;
|
||||
DWORD r;
|
||||
static CHAR text[] = "Text";
|
||||
|
||||
hwnd = CreateWindowEx(0, "SysListView32", "foo", LVS_REPORT,
|
||||
10, 10, 100, 200, hwndparent, NULL, NULL, NULL);
|
||||
ok(hwnd != NULL, "failed to create listview window\n");
|
||||
|
||||
/*
|
||||
* Test setting/getting item params
|
||||
*/
|
||||
|
||||
/* Set up two columns */
|
||||
insert_column(hwnd, 0);
|
||||
insert_column(hwnd, 1);
|
||||
|
||||
/* Insert an item with just a param */
|
||||
memset (&item, 0xaa, sizeof (item));
|
||||
item.mask = LVIF_PARAM;
|
||||
item.iItem = 0;
|
||||
item.iSubItem = 0;
|
||||
item.lParam = lparamTest;
|
||||
r = SendMessage(hwnd, LVM_INSERTITEMA, 0, (LPARAM) &item);
|
||||
ok(r == 0, "ret %d\n", r);
|
||||
|
||||
/* Test getting of the param */
|
||||
memset (&item, 0xaa, sizeof (item));
|
||||
item.mask = LVIF_PARAM;
|
||||
item.iItem = 0;
|
||||
item.iSubItem = 0;
|
||||
r = SendMessage(hwnd, LVM_GETITEMA, 0, (LPARAM) &item);
|
||||
ok(r != 0, "ret %d\n", r);
|
||||
ok(item.lParam == lparamTest, "got lParam %lx, expected %lx\n", item.lParam, lparamTest);
|
||||
|
||||
/* Set up a subitem */
|
||||
memset (&item, 0xaa, sizeof (item));
|
||||
item.mask = LVIF_TEXT;
|
||||
item.iItem = 0;
|
||||
item.iSubItem = 1;
|
||||
item.pszText = text;
|
||||
r = SendMessage(hwnd, LVM_SETITEMA, 0, (LPARAM) &item);
|
||||
ok(r != 0, "ret %d\n", r);
|
||||
|
||||
/* Query param from subitem: returns main item param */
|
||||
memset (&item, 0xaa, sizeof (item));
|
||||
item.mask = LVIF_PARAM;
|
||||
item.iItem = 0;
|
||||
item.iSubItem = 1;
|
||||
r = SendMessage(hwnd, LVM_GETITEMA, 0, (LPARAM) &item);
|
||||
ok(r != 0, "ret %d\n", r);
|
||||
ok(item.lParam == lparamTest, "got lParam %lx, expected %lx\n", item.lParam, lparamTest);
|
||||
|
||||
/* Set up param on first subitem: no effect */
|
||||
memset (&item, 0xaa, sizeof (item));
|
||||
item.mask = LVIF_PARAM;
|
||||
item.iItem = 0;
|
||||
item.iSubItem = 1;
|
||||
item.lParam = lparamTest+1;
|
||||
r = SendMessage(hwnd, LVM_SETITEMA, 0, (LPARAM) &item);
|
||||
ok(r == 0, "ret %d\n", r);
|
||||
|
||||
/* Query param from subitem again: should still return main item param */
|
||||
memset (&item, 0xaa, sizeof (item));
|
||||
item.mask = LVIF_PARAM;
|
||||
item.iItem = 0;
|
||||
item.iSubItem = 1;
|
||||
r = SendMessage(hwnd, LVM_GETITEMA, 0, (LPARAM) &item);
|
||||
ok(r != 0, "ret %d\n", r);
|
||||
ok(item.lParam == lparamTest, "got lParam %lx, expected %lx\n", item.lParam, lparamTest);
|
||||
|
||||
/**** Some tests of state highlighting ****/
|
||||
memset (&item, 0xaa, sizeof (item));
|
||||
item.mask = LVIF_STATE;
|
||||
item.iItem = 0;
|
||||
item.iSubItem = 0;
|
||||
item.state = LVIS_SELECTED;
|
||||
item.stateMask = LVIS_SELECTED | LVIS_DROPHILITED;
|
||||
r = SendMessage(hwnd, LVM_SETITEM, 0, (LPARAM) &item);
|
||||
ok(r != 0, "ret %d\n", r);
|
||||
item.iSubItem = 1;
|
||||
item.state = LVIS_DROPHILITED;
|
||||
r = SendMessage(hwnd, LVM_SETITEM, 0, (LPARAM) &item);
|
||||
ok(r != 0, "ret %d\n", r);
|
||||
|
||||
memset (&item, 0xaa, sizeof (item));
|
||||
item.mask = LVIF_STATE;
|
||||
item.iItem = 0;
|
||||
item.iSubItem = 0;
|
||||
item.stateMask = -1;
|
||||
r = SendMessage(hwnd, LVM_GETITEM, 0, (LPARAM) &item);
|
||||
ok(r != 0, "ret %d\n", r);
|
||||
ok(item.state == LVIS_SELECTED, "got state %x, expected %x\n", item.state, LVIS_SELECTED);
|
||||
item.iSubItem = 1;
|
||||
r = SendMessage(hwnd, LVM_GETITEM, 0, (LPARAM) &item);
|
||||
ok(r != 0, "ret %d\n", r);
|
||||
todo_wine ok(item.state == LVIS_DROPHILITED, "got state %x, expected %x\n", item.state, LVIS_DROPHILITED);
|
||||
|
||||
DestroyWindow(hwnd);
|
||||
}
|
||||
|
||||
static void test_columns(void)
|
||||
{
|
||||
HWND hwnd;
|
||||
LVCOLUMN column;
|
||||
DWORD rc;
|
||||
|
||||
hwnd = CreateWindowEx(0, "SysListView32", "foo", LVS_REPORT,
|
||||
10, 10, 100, 200, hwndparent, NULL, NULL, NULL);
|
||||
ok(hwnd != NULL, "failed to create listview window\n");
|
||||
|
||||
/* Add a column with no mask */
|
||||
memset(&column, 0xaa, sizeof(column));
|
||||
column.mask = 0;
|
||||
rc = ListView_InsertColumn(hwnd, 0, &column);
|
||||
ok(rc==0, "Inserting column with no mask failed with %d\n", rc);
|
||||
|
||||
/* Check its width */
|
||||
rc = ListView_GetColumnWidth(hwnd, 0);
|
||||
ok(rc==10, "Inserting column with no mask failed to set width to 10 with %d\n", rc);
|
||||
|
||||
DestroyWindow(hwnd);
|
||||
}
|
||||
/* test setting imagelist between WM_NCCREATE and WM_CREATE */
|
||||
static WNDPROC listviewWndProc;
|
||||
static HIMAGELIST test_create_imagelist;
|
||||
|
||||
static LRESULT CALLBACK create_test_wndproc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
if (uMsg == WM_CREATE)
|
||||
{
|
||||
LPCREATESTRUCT lpcs = (LPCREATESTRUCT)lParam;
|
||||
lpcs->style |= LVS_REPORT;
|
||||
SendMessage(hwnd, LVM_SETIMAGELIST, 0, (LPARAM)test_create_imagelist);
|
||||
}
|
||||
return CallWindowProc(listviewWndProc, hwnd, uMsg, wParam, lParam);
|
||||
}
|
||||
|
||||
static void test_create(void)
|
||||
{
|
||||
HWND hList;
|
||||
HWND hHeader;
|
||||
WNDCLASSEX cls;
|
||||
cls.cbSize = sizeof(WNDCLASSEX);
|
||||
ok(GetClassInfoEx(GetModuleHandle(NULL), "SysListView32", &cls), "GetClassInfoEx failed\n");
|
||||
listviewWndProc = cls.lpfnWndProc;
|
||||
cls.lpfnWndProc = create_test_wndproc;
|
||||
cls.lpszClassName = "MyListView32";
|
||||
ok(RegisterClassEx(&cls), "RegisterClassEx failed\n");
|
||||
|
||||
test_create_imagelist = ImageList_Create(16, 16, 0, 5, 10);
|
||||
hList = CreateWindow("MyListView32", "Test", WS_VISIBLE, 0, 0, 100, 100, NULL, NULL, GetModuleHandle(NULL), 0);
|
||||
ok((HIMAGELIST)SendMessage(hList, LVM_GETIMAGELIST, 0, 0) == test_create_imagelist, "Image list not obtained\n");
|
||||
hHeader = (HWND)SendMessage(hList, LVM_GETHEADER, 0, 0);
|
||||
ok(IsWindow(hHeader) && IsWindowVisible(hHeader), "Listview not in report mode\n");
|
||||
DestroyWindow(hList);
|
||||
}
|
||||
|
||||
static void test_redraw(void)
|
||||
{
|
||||
HWND hwnd, hwndheader;
|
||||
|
||||
hwnd = create_listview_control();
|
||||
hwndheader = subclass_header(hwnd);
|
||||
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
|
||||
trace("invalidate & update\n");
|
||||
InvalidateRect(hwnd, NULL, TRUE);
|
||||
UpdateWindow(hwnd);
|
||||
ok_sequence(sequences, LISTVIEW_SEQ_INDEX, redraw_listview_seq, "redraw listview", FALSE);
|
||||
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
|
||||
DestroyWindow(hwnd);
|
||||
}
|
||||
|
||||
static LRESULT WINAPI cd_wndproc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
|
||||
{
|
||||
COLORREF clr, c0ffee = RGB(0xc0, 0xff, 0xee);
|
||||
|
||||
if(msg == WM_NOTIFY) {
|
||||
NMHDR *nmhdr = (PVOID)lp;
|
||||
if(nmhdr->code == NM_CUSTOMDRAW) {
|
||||
NMLVCUSTOMDRAW *nmlvcd = (PVOID)nmhdr;
|
||||
trace("NMCUSTOMDRAW (0x%.8x)\n", nmlvcd->nmcd.dwDrawStage);
|
||||
switch(nmlvcd->nmcd.dwDrawStage) {
|
||||
case CDDS_PREPAINT:
|
||||
SetBkColor(nmlvcd->nmcd.hdc, c0ffee);
|
||||
return CDRF_NOTIFYITEMDRAW;
|
||||
case CDDS_ITEMPREPAINT:
|
||||
nmlvcd->clrTextBk = CLR_DEFAULT;
|
||||
return CDRF_NOTIFYSUBITEMDRAW;
|
||||
case CDDS_ITEMPREPAINT | CDDS_SUBITEM:
|
||||
clr = GetBkColor(nmlvcd->nmcd.hdc);
|
||||
todo_wine ok(clr == c0ffee, "clr=%.8x\n", clr);
|
||||
return CDRF_NOTIFYPOSTPAINT;
|
||||
case CDDS_ITEMPOSTPAINT | CDDS_SUBITEM:
|
||||
clr = GetBkColor(nmlvcd->nmcd.hdc);
|
||||
todo_wine ok(clr == c0ffee, "clr=%.8x\n", clr);
|
||||
return CDRF_DODEFAULT;
|
||||
}
|
||||
return CDRF_DODEFAULT;
|
||||
}
|
||||
}
|
||||
|
||||
return DefWindowProcA(hwnd, msg, wp, lp);
|
||||
}
|
||||
|
||||
static void test_customdraw(void)
|
||||
{
|
||||
HWND hwnd;
|
||||
WNDPROC oldwndproc;
|
||||
|
||||
hwnd = create_listview_control();
|
||||
|
||||
insert_column(hwnd, 0);
|
||||
insert_column(hwnd, 1);
|
||||
insert_item(hwnd, 0);
|
||||
|
||||
oldwndproc = (WNDPROC)SetWindowLongPtr(hwndparent, GWLP_WNDPROC,
|
||||
(LONG_PTR)cd_wndproc);
|
||||
|
||||
InvalidateRect(hwnd, NULL, TRUE);
|
||||
UpdateWindow(hwnd);
|
||||
|
||||
SetWindowLongPtr(hwndparent, GWLP_WNDPROC, (LONG_PTR)oldwndproc);
|
||||
|
||||
DestroyWindow(hwnd);
|
||||
}
|
||||
|
||||
static void test_icon_spacing(void)
|
||||
{
|
||||
/* LVM_SETICONSPACING */
|
||||
/* note: LVM_SETICONSPACING returns the previous icon spacing if successful */
|
||||
/* note: the first test will fail if the default icon spacing is not (43,43) */
|
||||
|
||||
HWND hwnd;
|
||||
DWORD r;
|
||||
|
||||
hwnd = create_custom_listview_control(LVS_ICON);
|
||||
ok(hwnd != NULL, "failed to create a listview window\n");
|
||||
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
|
||||
trace("test icon spacing\n");
|
||||
todo_wine {
|
||||
r = SendMessage(hwnd, LVM_SETICONSPACING, 0, (LPARAM) MAKELONG(20, 30));
|
||||
expect(MAKELONG(43,43), r);
|
||||
}
|
||||
r = SendMessage(hwnd, LVM_SETICONSPACING, 0, (LPARAM) MAKELONG(25, 35));
|
||||
expect(MAKELONG(20,30), r);
|
||||
r = SendMessage(hwnd, LVM_SETICONSPACING, 0, (LPARAM) MAKELONG(-1,-1));
|
||||
expect(MAKELONG(25,35), r);
|
||||
|
||||
ok_sequence(sequences, LISTVIEW_SEQ_INDEX, listview_icon_spacing_seq, "test icon spacing seq", FALSE);
|
||||
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
DestroyWindow(hwnd);
|
||||
}
|
||||
|
||||
static void test_color(void)
|
||||
{
|
||||
/* SETBKCOLOR/GETBKCOLOR, SETTEXTCOLOR/GETTEXTCOLOR, SETTEXTBKCOLOR/GETTEXTBKCOLOR */
|
||||
|
||||
HWND hwnd;
|
||||
DWORD r;
|
||||
int i;
|
||||
|
||||
COLORREF color;
|
||||
COLORREF colors[4] = {RGB(0,0,0), RGB(100,50,200), CLR_NONE, RGB(255,255,255)};
|
||||
|
||||
hwnd = create_listview_control();
|
||||
ok(hwnd != NULL, "failed to create a listview window\n");
|
||||
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
|
||||
trace("test color seq\n");
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
color = colors[i];
|
||||
|
||||
r = SendMessage(hwnd, LVM_SETBKCOLOR, 0, color);
|
||||
expect(TRUE, r);
|
||||
r = SendMessage(hwnd, LVM_GETBKCOLOR, 0, color);
|
||||
expect(color, r);
|
||||
|
||||
r = SendMessage(hwnd, LVM_SETTEXTCOLOR, 0, color);
|
||||
expect (TRUE, r);
|
||||
r = SendMessage(hwnd, LVM_GETTEXTCOLOR, 0, color);
|
||||
expect(color, r);
|
||||
|
||||
r = SendMessage(hwnd, LVM_SETTEXTBKCOLOR, 0, color);
|
||||
expect(TRUE, r);
|
||||
r = SendMessage(hwnd, LVM_GETTEXTBKCOLOR, 0, color);
|
||||
expect(color, r);
|
||||
}
|
||||
|
||||
ok_sequence(sequences, LISTVIEW_SEQ_INDEX, listview_color_seq, "test color seq", FALSE);
|
||||
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
DestroyWindow(hwnd);
|
||||
}
|
||||
|
||||
static void test_item_count(void)
|
||||
{
|
||||
/* LVM_INSERTITEM, LVM_DELETEITEM, LVM_DELETEALLITEMS, LVM_GETITEMCOUNT */
|
||||
|
||||
HWND hwnd;
|
||||
DWORD r;
|
||||
|
||||
LVITEM item0;
|
||||
LVITEM item1;
|
||||
LVITEM item2;
|
||||
static CHAR item0text[] = "item0";
|
||||
static CHAR item1text[] = "item1";
|
||||
static CHAR item2text[] = "item2";
|
||||
|
||||
hwnd = create_listview_control();
|
||||
ok(hwnd != NULL, "failed to create a listview window\n");
|
||||
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
|
||||
trace("test item count\n");
|
||||
|
||||
r = SendMessage(hwnd, LVM_GETITEMCOUNT, 0, 0);
|
||||
expect(0, r);
|
||||
|
||||
/* [item0] */
|
||||
item0.mask = LVIF_TEXT;
|
||||
item0.iItem = 0;
|
||||
item0.iSubItem = 0;
|
||||
item0.pszText = item0text;
|
||||
r = SendMessage(hwnd, LVM_INSERTITEM, 0, (LPARAM) &item0);
|
||||
expect(0, r);
|
||||
|
||||
/* [item0, item1] */
|
||||
item1.mask = LVIF_TEXT;
|
||||
item1.iItem = 1;
|
||||
item1.iSubItem = 0;
|
||||
item1.pszText = item1text;
|
||||
r = SendMessage(hwnd, LVM_INSERTITEM, 0, (LPARAM) &item1);
|
||||
expect(1, r);
|
||||
|
||||
/* [item0, item1, item2] */
|
||||
item2.mask = LVIF_TEXT;
|
||||
item2.iItem = 2;
|
||||
item2.iSubItem = 0;
|
||||
item2.pszText = item2text;
|
||||
r = SendMessage(hwnd, LVM_INSERTITEM, 0, (LPARAM) &item2);
|
||||
expect(2, r);
|
||||
|
||||
r = SendMessage(hwnd, LVM_GETITEMCOUNT, 0, 0);
|
||||
expect(3, r);
|
||||
|
||||
/* [item0, item1] */
|
||||
r = SendMessage(hwnd, LVM_DELETEITEM, (WPARAM) 2, 0);
|
||||
expect(TRUE, r);
|
||||
|
||||
r = SendMessage(hwnd, LVM_GETITEMCOUNT, 0, 0);
|
||||
expect(2, r);
|
||||
|
||||
/* [] */
|
||||
r = SendMessage(hwnd, LVM_DELETEALLITEMS, 0, 0);
|
||||
expect(TRUE, r);
|
||||
|
||||
r = SendMessage(hwnd, LVM_GETITEMCOUNT, 0, 0);
|
||||
expect(0, r);
|
||||
|
||||
/* [item0] */
|
||||
r = SendMessage(hwnd, LVM_INSERTITEM, 0, (LPARAM) &item1);
|
||||
expect(0, r);
|
||||
|
||||
/* [item0, item1] */
|
||||
r = SendMessage(hwnd, LVM_INSERTITEM, 0, (LPARAM) &item1);
|
||||
expect(1, r);
|
||||
|
||||
r = SendMessage(hwnd, LVM_GETITEMCOUNT, 0, 0);
|
||||
expect(2, r);
|
||||
|
||||
/* [item0, item1, item2] */
|
||||
r = SendMessage(hwnd, LVM_INSERTITEM, 0, (LPARAM) &item2);
|
||||
expect(2, r);
|
||||
|
||||
r = SendMessage(hwnd, LVM_GETITEMCOUNT, 0, 0);
|
||||
expect(3, r);
|
||||
|
||||
ok_sequence(sequences, LISTVIEW_SEQ_INDEX, listview_item_count_seq, "test item count seq", FALSE);
|
||||
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
DestroyWindow(hwnd);
|
||||
}
|
||||
|
||||
static void test_item_position(void)
|
||||
{
|
||||
/* LVM_SETITEMPOSITION/LVM_GETITEMPOSITION */
|
||||
|
||||
HWND hwnd;
|
||||
DWORD r;
|
||||
POINT position;
|
||||
|
||||
LVITEM item0;
|
||||
LVITEM item1;
|
||||
LVITEM item2;
|
||||
static CHAR item0text[] = "item0";
|
||||
static CHAR item1text[] = "item1";
|
||||
static CHAR item2text[] = "item2";
|
||||
|
||||
hwnd = create_custom_listview_control(LVS_ICON);
|
||||
ok(hwnd != NULL, "failed to create a listview window\n");
|
||||
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
|
||||
trace("test item position\n");
|
||||
|
||||
/* [item0] */
|
||||
item0.mask = LVIF_TEXT;
|
||||
item0.iItem = 0;
|
||||
item0.iSubItem = 0;
|
||||
item0.pszText = item0text;
|
||||
r = SendMessage(hwnd, LVM_INSERTITEM, 0, (LPARAM) &item0);
|
||||
expect(0, r);
|
||||
|
||||
/* [item0, item1] */
|
||||
item1.mask = LVIF_TEXT;
|
||||
item1.iItem = 1;
|
||||
item1.iSubItem = 0;
|
||||
item1.pszText = item1text;
|
||||
r = SendMessage(hwnd, LVM_INSERTITEM, 0, (LPARAM) &item1);
|
||||
expect(1, r);
|
||||
|
||||
/* [item0, item1, item2] */
|
||||
item2.mask = LVIF_TEXT;
|
||||
item2.iItem = 2;
|
||||
item2.iSubItem = 0;
|
||||
item2.pszText = item2text;
|
||||
r = SendMessage(hwnd, LVM_INSERTITEM, 0, (LPARAM) &item2);
|
||||
expect(2, r);
|
||||
|
||||
r = SendMessage(hwnd, LVM_SETITEMPOSITION, 1, MAKELPARAM(10,5));
|
||||
expect(TRUE, r);
|
||||
r = SendMessage(hwnd, LVM_GETITEMPOSITION, 1, (LPARAM) &position);
|
||||
expect(TRUE, r);
|
||||
expect2(10, 5, position.x, position.y);
|
||||
|
||||
r = SendMessage(hwnd, LVM_SETITEMPOSITION, 2, MAKELPARAM(0,0));
|
||||
expect(TRUE, r);
|
||||
r = SendMessage(hwnd, LVM_GETITEMPOSITION, 2, (LPARAM) &position);
|
||||
expect(TRUE, r);
|
||||
expect2(0, 0, position.x, position.y);
|
||||
|
||||
r = SendMessage(hwnd, LVM_SETITEMPOSITION, 0, MAKELPARAM(20,20));
|
||||
expect(TRUE, r);
|
||||
r = SendMessage(hwnd, LVM_GETITEMPOSITION, 0, (LPARAM) &position);
|
||||
expect(TRUE, r);
|
||||
expect2(20, 20, position.x, position.y);
|
||||
|
||||
ok_sequence(sequences, LISTVIEW_SEQ_INDEX, listview_itempos_seq, "test item position seq", TRUE);
|
||||
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
DestroyWindow(hwnd);
|
||||
}
|
||||
|
||||
START_TEST(listview)
|
||||
{
|
||||
INITCOMMONCONTROLSEX icc;
|
||||
|
@ -230,6 +1046,22 @@ START_TEST(listview)
|
|||
icc.dwSize = sizeof icc;
|
||||
InitCommonControlsEx(&icc);
|
||||
|
||||
init_msg_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
hwndparent = create_parent_window();
|
||||
ok_sequence(sequences, PARENT_SEQ_INDEX, create_parent_wnd_seq, "create parent window", TRUE);
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
|
||||
test_images();
|
||||
test_checkboxes();
|
||||
test_items();
|
||||
test_create();
|
||||
test_redraw();
|
||||
test_customdraw();
|
||||
test_icon_spacing();
|
||||
test_color();
|
||||
test_item_count();
|
||||
test_item_position();
|
||||
test_columns();
|
||||
}
|
||||
|
|
159
rostests/winetests/comctl32/misc.c
Normal file
159
rostests/winetests/comctl32/misc.c
Normal file
|
@ -0,0 +1,159 @@
|
|||
/*
|
||||
* Misc tests
|
||||
*
|
||||
* Copyright 2006 Paul Vriens
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
|
||||
#include "wine/test.h"
|
||||
|
||||
static PVOID (WINAPI * pAlloc)(LONG);
|
||||
static PVOID (WINAPI * pReAlloc)(PVOID, LONG);
|
||||
static BOOL (WINAPI * pFree)(PVOID);
|
||||
static LONG (WINAPI * pGetSize)(PVOID);
|
||||
|
||||
static INT (WINAPI * pStr_GetPtrA)(LPCSTR, LPSTR, INT);
|
||||
static BOOL (WINAPI * pStr_SetPtrA)(LPSTR, LPCSTR);
|
||||
static INT (WINAPI * pStr_GetPtrW)(LPCWSTR, LPWSTR, INT);
|
||||
static BOOL (WINAPI * pStr_SetPtrW)(LPWSTR, LPCWSTR);
|
||||
|
||||
static HMODULE hComctl32 = 0;
|
||||
|
||||
#define COMCTL32_GET_PROC(ordinal, func) \
|
||||
p ## func = (void*)GetProcAddress(hComctl32, (LPSTR)ordinal); \
|
||||
if(!p ## func) { \
|
||||
trace("GetProcAddress(%d)(%s) failed\n", ordinal, #func); \
|
||||
FreeLibrary(hComctl32); \
|
||||
}
|
||||
|
||||
#define expect(expected, got) ok(expected == got, "expected %d, got %d\n", expected,got)
|
||||
|
||||
static BOOL InitFunctionPtrs(void)
|
||||
{
|
||||
hComctl32 = LoadLibraryA("comctl32.dll");
|
||||
|
||||
if(!hComctl32)
|
||||
{
|
||||
trace("Could not load comctl32.dll\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
COMCTL32_GET_PROC(71, Alloc);
|
||||
COMCTL32_GET_PROC(72, ReAlloc);
|
||||
COMCTL32_GET_PROC(73, Free);
|
||||
COMCTL32_GET_PROC(74, GetSize);
|
||||
|
||||
COMCTL32_GET_PROC(233, Str_GetPtrA)
|
||||
COMCTL32_GET_PROC(234, Str_SetPtrA)
|
||||
COMCTL32_GET_PROC(235, Str_GetPtrW)
|
||||
COMCTL32_GET_PROC(236, Str_SetPtrW)
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void test_GetPtrAW(void)
|
||||
{
|
||||
if (pStr_GetPtrA)
|
||||
{
|
||||
static const char source[] = "Just a source string";
|
||||
static const char desttest[] = "Just a destination string";
|
||||
static char dest[MAX_PATH];
|
||||
int sourcelen;
|
||||
int destsize = MAX_PATH;
|
||||
int count = -1;
|
||||
|
||||
sourcelen = strlen(source) + 1;
|
||||
|
||||
count = pStr_GetPtrA(NULL, NULL, 0);
|
||||
ok (count == 0, "Expected count to be 0, it was %d\n", count);
|
||||
|
||||
if (0)
|
||||
{
|
||||
/* Crashes on W98, NT4, W2K, XP, W2K3
|
||||
* Our implementation also crashes and we should probably leave
|
||||
* it like that.
|
||||
*/
|
||||
count = -1;
|
||||
count = pStr_GetPtrA(NULL, NULL, destsize);
|
||||
trace("count : %d\n", count);
|
||||
}
|
||||
|
||||
count = 0;
|
||||
count = pStr_GetPtrA(source, NULL, 0);
|
||||
ok (count == sourcelen, "Expected count to be %d, it was %d\n", sourcelen , count);
|
||||
|
||||
count = 0;
|
||||
strcpy(dest, desttest);
|
||||
count = pStr_GetPtrA(source, dest, 0);
|
||||
ok (count == sourcelen, "Expected count to be %d, it was %d\n", sourcelen , count);
|
||||
ok (!lstrcmp(dest, desttest), "Expected destination to not have changed\n");
|
||||
|
||||
count = 0;
|
||||
count = pStr_GetPtrA(source, NULL, destsize);
|
||||
ok (count == sourcelen, "Expected count to be %d, it was %d\n", sourcelen , count);
|
||||
|
||||
count = 0;
|
||||
count = pStr_GetPtrA(source, dest, destsize);
|
||||
ok (count == sourcelen, "Expected count to be %d, it was %d\n", sourcelen , count);
|
||||
ok (!lstrcmp(source, dest), "Expected source and destination to be the same\n");
|
||||
|
||||
count = -1;
|
||||
strcpy(dest, desttest);
|
||||
count = pStr_GetPtrA(NULL, dest, destsize);
|
||||
ok (count == 0, "Expected count to be 0, it was %d\n", count);
|
||||
ok (dest[0] == '\0', "Expected destination to be cut-off and 0 terminated\n");
|
||||
|
||||
count = 0;
|
||||
destsize = 15;
|
||||
count = pStr_GetPtrA(source, dest, destsize);
|
||||
ok (count == 15, "Expected count to be 15, it was %d\n", count);
|
||||
ok (!memcmp(source, dest, 14), "Expected first part of source and destination to be the same\n");
|
||||
ok (dest[14] == '\0', "Expected destination to be cut-off and 0 terminated\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void test_Alloc(void)
|
||||
{
|
||||
PCHAR p = pAlloc(0);
|
||||
ok(p != NULL, "p=%p\n", p);
|
||||
ok(pFree(p), "\n");
|
||||
p = pAlloc(1);
|
||||
ok(p != NULL, "\n");
|
||||
*p = '\0';
|
||||
expect(1, pGetSize(p));
|
||||
p = pReAlloc(p, 2);
|
||||
ok(p != NULL, "\n");
|
||||
expect(2, pGetSize(p));
|
||||
ok(pFree(p), "\n");
|
||||
ok(pFree(NULL), "\n");
|
||||
p = pReAlloc(NULL, 2);
|
||||
ok(p != NULL, "\n");
|
||||
ok(pFree(p), "\n");
|
||||
}
|
||||
|
||||
START_TEST(misc)
|
||||
{
|
||||
if(!InitFunctionPtrs())
|
||||
return;
|
||||
|
||||
test_GetPtrAW();
|
||||
test_Alloc();
|
||||
|
||||
FreeLibrary(hComctl32);
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -111,7 +111,7 @@ static void check_reg_entries(const char *mrulist, const char**items)
|
|||
buff[0] = '\0';
|
||||
ret = RegQueryValueExA(hKey, "MRUList", NULL, &type, (LPBYTE)buff, &size);
|
||||
|
||||
ok(!ret && buff[0], "Checking MRU: got %ld from RegQueryValueExW\n", ret);
|
||||
ok(!ret && buff[0], "Checking MRU: got %d from RegQueryValueExW\n", ret);
|
||||
if(ret || !buff[0]) return;
|
||||
|
||||
ok(strcmp(buff, mrulist) == 0, "Checking MRU: Expected list %s, got %s\n",
|
||||
|
@ -128,7 +128,7 @@ static void check_reg_entries(const char *mrulist, const char**items)
|
|||
buff[0] = '\0';
|
||||
ret = RegQueryValueExA(hKey, name, NULL, &type, (LPBYTE)buff, &size);
|
||||
ok(!ret && buff[0],
|
||||
"Checking MRU item %d ('%c'): got %ld from RegQueryValueExW\n",
|
||||
"Checking MRU item %d ('%c'): got %d from RegQueryValueExW\n",
|
||||
i, mrulist[i], ret);
|
||||
if(ret || !buff[0]) return;
|
||||
ok(!strcmp(buff, items[mrulist[i]-'a']),
|
||||
|
@ -165,37 +165,39 @@ static void test_MRUListA(void)
|
|||
if (!pCreateMRUListA || !pFreeMRUList || !pAddMRUStringA)
|
||||
return;
|
||||
|
||||
#if 0 /* Create (NULL) - crashes native */
|
||||
if (0)
|
||||
{
|
||||
/* Create (NULL) - crashes native */
|
||||
hMRU = pCreateMRUListA(NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Create (size too small) */
|
||||
mruA.cbSize = sizeof(mruA) - 2;
|
||||
hMRU = create_mruA(NULL, MRUF_STRING_LIST, cmp_mru_strA);
|
||||
hMRU = create_mruA(NULL, MRUF_STRING_LIST, (PROC)cmp_mru_strA);
|
||||
ok (!hMRU && !GetLastError(),
|
||||
"CreateMRUListA(too small) expected NULL,0 got %p,%ld\n",
|
||||
"CreateMRUListA(too small) expected NULL,0 got %p,%d\n",
|
||||
hMRU, GetLastError());
|
||||
mruA.cbSize = sizeof(mruA);
|
||||
|
||||
/* Create (size too big) */
|
||||
mruA.cbSize = sizeof(mruA) + 2;
|
||||
hMRU = create_mruA(NULL, MRUF_STRING_LIST, cmp_mru_strA);
|
||||
hMRU = create_mruA(NULL, MRUF_STRING_LIST, (PROC)cmp_mru_strA);
|
||||
ok (!hMRU && !GetLastError(),
|
||||
"CreateMRUListA(too big) expected NULL,0 got %p,%ld\n",
|
||||
"CreateMRUListA(too big) expected NULL,0 got %p,%d\n",
|
||||
hMRU, GetLastError());
|
||||
mruA.cbSize = sizeof(mruA);
|
||||
|
||||
/* Create (NULL hKey) */
|
||||
hMRU = create_mruA(NULL, MRUF_STRING_LIST, cmp_mru_strA);
|
||||
hMRU = create_mruA(NULL, MRUF_STRING_LIST, (PROC)cmp_mru_strA);
|
||||
ok (!hMRU && !GetLastError(),
|
||||
"CreateMRUListA(NULL key) expected NULL,0 got %p,%ld\n",
|
||||
"CreateMRUListA(NULL key) expected NULL,0 got %p,%d\n",
|
||||
hMRU, GetLastError());
|
||||
|
||||
/* Create (NULL name) */
|
||||
mruA.lpszSubKey = NULL;
|
||||
hMRU = create_mruA(NULL, MRUF_STRING_LIST, cmp_mru_strA);
|
||||
hMRU = create_mruA(NULL, MRUF_STRING_LIST, (PROC)cmp_mru_strA);
|
||||
ok (!hMRU && !GetLastError(),
|
||||
"CreateMRUListA(NULL name) expected NULL,0 got %p,%ld\n",
|
||||
"CreateMRUListA(NULL name) expected NULL,0 got %p,%d\n",
|
||||
hMRU, GetLastError());
|
||||
mruA.lpszSubKey = REG_TEST_SUBKEYA;
|
||||
|
||||
|
@ -204,9 +206,9 @@ static void test_MRUListA(void)
|
|||
"Couldn't create test key \"%s\"\n", REG_TEST_KEYA);
|
||||
if (!hKey)
|
||||
return;
|
||||
hMRU = create_mruA(hKey, MRUF_STRING_LIST, cmp_mru_strA);
|
||||
hMRU = create_mruA(hKey, MRUF_STRING_LIST, (PROC)cmp_mru_strA);
|
||||
ok(hMRU && !GetLastError(),
|
||||
"CreateMRUListA(string) expected non-NULL,0 got %p,%ld\n",
|
||||
"CreateMRUListA(string) expected non-NULL,0 got %p,%d\n",
|
||||
hMRU, GetLastError());
|
||||
|
||||
if (hMRU)
|
||||
|
@ -220,38 +222,39 @@ static void test_MRUListA(void)
|
|||
SetLastError(0);
|
||||
iRet = pAddMRUStringA(NULL, checks[0]);
|
||||
ok(iRet == -1 && !GetLastError(),
|
||||
"AddMRUStringA(NULL list) expected -1,0 got %d,%ld\n",
|
||||
"AddMRUStringA(NULL list) expected -1,0 got %d,%d\n",
|
||||
iRet, GetLastError());
|
||||
|
||||
/* Add (NULL string) */
|
||||
#if 0
|
||||
if (0)
|
||||
{
|
||||
/* Some native versions crash when passed NULL or fail to SetLastError() */
|
||||
SetLastError(0);
|
||||
iRet = pAddMRUStringA(hMRU, NULL);
|
||||
ok(iRet == 0 && GetLastError() == ERROR_INVALID_PARAMETER,
|
||||
"AddMRUStringA(NULL str) expected 0,ERROR_INVALID_PARAMETER got %d,%ld\n",
|
||||
"AddMRUStringA(NULL str) expected 0,ERROR_INVALID_PARAMETER got %d,%d\n",
|
||||
iRet, GetLastError());
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Add 3 strings. Check the registry is correct after each add */
|
||||
SetLastError(0);
|
||||
iRet = pAddMRUStringA(hMRU, checks[0]);
|
||||
ok(iRet == 0 && !GetLastError(),
|
||||
"AddMRUStringA(1) expected 0,0 got %d,%ld\n",
|
||||
"AddMRUStringA(1) expected 0,0 got %d,%d\n",
|
||||
iRet, GetLastError());
|
||||
check_reg_entries("a", checks);
|
||||
|
||||
SetLastError(0);
|
||||
iRet = pAddMRUStringA(hMRU, checks[1]);
|
||||
ok(iRet == 1 && !GetLastError(),
|
||||
"AddMRUStringA(2) expected 1,0 got %d,%ld\n",
|
||||
"AddMRUStringA(2) expected 1,0 got %d,%d\n",
|
||||
iRet, GetLastError());
|
||||
check_reg_entries("ba", checks);
|
||||
|
||||
SetLastError(0);
|
||||
iRet = pAddMRUStringA(hMRU, checks[2]);
|
||||
ok(iRet == 2 && !GetLastError(),
|
||||
"AddMRUStringA(2) expected 2,0 got %d,%ld\n",
|
||||
"AddMRUStringA(2) expected 2,0 got %d,%d\n",
|
||||
iRet, GetLastError());
|
||||
check_reg_entries("cba", checks);
|
||||
|
||||
|
@ -261,7 +264,7 @@ static void test_MRUListA(void)
|
|||
SetLastError(0);
|
||||
iRet = pAddMRUStringA(hMRU, checks[1]);
|
||||
ok(iRet == 1 && !GetLastError(),
|
||||
"AddMRUStringA(re-add 1) expected 1,0 got %d,%ld\n",
|
||||
"AddMRUStringA(re-add 1) expected 1,0 got %d,%d\n",
|
||||
iRet, GetLastError());
|
||||
check_reg_entries("bca", checks);
|
||||
|
||||
|
@ -269,7 +272,7 @@ static void test_MRUListA(void)
|
|||
SetLastError(0);
|
||||
iRet = pAddMRUStringA(hMRU, checks[3]);
|
||||
ok(iRet == 0 && !GetLastError(),
|
||||
"AddMRUStringA(add new) expected 0,0 got %d,%ld\n",
|
||||
"AddMRUStringA(add new) expected 0,0 got %d,%d\n",
|
||||
iRet, GetLastError());
|
||||
checks[0] = checks[3];
|
||||
check_reg_entries("abc", checks);
|
||||
|
@ -285,8 +288,6 @@ static void test_MRUListA(void)
|
|||
START_TEST(mru)
|
||||
{
|
||||
hComctl32 = GetModuleHandleA("comctl32.dll");
|
||||
if (!hComctl32)
|
||||
return;
|
||||
|
||||
delete_reg_entries();
|
||||
if (!create_reg_entries())
|
||||
|
|
251
rostests/winetests/comctl32/msg.c
Normal file
251
rostests/winetests/comctl32/msg.c
Normal file
|
@ -0,0 +1,251 @@
|
|||
/* Message Sequence Testing Code
|
||||
*
|
||||
* Copyright (C) 2007 James Hawkins
|
||||
* Copyright (C) 2007 Lei Zhang
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "msg.h"
|
||||
|
||||
void add_message(struct msg_sequence **seq, int sequence_index,
|
||||
const struct message *msg)
|
||||
{
|
||||
struct msg_sequence *msg_seq = seq[sequence_index];
|
||||
|
||||
if (!msg_seq->sequence)
|
||||
{
|
||||
msg_seq->size = 10;
|
||||
msg_seq->sequence = HeapAlloc(GetProcessHeap(), 0,
|
||||
msg_seq->size * sizeof (struct message));
|
||||
}
|
||||
|
||||
if (msg_seq->count == msg_seq->size)
|
||||
{
|
||||
msg_seq->size *= 2;
|
||||
msg_seq->sequence = HeapReAlloc(GetProcessHeap(), 0,
|
||||
msg_seq->sequence,
|
||||
msg_seq->size * sizeof (struct message));
|
||||
}
|
||||
|
||||
assert(msg_seq->sequence);
|
||||
|
||||
msg_seq->sequence[msg_seq->count].message = msg->message;
|
||||
msg_seq->sequence[msg_seq->count].flags = msg->flags;
|
||||
msg_seq->sequence[msg_seq->count].wParam = msg->wParam;
|
||||
msg_seq->sequence[msg_seq->count].lParam = msg->lParam;
|
||||
msg_seq->sequence[msg_seq->count].id = msg->id;
|
||||
|
||||
msg_seq->count++;
|
||||
}
|
||||
|
||||
void flush_sequence(struct msg_sequence **seg, int sequence_index)
|
||||
{
|
||||
struct msg_sequence *msg_seq = seg[sequence_index];
|
||||
HeapFree(GetProcessHeap(), 0, msg_seq->sequence);
|
||||
msg_seq->sequence = NULL;
|
||||
msg_seq->count = msg_seq->size = 0;
|
||||
}
|
||||
|
||||
void flush_sequences(struct msg_sequence **seq, int n)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
flush_sequence(seq, i);
|
||||
}
|
||||
|
||||
void ok_sequence_(struct msg_sequence **seq, int sequence_index,
|
||||
const struct message *expected, const char *context, int todo,
|
||||
const char *file, int line)
|
||||
{
|
||||
struct msg_sequence *msg_seq = seq[sequence_index];
|
||||
static const struct message end_of_sequence = {0, 0, 0, 0};
|
||||
const struct message *actual, *sequence;
|
||||
int failcount = 0;
|
||||
|
||||
add_message(seq, sequence_index, &end_of_sequence);
|
||||
|
||||
sequence = msg_seq->sequence;
|
||||
actual = sequence;
|
||||
|
||||
while (expected->message && actual->message)
|
||||
{
|
||||
trace_( file, line)("expected %04x - actual %04x\n", expected->message, actual->message);
|
||||
|
||||
if (expected->message == actual->message)
|
||||
{
|
||||
if (expected->flags & wparam)
|
||||
{
|
||||
if (expected->wParam != actual->wParam && todo)
|
||||
{
|
||||
todo_wine
|
||||
{
|
||||
failcount++;
|
||||
ok_(file, line) (FALSE,
|
||||
"%s: in msg 0x%04x expecting wParam 0x%lx got 0x%lx\n",
|
||||
context, expected->message, expected->wParam, actual->wParam);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ok_(file, line) (expected->wParam == actual->wParam,
|
||||
"%s: in msg 0x%04x expecting wParam 0x%lx got 0x%lx\n",
|
||||
context, expected->message, expected->wParam, actual->wParam);
|
||||
}
|
||||
}
|
||||
|
||||
if (expected->flags & lparam)
|
||||
{
|
||||
if (expected->lParam != actual->lParam && todo)
|
||||
{
|
||||
todo_wine
|
||||
{
|
||||
failcount++;
|
||||
ok_(file, line) (FALSE,
|
||||
"%s: in msg 0x%04x expecting lParam 0x%lx got 0x%lx\n",
|
||||
context, expected->message, expected->lParam, actual->lParam);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ok_(file, line) (expected->lParam == actual->lParam,
|
||||
"%s: in msg 0x%04x expecting lParam 0x%lx got 0x%lx\n",
|
||||
context, expected->message, expected->lParam, actual->lParam);
|
||||
}
|
||||
}
|
||||
|
||||
if (expected->flags & id)
|
||||
{
|
||||
if (expected->id != actual->id && todo)
|
||||
{
|
||||
todo_wine
|
||||
{
|
||||
failcount++;
|
||||
ok_(file, line) (FALSE,
|
||||
"%s: in msg 0x%04x expecting id 0x%x got 0x%x\n",
|
||||
context, expected->message, expected->id, actual->id);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ok_(file, line) (expected->id == actual->id,
|
||||
"%s: in msg 0x%04x expecting id 0x%x got 0x%x\n",
|
||||
context, expected->message, expected->id, actual->id);
|
||||
}
|
||||
}
|
||||
|
||||
if ((expected->flags & defwinproc) != (actual->flags & defwinproc) && todo)
|
||||
{
|
||||
todo_wine
|
||||
{
|
||||
failcount++;
|
||||
ok_(file, line) (FALSE,
|
||||
"%s: the msg 0x%04x should %shave been sent by DefWindowProc\n",
|
||||
context, expected->message, (expected->flags & defwinproc) ? "" : "NOT ");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ok_(file, line) ((expected->flags & defwinproc) == (actual->flags & defwinproc),
|
||||
"%s: the msg 0x%04x should %shave been sent by DefWindowProc\n",
|
||||
context, expected->message, (expected->flags & defwinproc) ? "" : "NOT ");
|
||||
}
|
||||
|
||||
ok_(file, line) ((expected->flags & beginpaint) == (actual->flags & beginpaint),
|
||||
"%s: the msg 0x%04x should %shave been sent by BeginPaint\n",
|
||||
context, expected->message, (expected->flags & beginpaint) ? "" : "NOT ");
|
||||
ok_(file, line) ((expected->flags & (sent|posted)) == (actual->flags & (sent|posted)),
|
||||
"%s: the msg 0x%04x should have been %s\n",
|
||||
context, expected->message, (expected->flags & posted) ? "posted" : "sent");
|
||||
ok_(file, line) ((expected->flags & parent) == (actual->flags & parent),
|
||||
"%s: the msg 0x%04x was expected in %s\n",
|
||||
context, expected->message, (expected->flags & parent) ? "parent" : "child");
|
||||
ok_(file, line) ((expected->flags & hook) == (actual->flags & hook),
|
||||
"%s: the msg 0x%04x should have been sent by a hook\n",
|
||||
context, expected->message);
|
||||
ok_(file, line) ((expected->flags & winevent_hook) == (actual->flags & winevent_hook),
|
||||
"%s: the msg 0x%04x should have been sent by a winevent hook\n",
|
||||
context, expected->message);
|
||||
expected++;
|
||||
actual++;
|
||||
}
|
||||
else if (expected->flags & optional)
|
||||
expected++;
|
||||
else if (todo)
|
||||
{
|
||||
failcount++;
|
||||
todo_wine
|
||||
{
|
||||
ok_(file, line) (FALSE, "%s: the msg 0x%04x was expected, but got msg 0x%04x instead\n",
|
||||
context, expected->message, actual->message);
|
||||
}
|
||||
|
||||
flush_sequence(seq, sequence_index);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
ok_(file, line) (FALSE, "%s: the msg 0x%04x was expected, but got msg 0x%04x instead\n",
|
||||
context, expected->message, actual->message);
|
||||
expected++;
|
||||
actual++;
|
||||
}
|
||||
}
|
||||
|
||||
/* skip all optional trailing messages */
|
||||
while (expected->message && ((expected->flags & optional)))
|
||||
expected++;
|
||||
|
||||
if (todo)
|
||||
{
|
||||
todo_wine
|
||||
{
|
||||
if (expected->message || actual->message)
|
||||
{
|
||||
failcount++;
|
||||
ok_(file, line) (FALSE, "%s: the msg sequence is not complete: expected %04x - actual %04x\n",
|
||||
context, expected->message, actual->message);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (expected->message || actual->message)
|
||||
{
|
||||
ok_(file, line) (FALSE, "%s: the msg sequence is not complete: expected %04x - actual %04x\n",
|
||||
context, expected->message, actual->message);
|
||||
}
|
||||
|
||||
if(todo && !failcount) /* succeeded yet marked todo */
|
||||
{
|
||||
todo_wine
|
||||
{
|
||||
ok_(file, line)(TRUE, "%s: marked \"todo_wine\" but succeeds\n", context);
|
||||
}
|
||||
}
|
||||
|
||||
flush_sequence(seq, sequence_index);
|
||||
}
|
||||
|
||||
void init_msg_sequences(struct msg_sequence **seq, int n)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
seq[i] = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct msg_sequence));
|
||||
}
|
||||
|
||||
START_TEST(msg)
|
||||
{
|
||||
}
|
73
rostests/winetests/comctl32/msg.h
Normal file
73
rostests/winetests/comctl32/msg.h
Normal file
|
@ -0,0 +1,73 @@
|
|||
/* Message Sequence Testing Code
|
||||
*
|
||||
* Copyright (C) 2007 James Hawkins
|
||||
* Copyright (C) 2007 Lei Zhang
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <windows.h>
|
||||
#include "wine/test.h"
|
||||
|
||||
/* undocumented SWP flags - from SDK 3.1 */
|
||||
#define SWP_NOCLIENTSIZE 0x0800
|
||||
#define SWP_NOCLIENTMOVE 0x1000
|
||||
|
||||
typedef enum
|
||||
{
|
||||
sent = 0x1,
|
||||
posted = 0x2,
|
||||
parent = 0x4,
|
||||
wparam = 0x8,
|
||||
lparam = 0x10,
|
||||
defwinproc = 0x20,
|
||||
beginpaint = 0x40,
|
||||
optional = 0x80,
|
||||
hook = 0x100,
|
||||
winevent_hook =0x200,
|
||||
id = 0x400
|
||||
} msg_flags_t;
|
||||
|
||||
struct message
|
||||
{
|
||||
UINT message; /* the WM_* code */
|
||||
msg_flags_t flags; /* message props */
|
||||
WPARAM wParam; /* expected value of wParam */
|
||||
LPARAM lParam; /* expected value of lParam */
|
||||
UINT id; /* id of the window */
|
||||
};
|
||||
|
||||
struct msg_sequence
|
||||
{
|
||||
int count;
|
||||
int size;
|
||||
struct message *sequence;
|
||||
};
|
||||
|
||||
void add_message(struct msg_sequence **seq, int sequence_index,
|
||||
const struct message *msg);
|
||||
void flush_sequence(struct msg_sequence **seg, int sequence_index);
|
||||
void flush_sequences(struct msg_sequence **seq, int n);
|
||||
|
||||
#define ok_sequence(seq, index, exp, contx, todo) \
|
||||
ok_sequence_(seq, index, (exp), (contx), (todo), __FILE__, __LINE__)
|
||||
|
||||
|
||||
void ok_sequence_(struct msg_sequence **seq, int sequence_index,
|
||||
const struct message *expected, const char *context, int todo,
|
||||
const char *file, int line);
|
||||
|
||||
void init_msg_sequences(struct msg_sequence **seq, int n);
|
|
@ -24,27 +24,42 @@
|
|||
#include "winbase.h"
|
||||
#include "wingdi.h"
|
||||
#include "winuser.h"
|
||||
#include "commctrl.h"
|
||||
#include "commctrl.h"
|
||||
|
||||
#include "wine/test.h"
|
||||
|
||||
|
||||
HWND hProgressParentWnd, hProgressWnd;
|
||||
static HWND hProgressParentWnd, hProgressWnd;
|
||||
static const char progressTestClass[] = "ProgressBarTestClass";
|
||||
|
||||
|
||||
LRESULT CALLBACK ProgressTestWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
/* try to make sure pending X events have been processed before continuing */
|
||||
static void flush_events(void)
|
||||
{
|
||||
MSG msg;
|
||||
int diff = 100;
|
||||
DWORD time = GetTickCount() + diff;
|
||||
|
||||
while (diff > 0)
|
||||
{
|
||||
if (MsgWaitForMultipleObjects( 0, NULL, FALSE, min(10,diff), QS_ALLINPUT ) == WAIT_TIMEOUT) break;
|
||||
while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessage( &msg );
|
||||
diff = time - GetTickCount();
|
||||
}
|
||||
}
|
||||
|
||||
static LRESULT CALLBACK ProgressTestWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch(msg) {
|
||||
|
||||
case WM_DESTROY:
|
||||
PostQuitMessage(0);
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
return DefWindowProcA(hWnd, msg, wParam, lParam);
|
||||
}
|
||||
|
||||
|
||||
return 0L;
|
||||
}
|
||||
|
||||
|
@ -52,7 +67,7 @@ static WNDPROC progress_wndproc;
|
|||
static BOOL erased;
|
||||
static RECT last_paint_rect;
|
||||
|
||||
LRESULT CALLBACK ProgressSubclassProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
static LRESULT CALLBACK ProgressSubclassProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
if (msg == WM_PAINT)
|
||||
{
|
||||
|
@ -69,7 +84,7 @@ LRESULT CALLBACK ProgressSubclassProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM
|
|||
static void update_window(HWND hWnd)
|
||||
{
|
||||
UpdateWindow(hWnd);
|
||||
ok(!GetUpdateRect(hWnd, NULL, FALSE), "GetUpdateRect must return zero after UpdateWindow\n");
|
||||
ok(!GetUpdateRect(hWnd, NULL, FALSE), "GetUpdateRect must return zero after UpdateWindow\n");
|
||||
}
|
||||
|
||||
|
||||
|
@ -78,29 +93,29 @@ static void init(void)
|
|||
WNDCLASSA wc;
|
||||
INITCOMMONCONTROLSEX icex;
|
||||
RECT rect;
|
||||
|
||||
|
||||
icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
|
||||
icex.dwICC = ICC_PROGRESS_CLASS;
|
||||
InitCommonControlsEx(&icex);
|
||||
|
||||
|
||||
wc.style = CS_HREDRAW | CS_VREDRAW;
|
||||
wc.cbClsExtra = 0;
|
||||
wc.cbWndExtra = 0;
|
||||
wc.hInstance = GetModuleHandleA(NULL);
|
||||
wc.hIcon = NULL;
|
||||
wc.hCursor = LoadCursorA(NULL, MAKEINTRESOURCEA(IDC_ARROW));
|
||||
wc.hCursor = LoadCursorA(NULL, IDC_ARROW);
|
||||
wc.hbrBackground = GetSysColorBrush(COLOR_WINDOW);
|
||||
wc.lpszMenuName = NULL;
|
||||
wc.lpszClassName = progressTestClass;
|
||||
wc.lpfnWndProc = ProgressTestWndProc;
|
||||
RegisterClassA(&wc);
|
||||
|
||||
|
||||
rect.left = 0;
|
||||
rect.top = 0;
|
||||
rect.right = 400;
|
||||
rect.bottom = 20;
|
||||
assert(AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW, FALSE));
|
||||
|
||||
|
||||
hProgressParentWnd = CreateWindowExA(0, progressTestClass, "Progress Bar Test", WS_OVERLAPPEDWINDOW,
|
||||
CW_USEDEFAULT, CW_USEDEFAULT, rect.right - rect.left, rect.bottom - rect.top, NULL, NULL, GetModuleHandleA(NULL), 0);
|
||||
assert(hProgressParentWnd != NULL);
|
||||
|
@ -110,23 +125,24 @@ static void init(void)
|
|||
0, 0, rect.right, rect.bottom, hProgressParentWnd, NULL, GetModuleHandleA(NULL), 0);
|
||||
assert(hProgressWnd != NULL);
|
||||
progress_wndproc = (WNDPROC)SetWindowLongPtr(hProgressWnd, GWLP_WNDPROC, (LPARAM)ProgressSubclassProc);
|
||||
|
||||
|
||||
ShowWindow(hProgressParentWnd, SW_SHOWNORMAL);
|
||||
ok(GetUpdateRect(hProgressParentWnd, NULL, FALSE), "GetUpdateRect: There should be a region that needs to be updated\n");
|
||||
update_window(hProgressParentWnd);
|
||||
flush_events();
|
||||
update_window(hProgressParentWnd);
|
||||
}
|
||||
|
||||
|
||||
static void cleanup(void)
|
||||
{
|
||||
MSG msg;
|
||||
|
||||
|
||||
PostMessageA(hProgressParentWnd, WM_CLOSE, 0, 0);
|
||||
while (GetMessageA(&msg,0,0,0)) {
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessageA(&msg);
|
||||
}
|
||||
|
||||
|
||||
UnregisterClassA(progressTestClass, GetModuleHandleA(NULL));
|
||||
}
|
||||
|
||||
|
@ -147,20 +163,20 @@ static void test_redraw(void)
|
|||
/* PBM_SETPOS */
|
||||
ok(SendMessageA(hProgressWnd, PBM_SETPOS, 50, 0) == 10, "PBM_SETPOS must return the previous position\n");
|
||||
ok(!GetUpdateRect(hProgressWnd, NULL, FALSE), "PBM_SETPOS: The progress bar should be redrawn immediately\n");
|
||||
|
||||
|
||||
/* PBM_DELTAPOS */
|
||||
ok(SendMessageA(hProgressWnd, PBM_DELTAPOS, 15, 0) == 50, "PBM_DELTAPOS must return the previous position\n");
|
||||
ok(!GetUpdateRect(hProgressWnd, NULL, FALSE), "PBM_DELTAPOS: The progress bar should be redrawn immediately\n");
|
||||
|
||||
|
||||
/* PBM_SETPOS */
|
||||
ok(SendMessageA(hProgressWnd, PBM_SETPOS, 80, 0) == 65, "PBM_SETPOS must return the previous position\n");
|
||||
ok(!GetUpdateRect(hProgressWnd, NULL, FALSE), "PBM_SETPOS: The progress bar should be redrawn immediately\n");
|
||||
|
||||
|
||||
/* PBM_STEPIT */
|
||||
ok(SendMessageA(hProgressWnd, PBM_STEPIT, 0, 0) == 80, "PBM_STEPIT must return the previous position\n");
|
||||
ok(!GetUpdateRect(hProgressWnd, NULL, FALSE), "PBM_STEPIT: The progress bar should be redrawn immediately\n");
|
||||
ok((UINT)SendMessageA(hProgressWnd, PBM_GETPOS, 0, 0) == 100, "PBM_GETPOS returned a wrong position\n");
|
||||
|
||||
|
||||
/* PBM_SETRANGE and PBM_SETRANGE32:
|
||||
Usually the progress bar doesn't repaint itself immediately. If the
|
||||
position is not in the new range, it does.
|
||||
|
@ -175,7 +191,7 @@ static void test_redraw(void)
|
|||
SendMessage(hProgressWnd, PBM_SETPOS, 10, 0);
|
||||
GetClientRect(hProgressWnd, &client_rect);
|
||||
ok(EqualRect(&last_paint_rect, &client_rect),
|
||||
"last_paint_rect was { %ld, %ld, %ld, %ld } instead of { %ld, %ld, %ld, %ld }\n",
|
||||
"last_paint_rect was { %d, %d, %d, %d } instead of { %d, %d, %d, %d }\n",
|
||||
last_paint_rect.left, last_paint_rect.top, last_paint_rect.right, last_paint_rect.bottom,
|
||||
client_rect.left, client_rect.top, client_rect.right, client_rect.bottom);
|
||||
update_window(hProgressWnd);
|
||||
|
@ -187,7 +203,7 @@ static void test_redraw(void)
|
|||
SendMessage(hProgressWnd, PBM_SETPOS, 0, 0);
|
||||
GetClientRect(hProgressWnd, &client_rect);
|
||||
ok(EqualRect(&last_paint_rect, &client_rect),
|
||||
"last_paint_rect was { %ld, %ld, %ld, %ld } instead of { %ld, %ld, %ld, %ld }\n",
|
||||
"last_paint_rect was { %d, %d, %d, %d } instead of { %d, %d, %d, %d }\n",
|
||||
last_paint_rect.left, last_paint_rect.top, last_paint_rect.right, last_paint_rect.bottom,
|
||||
client_rect.left, client_rect.top, client_rect.right, client_rect.bottom);
|
||||
update_window(hProgressWnd);
|
||||
|
@ -198,8 +214,8 @@ static void test_redraw(void)
|
|||
START_TEST(progress)
|
||||
{
|
||||
init();
|
||||
|
||||
|
||||
test_redraw();
|
||||
|
||||
|
||||
cleanup();
|
||||
}
|
||||
|
|
|
@ -17,9 +17,6 @@
|
|||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#define NONAMELESSUNION
|
||||
#define NONAMELESSSTRUCT
|
||||
|
||||
#include <windows.h>
|
||||
#include <commctrl.h>
|
||||
|
||||
|
@ -39,7 +36,7 @@ static int CALLBACK sheet_callback(HWND hwnd, UINT msg, LPARAM lparam)
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static INT_PTR CALLBACK page_dlg_proc(HWND hwnd, UINT msg, WPARAM wparam,
|
||||
LPARAM lparam)
|
||||
{
|
||||
|
@ -81,8 +78,8 @@ static void test_title(void)
|
|||
psp.dwSize = sizeof(psp);
|
||||
psp.dwFlags = 0;
|
||||
psp.hInstance = GetModuleHandleW(NULL);
|
||||
psp.u.pszTemplate = "prop_page1";
|
||||
psp.u2.pszIcon = NULL;
|
||||
U(psp).pszTemplate = "prop_page1";
|
||||
U2(psp).pszIcon = NULL;
|
||||
psp.pfnDlgProc = page_dlg_proc;
|
||||
psp.lParam = 0;
|
||||
|
||||
|
@ -94,14 +91,49 @@ static void test_title(void)
|
|||
psh.pszCaption = "test caption";
|
||||
psh.nPages = 1;
|
||||
psh.hwndParent = GetDesktopWindow();
|
||||
psh.u3.phpage = hpsp;
|
||||
U3(psh).phpage = hpsp;
|
||||
psh.pfnCallback = sheet_callback;
|
||||
|
||||
hdlg = (HWND)PropertySheetA(&psh);
|
||||
DestroyWindow(hdlg);
|
||||
}
|
||||
|
||||
static void test_nopage(void)
|
||||
{
|
||||
HPROPSHEETPAGE hpsp[1];
|
||||
PROPSHEETPAGEA psp;
|
||||
PROPSHEETHEADERA psh;
|
||||
HWND hdlg;
|
||||
|
||||
memset(&psp, 0, sizeof(psp));
|
||||
psp.dwSize = sizeof(psp);
|
||||
psp.dwFlags = 0;
|
||||
psp.hInstance = GetModuleHandleW(NULL);
|
||||
U(psp).pszTemplate = "prop_page1";
|
||||
U2(psp).pszIcon = NULL;
|
||||
psp.pfnDlgProc = page_dlg_proc;
|
||||
psp.lParam = 0;
|
||||
|
||||
hpsp[0] = CreatePropertySheetPageA(&psp);
|
||||
|
||||
memset(&psh, 0, sizeof(psh));
|
||||
psh.dwSize = sizeof(psh);
|
||||
psh.dwFlags = PSH_MODELESS | PSH_USECALLBACK;
|
||||
psh.pszCaption = "test caption";
|
||||
psh.nPages = 1;
|
||||
psh.hwndParent = GetDesktopWindow();
|
||||
U3(psh).phpage = hpsp;
|
||||
psh.pfnCallback = sheet_callback;
|
||||
|
||||
hdlg = (HWND)PropertySheetA(&psh);
|
||||
ShowWindow(hdlg,SW_NORMAL);
|
||||
SendMessage(hdlg, PSM_REMOVEPAGE, 0, 0);
|
||||
RedrawWindow(hdlg,NULL,NULL,RDW_UPDATENOW|RDW_ERASENOW);
|
||||
DestroyWindow(hdlg);
|
||||
}
|
||||
|
||||
START_TEST(propsheet)
|
||||
{
|
||||
test_title();
|
||||
test_nopage();
|
||||
}
|
||||
|
|
831
rostests/winetests/comctl32/rebar.c
Normal file
831
rostests/winetests/comctl32/rebar.c
Normal file
|
@ -0,0 +1,831 @@
|
|||
/* Unit tests for rebar.
|
||||
*
|
||||
* Copyright 2007 Mikolaj Zalewski
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include <windows.h>
|
||||
#include <commctrl.h>
|
||||
#include <uxtheme.h>
|
||||
|
||||
#include "wine/test.h"
|
||||
|
||||
RECT height_change_notify_rect;
|
||||
static HWND hMainWnd;
|
||||
static HWND hRebar;
|
||||
|
||||
|
||||
#define check_rect(name, val, exp) ok(val.top == exp.top && val.bottom == exp.bottom && \
|
||||
val.left == exp.left && val.right == exp.right, "invalid rect (" name ") (%d,%d) (%d,%d) - expected (%d,%d) (%d,%d)\n", \
|
||||
val.left, val.top, val.right, val.bottom, exp.left, exp.top, exp.right, exp.bottom);
|
||||
|
||||
#define check_rect_no_top(name, val, exp) { \
|
||||
ok((val.bottom - val.top == exp.bottom - exp.top) && \
|
||||
val.left == exp.left && val.right == exp.right, "invalid rect (" name ") (%d,%d) (%d,%d) - expected (%d,%d) (%d,%d), ignoring top\n", \
|
||||
val.left, val.top, val.right, val.bottom, exp.left, exp.top, exp.right, exp.bottom); \
|
||||
}
|
||||
|
||||
#define compare(val, exp, format) ok((val) == (exp), #val " value " format " expected " format "\n", (val), (exp));
|
||||
|
||||
#define expect_eq(expr, value, type, format) { type ret = expr; ok((value) == ret, #expr " expected " format " got " format "\n", (value), (ret)); }
|
||||
|
||||
static INT CALLBACK is_font_installed_proc(const LOGFONT *elf, const TEXTMETRIC *ntm, DWORD type, LPARAM lParam)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static BOOL is_font_installed(const char *name)
|
||||
{
|
||||
HDC hdc = GetDC(0);
|
||||
BOOL ret = FALSE;
|
||||
|
||||
if(!EnumFontFamiliesA(hdc, name, is_font_installed_proc, 0))
|
||||
ret = TRUE;
|
||||
|
||||
ReleaseDC(0, hdc);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void rebuild_rebar(HWND *hRebar)
|
||||
{
|
||||
if (*hRebar)
|
||||
DestroyWindow(*hRebar);
|
||||
|
||||
*hRebar = CreateWindow(REBARCLASSNAME, NULL, WS_CHILD | WS_VISIBLE, 0, 0, 0, 0,
|
||||
hMainWnd, (HMENU)17, GetModuleHandle(NULL), NULL);
|
||||
SendMessageA(*hRebar, WM_SETFONT, (WPARAM)GetStockObject(SYSTEM_FONT), 0);
|
||||
}
|
||||
|
||||
static HWND build_toolbar(int nr, HWND hParent)
|
||||
{
|
||||
TBBUTTON btns[8];
|
||||
HWND hToolbar = CreateWindowEx(0, TOOLBARCLASSNAME, NULL, WS_CHILD | WS_VISIBLE | CCS_NORESIZE, 0, 0, 0, 0,
|
||||
hParent, (HMENU)5, GetModuleHandle(NULL), NULL);
|
||||
int iBitmapId = 0;
|
||||
int i;
|
||||
|
||||
ok(hToolbar != NULL, "Toolbar creation problem\n");
|
||||
ok(SendMessage(hToolbar, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0) == 0, "TB_BUTTONSTRUCTSIZE failed\n");
|
||||
ok(SendMessage(hToolbar, TB_AUTOSIZE, 0, 0) == 0, "TB_AUTOSIZE failed\n");
|
||||
ok(SendMessage(hToolbar, WM_SETFONT, (WPARAM)GetStockObject(SYSTEM_FONT), 0)==1, "WM_SETFONT\n");
|
||||
|
||||
for (i=0; i<5+nr; i++)
|
||||
{
|
||||
btns[i].iBitmap = i;
|
||||
btns[i].idCommand = i;
|
||||
btns[i].fsStyle = BTNS_BUTTON;
|
||||
btns[i].fsState = TBSTATE_ENABLED;
|
||||
btns[i].iString = 0;
|
||||
}
|
||||
|
||||
switch (nr)
|
||||
{
|
||||
case 0: iBitmapId = IDB_HIST_SMALL_COLOR; break;
|
||||
case 1: iBitmapId = IDB_VIEW_SMALL_COLOR; break;
|
||||
case 2: iBitmapId = IDB_STD_SMALL_COLOR; break;
|
||||
}
|
||||
ok(SendMessage(hToolbar, TB_LOADIMAGES, iBitmapId, (LPARAM)HINST_COMMCTRL) == 0, "TB_LOADIMAGE failed\n");
|
||||
ok(SendMessage(hToolbar, TB_ADDBUTTONS, 5+nr, (LPARAM)btns), "TB_ADDBUTTONS failed\n");
|
||||
return hToolbar;
|
||||
}
|
||||
|
||||
static LRESULT CALLBACK MyWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch (msg)
|
||||
{
|
||||
case WM_NOTIFY:
|
||||
{
|
||||
NMHDR *lpnm = (NMHDR *)lParam;
|
||||
if (lpnm->code == RBN_HEIGHTCHANGE)
|
||||
GetClientRect(hRebar, &height_change_notify_rect);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return DefWindowProcA(hWnd, msg, wParam, lParam);
|
||||
}
|
||||
|
||||
#if 0 /* use this to generate more tests*/
|
||||
|
||||
static void dump_sizes(HWND hRebar)
|
||||
{
|
||||
SIZE sz;
|
||||
RECT r;
|
||||
int count;
|
||||
int i, h;
|
||||
|
||||
GetClientRect(hRebar, &r);
|
||||
count = SendMessageA(hRebar, RB_GETROWCOUNT, 0, 0);
|
||||
printf(" { {%d, %d, %d, %d}, %d, %d, {", r.left, r.top, r.right, r.bottom,
|
||||
SendMessageA(hRebar, RB_GETBARHEIGHT, 0, 0), count);
|
||||
if (count == 0)
|
||||
printf("0, ");
|
||||
for (i = 0; i < count; i++) /* rows */
|
||||
printf("%d, ", SendMessageA(hRebar, RB_GETROWHEIGHT, i, 0));
|
||||
printf("}, ");
|
||||
|
||||
count = SendMessageA(hRebar, RB_GETBANDCOUNT, 0, 0);
|
||||
printf("%d, {", count);
|
||||
if (count == 0)
|
||||
printf("{{0, 0, 0, 0}, 0, 0},");
|
||||
for (i=0; i<count; i++)
|
||||
{
|
||||
REBARBANDINFO rbi;
|
||||
rbi.cbSize = sizeof(REBARBANDINFO);
|
||||
rbi.fMask = RBBIM_SIZE | RBBIM_CHILDSIZE | RBBIM_STYLE;
|
||||
ok(SendMessageA(hRebar, RB_GETBANDINFOA, i, (LPARAM)&rbi), "RB_GETBANDINFO failed\n");
|
||||
ok(SendMessageA(hRebar, RB_GETRECT, i, (LPARAM)&r), "RB_GETRECT failed\n");
|
||||
printf("%s{ {%3d, %3d, %3d, %3d}, 0x%02x, %d}, ", (i%2==0 ? "\n " : ""), r.left, r.top, r.right, r.bottom,
|
||||
rbi.fStyle, rbi.cx);
|
||||
}
|
||||
printf("\n }, }, \n");
|
||||
}
|
||||
|
||||
#define check_sizes() dump_sizes(hRebar);
|
||||
#define check_sizes_todo(todomask) dump_sizes(hRebar);
|
||||
|
||||
#else
|
||||
|
||||
typedef struct {
|
||||
RECT rc;
|
||||
DWORD fStyle;
|
||||
INT cx;
|
||||
} rbband_result_t;
|
||||
|
||||
typedef struct {
|
||||
RECT rcClient;
|
||||
int cyBarHeight;
|
||||
int nRows;
|
||||
int cyRowHeights[50];
|
||||
int nBands;
|
||||
rbband_result_t bands[50];
|
||||
} rbsize_result_t;
|
||||
|
||||
rbsize_result_t rbsize_results[] = {
|
||||
{ {0, 0, 672, 0}, 0, 0, {0, }, 0, {{{0, 0, 0, 0}, 0, 0},
|
||||
}, },
|
||||
{ {0, 0, 672, 4}, 4, 1, {4, }, 1, {
|
||||
{ { 0, 0, 672, 4}, 0x00, 200},
|
||||
}, },
|
||||
{ {0, 0, 672, 4}, 4, 1, {4, }, 2, {
|
||||
{ { 0, 0, 200, 4}, 0x00, 200}, { {200, 0, 672, 4}, 0x04, 200},
|
||||
}, },
|
||||
{ {0, 0, 672, 30}, 30, 1, {30, }, 3, {
|
||||
{ { 0, 0, 200, 30}, 0x00, 200}, { {200, 0, 400, 30}, 0x04, 200},
|
||||
{ {400, 0, 672, 30}, 0x00, 200},
|
||||
}, },
|
||||
{ {0, 0, 672, 34}, 34, 1, {34, }, 4, {
|
||||
{ { 0, 0, 200, 34}, 0x00, 200}, { {200, 0, 400, 34}, 0x04, 200},
|
||||
{ {400, 0, 604, 34}, 0x00, 200}, { {604, 0, 672, 34}, 0x04, 68},
|
||||
}, },
|
||||
{ {0, 0, 672, 34}, 34, 1, {34, }, 4, {
|
||||
{ { 0, 0, 200, 34}, 0x00, 200}, { {200, 0, 400, 34}, 0x04, 200},
|
||||
{ {400, 0, 604, 34}, 0x00, 200}, { {604, 0, 672, 34}, 0x04, 68},
|
||||
}, },
|
||||
{ {0, 0, 672, 34}, 34, 1, {34, }, 4, {
|
||||
{ { 0, 0, 200, 34}, 0x00, 200}, { {202, 0, 402, 34}, 0x04, 200},
|
||||
{ {404, 0, 604, 34}, 0x00, 200}, { {606, 0, 672, 34}, 0x04, 66},
|
||||
}, },
|
||||
{ {0, 0, 672, 70}, 70, 2, {34, 34, }, 5, {
|
||||
{ { 0, 0, 142, 34}, 0x00, 200}, { {144, 0, 557, 34}, 0x00, 200},
|
||||
{ {559, 0, 672, 34}, 0x04, 200}, { { 0, 36, 200, 70}, 0x00, 200},
|
||||
{ {202, 36, 672, 70}, 0x04, 66},
|
||||
}, },
|
||||
{ {0, 0, 672, 34}, 34, 1, {34, }, 5, {
|
||||
{ { 0, 0, 167, 34}, 0x00, 200}, { {169, 0, 582, 34}, 0x00, 200},
|
||||
{ {559, 0, 759, 34}, 0x08, 200}, { {584, 0, 627, 34}, 0x00, 200},
|
||||
{ {629, 0, 672, 34}, 0x04, 66},
|
||||
}, },
|
||||
{ {0, 0, 672, 34}, 34, 1, {34, }, 4, {
|
||||
{ { 0, 0, 167, 34}, 0x00, 200}, { {169, 0, 582, 34}, 0x00, 200},
|
||||
{ {584, 0, 627, 34}, 0x00, 200}, { {629, 0, 672, 34}, 0x04, 66},
|
||||
}, },
|
||||
{ {0, 0, 672, 34}, 34, 1, {34, }, 3, {
|
||||
{ { 0, 0, 413, 34}, 0x00, 200}, { {415, 0, 615, 34}, 0x00, 200},
|
||||
{ {617, 0, 672, 34}, 0x04, 66},
|
||||
}, },
|
||||
{ {0, 0, 672, 34}, 34, 1, {34, }, 2, {
|
||||
{ { 0, 0, 604, 34}, 0x00, 200}, { {606, 0, 672, 34}, 0x04, 66},
|
||||
}, },
|
||||
{ {0, 0, 672, 40}, 40, 2, {20, 20, }, 5, {
|
||||
{ { 0, 0, 114, 20}, 0x00, 40}, { {114, 0, 184, 20}, 0x00, 70},
|
||||
{ {184, 0, 424, 20}, 0x00, 240}, { {424, 0, 672, 20}, 0x00, 60},
|
||||
{ { 0, 20, 672, 40}, 0x00, 200},
|
||||
}, },
|
||||
{ {0, 0, 672, 40}, 40, 2, {20, 20, }, 5, {
|
||||
{ { 0, 0, 114, 20}, 0x00, 40}, { {114, 0, 227, 20}, 0x00, 113},
|
||||
{ {227, 0, 424, 20}, 0x00, 197}, { {424, 0, 672, 20}, 0x00, 60},
|
||||
{ { 0, 20, 672, 40}, 0x00, 200},
|
||||
}, },
|
||||
{ {0, 0, 672, 40}, 40, 2, {20, 20, }, 5, {
|
||||
{ { 0, 0, 114, 20}, 0x00, 40}, { {114, 0, 328, 20}, 0x00, 214},
|
||||
{ {328, 0, 511, 20}, 0x00, 183}, { {511, 0, 672, 20}, 0x00, 161},
|
||||
{ { 0, 20, 672, 40}, 0x00, 200},
|
||||
}, },
|
||||
{ {0, 0, 672, 40}, 40, 2, {20, 20, }, 5, {
|
||||
{ { 0, 0, 114, 20}, 0x00, 40}, { {114, 0, 167, 20}, 0x00, 53},
|
||||
{ {167, 0, 511, 20}, 0x00, 344}, { {511, 0, 672, 20}, 0x00, 161},
|
||||
{ { 0, 20, 672, 40}, 0x00, 200},
|
||||
}, },
|
||||
{ {0, 0, 672, 40}, 40, 2, {20, 20, }, 5, {
|
||||
{ { 0, 0, 114, 20}, 0x00, 40}, { {114, 0, 328, 20}, 0x00, 214},
|
||||
{ {328, 0, 511, 20}, 0x00, 183}, { {511, 0, 672, 20}, 0x00, 161},
|
||||
{ { 0, 20, 672, 40}, 0x00, 200},
|
||||
}, },
|
||||
{ {0, 0, 672, 40}, 40, 2, {20, 20, }, 5, {
|
||||
{ { 0, 0, 114, 20}, 0x00, 40}, { {114, 0, 328, 20}, 0x00, 214},
|
||||
{ {328, 0, 511, 20}, 0x00, 183}, { {511, 0, 672, 20}, 0x00, 161},
|
||||
{ { 0, 20, 672, 40}, 0x00, 200},
|
||||
}, },
|
||||
{ {0, 0, 672, 0}, 0, 0, {0, }, 0, {{{0, 0, 0, 0}, 0, 0},
|
||||
}, },
|
||||
{ {0, 0, 672, 65}, 65, 1, {65, }, 3, {
|
||||
{ { 0, 0, 90, 65}, 0x40, 90}, { { 90, 0, 180, 65}, 0x40, 90},
|
||||
{ {180, 0, 672, 65}, 0x40, 90},
|
||||
}, },
|
||||
{ {0, 0, 0, 226}, 0, 0, {0, }, 0, {{{0, 0, 0, 0}, 0, 0},
|
||||
}, },
|
||||
{ {0, 0, 65, 226}, 65, 1, {65, }, 1, {
|
||||
{ { 0, 0, 226, 65}, 0x40, 90},
|
||||
}, },
|
||||
{ {0, 0, 65, 226}, 65, 1, {65, }, 2, {
|
||||
{ { 0, 0, 90, 65}, 0x40, 90}, { { 90, 0, 226, 65}, 0x40, 90},
|
||||
}, },
|
||||
{ {0, 0, 65, 226}, 65, 1, {65, }, 3, {
|
||||
{ { 0, 0, 90, 65}, 0x40, 90}, { { 90, 0, 163, 65}, 0x40, 90},
|
||||
{ {163, 0, 226, 65}, 0x40, 90},
|
||||
}, },
|
||||
};
|
||||
|
||||
static int rbsize_numtests = 0;
|
||||
|
||||
#define check_sizes_todo(todomask) { \
|
||||
RECT rc; \
|
||||
REBARBANDINFO rbi; \
|
||||
int count, i/*, mask=(todomask)*/; \
|
||||
rbsize_result_t *res = &rbsize_results[rbsize_numtests]; \
|
||||
assert(rbsize_numtests < sizeof(rbsize_results)/sizeof(rbsize_results[0])); \
|
||||
GetClientRect(hRebar, &rc); \
|
||||
check_rect("client", rc, res->rcClient); \
|
||||
count = SendMessage(hRebar, RB_GETROWCOUNT, 0, 0); \
|
||||
compare(count, res->nRows, "%d"); \
|
||||
for (i=0; i<min(count, res->nRows); i++) { \
|
||||
int height = SendMessageA(hRebar, RB_GETROWHEIGHT, 0, 0);\
|
||||
ok(height == res->cyRowHeights[i], "Height mismatch for row %d - %d vs %d\n", i, res->cyRowHeights[i], height); \
|
||||
} \
|
||||
count = SendMessage(hRebar, RB_GETBANDCOUNT, 0, 0); \
|
||||
compare(count, res->nBands, "%d"); \
|
||||
for (i=0; i<min(count, res->nBands); i++) { \
|
||||
ok(SendMessageA(hRebar, RB_GETRECT, i, (LPARAM)&rc) == 1, "RB_ITEMRECT\n"); \
|
||||
if (!(res->bands[i].fStyle & RBBS_HIDDEN)) \
|
||||
check_rect("band", rc, res->bands[i].rc); \
|
||||
rbi.cbSize = sizeof(REBARBANDINFO); \
|
||||
rbi.fMask = RBBIM_STYLE | RBBIM_SIZE; \
|
||||
ok(SendMessageA(hRebar, RB_GETBANDINFO, i, (LPARAM)&rbi) == 1, "RB_GETBANDINFO\n"); \
|
||||
compare(rbi.fStyle, res->bands[i].fStyle, "%x"); \
|
||||
compare(rbi.cx, res->bands[i].cx, "%d"); \
|
||||
} \
|
||||
rbsize_numtests++; \
|
||||
}
|
||||
|
||||
#define check_sizes() check_sizes_todo(0)
|
||||
|
||||
#endif
|
||||
|
||||
static void add_band_w(HWND hRebar, LPCSTR lpszText, int cxMinChild, int cx, int cxIdeal)
|
||||
{
|
||||
CHAR buffer[MAX_PATH];
|
||||
REBARBANDINFO rbi;
|
||||
|
||||
if (lpszText != NULL)
|
||||
strcpy(buffer, lpszText);
|
||||
rbi.cbSize = sizeof(rbi);
|
||||
rbi.fMask = RBBIM_SIZE | RBBIM_CHILDSIZE | RBBIM_CHILD | RBBIM_IDEALSIZE | RBBIM_TEXT;
|
||||
rbi.cx = cx;
|
||||
rbi.cxMinChild = cxMinChild;
|
||||
rbi.cxIdeal = cxIdeal;
|
||||
rbi.cyMinChild = 20;
|
||||
rbi.hwndChild = build_toolbar(1, hRebar);
|
||||
rbi.lpText = (lpszText ? buffer : NULL);
|
||||
SendMessage(hRebar, RB_INSERTBAND, -1, (LPARAM)&rbi);
|
||||
}
|
||||
|
||||
static void layout_test(void)
|
||||
{
|
||||
HWND hRebar = NULL;
|
||||
REBARBANDINFO rbi;
|
||||
|
||||
rebuild_rebar(&hRebar);
|
||||
check_sizes();
|
||||
rbi.cbSize = sizeof(rbi);
|
||||
rbi.fMask = RBBIM_SIZE | RBBIM_CHILDSIZE | RBBIM_CHILD;
|
||||
rbi.cx = 200;
|
||||
rbi.cxMinChild = 100;
|
||||
rbi.cyMinChild = 30;
|
||||
rbi.hwndChild = NULL;
|
||||
SendMessageA(hRebar, RB_INSERTBAND, -1, (LPARAM)&rbi);
|
||||
check_sizes();
|
||||
|
||||
rbi.fMask |= RBBIM_STYLE;
|
||||
rbi.fStyle = RBBS_CHILDEDGE;
|
||||
SendMessageA(hRebar, RB_INSERTBAND, -1, (LPARAM)&rbi);
|
||||
check_sizes();
|
||||
|
||||
rbi.fStyle = 0;
|
||||
rbi.cx = 200;
|
||||
rbi.cxMinChild = 30;
|
||||
rbi.cyMinChild = 30;
|
||||
rbi.hwndChild = build_toolbar(0, hRebar);
|
||||
SendMessageA(hRebar, RB_INSERTBAND, -1, (LPARAM)&rbi);
|
||||
check_sizes();
|
||||
|
||||
rbi.fStyle = RBBS_CHILDEDGE;
|
||||
rbi.cx = 68;
|
||||
rbi.hwndChild = build_toolbar(0, hRebar);
|
||||
SendMessageA(hRebar, RB_INSERTBAND, -1, (LPARAM)&rbi);
|
||||
check_sizes();
|
||||
|
||||
SetWindowLong(hRebar, GWL_STYLE, GetWindowLong(hRebar, GWL_STYLE) | RBS_BANDBORDERS);
|
||||
check_sizes(); /* a style change won't start a relayout */
|
||||
rbi.fMask = RBBIM_SIZE;
|
||||
rbi.cx = 66;
|
||||
SendMessageA(hRebar, RB_SETBANDINFO, 3, (LPARAM)&rbi);
|
||||
check_sizes(); /* here it will be relayouted */
|
||||
|
||||
/* this will force a new row */
|
||||
rbi.fMask = RBBIM_SIZE | RBBIM_CHILDSIZE | RBBIM_CHILD;
|
||||
rbi.cx = 200;
|
||||
rbi.cxMinChild = 400;
|
||||
rbi.cyMinChild = 30;
|
||||
rbi.hwndChild = build_toolbar(0, hRebar);
|
||||
SendMessageA(hRebar, RB_INSERTBAND, 1, (LPARAM)&rbi);
|
||||
check_sizes();
|
||||
|
||||
rbi.fMask = RBBIM_STYLE;
|
||||
rbi.fStyle = RBBS_HIDDEN;
|
||||
SendMessageA(hRebar, RB_SETBANDINFO, 2, (LPARAM)&rbi);
|
||||
check_sizes();
|
||||
|
||||
SendMessageA(hRebar, RB_DELETEBAND, 2, 0);
|
||||
check_sizes();
|
||||
SendMessageA(hRebar, RB_DELETEBAND, 0, 0);
|
||||
check_sizes();
|
||||
SendMessageA(hRebar, RB_DELETEBAND, 1, 0);
|
||||
check_sizes();
|
||||
|
||||
rebuild_rebar(&hRebar);
|
||||
add_band_w(hRebar, "ABC", 70, 40, 100);
|
||||
add_band_w(hRebar, NULL, 40, 70, 100);
|
||||
add_band_w(hRebar, NULL, 170, 240, 100);
|
||||
add_band_w(hRebar, "MMMMMMM", 60, 60, 100);
|
||||
add_band_w(hRebar, NULL, 200, 200, 100);
|
||||
check_sizes();
|
||||
SendMessageA(hRebar, RB_MAXIMIZEBAND, 1, TRUE);
|
||||
check_sizes();
|
||||
SendMessageA(hRebar, RB_MAXIMIZEBAND, 1, TRUE);
|
||||
check_sizes();
|
||||
SendMessageA(hRebar, RB_MAXIMIZEBAND, 2, FALSE);
|
||||
check_sizes();
|
||||
SendMessageA(hRebar, RB_MINIMIZEBAND, 2, 0);
|
||||
check_sizes();
|
||||
SendMessageA(hRebar, RB_MINIMIZEBAND, 0, 0);
|
||||
check_sizes();
|
||||
|
||||
/* VARHEIGHT resizing test on a horizontal rebar */
|
||||
rebuild_rebar(&hRebar);
|
||||
SetWindowLong(hRebar, GWL_STYLE, GetWindowLong(hRebar, GWL_STYLE) | RBS_AUTOSIZE);
|
||||
check_sizes();
|
||||
rbi.fMask = RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_SIZE | RBBIM_STYLE;
|
||||
rbi.fStyle = RBBS_VARIABLEHEIGHT;
|
||||
rbi.cxMinChild = 50;
|
||||
rbi.cyMinChild = 10;
|
||||
rbi.cyIntegral = 11;
|
||||
rbi.cyChild = 70;
|
||||
rbi.cyMaxChild = 200;
|
||||
rbi.cx = 90;
|
||||
rbi.hwndChild = build_toolbar(0, hRebar);
|
||||
SendMessageA(hRebar, RB_INSERTBAND, -1, (LPARAM)&rbi);
|
||||
|
||||
rbi.cyChild = 50;
|
||||
rbi.hwndChild = build_toolbar(0, hRebar);
|
||||
SendMessageA(hRebar, RB_INSERTBAND, -1, (LPARAM)&rbi);
|
||||
|
||||
rbi.cyMinChild = 40;
|
||||
rbi.cyChild = 50;
|
||||
rbi.cyIntegral = 5;
|
||||
rbi.hwndChild = build_toolbar(0, hRebar);
|
||||
SendMessageA(hRebar, RB_INSERTBAND, -1, (LPARAM)&rbi);
|
||||
check_sizes();
|
||||
|
||||
/* VARHEIGHT resizing on a vertical rebar */
|
||||
rebuild_rebar(&hRebar);
|
||||
SetWindowLong(hRebar, GWL_STYLE, GetWindowLong(hRebar, GWL_STYLE) | CCS_VERT | RBS_AUTOSIZE);
|
||||
check_sizes();
|
||||
rbi.fMask = RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_SIZE | RBBIM_STYLE;
|
||||
rbi.fStyle = RBBS_VARIABLEHEIGHT;
|
||||
rbi.cxMinChild = 50;
|
||||
rbi.cyMinChild = 10;
|
||||
rbi.cyIntegral = 11;
|
||||
rbi.cyChild = 70;
|
||||
rbi.cyMaxChild = 90;
|
||||
rbi.cx = 90;
|
||||
rbi.hwndChild = build_toolbar(0, hRebar);
|
||||
SendMessageA(hRebar, RB_INSERTBAND, -1, (LPARAM)&rbi);
|
||||
check_sizes();
|
||||
|
||||
rbi.cyChild = 50;
|
||||
rbi.hwndChild = build_toolbar(0, hRebar);
|
||||
SendMessageA(hRebar, RB_INSERTBAND, -1, (LPARAM)&rbi);
|
||||
check_sizes();
|
||||
|
||||
rbi.cyMinChild = 40;
|
||||
rbi.cyChild = 50;
|
||||
rbi.cyIntegral = 5;
|
||||
rbi.hwndChild = build_toolbar(0, hRebar);
|
||||
SendMessageA(hRebar, RB_INSERTBAND, -1, (LPARAM)&rbi);
|
||||
check_sizes();
|
||||
|
||||
DestroyWindow(hRebar);
|
||||
}
|
||||
|
||||
#if 0 /* use this to generate more tests */
|
||||
|
||||
static void dump_client(HWND hRebar)
|
||||
{
|
||||
RECT r;
|
||||
BOOL notify;
|
||||
GetWindowRect(hRebar, &r);
|
||||
MapWindowPoints(HWND_DESKTOP, hMainWnd, (LPPOINT)&r, 2);
|
||||
if (height_change_notify_rect.top != -1)
|
||||
{
|
||||
RECT rcClient;
|
||||
GetClientRect(hRebar, &rcClient);
|
||||
assert(EqualRect(&rcClient, &height_change_notify_rect));
|
||||
notify = TRUE;
|
||||
}
|
||||
else
|
||||
notify = FALSE;
|
||||
printf(" {{%d, %d, %d, %d}, %d, %s},\n", r.left, r.top, r.right, r.bottom, SendMessage(hRebar, RB_GETROWCOUNT, 0, 0),
|
||||
notify ? "TRUE" : "FALSE");
|
||||
SetRect(&height_change_notify_rect, -1, -1, -1, -1);
|
||||
}
|
||||
|
||||
#define comment(fmt, arg1) printf("/* " fmt " */\n", arg1);
|
||||
#define check_client() dump_client(hRebar)
|
||||
|
||||
#else
|
||||
|
||||
typedef struct {
|
||||
RECT rc;
|
||||
INT iNumRows;
|
||||
BOOL heightNotify;
|
||||
} rbresize_test_result_t;
|
||||
|
||||
rbresize_test_result_t resize_results[] = {
|
||||
/* style 00000001 */
|
||||
{{0, 2, 672, 2}, 0, FALSE},
|
||||
{{0, 2, 672, 22}, 1, TRUE},
|
||||
{{0, 2, 672, 22}, 1, FALSE},
|
||||
{{0, 2, 672, 22}, 1, FALSE},
|
||||
{{0, 2, 672, 22}, 1, FALSE},
|
||||
{{0, 2, 672, 22}, 0, FALSE},
|
||||
/* style 00000041 */
|
||||
{{0, 0, 672, 0}, 0, FALSE},
|
||||
{{0, 0, 672, 20}, 1, TRUE},
|
||||
{{0, 0, 672, 20}, 1, FALSE},
|
||||
{{0, 0, 672, 20}, 1, FALSE},
|
||||
{{0, 0, 672, 20}, 1, FALSE},
|
||||
{{0, 0, 672, 20}, 0, FALSE},
|
||||
/* style 00000003 */
|
||||
{{0, 226, 672, 226}, 0, FALSE},
|
||||
{{0, 206, 672, 226}, 1, TRUE},
|
||||
{{0, 206, 672, 226}, 1, FALSE},
|
||||
{{0, 206, 672, 226}, 1, FALSE},
|
||||
{{0, 206, 672, 226}, 1, FALSE},
|
||||
{{0, 206, 672, 226}, 0, FALSE},
|
||||
/* style 00000043 */
|
||||
{{0, 226, 672, 226}, 0, FALSE},
|
||||
{{0, 206, 672, 226}, 1, TRUE},
|
||||
{{0, 206, 672, 226}, 1, FALSE},
|
||||
{{0, 206, 672, 226}, 1, FALSE},
|
||||
{{0, 206, 672, 226}, 1, FALSE},
|
||||
{{0, 206, 672, 226}, 0, FALSE},
|
||||
/* style 00000080 */
|
||||
{{2, 0, 2, 226}, 0, FALSE},
|
||||
{{2, 0, 22, 226}, 1, TRUE},
|
||||
{{2, 0, 22, 226}, 1, FALSE},
|
||||
{{2, 0, 22, 226}, 1, FALSE},
|
||||
{{2, 0, 22, 226}, 1, FALSE},
|
||||
{{2, 0, 22, 226}, 0, FALSE},
|
||||
/* style 00000083 */
|
||||
{{672, 0, 672, 226}, 0, FALSE},
|
||||
{{652, 0, 672, 226}, 1, TRUE},
|
||||
{{652, 0, 672, 226}, 1, FALSE},
|
||||
{{652, 0, 672, 226}, 1, FALSE},
|
||||
{{652, 0, 672, 226}, 1, FALSE},
|
||||
{{652, 0, 672, 226}, 0, FALSE},
|
||||
/* style 00000008 */
|
||||
{{10, 11, 510, 11}, 0, FALSE},
|
||||
{{10, 15, 510, 35}, 1, TRUE},
|
||||
{{10, 17, 510, 37}, 1, FALSE},
|
||||
{{10, 14, 110, 54}, 2, TRUE},
|
||||
{{0, 4, 0, 44}, 2, FALSE},
|
||||
{{0, 6, 0, 46}, 2, FALSE},
|
||||
{{0, 8, 0, 48}, 2, FALSE},
|
||||
{{0, 12, 0, 32}, 1, TRUE},
|
||||
{{0, 4, 100, 24}, 0, FALSE},
|
||||
/* style 00000048 */
|
||||
{{10, 5, 510, 5}, 0, FALSE},
|
||||
{{10, 5, 510, 25}, 1, TRUE},
|
||||
{{10, 5, 510, 25}, 1, FALSE},
|
||||
{{10, 10, 110, 50}, 2, TRUE},
|
||||
{{0, 0, 0, 40}, 2, FALSE},
|
||||
{{0, 0, 0, 40}, 2, FALSE},
|
||||
{{0, 0, 0, 40}, 2, FALSE},
|
||||
{{0, 0, 0, 20}, 1, TRUE},
|
||||
{{0, 0, 100, 20}, 0, FALSE},
|
||||
/* style 00000004 */
|
||||
{{10, 5, 510, 20}, 0, FALSE},
|
||||
{{10, 5, 510, 20}, 1, TRUE},
|
||||
{{10, 10, 110, 110}, 2, TRUE},
|
||||
{{0, 0, 0, 0}, 2, FALSE},
|
||||
{{0, 0, 0, 0}, 2, FALSE},
|
||||
{{0, 0, 0, 0}, 2, FALSE},
|
||||
{{0, 0, 0, 0}, 1, TRUE},
|
||||
{{0, 0, 100, 100}, 0, FALSE},
|
||||
/* style 00000002 */
|
||||
{{0, 5, 672, 5}, 0, FALSE},
|
||||
{{0, 5, 672, 25}, 1, TRUE},
|
||||
{{0, 10, 672, 30}, 1, FALSE},
|
||||
{{0, 0, 672, 20}, 1, FALSE},
|
||||
{{0, 0, 672, 20}, 1, FALSE},
|
||||
{{0, 0, 672, 20}, 0, FALSE},
|
||||
/* style 00000082 */
|
||||
{{10, 0, 10, 226}, 0, FALSE},
|
||||
{{10, 0, 30, 226}, 1, TRUE},
|
||||
{{10, 0, 30, 226}, 1, FALSE},
|
||||
{{0, 0, 20, 226}, 1, FALSE},
|
||||
{{0, 0, 20, 226}, 1, FALSE},
|
||||
{{0, 0, 20, 226}, 0, FALSE},
|
||||
/* style 00800001 */
|
||||
{{-2, 0, 674, 4}, 0, FALSE},
|
||||
{{-2, 0, 674, 24}, 1, TRUE},
|
||||
{{-2, 0, 674, 24}, 1, FALSE},
|
||||
{{-2, 0, 674, 24}, 1, FALSE},
|
||||
{{-2, 0, 674, 24}, 1, FALSE},
|
||||
{{-2, 0, 674, 24}, 0, FALSE},
|
||||
/* style 00800048 */
|
||||
{{10, 5, 510, 9}, 0, FALSE},
|
||||
{{10, 5, 510, 29}, 1, TRUE},
|
||||
{{10, 5, 510, 29}, 1, FALSE},
|
||||
{{10, 10, 110, 54}, 2, TRUE},
|
||||
{{0, 0, 0, 44}, 2, FALSE},
|
||||
{{0, 0, 0, 44}, 2, FALSE},
|
||||
{{0, 0, 0, 44}, 2, FALSE},
|
||||
{{0, 0, 0, 24}, 1, TRUE},
|
||||
{{0, 0, 100, 24}, 0, FALSE},
|
||||
/* style 00800004 */
|
||||
{{10, 5, 510, 20}, 0, FALSE},
|
||||
{{10, 5, 510, 20}, 1, TRUE},
|
||||
{{10, 10, 110, 110}, 2, TRUE},
|
||||
{{0, 0, 0, 0}, 2, FALSE},
|
||||
{{0, 0, 0, 0}, 2, FALSE},
|
||||
{{0, 0, 0, 0}, 2, FALSE},
|
||||
{{0, 0, 0, 0}, 1, TRUE},
|
||||
{{0, 0, 100, 100}, 0, FALSE},
|
||||
/* style 00800002 */
|
||||
{{-2, 5, 674, 9}, 0, FALSE},
|
||||
{{-2, 5, 674, 29}, 1, TRUE},
|
||||
{{-2, 10, 674, 34}, 1, FALSE},
|
||||
{{-2, 0, 674, 24}, 1, FALSE},
|
||||
{{-2, 0, 674, 24}, 1, FALSE},
|
||||
{{-2, 0, 674, 24}, 0, FALSE},
|
||||
};
|
||||
|
||||
static int resize_numtests = 0;
|
||||
|
||||
#define comment(fmt, arg1)
|
||||
#define check_client() { \
|
||||
RECT r; \
|
||||
rbresize_test_result_t *res = &resize_results[resize_numtests++]; \
|
||||
assert(resize_numtests <= sizeof(resize_results)/sizeof(resize_results[0])); \
|
||||
GetWindowRect(hRebar, &r); \
|
||||
MapWindowPoints(HWND_DESKTOP, hMainWnd, (LPPOINT)&r, 2); \
|
||||
if ((dwStyles[i] & (CCS_NOPARENTALIGN|CCS_NODIVIDER)) == CCS_NOPARENTALIGN) {\
|
||||
check_rect_no_top("client", r, res->rc); /* the top coordinate changes after every layout and is very implementation-dependent */ \
|
||||
} else { \
|
||||
check_rect("client", r, res->rc); \
|
||||
} \
|
||||
expect_eq((int)SendMessage(hRebar, RB_GETROWCOUNT, 0, 0), res->iNumRows, int, "%d"); \
|
||||
if (res->heightNotify) { \
|
||||
RECT rcClient; \
|
||||
GetClientRect(hRebar, &rcClient); \
|
||||
check_rect("notify", height_change_notify_rect, rcClient); \
|
||||
} else ok(height_change_notify_rect.top == -1, "Unexpected RBN_HEIGHTCHANGE received\n"); \
|
||||
SetRect(&height_change_notify_rect, -1, -1, -1, -1); \
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static void resize_test(void)
|
||||
{
|
||||
DWORD dwStyles[] = {CCS_TOP, CCS_TOP | CCS_NODIVIDER, CCS_BOTTOM, CCS_BOTTOM | CCS_NODIVIDER, CCS_VERT, CCS_RIGHT,
|
||||
CCS_NOPARENTALIGN, CCS_NOPARENTALIGN | CCS_NODIVIDER, CCS_NORESIZE, CCS_NOMOVEY, CCS_NOMOVEY | CCS_VERT,
|
||||
CCS_TOP | WS_BORDER, CCS_NOPARENTALIGN | CCS_NODIVIDER | WS_BORDER, CCS_NORESIZE | WS_BORDER,
|
||||
CCS_NOMOVEY | WS_BORDER};
|
||||
|
||||
const int styles_count = sizeof(dwStyles) / sizeof(dwStyles[0]);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < styles_count; i++)
|
||||
{
|
||||
comment("style %08x", dwStyles[i]);
|
||||
SetRect(&height_change_notify_rect, -1, -1, -1, -1);
|
||||
hRebar = CreateWindow(REBARCLASSNAME, "A", dwStyles[i] | WS_CHILD | WS_VISIBLE, 10, 5, 500, 15, hMainWnd, NULL, GetModuleHandle(NULL), 0);
|
||||
check_client();
|
||||
add_band_w(hRebar, NULL, 70, 100, 0);
|
||||
if (dwStyles[i] & CCS_NOPARENTALIGN) /* the window drifts downward for CCS_NOPARENTALIGN without CCS_NODIVIDER */
|
||||
check_client();
|
||||
add_band_w(hRebar, NULL, 70, 100, 0);
|
||||
check_client();
|
||||
MoveWindow(hRebar, 10, 10, 100, 100, TRUE);
|
||||
check_client();
|
||||
MoveWindow(hRebar, 0, 0, 0, 0, TRUE);
|
||||
check_client();
|
||||
/* try to fool the rebar by sending invalid width/height - won't work */
|
||||
if (dwStyles[i] & (CCS_NORESIZE | CCS_NOPARENTALIGN))
|
||||
{
|
||||
WINDOWPOS pos;
|
||||
pos.hwnd = hRebar;
|
||||
pos.hwndInsertAfter = NULL;
|
||||
pos.cx = 500;
|
||||
pos.cy = 500;
|
||||
pos.x = 10;
|
||||
pos.y = 10;
|
||||
pos.flags = 0;
|
||||
SendMessage(hRebar, WM_WINDOWPOSCHANGING, 0, (LPARAM)&pos);
|
||||
SendMessage(hRebar, WM_WINDOWPOSCHANGED, 0, (LPARAM)&pos);
|
||||
check_client();
|
||||
SendMessage(hRebar, WM_SIZE, SIZE_RESTORED, MAKELONG(500, 500));
|
||||
check_client();
|
||||
}
|
||||
SendMessage(hRebar, RB_DELETEBAND, 0, 0);
|
||||
check_client();
|
||||
SendMessage(hRebar, RB_DELETEBAND, 0, 0);
|
||||
MoveWindow(hRebar, 0, 0, 100, 100, TRUE);
|
||||
check_client();
|
||||
DestroyWindow(hRebar);
|
||||
}
|
||||
}
|
||||
|
||||
static void expect_band_content(UINT uBand, INT fStyle, COLORREF clrFore,
|
||||
COLORREF clrBack, LPCSTR lpText, int iImage, HWND hwndChild,
|
||||
INT cxMinChild, INT cyMinChild, INT cx, HBITMAP hbmBack, INT wID,
|
||||
INT cyChild, INT cyMaxChild, INT cyIntegral, INT cxIdeal, LPARAM lParam,
|
||||
INT cxHeader)
|
||||
{
|
||||
CHAR buf[MAX_PATH] = "abc";
|
||||
REBARBANDINFO rb;
|
||||
|
||||
memset(&rb, 0xdd, sizeof(rb));
|
||||
rb.cbSize = sizeof(rb);
|
||||
rb.fMask = RBBIM_BACKGROUND | RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_COLORS
|
||||
| RBBIM_HEADERSIZE | RBBIM_ID | RBBIM_IDEALSIZE | RBBIM_IMAGE | RBBIM_LPARAM
|
||||
| RBBIM_SIZE | RBBIM_STYLE | RBBIM_TEXT;
|
||||
rb.lpText = buf;
|
||||
rb.cch = MAX_PATH;
|
||||
ok(SendMessageA(hRebar, RB_GETBANDINFOA, uBand, (LPARAM)&rb), "RB_GETBANDINFO failed\n");
|
||||
expect_eq(rb.fStyle, fStyle, int, "%x");
|
||||
todo_wine expect_eq(rb.clrFore, clrFore, COLORREF, "%x");
|
||||
todo_wine expect_eq(rb.clrBack, clrBack, unsigned, "%x");
|
||||
expect_eq(strcmp(rb.lpText, lpText), 0, int, "%d");
|
||||
expect_eq(rb.iImage, iImage, int, "%x");
|
||||
expect_eq(rb.hwndChild, hwndChild, HWND, "%p");
|
||||
expect_eq(rb.cxMinChild, cxMinChild, int, "%d");
|
||||
expect_eq(rb.cyMinChild, cyMinChild, int, "%d");
|
||||
expect_eq(rb.cx, cx, int, "%d");
|
||||
expect_eq(rb.hbmBack, hbmBack, HBITMAP, "%p");
|
||||
expect_eq(rb.wID, wID, int, "%d");
|
||||
/* the values of cyChild, cyMaxChild and cyIntegral can't be read unless the band is RBBS_VARIABLEHEIGHT */
|
||||
expect_eq(rb.cyChild, cyChild, int, "%x");
|
||||
expect_eq(rb.cyMaxChild, cyMaxChild, int, "%x");
|
||||
expect_eq(rb.cyIntegral, cyIntegral, int, "%x");
|
||||
expect_eq(rb.cxIdeal, cxIdeal, int, "%d");
|
||||
expect_eq(rb.lParam, lParam, LPARAM, "%ld");
|
||||
expect_eq(rb.cxHeader, cxHeader, int, "%d");
|
||||
}
|
||||
|
||||
static void bandinfo_test(void)
|
||||
{
|
||||
REBARBANDINFOA rb;
|
||||
CHAR szABC[] = "ABC";
|
||||
CHAR szABCD[] = "ABCD";
|
||||
|
||||
rebuild_rebar(&hRebar);
|
||||
rb.cbSize = sizeof(REBARBANDINFO);
|
||||
rb.fMask = 0;
|
||||
ok(SendMessageA(hRebar, RB_INSERTBANDA, 0, (LPARAM)&rb), "RB_INSERTBAND failed\n");
|
||||
expect_band_content(0, 0, 0, GetSysColor(COLOR_3DFACE), "", -1, NULL, 0, 0, 0, NULL, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 0);
|
||||
|
||||
rb.fMask = RBBIM_CHILDSIZE;
|
||||
rb.cxMinChild = 15;
|
||||
rb.cyMinChild = 20;
|
||||
rb.cyChild = 30;
|
||||
rb.cyMaxChild = 20;
|
||||
rb.cyIntegral = 10;
|
||||
ok(SendMessageA(hRebar, RB_SETBANDINFOA, 0, (LPARAM)&rb), "RB_INSERTBAND failed\n");
|
||||
expect_band_content(0, 0, 0, GetSysColor(COLOR_3DFACE), "", -1, NULL, 15, 20, 0, NULL, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 0);
|
||||
|
||||
rb.fMask = RBBIM_TEXT;
|
||||
rb.lpText = szABC;
|
||||
ok(SendMessageA(hRebar, RB_SETBANDINFOA, 0, (LPARAM)&rb), "RB_INSERTBAND failed\n");
|
||||
expect_band_content(0, 0, 0, GetSysColor(COLOR_3DFACE), "ABC", -1, NULL, 15, 20, 0, NULL, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 35);
|
||||
|
||||
rb.cbSize = sizeof(REBARBANDINFO);
|
||||
rb.fMask = 0;
|
||||
ok(SendMessageA(hRebar, RB_INSERTBANDA, 1, (LPARAM)&rb), "RB_INSERTBAND failed\n");
|
||||
expect_band_content(1, 0, 0, GetSysColor(COLOR_3DFACE), "", -1, NULL, 0, 0, 0, NULL, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 9);
|
||||
expect_band_content(0, 0, 0, GetSysColor(COLOR_3DFACE), "ABC", -1, NULL, 15, 20, 0, NULL, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 40);
|
||||
|
||||
rb.fMask = RBBIM_HEADERSIZE;
|
||||
rb.cxHeader = 50;
|
||||
ok(SendMessageA(hRebar, RB_SETBANDINFOA, 0, (LPARAM)&rb), "RB_INSERTBAND failed\n");
|
||||
expect_band_content(0, 0x40000000, 0, GetSysColor(COLOR_3DFACE), "ABC", -1, NULL, 15, 20, 0, NULL, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 50);
|
||||
|
||||
rb.cxHeader = 5;
|
||||
ok(SendMessageA(hRebar, RB_SETBANDINFOA, 0, (LPARAM)&rb), "RB_INSERTBAND failed\n");
|
||||
expect_band_content(0, 0x40000000, 0, GetSysColor(COLOR_3DFACE), "ABC", -1, NULL, 15, 20, 0, NULL, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 5);
|
||||
|
||||
rb.fMask = RBBIM_TEXT;
|
||||
rb.lpText = szABCD;
|
||||
ok(SendMessageA(hRebar, RB_SETBANDINFOA, 0, (LPARAM)&rb), "RB_INSERTBAND failed\n");
|
||||
expect_band_content(0, 0x40000000, 0, GetSysColor(COLOR_3DFACE), "ABCD", -1, NULL, 15, 20, 0, NULL, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 5);
|
||||
rb.fMask = RBBIM_STYLE | RBBIM_TEXT;
|
||||
rb.fStyle = RBBS_VARIABLEHEIGHT;
|
||||
rb.lpText = szABC;
|
||||
ok(SendMessageA(hRebar, RB_SETBANDINFOA, 0, (LPARAM)&rb), "RB_INSERTBAND failed\n");
|
||||
expect_band_content(0, RBBS_VARIABLEHEIGHT, 0, GetSysColor(COLOR_3DFACE), "ABC", -1, NULL, 15, 20, 0, NULL, 0, 20, 0x7fffffff, 0, 0, 0, 40);
|
||||
|
||||
DestroyWindow(hRebar);
|
||||
}
|
||||
|
||||
START_TEST(rebar)
|
||||
{
|
||||
INITCOMMONCONTROLSEX icc;
|
||||
WNDCLASSA wc;
|
||||
MSG msg;
|
||||
RECT rc;
|
||||
|
||||
icc.dwSize = sizeof(icc);
|
||||
icc.dwICC = ICC_COOL_CLASSES;
|
||||
InitCommonControlsEx(&icc);
|
||||
|
||||
wc.style = CS_HREDRAW | CS_VREDRAW;
|
||||
wc.cbClsExtra = 0;
|
||||
wc.cbWndExtra = 0;
|
||||
wc.hInstance = GetModuleHandleA(NULL);
|
||||
wc.hIcon = NULL;
|
||||
wc.hCursor = LoadCursorA(NULL, IDC_IBEAM);
|
||||
wc.hbrBackground = GetSysColorBrush(COLOR_WINDOW);
|
||||
wc.lpszMenuName = NULL;
|
||||
wc.lpszClassName = "MyTestWnd";
|
||||
wc.lpfnWndProc = MyWndProc;
|
||||
RegisterClassA(&wc);
|
||||
hMainWnd = CreateWindowExA(0, "MyTestWnd", "Blah", WS_OVERLAPPEDWINDOW,
|
||||
CW_USEDEFAULT, CW_USEDEFAULT, 672+2*GetSystemMetrics(SM_CXSIZEFRAME),
|
||||
226+GetSystemMetrics(SM_CYCAPTION)+2*GetSystemMetrics(SM_CYSIZEFRAME),
|
||||
NULL, NULL, GetModuleHandleA(NULL), 0);
|
||||
GetClientRect(hMainWnd, &rc);
|
||||
ShowWindow(hMainWnd, SW_SHOW);
|
||||
|
||||
bandinfo_test();
|
||||
|
||||
if(is_font_installed("System") && is_font_installed("Tahoma"))
|
||||
{
|
||||
layout_test();
|
||||
resize_test();
|
||||
} else
|
||||
skip("Missing System or Tahoma font\n");
|
||||
|
||||
PostQuitMessage(0);
|
||||
while(GetMessageA(&msg,0,0,0)) {
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessageA(&msg);
|
||||
}
|
||||
DestroyWindow(hMainWnd);
|
||||
}
|
34
rostests/winetests/comctl32/resources.h
Normal file
34
rostests/winetests/comctl32/resources.h
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Resource IDs
|
||||
*
|
||||
* Copyright 2006 Mikolaj Zalewski
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef __WINE_COMCTL32_TEST_RESOURCES_H
|
||||
#define __WINE_COMCTL32_TEST_RESOURCES_H
|
||||
|
||||
#define IDB_BITMAP_128x15 10
|
||||
#define IDB_BITMAP_80x15 11
|
||||
|
||||
#define IDS_TBADD1 16
|
||||
#define IDS_TBADD2 17
|
||||
#define IDS_TBADD3 18
|
||||
#define IDS_TBADD4 19
|
||||
#define IDS_TBADD5 20
|
||||
#define IDS_TBADD7 22
|
||||
|
||||
#endif /* __WINE_COMCTL32_TEST_RESOURCES_H */
|
|
@ -1,6 +1,7 @@
|
|||
/* Resources for the unit test suite for property sheet control.
|
||||
/* Resources for the common control unit test suite.
|
||||
*
|
||||
* Copyright 2006 Huw Davies
|
||||
* Copyright 2006 Mikolaj Zalewski
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -19,6 +20,7 @@
|
|||
|
||||
#include "windef.h"
|
||||
#include "winuser.h"
|
||||
#include "resources.h"
|
||||
|
||||
PROP_PAGE1 DIALOG LOADONCALL MOVEABLE DISCARDABLE 5, 43, 227, 215
|
||||
STYLE WS_POPUP | WS_CAPTION | WS_CLIPSIBLINGS | WS_VISIBLE
|
||||
|
@ -27,3 +29,19 @@ FONT 8, "MS Shell Dlg"
|
|||
{
|
||||
LTEXT "Test", -1, 10, 6, 100, 8
|
||||
}
|
||||
|
||||
STRINGTABLE
|
||||
{
|
||||
IDS_TBADD1 "abc"
|
||||
IDS_TBADD2 "|p|q|r"
|
||||
IDS_TBADD3 "*p*q*"
|
||||
IDS_TBADD4 "#p#q##"
|
||||
IDS_TBADD5 "|p||q|r|"
|
||||
IDS_TBADD7 "abracadabra"
|
||||
}
|
||||
|
||||
/* @makedep: bmp128x15.bmp */
|
||||
IDB_BITMAP_128x15 BITMAP bmp128x15.bmp
|
||||
|
||||
/* @makedep: bmp80x15.bmp */
|
||||
IDB_BITMAP_80x15 BITMAP bmp80x15.bmp
|
196
rostests/winetests/comctl32/status.c
Normal file
196
rostests/winetests/comctl32/status.c
Normal file
|
@ -0,0 +1,196 @@
|
|||
/* Unit test suite for status control.
|
||||
*
|
||||
* Copyright 2007 Google (Lei Zhang)
|
||||
* Copyright 2007 Alex Arazi
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <windows.h>
|
||||
#include <commctrl.h>
|
||||
|
||||
#include "wine/test.h"
|
||||
|
||||
#define expect(expected,got) ok (expected == got,"Expected %d, got %d\n",expected,got);
|
||||
|
||||
static HINSTANCE hinst;
|
||||
|
||||
static HWND create_status_control(DWORD style, DWORD exstyle)
|
||||
{
|
||||
HWND hWndStatus;
|
||||
|
||||
/* make the control */
|
||||
hWndStatus = CreateWindowEx(exstyle, STATUSCLASSNAME, NULL, style,
|
||||
/* placement */
|
||||
0, 0, 300, 20,
|
||||
/* parent, etc */
|
||||
NULL, NULL, hinst, NULL);
|
||||
assert (hWndStatus);
|
||||
return hWndStatus;
|
||||
}
|
||||
|
||||
static void test_status_control(void)
|
||||
{
|
||||
HWND hWndStatus;
|
||||
int r;
|
||||
int nParts[] = {50, 150, -1};
|
||||
int checkParts[] = {0, 0, 0};
|
||||
int borders[] = {0, 0, 0};
|
||||
RECT rc;
|
||||
CHAR charArray[20];
|
||||
HICON hIcon;
|
||||
|
||||
hWndStatus = create_status_control(WS_VISIBLE, 0);
|
||||
|
||||
/* Divide into parts and set text */
|
||||
r = SendMessage(hWndStatus, SB_SETPARTS, 3, (long)nParts);
|
||||
expect(TRUE,r);
|
||||
r = SendMessage(hWndStatus, SB_SETTEXT, 0, (LPARAM)"First");
|
||||
expect(TRUE,r);
|
||||
r = SendMessage(hWndStatus, SB_SETTEXT, 1, (LPARAM)"Second");
|
||||
expect(TRUE,r);
|
||||
r = SendMessage(hWndStatus, SB_SETTEXT, 2, (LPARAM)"Third");
|
||||
expect(TRUE,r);
|
||||
|
||||
/* Get RECT Information */
|
||||
r = SendMessage(hWndStatus, SB_GETRECT, 0, (LPARAM)&rc);
|
||||
expect(TRUE,r);
|
||||
expect(2,rc.top);
|
||||
/* The rc.bottom test is system dependent
|
||||
expect(22,rc.bottom); */
|
||||
expect(0,rc.left);
|
||||
expect(50,rc.right);
|
||||
r = SendMessage(hWndStatus, SB_GETRECT, -1, (LPARAM)&rc);
|
||||
expect(FALSE,r);
|
||||
r = SendMessage(hWndStatus, SB_GETRECT, 3, (LPARAM)&rc);
|
||||
expect(FALSE,r);
|
||||
/* Get text length and text */
|
||||
r = SendMessage(hWndStatus, SB_GETTEXTLENGTH, 2, 0);
|
||||
expect(5,LOWORD(r));
|
||||
expect(0,HIWORD(r));
|
||||
r = SendMessage(hWndStatus, SB_GETTEXT, 2, (LPARAM) charArray);
|
||||
ok(strcmp(charArray,"Third") == 0, "Expected Third, got %s\n", charArray);
|
||||
expect(5,LOWORD(r));
|
||||
expect(0,HIWORD(r));
|
||||
|
||||
/* Get parts and borders */
|
||||
r = SendMessage(hWndStatus, SB_GETPARTS, 3, (long)checkParts);
|
||||
ok(r == 3, "Expected 3, got %d\n", r);
|
||||
expect(50,checkParts[0]);
|
||||
expect(150,checkParts[1]);
|
||||
expect(-1,checkParts[2]);
|
||||
r = SendMessage(hWndStatus, SB_GETBORDERS, 0, (long)borders);
|
||||
ok(r == TRUE, "Expected TRUE, got %d\n", r);
|
||||
expect(0,borders[0]);
|
||||
expect(2,borders[1]);
|
||||
expect(2,borders[2]);
|
||||
|
||||
/* Test resetting text with different characters */
|
||||
r = SendMessage(hWndStatus, SB_SETTEXT, 0, (LPARAM)"First@Again");
|
||||
expect(TRUE,r);
|
||||
r = SendMessage(hWndStatus, SB_SETTEXT, 1, (LPARAM)"InvalidChars\\7\7");
|
||||
expect(TRUE,r);
|
||||
r = SendMessage(hWndStatus, SB_SETTEXT, 2, (LPARAM)"InvalidChars\\n\n");
|
||||
expect(TRUE,r);
|
||||
|
||||
/* Get text again */
|
||||
r = SendMessage(hWndStatus, SB_GETTEXT, 0, (LPARAM) charArray);
|
||||
ok(strcmp(charArray,"First@Again") == 0, "Expected First@Again, got %s\n", charArray);
|
||||
expect(11,LOWORD(r));
|
||||
expect(0,HIWORD(r));
|
||||
r = SendMessage(hWndStatus, SB_GETTEXT, 1, (LPARAM) charArray);
|
||||
todo_wine
|
||||
{
|
||||
ok(strcmp(charArray,"InvalidChars\\7 ") == 0, "Expected InvalidChars\\7 , got %s\n", charArray);
|
||||
}
|
||||
expect(15,LOWORD(r));
|
||||
expect(0,HIWORD(r));
|
||||
r = SendMessage(hWndStatus, SB_GETTEXT, 2, (LPARAM) charArray);
|
||||
todo_wine
|
||||
{
|
||||
ok(strcmp(charArray,"InvalidChars\\n ") == 0, "Expected InvalidChars\\n , got %s\n", charArray);
|
||||
}
|
||||
expect(15,LOWORD(r));
|
||||
expect(0,HIWORD(r));
|
||||
|
||||
/* Set background color */
|
||||
r = SendMessage(hWndStatus, SB_SETBKCOLOR , 0, RGB(255,0,0));
|
||||
expect(CLR_DEFAULT,r);
|
||||
r = SendMessage(hWndStatus, SB_SETBKCOLOR , 0, CLR_DEFAULT);
|
||||
expect(RGB(255,0,0),r);
|
||||
|
||||
/* Add an icon to the status bar */
|
||||
hIcon = LoadIcon(NULL, IDI_QUESTION);
|
||||
r = SendMessage(hWndStatus, SB_SETICON, 1, (LPARAM) NULL);
|
||||
ok(r != 0, "Expected non-zero, got %d\n", r);
|
||||
r = SendMessage(hWndStatus, SB_SETICON, 1, (LPARAM) hIcon);
|
||||
ok(r != 0, "Expected non-zero, got %d\n", r);
|
||||
r = SendMessage(hWndStatus, SB_SETICON, 1, (LPARAM) NULL);
|
||||
ok(r != 0, "Expected non-zero, got %d\n", r);
|
||||
|
||||
/* Set the Unicode format */
|
||||
r = SendMessage(hWndStatus, SB_SETUNICODEFORMAT, FALSE, 0);
|
||||
r = SendMessage(hWndStatus, SB_GETUNICODEFORMAT, 0, 0);
|
||||
expect(FALSE,r);
|
||||
r = SendMessage(hWndStatus, SB_SETUNICODEFORMAT, TRUE, 0);
|
||||
expect(FALSE,r);
|
||||
r = SendMessage(hWndStatus, SB_GETUNICODEFORMAT, 0, 0);
|
||||
expect(TRUE,r);
|
||||
|
||||
/* Reset number of parts */
|
||||
r = SendMessage(hWndStatus, SB_SETPARTS, 2, (long)nParts);
|
||||
expect(TRUE,r);
|
||||
|
||||
/* Set the minimum height and get rectangle information again */
|
||||
SendMessage(hWndStatus, SB_SETMINHEIGHT, 50, (LPARAM) 0);
|
||||
r = SendMessage(hWndStatus, WM_SIZE, 0, (LPARAM) 0);
|
||||
expect(0,r);
|
||||
r = SendMessage(hWndStatus, SB_GETRECT, 0, (LPARAM)&rc);
|
||||
expect(TRUE,r);
|
||||
expect(2,rc.top);
|
||||
/* The rc.bottom test is system dependent
|
||||
expect(22,rc.bottom); */
|
||||
expect(0,rc.left);
|
||||
expect(50,rc.right);
|
||||
r = SendMessage(hWndStatus, SB_GETRECT, -1, (LPARAM)&rc);
|
||||
expect(FALSE,r);
|
||||
r = SendMessage(hWndStatus, SB_GETRECT, 3, (LPARAM)&rc);
|
||||
expect(FALSE,r);
|
||||
|
||||
/* Set the ToolTip text */
|
||||
todo_wine
|
||||
{
|
||||
SendMessage(hWndStatus, SB_SETTIPTEXT, 0,(LPARAM) "Tooltip Text");
|
||||
SendMessage(hWndStatus, SB_GETTIPTEXT, MAKEWPARAM (0, 20),(LPARAM) charArray);
|
||||
ok(strcmp(charArray,"Tooltip Text") == 0, "Expected Tooltip Text, got %s\n", charArray);
|
||||
}
|
||||
|
||||
/* Make simple */
|
||||
SendMessage(hWndStatus, SB_SIMPLE, TRUE, 0);
|
||||
r = SendMessage(hWndStatus, SB_ISSIMPLE, 0, 0);
|
||||
expect(TRUE,r);
|
||||
|
||||
DestroyWindow(hWndStatus);
|
||||
}
|
||||
|
||||
START_TEST(status)
|
||||
{
|
||||
hinst = GetModuleHandleA(NULL);
|
||||
|
||||
InitCommonControls();
|
||||
|
||||
test_status_control();
|
||||
}
|
|
@ -156,7 +156,7 @@ static void ok_sequence(const struct message *expected, const char *context)
|
|||
"%s: the procnum %d was expected, but got procnum %d instead\n",
|
||||
context, expected->procnum, actual->procnum);
|
||||
ok(expected->wParam == actual->wParam,
|
||||
"%s: in procnum %d expecting wParam 0x%x got 0x%x\n",
|
||||
"%s: in procnum %d expecting wParam 0x%lx got 0x%lx\n",
|
||||
context, expected->procnum, expected->wParam, actual->wParam);
|
||||
expected++;
|
||||
actual++;
|
||||
|
@ -169,7 +169,7 @@ static void ok_sequence(const struct message *expected, const char *context)
|
|||
static LRESULT WINAPI WndProc1(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
struct message msg;
|
||||
|
||||
|
||||
if(message == WM_USER) {
|
||||
msg.wParam = wParam;
|
||||
msg.procnum = 1;
|
||||
|
@ -183,7 +183,7 @@ static WNDPROC origProc3;
|
|||
static LRESULT WINAPI WndProc3(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
struct message msg;
|
||||
|
||||
|
||||
if(message == WM_USER) {
|
||||
msg.wParam = wParam;
|
||||
msg.procnum = 3;
|
||||
|
@ -195,12 +195,12 @@ static LRESULT WINAPI WndProc3(HWND hwnd, UINT message, WPARAM wParam, LPARAM lP
|
|||
static LRESULT WINAPI WndProcSub(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam, UINT_PTR uldSubclass, DWORD_PTR dwRefData)
|
||||
{
|
||||
struct message msg;
|
||||
|
||||
|
||||
if(message == WM_USER) {
|
||||
msg.wParam = wParam;
|
||||
msg.procnum = uldSubclass;
|
||||
add_message(&msg);
|
||||
|
||||
|
||||
if(lParam) {
|
||||
if(dwRefData & DELETE_SELF) {
|
||||
pRemoveWindowSubclass(hwnd, WndProcSub, uldSubclass);
|
||||
|
@ -275,20 +275,23 @@ static BOOL RegisterWindowClasses(void)
|
|||
cls.lpszMenuName = NULL;
|
||||
cls.lpszClassName = "TestSubclass";
|
||||
if(!RegisterClassA(&cls)) return FALSE;
|
||||
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
START_TEST(subclass)
|
||||
{
|
||||
HMODULE hdll;
|
||||
|
||||
|
||||
hdll = GetModuleHandleA("comctl32.dll");
|
||||
assert(hdll);
|
||||
pSetWindowSubclass = (void*)GetProcAddress(hdll, "SetWindowSubclass");
|
||||
pRemoveWindowSubclass = (void*)GetProcAddress(hdll, "RemoveWindowSubclass");
|
||||
pDefSubclassProc = (void*)GetProcAddress(hdll, "DefSubclassProc");
|
||||
|
||||
/* Functions have to be loaded by ordinal. Only XP and W2K3 export
|
||||
* them by name.
|
||||
*/
|
||||
pSetWindowSubclass = (void*)GetProcAddress(hdll, (LPSTR)410);
|
||||
pRemoveWindowSubclass = (void*)GetProcAddress(hdll, (LPSTR)412);
|
||||
pDefSubclassProc = (void*)GetProcAddress(hdll, (LPSTR)413);
|
||||
|
||||
if(!pSetWindowSubclass || !pRemoveWindowSubclass || !pDefSubclassProc)
|
||||
return;
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/* Unit test suite for tab control.
|
||||
*
|
||||
* Copyright 2003 Vitaliy Margolen
|
||||
* Copyright 2007 Hagop Hagopian
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -20,13 +21,24 @@
|
|||
#include <assert.h>
|
||||
#include <windows.h>
|
||||
#include <commctrl.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "wine/test.h"
|
||||
#include "msg.h"
|
||||
|
||||
#define DEFAULT_MIN_TAB_WIDTH 54
|
||||
#define TAB_DEFAULT_WIDTH 96
|
||||
#define TAB_PADDING_X 6
|
||||
#define EXTRA_ICON_PADDING 3
|
||||
#define MAX_TABLEN 32
|
||||
|
||||
#define NUM_MSG_SEQUENCES 2
|
||||
#define PARENT_SEQ_INDEX 0
|
||||
#define TAB_SEQ_INDEX 1
|
||||
|
||||
#define expect(expected, got) ok ( expected == got, "Expected %d, got %d\n", expected, got)
|
||||
#define expect_str(expected, got)\
|
||||
ok ( strcmp(expected, got) == 0, "Expected '%s', got '%s'\n", expected, got)
|
||||
|
||||
#define TabWidthPadded(padd_x, num) (DEFAULT_MIN_TAB_WIDTH - (TAB_PADDING_X - (padd_x)) * num)
|
||||
|
||||
|
@ -39,19 +51,222 @@
|
|||
#define CheckSize(hwnd,width,height,msg)\
|
||||
SendMessage (hwnd, TCM_GETITEMRECT, 0, (LPARAM) &rTab);\
|
||||
if ((width >= 0) && (height < 0))\
|
||||
ok (width == rTab.right - rTab.left, "%s: Expected width [%d] got [%ld]\n",\
|
||||
ok (width == rTab.right - rTab.left, "%s: Expected width [%d] got [%d]\n",\
|
||||
msg, (int)width, rTab.right - rTab.left);\
|
||||
else if ((height >= 0) && (width < 0))\
|
||||
ok (height == rTab.bottom - rTab.top, "%s: Expected height [%d] got [%ld]\n",\
|
||||
ok (height == rTab.bottom - rTab.top, "%s: Expected height [%d] got [%d]\n",\
|
||||
msg, (int)height, rTab.bottom - rTab.top);\
|
||||
else\
|
||||
ok ((width == rTab.right - rTab.left) &&\
|
||||
(height == rTab.bottom - rTab.top ),\
|
||||
"%s: Expected [%d,%d] got [%ld,%ld]\n", msg, (int)width, (int)height,\
|
||||
"%s: Expected [%d,%d] got [%d,%d]\n", msg, (int)width, (int)height,\
|
||||
rTab.right - rTab.left, rTab.bottom - rTab.top);
|
||||
|
||||
static HFONT hFont = 0;
|
||||
|
||||
static struct msg_sequence *sequences[NUM_MSG_SEQUENCES];
|
||||
|
||||
static const struct message create_parent_wnd_seq[] = {
|
||||
{ WM_GETMINMAXINFO, sent },
|
||||
{ WM_NCCREATE, sent },
|
||||
{ WM_NCCALCSIZE, sent|wparam, 0 },
|
||||
{ WM_CREATE, sent },
|
||||
{ WM_SHOWWINDOW, sent|wparam, 1 },
|
||||
{ WM_WINDOWPOSCHANGING, sent|wparam, 0 },
|
||||
{ WM_WINDOWPOSCHANGING, sent|wparam, 0 },
|
||||
{ WM_ACTIVATEAPP, sent|wparam, 1 },
|
||||
{ WM_NCACTIVATE, sent|wparam, 1 },
|
||||
{ WM_ACTIVATE, sent|wparam, 1 },
|
||||
{ WM_IME_SETCONTEXT, sent|wparam|defwinproc|optional, 1 },
|
||||
{ WM_IME_NOTIFY, sent|defwinproc|optional },
|
||||
{ WM_SETFOCUS, sent|wparam|defwinproc, 0 },
|
||||
/* Win9x adds SWP_NOZORDER below */
|
||||
{ WM_WINDOWPOSCHANGED, sent},
|
||||
{ WM_NCCALCSIZE, sent|wparam|optional, 1 },
|
||||
{ WM_SIZE, sent },
|
||||
{ WM_MOVE, sent },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message add_tab_to_parent[] = {
|
||||
{ TCM_INSERTITEMA, sent },
|
||||
{ TCM_INSERTITEMA, sent },
|
||||
{ WM_NOTIFYFORMAT, sent|defwinproc },
|
||||
{ WM_QUERYUISTATE, sent|wparam|lparam|defwinproc, 0, 0 },
|
||||
{ WM_PARENTNOTIFY, sent|defwinproc },
|
||||
{ TCM_INSERTITEMA, sent },
|
||||
{ TCM_INSERTITEMA, sent },
|
||||
{ TCM_INSERTITEMA, sent },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message add_tab_to_parent_interactive[] = {
|
||||
{ TCM_INSERTITEMA, sent },
|
||||
{ TCM_INSERTITEMA, sent },
|
||||
{ WM_NOTIFYFORMAT, sent|defwinproc },
|
||||
{ WM_QUERYUISTATE, sent|wparam|lparam|defwinproc, 0, 0 },
|
||||
{ WM_PARENTNOTIFY, sent|defwinproc },
|
||||
{ TCM_INSERTITEMA, sent },
|
||||
{ TCM_INSERTITEMA, sent },
|
||||
{ TCM_INSERTITEMA, sent },
|
||||
{ WM_SHOWWINDOW, sent},
|
||||
{ WM_WINDOWPOSCHANGING, sent},
|
||||
{ WM_WINDOWPOSCHANGING, sent},
|
||||
{ WM_NCACTIVATE, sent},
|
||||
{ WM_ACTIVATE, sent},
|
||||
{ WM_IME_SETCONTEXT, sent|defwinproc|optional},
|
||||
{ WM_IME_NOTIFY, sent|defwinproc|optional},
|
||||
{ WM_SETFOCUS, sent|defwinproc},
|
||||
{ WM_WINDOWPOSCHANGED, sent},
|
||||
{ WM_SIZE, sent},
|
||||
{ WM_MOVE, sent},
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message add_tab_control_parent_seq[] = {
|
||||
{ WM_NOTIFYFORMAT, sent },
|
||||
{ WM_QUERYUISTATE, sent|wparam|lparam, 0, 0 },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message add_tab_control_parent_seq_interactive[] = {
|
||||
{ WM_NOTIFYFORMAT, sent },
|
||||
{ WM_QUERYUISTATE, sent|wparam|lparam, 0, 0 },
|
||||
{ WM_WINDOWPOSCHANGING, sent|optional},
|
||||
{ WM_NCACTIVATE, sent},
|
||||
{ WM_ACTIVATE, sent},
|
||||
{ WM_WINDOWPOSCHANGING, sent|optional},
|
||||
{ WM_KILLFOCUS, sent},
|
||||
{ WM_IME_SETCONTEXT, sent|optional},
|
||||
{ WM_IME_NOTIFY, sent|optional},
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message empty_sequence[] = {
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message set_min_tab_width_seq[] = {
|
||||
{ TCM_SETMINTABWIDTH, sent|wparam, 0 },
|
||||
{ TCM_SETMINTABWIDTH, sent|wparam, 0 },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message get_item_count_seq[] = {
|
||||
{ TCM_GETITEMCOUNT, sent|wparam|lparam, 0, 0 },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message get_row_count_seq[] = {
|
||||
{ TCM_GETROWCOUNT, sent|wparam|lparam, 0, 0 },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message get_item_rect_seq[] = {
|
||||
{ TCM_GETITEMRECT, sent },
|
||||
{ TCM_GETITEMRECT, sent },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message getset_cur_focus_seq[] = {
|
||||
{ TCM_SETCURFOCUS, sent|lparam, 0 },
|
||||
{ TCM_GETCURFOCUS, sent|wparam|lparam, 0, 0 },
|
||||
{ TCM_SETCURFOCUS, sent|lparam, 0 },
|
||||
{ TCM_GETCURFOCUS, sent|wparam|lparam, 0, 0 },
|
||||
{ TCM_SETCURSEL, sent|lparam, 0 },
|
||||
{ TCM_SETCURFOCUS, sent|lparam, 0 },
|
||||
{ TCM_GETCURFOCUS, sent|wparam|lparam, 0, 0 },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message getset_cur_sel_seq[] = {
|
||||
{ TCM_SETCURSEL, sent|lparam, 0 },
|
||||
{ TCM_GETCURSEL, sent|wparam|lparam, 0, 0 },
|
||||
{ TCM_GETCURFOCUS, sent|wparam|lparam, 0, 0 },
|
||||
{ TCM_SETCURSEL, sent|lparam, 0 },
|
||||
{ TCM_GETCURSEL, sent|wparam|lparam, 0, 0 },
|
||||
{ TCM_SETCURSEL, sent|lparam, 0 },
|
||||
{ TCM_SETCURSEL, sent|lparam, 0 },
|
||||
{ TCM_GETCURFOCUS, sent|wparam|lparam, 0, 0 },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message getset_extended_style_seq[] = {
|
||||
{ TCM_GETEXTENDEDSTYLE, sent|wparam|lparam, 0, 0 },
|
||||
{ TCM_SETEXTENDEDSTYLE, sent },
|
||||
{ TCM_GETEXTENDEDSTYLE, sent|wparam|lparam, 0, 0 },
|
||||
{ TCM_SETEXTENDEDSTYLE, sent },
|
||||
{ TCM_GETEXTENDEDSTYLE, sent|wparam|lparam, 0, 0 },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message getset_unicode_format_seq[] = {
|
||||
{ CCM_SETUNICODEFORMAT, sent|lparam, 0 },
|
||||
{ CCM_GETUNICODEFORMAT, sent|wparam|lparam, 0, 0 },
|
||||
{ CCM_SETUNICODEFORMAT, sent|lparam, 0 },
|
||||
{ CCM_GETUNICODEFORMAT, sent|wparam|lparam, 0, 0 },
|
||||
{ CCM_SETUNICODEFORMAT, sent|lparam, 0 },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message getset_item_seq[] = {
|
||||
{ TCM_SETITEMA, sent },
|
||||
{ TCM_GETITEMA, sent },
|
||||
{ TCM_GETITEMA, sent },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message getset_tooltip_seq[] = {
|
||||
{ WM_NOTIFYFORMAT, sent },
|
||||
{ WM_QUERYUISTATE, sent|wparam|lparam, 0, 0 },
|
||||
{ WM_WINDOWPOSCHANGING, sent|wparam, 0 },
|
||||
{ WM_NOTIFYFORMAT, sent },
|
||||
{ TCM_SETTOOLTIPS, sent|lparam, 0 },
|
||||
{ TCM_GETTOOLTIPS, sent|wparam|lparam, 0, 0 },
|
||||
{ TCM_SETTOOLTIPS, sent|lparam, 0 },
|
||||
{ TCM_GETTOOLTIPS, sent|wparam|lparam, 0, 0 },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message getset_tooltip_parent_seq[] = {
|
||||
{ WM_WINDOWPOSCHANGING, sent|wparam, 0 },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message insert_focus_seq[] = {
|
||||
{ TCM_GETITEMCOUNT, sent|wparam|lparam, 0, 0 },
|
||||
{ TCM_GETCURFOCUS, sent|wparam|lparam, 0, 0 },
|
||||
{ TCM_INSERTITEM, sent|wparam, 1 },
|
||||
{ TCM_GETITEMCOUNT, sent|wparam|lparam, 0, 0 },
|
||||
{ TCM_GETCURFOCUS, sent|wparam|lparam, 0, 0 },
|
||||
{ TCM_INSERTITEM, sent|wparam, 2 },
|
||||
{ WM_NOTIFYFORMAT, sent|defwinproc, },
|
||||
{ WM_QUERYUISTATE, sent|defwinproc, },
|
||||
{ WM_PARENTNOTIFY, sent|defwinproc, },
|
||||
{ TCM_GETITEMCOUNT, sent|wparam|lparam, 0, 0 },
|
||||
{ TCM_GETCURFOCUS, sent|wparam|lparam, 0, 0 },
|
||||
{ TCM_SETCURFOCUS, sent|wparam|lparam, -1, 0 },
|
||||
{ TCM_GETCURFOCUS, sent|wparam|lparam, 0, 0 },
|
||||
{ TCM_INSERTITEM, sent|wparam, 3 },
|
||||
{ TCM_GETCURFOCUS, sent|wparam|lparam, 0, 0 },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message delete_focus_seq[] = {
|
||||
{ TCM_GETITEMCOUNT, sent|wparam|lparam, 0, 0 },
|
||||
{ TCM_GETCURFOCUS, sent|wparam|lparam, 0, 0 },
|
||||
{ TCM_DELETEITEM, sent|wparam|lparam, 1, 0 },
|
||||
{ TCM_GETITEMCOUNT, sent|wparam|lparam, 0, 0 },
|
||||
{ TCM_GETCURFOCUS, sent|wparam|lparam, 0, 0 },
|
||||
{ TCM_SETCURFOCUS, sent|wparam|lparam, -1, 0 },
|
||||
{ TCM_GETCURFOCUS, sent|wparam|lparam, 0, 0 },
|
||||
{ TCM_DELETEITEM, sent|wparam|lparam, 0, 0 },
|
||||
{ TCM_GETITEMCOUNT, sent|wparam|lparam, 0, 0 },
|
||||
{ TCM_GETCURFOCUS, sent|wparam|lparam, 0, 0 },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
|
||||
static HWND
|
||||
create_tabcontrol (DWORD style, DWORD mask)
|
||||
{
|
||||
|
@ -94,6 +309,195 @@ create_tabcontrol (DWORD style, DWORD mask)
|
|||
return handle;
|
||||
}
|
||||
|
||||
static LRESULT WINAPI parentWindowProcess(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
static long defwndproc_counter = 0;
|
||||
LRESULT ret;
|
||||
struct message msg;
|
||||
|
||||
/* do not log painting messages */
|
||||
if (message != WM_PAINT &&
|
||||
message != WM_ERASEBKGND &&
|
||||
message != WM_NCPAINT &&
|
||||
message != WM_NCHITTEST &&
|
||||
message != WM_GETTEXT &&
|
||||
message != WM_GETICON &&
|
||||
message != WM_DEVICECHANGE)
|
||||
{
|
||||
trace("parent: %p, %04x, %08lx, %08lx\n", hwnd, message, wParam, lParam);
|
||||
|
||||
msg.message = message;
|
||||
msg.flags = sent|wparam|lparam;
|
||||
if (defwndproc_counter) msg.flags |= defwinproc;
|
||||
msg.wParam = wParam;
|
||||
msg.lParam = lParam;
|
||||
add_message(sequences, PARENT_SEQ_INDEX, &msg);
|
||||
}
|
||||
|
||||
defwndproc_counter++;
|
||||
ret = DefWindowProcA(hwnd, message, wParam, lParam);
|
||||
defwndproc_counter--;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL registerParentWindowClass(void)
|
||||
{
|
||||
WNDCLASSA cls;
|
||||
|
||||
cls.style = 0;
|
||||
cls.lpfnWndProc = parentWindowProcess;
|
||||
cls.cbClsExtra = 0;
|
||||
cls.cbWndExtra = 0;
|
||||
cls.hInstance = GetModuleHandleA(NULL);
|
||||
cls.hIcon = 0;
|
||||
cls.hCursor = LoadCursorA(0, (LPSTR)IDC_ARROW);
|
||||
cls.hbrBackground = GetStockObject(WHITE_BRUSH);
|
||||
cls.lpszMenuName = NULL;
|
||||
cls.lpszClassName = "Tab test parent class";
|
||||
return RegisterClassA(&cls);
|
||||
}
|
||||
|
||||
static HWND createParentWindow(void)
|
||||
{
|
||||
if (!registerParentWindowClass())
|
||||
return NULL;
|
||||
|
||||
return CreateWindowEx(0, "Tab test parent class",
|
||||
"Tab test parent window",
|
||||
WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX |
|
||||
WS_MAXIMIZEBOX | WS_VISIBLE,
|
||||
0, 0, 100, 100,
|
||||
GetDesktopWindow(), NULL, GetModuleHandleA(NULL), NULL);
|
||||
}
|
||||
|
||||
struct subclass_info
|
||||
{
|
||||
WNDPROC oldproc;
|
||||
};
|
||||
|
||||
static LRESULT WINAPI tabSubclassProcess(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
struct subclass_info *info = (struct subclass_info *)GetWindowLongPtrA(hwnd, GWLP_USERDATA);
|
||||
static long defwndproc_counter = 0;
|
||||
LRESULT ret;
|
||||
struct message msg;
|
||||
|
||||
/* do not log painting messages */
|
||||
if (message != WM_PAINT &&
|
||||
message != WM_ERASEBKGND &&
|
||||
message != WM_NCPAINT &&
|
||||
message != WM_NCHITTEST &&
|
||||
message != WM_GETTEXT &&
|
||||
message != WM_GETICON &&
|
||||
message != WM_DEVICECHANGE)
|
||||
{
|
||||
trace("tab: %p, %04x, %08lx, %08lx\n", hwnd, message, wParam, lParam);
|
||||
|
||||
msg.message = message;
|
||||
msg.flags = sent|wparam|lparam;
|
||||
if (defwndproc_counter) msg.flags |= defwinproc;
|
||||
msg.wParam = wParam;
|
||||
msg.lParam = lParam;
|
||||
add_message(sequences, TAB_SEQ_INDEX, &msg);
|
||||
}
|
||||
|
||||
defwndproc_counter++;
|
||||
ret = CallWindowProcA(info->oldproc, hwnd, message, wParam, lParam);
|
||||
defwndproc_counter--;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static HWND createFilledTabControl(HWND parent_wnd, DWORD style, DWORD mask, INT nTabs)
|
||||
{
|
||||
HWND tabHandle;
|
||||
TCITEM tcNewTab;
|
||||
struct subclass_info *info;
|
||||
RECT rect;
|
||||
INT i;
|
||||
|
||||
info = HeapAlloc(GetProcessHeap(), 0, sizeof(struct subclass_info));
|
||||
if (!info)
|
||||
return NULL;
|
||||
|
||||
GetClientRect(parent_wnd, &rect);
|
||||
|
||||
tabHandle = CreateWindow (
|
||||
WC_TABCONTROLA,
|
||||
"TestTab",
|
||||
WS_CLIPSIBLINGS | WS_CLIPCHILDREN | TCS_FOCUSNEVER | style,
|
||||
0, 0, rect.right, rect.bottom,
|
||||
parent_wnd, NULL, NULL, 0);
|
||||
|
||||
assert(tabHandle);
|
||||
|
||||
info->oldproc = (WNDPROC)SetWindowLongPtrA(tabHandle, GWLP_WNDPROC, (LONG_PTR)tabSubclassProcess);
|
||||
SetWindowLongPtrA(tabHandle, GWLP_USERDATA, (LONG_PTR)info);
|
||||
|
||||
tcNewTab.mask = mask;
|
||||
|
||||
for (i = 0; i < nTabs; i++)
|
||||
{
|
||||
char tabName[MAX_TABLEN];
|
||||
|
||||
sprintf(tabName, "Tab %d", i+1);
|
||||
tcNewTab.pszText = tabName;
|
||||
tcNewTab.iImage = i;
|
||||
SendMessage (tabHandle, TCM_INSERTITEM, i, (LPARAM) &tcNewTab);
|
||||
}
|
||||
|
||||
if (winetest_interactive)
|
||||
{
|
||||
ShowWindow (tabHandle, SW_SHOW);
|
||||
RedrawWindow (tabHandle, NULL, 0, RDW_UPDATENOW);
|
||||
Sleep (1000);
|
||||
}
|
||||
|
||||
return tabHandle;
|
||||
}
|
||||
|
||||
static HWND create_tooltip (HWND hTab, char toolTipText[])
|
||||
{
|
||||
HWND hwndTT;
|
||||
|
||||
TOOLINFO ti;
|
||||
LPTSTR lptstr = toolTipText;
|
||||
RECT rect;
|
||||
|
||||
/* Creating a tooltip window*/
|
||||
hwndTT = CreateWindowEx(
|
||||
WS_EX_TOPMOST,
|
||||
TOOLTIPS_CLASS,
|
||||
NULL,
|
||||
WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP,
|
||||
CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
|
||||
hTab, NULL, 0, NULL);
|
||||
|
||||
SetWindowPos(
|
||||
hwndTT,
|
||||
HWND_TOPMOST,
|
||||
0, 0, 0, 0,
|
||||
SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
|
||||
|
||||
GetClientRect (hTab, &rect);
|
||||
|
||||
/* Initialize members of toolinfo*/
|
||||
ti.cbSize = sizeof(TOOLINFO);
|
||||
ti.uFlags = TTF_SUBCLASS;
|
||||
ti.hwnd = hTab;
|
||||
ti.hinst = 0;
|
||||
ti.uId = 0;
|
||||
ti.lpszText = lptstr;
|
||||
|
||||
ti.rect = rect;
|
||||
|
||||
/* Add toolinfo structure to the tooltip control */
|
||||
SendMessage(hwndTT, TTM_ADDTOOL, 0, (LPARAM) (LPTOOLINFO) &ti);
|
||||
|
||||
return hwndTT;
|
||||
}
|
||||
|
||||
static void test_tab(INT nMinTabWidth)
|
||||
{
|
||||
HWND hwTab;
|
||||
|
@ -110,7 +514,7 @@ static void test_tab(INT nMinTabWidth)
|
|||
hdc = GetDC(hwTab);
|
||||
hOldFont = SelectObject(hdc, (HFONT)SendMessage(hwTab, WM_GETFONT, 0, 0));
|
||||
GetTextExtentPoint32A(hdc, "Tab 1", strlen("Tab 1"), &size);
|
||||
trace("Tab1 text size: size.cx=%ld size.cy=%ld\n", size.cx, size.cy);
|
||||
trace("Tab1 text size: size.cx=%d size.cy=%d\n", size.cx, size.cy);
|
||||
SelectObject(hdc, hOldFont);
|
||||
ReleaseDC(hwTab, hdc);
|
||||
|
||||
|
@ -223,8 +627,338 @@ static void test_tab(INT nMinTabWidth)
|
|||
DeleteObject(hFont);
|
||||
}
|
||||
|
||||
static void test_getters_setters(HWND parent_wnd, INT nTabs)
|
||||
{
|
||||
HWND hTab;
|
||||
RECT rTab;
|
||||
INT nTabsRetrieved;
|
||||
INT rowCount;
|
||||
|
||||
ok(parent_wnd != NULL, "no parent window!\n");
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
|
||||
hTab = createFilledTabControl(parent_wnd, TCS_FIXEDWIDTH, TCIF_TEXT|TCIF_IMAGE, nTabs);
|
||||
ok(hTab != NULL, "Failed to create tab control\n");
|
||||
|
||||
if(!winetest_interactive)
|
||||
ok_sequence(sequences, TAB_SEQ_INDEX, add_tab_to_parent,
|
||||
"Tab sequence, after adding tab control to parent", TRUE);
|
||||
else
|
||||
ok_sequence(sequences, TAB_SEQ_INDEX, add_tab_to_parent_interactive,
|
||||
"Tab sequence, after adding tab control to parent", TRUE);
|
||||
|
||||
if(!winetest_interactive)
|
||||
ok_sequence(sequences, PARENT_SEQ_INDEX, add_tab_control_parent_seq,
|
||||
"Parent after sequence, adding tab control to parent", TRUE);
|
||||
else
|
||||
ok_sequence(sequences, PARENT_SEQ_INDEX, add_tab_control_parent_seq_interactive,
|
||||
"Parent after sequence, adding tab control to parent", TRUE);
|
||||
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
todo_wine{
|
||||
expect(DEFAULT_MIN_TAB_WIDTH, (int)SendMessage(hTab, TCM_SETMINTABWIDTH, 0, -1));
|
||||
}
|
||||
ok_sequence(sequences, TAB_SEQ_INDEX, set_min_tab_width_seq, "Set minTabWidth test sequence", FALSE);
|
||||
ok_sequence(sequences, PARENT_SEQ_INDEX, empty_sequence, "Set minTabWidth test parent sequence", FALSE);
|
||||
|
||||
/* Testing GetItemCount */
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
nTabsRetrieved = SendMessage(hTab, TCM_GETITEMCOUNT, 0, 0);
|
||||
expect(nTabs, nTabsRetrieved);
|
||||
ok_sequence(sequences, TAB_SEQ_INDEX, get_item_count_seq, "Get itemCount test sequence", FALSE);
|
||||
ok_sequence(sequences, PARENT_SEQ_INDEX, empty_sequence, "Getset itemCount test parent sequence", FALSE);
|
||||
|
||||
/* Testing GetRowCount */
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
rowCount = SendMessage(hTab, TCM_GETROWCOUNT, 0, 0);
|
||||
expect(1, rowCount);
|
||||
ok_sequence(sequences, TAB_SEQ_INDEX, get_row_count_seq, "Get rowCount test sequence", FALSE);
|
||||
ok_sequence(sequences, PARENT_SEQ_INDEX, empty_sequence, "Get rowCount test parent sequence", FALSE);
|
||||
|
||||
/* Testing GetItemRect */
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
ok(SendMessage(hTab, TCM_GETITEMRECT, 0, (LPARAM) &rTab), "GetItemRect failed.\n");
|
||||
CheckSize(hTab, TAB_DEFAULT_WIDTH, -1 , "Default Width");
|
||||
ok_sequence(sequences, TAB_SEQ_INDEX, get_item_rect_seq, "Get itemRect test sequence", FALSE);
|
||||
ok_sequence(sequences, PARENT_SEQ_INDEX, empty_sequence, "Get itemRect test parent sequence", FALSE);
|
||||
|
||||
/* Testing CurFocus */
|
||||
{
|
||||
INT focusIndex;
|
||||
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
|
||||
/* Testing CurFocus with largest appropriate value */
|
||||
SendMessage(hTab, TCM_SETCURFOCUS, nTabs-1, 0);
|
||||
focusIndex = SendMessage(hTab, TCM_GETCURFOCUS, 0, 0);
|
||||
expect(nTabs-1, focusIndex);
|
||||
|
||||
/* Testing CurFocus with negative value */
|
||||
SendMessage(hTab, TCM_SETCURFOCUS, -10, 0);
|
||||
focusIndex = SendMessage(hTab, TCM_GETCURFOCUS, 0, 0);
|
||||
expect(-1, focusIndex);
|
||||
|
||||
/* Testing CurFocus with value larger than number of tabs */
|
||||
focusIndex = SendMessage(hTab, TCM_SETCURSEL, 1, 0);
|
||||
todo_wine{
|
||||
expect(-1, focusIndex);
|
||||
}
|
||||
|
||||
SendMessage(hTab, TCM_SETCURFOCUS, nTabs+1, 0);
|
||||
focusIndex = SendMessage(hTab, TCM_GETCURFOCUS, 0, 0);
|
||||
expect(1, focusIndex);
|
||||
|
||||
ok_sequence(sequences, TAB_SEQ_INDEX, getset_cur_focus_seq, "Getset curFoc test sequence", FALSE);
|
||||
}
|
||||
|
||||
/* Testing CurSel */
|
||||
{
|
||||
INT selectionIndex;
|
||||
INT focusIndex;
|
||||
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
|
||||
/* Testing CurSel with largest appropriate value */
|
||||
selectionIndex = SendMessage(hTab, TCM_SETCURSEL, nTabs-1, 0);
|
||||
expect(1, selectionIndex);
|
||||
selectionIndex = SendMessage(hTab, TCM_GETCURSEL, 0, 0);
|
||||
expect(nTabs-1, selectionIndex);
|
||||
|
||||
/* Focus should switch with selection */
|
||||
focusIndex = SendMessage(hTab, TCM_GETCURFOCUS, 0, 0);
|
||||
expect(nTabs-1, focusIndex);
|
||||
|
||||
/* Testing CurSel with negative value */
|
||||
SendMessage(hTab, TCM_SETCURSEL, -10, 0);
|
||||
selectionIndex = SendMessage(hTab, TCM_GETCURSEL, 0, 0);
|
||||
expect(-1, selectionIndex);
|
||||
|
||||
/* Testing CurSel with value larger than number of tabs */
|
||||
selectionIndex = SendMessage(hTab, TCM_SETCURSEL, 1, 0);
|
||||
expect(-1, selectionIndex);
|
||||
|
||||
selectionIndex = SendMessage(hTab, TCM_SETCURSEL, nTabs+1, 0);
|
||||
expect(-1, selectionIndex);
|
||||
selectionIndex = SendMessage(hTab, TCM_GETCURFOCUS, 0, 0);
|
||||
expect(1, selectionIndex);
|
||||
|
||||
ok_sequence(sequences, TAB_SEQ_INDEX, getset_cur_sel_seq, "Getset curSel test sequence", FALSE);
|
||||
ok_sequence(sequences, PARENT_SEQ_INDEX, empty_sequence, "Getset curSel test parent sequence", FALSE);
|
||||
}
|
||||
|
||||
/* Testing ExtendedStyle */
|
||||
{
|
||||
DWORD prevExtendedStyle;
|
||||
DWORD extendedStyle;
|
||||
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
|
||||
/* Testing Flat Separators */
|
||||
extendedStyle = SendMessage(hTab, TCM_GETEXTENDEDSTYLE, 0, 0);
|
||||
prevExtendedStyle = SendMessage(hTab, TCM_SETEXTENDEDSTYLE, 0, TCS_EX_FLATSEPARATORS);
|
||||
expect(extendedStyle, prevExtendedStyle);
|
||||
|
||||
extendedStyle = SendMessage(hTab, TCM_GETEXTENDEDSTYLE, 0, 0);
|
||||
todo_wine{
|
||||
expect(TCS_EX_FLATSEPARATORS, extendedStyle);
|
||||
}
|
||||
|
||||
/* Testing Register Drop */
|
||||
prevExtendedStyle = SendMessage(hTab, TCM_SETEXTENDEDSTYLE, 0, TCS_EX_REGISTERDROP);
|
||||
expect(extendedStyle, prevExtendedStyle);
|
||||
|
||||
extendedStyle = SendMessage(hTab, TCM_GETEXTENDEDSTYLE, 0, 0);
|
||||
todo_wine{
|
||||
expect(TCS_EX_REGISTERDROP, extendedStyle);
|
||||
}
|
||||
|
||||
ok_sequence(sequences, TAB_SEQ_INDEX, getset_extended_style_seq, "Getset extendedStyle test sequence", FALSE);
|
||||
ok_sequence(sequences, PARENT_SEQ_INDEX, empty_sequence, "Getset extendedStyle test parent sequence", FALSE);
|
||||
}
|
||||
|
||||
/* Testing UnicodeFormat */
|
||||
{
|
||||
INT unicodeFormat;
|
||||
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
|
||||
unicodeFormat = SendMessage(hTab, TCM_SETUNICODEFORMAT, TRUE, 0);
|
||||
todo_wine{
|
||||
expect(0, unicodeFormat);
|
||||
}
|
||||
unicodeFormat = SendMessage(hTab, TCM_GETUNICODEFORMAT, 0, 0);
|
||||
expect(1, unicodeFormat);
|
||||
|
||||
unicodeFormat = SendMessage(hTab, TCM_SETUNICODEFORMAT, FALSE, 0);
|
||||
expect(1, unicodeFormat);
|
||||
unicodeFormat = SendMessage(hTab, TCM_GETUNICODEFORMAT, 0, 0);
|
||||
expect(0, unicodeFormat);
|
||||
|
||||
unicodeFormat = SendMessage(hTab, TCM_SETUNICODEFORMAT, TRUE, 0);
|
||||
expect(0, unicodeFormat);
|
||||
|
||||
ok_sequence(sequences, TAB_SEQ_INDEX, getset_unicode_format_seq, "Getset unicodeFormat test sequence", FALSE);
|
||||
ok_sequence(sequences, PARENT_SEQ_INDEX, empty_sequence, "Getset unicodeFormat test parent sequence", FALSE);
|
||||
}
|
||||
|
||||
/* Testing GetSet Item */
|
||||
{
|
||||
TCITEM tcItem;
|
||||
char szText[32] = "New Label";
|
||||
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
|
||||
tcItem.mask = TCIF_TEXT;
|
||||
tcItem.pszText = &szText[0];
|
||||
tcItem.cchTextMax = sizeof(szText);
|
||||
|
||||
ok ( SendMessage(hTab, TCM_SETITEM, 0, (LPARAM) &tcItem), "Setting new item failed.\n");
|
||||
ok ( SendMessage(hTab, TCM_GETITEM, 0, (LPARAM) &tcItem), "Getting item failed.\n");
|
||||
expect_str("New Label", tcItem.pszText);
|
||||
|
||||
ok ( SendMessage(hTab, TCM_GETITEM, 1, (LPARAM) &tcItem), "Getting item failed.\n");
|
||||
expect_str("Tab 2", tcItem.pszText);
|
||||
|
||||
ok_sequence(sequences, TAB_SEQ_INDEX, getset_item_seq, "Getset item test sequence", FALSE);
|
||||
ok_sequence(sequences, PARENT_SEQ_INDEX, empty_sequence, "Getset item test parent sequence", FALSE);
|
||||
}
|
||||
|
||||
/* Testing GetSet ToolTip */
|
||||
{
|
||||
HWND toolTip;
|
||||
char toolTipText[32] = "ToolTip Text Test";
|
||||
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
|
||||
toolTip = create_tooltip(hTab, toolTipText);
|
||||
SendMessage(hTab, TCM_SETTOOLTIPS, (LPARAM) toolTip, 0);
|
||||
ok (toolTip == (HWND) SendMessage(hTab,TCM_GETTOOLTIPS,0,0), "ToolTip was set incorrectly.\n");
|
||||
|
||||
SendMessage(hTab, TCM_SETTOOLTIPS, (LPARAM) NULL, 0);
|
||||
ok (NULL == (HWND) SendMessage(hTab,TCM_GETTOOLTIPS,0,0), "ToolTip was set incorrectly.\n");
|
||||
|
||||
ok_sequence(sequences, TAB_SEQ_INDEX, getset_tooltip_seq, "Getset tooltip test sequence", TRUE);
|
||||
ok_sequence(sequences, PARENT_SEQ_INDEX, getset_tooltip_parent_seq, "Getset tooltip test parent sequence", TRUE);
|
||||
}
|
||||
|
||||
DestroyWindow(hTab);
|
||||
}
|
||||
|
||||
static void test_insert_focus(HWND parent_wnd)
|
||||
{
|
||||
HWND hTab;
|
||||
INT nTabsRetrieved;
|
||||
INT r;
|
||||
TCITEM tcNewTab;
|
||||
DWORD mask = TCIF_TEXT|TCIF_IMAGE;
|
||||
static char tabName[] = "TAB";
|
||||
tcNewTab.mask = mask;
|
||||
tcNewTab.pszText = tabName;
|
||||
|
||||
ok(parent_wnd != NULL, "no parent window!\n");
|
||||
|
||||
hTab = createFilledTabControl(parent_wnd, TCS_FIXEDWIDTH, mask, 0);
|
||||
ok(hTab != NULL, "Failed to create tab control\n");
|
||||
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
|
||||
nTabsRetrieved = SendMessage(hTab, TCM_GETITEMCOUNT, 0, 0);
|
||||
expect(0, nTabsRetrieved);
|
||||
|
||||
r = SendMessage(hTab, TCM_GETCURFOCUS, 0, 0);
|
||||
expect(-1, r);
|
||||
|
||||
tcNewTab.iImage = 1;
|
||||
r = SendMessage(hTab, TCM_INSERTITEM, 1, (LPARAM) &tcNewTab);
|
||||
expect(0, r);
|
||||
|
||||
nTabsRetrieved = SendMessage(hTab, TCM_GETITEMCOUNT, 0, 0);
|
||||
expect(1, nTabsRetrieved);
|
||||
|
||||
r = SendMessage(hTab, TCM_GETCURFOCUS, 0, 0);
|
||||
expect(0, r);
|
||||
|
||||
tcNewTab.iImage = 2;
|
||||
r = SendMessage(hTab, TCM_INSERTITEM, 2, (LPARAM) &tcNewTab);
|
||||
expect(1, r);
|
||||
|
||||
nTabsRetrieved = SendMessage(hTab, TCM_GETITEMCOUNT, 0, 0);
|
||||
expect(2, nTabsRetrieved);
|
||||
|
||||
r = SendMessage(hTab, TCM_GETCURFOCUS, 0, 0);
|
||||
expect(0, r);
|
||||
|
||||
r = SendMessage(hTab, TCM_SETCURFOCUS, -1, 0);
|
||||
expect(0, r);
|
||||
|
||||
r = SendMessage(hTab, TCM_GETCURFOCUS, 0, 0);
|
||||
expect(-1, r);
|
||||
|
||||
tcNewTab.iImage = 3;
|
||||
r = SendMessage(hTab, TCM_INSERTITEM, 3, (LPARAM) &tcNewTab);
|
||||
expect(2, r);
|
||||
|
||||
r = SendMessage(hTab, TCM_GETCURFOCUS, 0, 0);
|
||||
expect(2, r);
|
||||
|
||||
ok_sequence(sequences, TAB_SEQ_INDEX, insert_focus_seq, "insert_focus test sequence", TRUE);
|
||||
ok_sequence(sequences, PARENT_SEQ_INDEX, empty_sequence, "insert_focus parent test sequence", FALSE);
|
||||
|
||||
DestroyWindow(hTab);
|
||||
}
|
||||
|
||||
static void test_delete_focus(HWND parent_wnd)
|
||||
{
|
||||
HWND hTab;
|
||||
INT nTabsRetrieved;
|
||||
INT r;
|
||||
|
||||
ok(parent_wnd != NULL, "no parent window!\n");
|
||||
|
||||
hTab = createFilledTabControl(parent_wnd, TCS_FIXEDWIDTH, TCIF_TEXT|TCIF_IMAGE, 2);
|
||||
ok(hTab != NULL, "Failed to create tab control\n");
|
||||
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
|
||||
nTabsRetrieved = SendMessage(hTab, TCM_GETITEMCOUNT, 0, 0);
|
||||
expect(2, nTabsRetrieved);
|
||||
|
||||
r = SendMessage(hTab, TCM_GETCURFOCUS, 0, 0);
|
||||
expect(0, r);
|
||||
|
||||
r = SendMessage(hTab, TCM_DELETEITEM, 1, 0);
|
||||
expect(1, r);
|
||||
|
||||
nTabsRetrieved = SendMessage(hTab, TCM_GETITEMCOUNT, 0, 0);
|
||||
expect(1, nTabsRetrieved);
|
||||
|
||||
r = SendMessage(hTab, TCM_GETCURFOCUS, 0, 0);
|
||||
expect(0, r);
|
||||
|
||||
r = SendMessage(hTab, TCM_SETCURFOCUS, -1, 0);
|
||||
expect(0, r);
|
||||
|
||||
r = SendMessage(hTab, TCM_GETCURFOCUS, 0, 0);
|
||||
expect(-1, r);
|
||||
|
||||
r = SendMessage(hTab, TCM_DELETEITEM, 0, 0);
|
||||
expect(1, r);
|
||||
|
||||
nTabsRetrieved = SendMessage(hTab, TCM_GETITEMCOUNT, 0, 0);
|
||||
expect(0, nTabsRetrieved);
|
||||
|
||||
r = SendMessage(hTab, TCM_GETCURFOCUS, 0, 0);
|
||||
expect(-1, r);
|
||||
|
||||
ok_sequence(sequences, TAB_SEQ_INDEX, delete_focus_seq, "delete_focus test sequence", FALSE);
|
||||
ok_sequence(sequences, PARENT_SEQ_INDEX, empty_sequence, "delete_focus parent test sequence", FALSE);
|
||||
|
||||
DestroyWindow(hTab);
|
||||
}
|
||||
|
||||
START_TEST(tab)
|
||||
{
|
||||
HWND parent_wnd;
|
||||
LOGFONTA logfont;
|
||||
|
||||
lstrcpyA(logfont.lfFaceName, "Arial");
|
||||
|
@ -246,4 +980,17 @@ START_TEST(tab)
|
|||
test_tab(54);
|
||||
trace ("Testing with MinWidth set to 94\n");
|
||||
test_tab(94);
|
||||
|
||||
init_msg_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
|
||||
parent_wnd = createParentWindow();
|
||||
ok(parent_wnd != NULL, "Failed to create parent window!\n");
|
||||
|
||||
/* Testing getters and setters with 5 tabs */
|
||||
test_getters_setters(parent_wnd, 5);
|
||||
|
||||
test_insert_focus(parent_wnd);
|
||||
test_delete_focus(parent_wnd);
|
||||
|
||||
DestroyWindow(parent_wnd);
|
||||
}
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
/* Automatically generated file; DO NOT EDIT!! */
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
|
||||
|
@ -5,36 +7,48 @@
|
|||
#include "wine/test.h"
|
||||
|
||||
extern void func_comboex(void);
|
||||
extern void func_datetime(void);
|
||||
extern void func_dpa(void);
|
||||
extern void func_header(void);
|
||||
extern void func_imagelist(void);
|
||||
extern void func_listview(void);
|
||||
extern void func_misc(void);
|
||||
extern void func_monthcal(void);
|
||||
extern void func_mru(void);
|
||||
extern void func_msg(void);
|
||||
extern void func_progress(void);
|
||||
extern void func_propsheet(void);
|
||||
extern void func_rebar(void);
|
||||
extern void func_status(void);
|
||||
extern void func_subclass(void);
|
||||
extern void func_tab(void);
|
||||
extern void func_toolbar(void);
|
||||
extern void func_tooltips(void);
|
||||
extern void func_trackbar(void);
|
||||
extern void func_treeview(void);
|
||||
extern void func_updown(void);
|
||||
|
||||
const struct test winetest_testlist[] =
|
||||
{
|
||||
{ "comboex", func_comboex },
|
||||
{ "datetime", func_datetime },
|
||||
{ "dpa", func_dpa },
|
||||
{ "header", func_header },
|
||||
{ "imagelist", func_imagelist },
|
||||
{ "listview", func_listview },
|
||||
{ "misc", func_misc },
|
||||
{ "monthcal", func_monthcal },
|
||||
{ "mru", func_mru },
|
||||
{ "msg", func_msg },
|
||||
{ "progress", func_progress },
|
||||
{ "propsheet", func_propsheet },
|
||||
{ "rebar", func_rebar },
|
||||
{ "status", func_status },
|
||||
{ "subclass", func_subclass },
|
||||
{ "tab", func_tab },
|
||||
{ "toolbar", func_toolbar },
|
||||
{ "tooltips", func_tooltips },
|
||||
{ "trackbar", func_trackbar },
|
||||
{ "treeview", func_treeview },
|
||||
{ "updown", func_updown },
|
||||
{ 0, 0 }
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -38,10 +38,10 @@ static void test_create_tooltip(void)
|
|||
assert(hwnd);
|
||||
|
||||
style = GetWindowLong(hwnd, GWL_STYLE);
|
||||
trace("style = %08lx\n", style);
|
||||
trace("style = %08x\n", style);
|
||||
exp_style = 0x7fffffff | WS_POPUP;
|
||||
exp_style &= ~(WS_CHILD | WS_MAXIMIZE | WS_BORDER | WS_DLGFRAME);
|
||||
ok(style == exp_style,"wrong style %08lx/%08lx\n", style, exp_style);
|
||||
ok(style == exp_style,"wrong style %08x/%08x\n", style, exp_style);
|
||||
|
||||
DestroyWindow(hwnd);
|
||||
|
||||
|
@ -51,9 +51,9 @@ static void test_create_tooltip(void)
|
|||
assert(hwnd);
|
||||
|
||||
style = GetWindowLong(hwnd, GWL_STYLE);
|
||||
trace("style = %08lx\n", style);
|
||||
trace("style = %08x\n", style);
|
||||
ok(style == (WS_POPUP | WS_CLIPSIBLINGS | WS_BORDER),
|
||||
"wrong style %08lx\n", style);
|
||||
"wrong style %08x\n", style);
|
||||
|
||||
DestroyWindow(hwnd);
|
||||
|
||||
|
|
1012
rostests/winetests/comctl32/trackbar.c
Normal file
1012
rostests/winetests/comctl32/trackbar.c
Normal file
File diff suppressed because it is too large
Load diff
|
@ -1,6 +1,7 @@
|
|||
/* Unit tests for treeview.
|
||||
*
|
||||
* Copyright 2005 Krzysztof Foltman
|
||||
* Copyright 2007 Christopher James Peterson
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -26,13 +27,167 @@
|
|||
#include "winuser.h"
|
||||
#include "winnls.h"
|
||||
#include "winreg.h"
|
||||
#include "commctrl.h"
|
||||
#include "commctrl.h"
|
||||
|
||||
#include "wine/test.h"
|
||||
#include "msg.h"
|
||||
|
||||
#define NUM_MSG_SEQUENCES 1
|
||||
#define LISTVIEW_SEQ_INDEX 0
|
||||
|
||||
static struct msg_sequence *MsgSequences[NUM_MSG_SEQUENCES];
|
||||
|
||||
static const struct message FillRootSeq[] = {
|
||||
{ TVM_INSERTITEM, sent },
|
||||
{ TVM_GETITEM, sent },
|
||||
{ TVM_INSERTITEM, sent },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message DoTest1Seq[] = {
|
||||
{ TVM_SELECTITEM, sent|wparam, 0x00000009 },
|
||||
{ TVM_SELECTITEM, sent|wparam, 0x00000009 },
|
||||
{ TVM_SELECTITEM, sent|wparam, 0x00000009 },
|
||||
{ TVM_SELECTITEM, sent|wparam, 0x00000009 },
|
||||
{ TVM_SELECTITEM, sent|wparam, 0x00000009 },
|
||||
{ TVM_SELECTITEM, sent|wparam, 0x00000009 },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message DoTest2Seq[] = {
|
||||
{ TVM_SELECTITEM, sent|wparam, 0x00000009 },
|
||||
{ TVM_SELECTITEM, sent|wparam, 0x00000009 },
|
||||
{ TVM_SELECTITEM, sent|wparam, 0x00000009 },
|
||||
{ TVM_SELECTITEM, sent|wparam, 0x00000009 },
|
||||
{ TVM_SELECTITEM, sent|wparam, 0x00000009 },
|
||||
{ TVM_SELECTITEM, sent|wparam, 0x00000009 },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message DoFocusTestSeq[] = {
|
||||
{ TVM_INSERTITEM, sent },
|
||||
{ TVM_INSERTITEM, sent },
|
||||
{ WM_WINDOWPOSCHANGING, sent|defwinproc },
|
||||
{ WM_NCCALCSIZE, sent|wparam|defwinproc, 0x00000001 },
|
||||
{ WM_WINDOWPOSCHANGED, sent|defwinproc },
|
||||
{ WM_SIZE, sent|defwinproc },
|
||||
{ WM_WINDOWPOSCHANGING, sent },
|
||||
{ WM_NCCALCSIZE, sent|wparam, 0x00000001 },
|
||||
{ WM_WINDOWPOSCHANGED, sent },
|
||||
{ WM_SIZE, sent|defwinproc },
|
||||
{ WM_WINDOWPOSCHANGING, sent|defwinproc },
|
||||
{ WM_NCCALCSIZE, sent|wparam|defwinproc, 0x00000001 },
|
||||
{ WM_WINDOWPOSCHANGED, sent|defwinproc },
|
||||
{ WM_SIZE, sent|defwinproc },
|
||||
{ TVM_SELECTITEM, sent|wparam, 0x00000009 },
|
||||
/* The following end up out of order in wine */
|
||||
{ WM_PAINT, sent|defwinproc },
|
||||
{ WM_NCPAINT, sent|wparam|defwinproc, 0x00000001 },
|
||||
{ WM_ERASEBKGND, sent|defwinproc },
|
||||
{ TVM_EDITLABEL, sent },
|
||||
{ WM_COMMAND, sent|wparam|defwinproc, 0x04000000 },
|
||||
{ WM_COMMAND, sent|wparam|defwinproc, 0x03000000 },
|
||||
{ WM_PARENTNOTIFY, sent|wparam|defwinproc, 0x00000001 },
|
||||
{ WM_KILLFOCUS, sent|defwinproc },
|
||||
{ WM_PAINT, sent|defwinproc },
|
||||
{ WM_IME_SETCONTEXT, sent|defwinproc|optional },
|
||||
{ WM_COMMAND, sent|wparam|defwinproc, 0x01000000},
|
||||
{ WM_ERASEBKGND, sent|defwinproc },
|
||||
{ WM_CTLCOLOREDIT, sent|defwinproc|optional },
|
||||
{ WM_CTLCOLOREDIT, sent|defwinproc|optional },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message TestGetSetBkColorSeq[] = {
|
||||
{ TVM_GETBKCOLOR, sent|wparam|lparam, 0x00000000, 0x00000000 },
|
||||
{ TVM_SETBKCOLOR, sent|wparam|lparam, 0x00000000, 0x00000000 },
|
||||
{ TVM_GETBKCOLOR, sent|wparam|lparam, 0x00000000, 0x00000000 },
|
||||
{ TVM_SETBKCOLOR, sent|wparam|lparam, 0x00000000, 0x00ffffff },
|
||||
{ TVM_GETBKCOLOR, sent|wparam|lparam, 0x00000000, 0x00000000 },
|
||||
{ TVM_SETBKCOLOR, sent|wparam|lparam, 0x00000000, 0xffffffff },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message TestGetSetImageListSeq[] = {
|
||||
{ TVM_SETIMAGELIST, sent|wparam|lparam, 0x00000000, 0x00000000 },
|
||||
{ TVM_GETIMAGELIST, sent|wparam|lparam, 0x00000000, 0x00000000 },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message TestGetSetIndentSeq[] = {
|
||||
{ TVM_SETINDENT, sent|wparam|lparam, 0x00000000, 0x00000000 },
|
||||
{ TVM_GETINDENT, sent|wparam|lparam, 0x00000000, 0x00000000 },
|
||||
/* The actual amount to indent is dependent on the system for this message */
|
||||
{ TVM_SETINDENT, sent },
|
||||
{ TVM_GETINDENT, sent|wparam|lparam, 0x00000000, 0x00000000 },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message TestGetSetInsertMarkColorSeq[] = {
|
||||
{ TVM_SETINSERTMARKCOLOR, sent|wparam|lparam, 0x00000000, 0x00000000 },
|
||||
{ TVM_GETINSERTMARKCOLOR, sent|wparam|lparam, 0x00000000, 0x00000000 },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message TestGetSetItemSeq[] = {
|
||||
{ TVM_GETITEM, sent },
|
||||
{ TVM_SETITEM, sent },
|
||||
{ TVM_GETITEM, sent },
|
||||
{ TVM_SETITEM, sent },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message TestGetSetItemHeightSeq[] = {
|
||||
{ TVM_GETITEMHEIGHT, sent|wparam|lparam, 0x00000000, 0x00000000 },
|
||||
{ TVM_SETITEMHEIGHT, sent|wparam|lparam, 0xffffffff, 0x00000000 },
|
||||
{ TVM_GETITEMHEIGHT, sent|wparam|lparam, 0x00000000, 0x00000000 },
|
||||
{ TVM_SETITEMHEIGHT, sent|lparam, 0xcccccccc, 0x00000000 },
|
||||
{ TVM_GETITEMHEIGHT, sent|wparam|lparam, 0x00000000, 0x00000000 },
|
||||
{ TVM_SETITEMHEIGHT, sent|wparam|lparam, 0x00000009, 0x00000000 },
|
||||
{ WM_WINDOWPOSCHANGING, sent|defwinproc },
|
||||
{ WM_NCCALCSIZE, sent|wparam|defwinproc, 0x00000001 },
|
||||
{ WM_WINDOWPOSCHANGED, sent|defwinproc },
|
||||
{ WM_SIZE, sent|defwinproc },
|
||||
{ TVM_GETITEMHEIGHT, sent|wparam|lparam, 0x00000000, 0x00000000 },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message TestGetSetScrollTimeSeq[] = {
|
||||
{ TVM_SETSCROLLTIME, sent|wparam|lparam, 0x00000014, 0x00000000 },
|
||||
{ TVM_GETSCROLLTIME, sent|wparam|lparam, 0x00000000, 0x00000000 },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message TestGetSetTextColorSeq[] = {
|
||||
{ TVM_GETTEXTCOLOR, sent|wparam|lparam, 0x00000000, 0x00000000 },
|
||||
{ TVM_SETTEXTCOLOR, sent|wparam|lparam, 0x00000000, 0x00000000 },
|
||||
{ TVM_GETTEXTCOLOR, sent|wparam|lparam, 0x00000000, 0x00000000 },
|
||||
{ TVM_SETTEXTCOLOR, sent|wparam|lparam, 0x00000000, 0x00ffffff },
|
||||
{ TVM_GETTEXTCOLOR, sent|wparam|lparam, 0x00000000, 0x00000000 },
|
||||
{ TVM_SETTEXTCOLOR, sent|wparam|lparam, 0x00000000, 0xffffffff },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message TestGetSetToolTipsSeq[] = {
|
||||
{ WM_COMMAND, sent|wparam, 0x02000000 },
|
||||
{ WM_PARENTNOTIFY, sent|wparam|defwinproc, 0x00020002 },
|
||||
{ TVM_SETTOOLTIPS, sent|wparam|lparam, 0x00000000, 0x00000000 },
|
||||
{ TVM_GETTOOLTIPS, sent|wparam|lparam, 0x00000000, 0x00000000 },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message TestGetSetUnicodeFormatSeq[] = {
|
||||
{ TVM_SETUNICODEFORMAT, sent|wparam|lparam, 0x00000001, 0x00000000 },
|
||||
{ TVM_GETUNICODEFORMAT, sent|wparam|lparam, 0x00000000, 0x00000000 },
|
||||
{ TVM_SETUNICODEFORMAT, sent|wparam|lparam, 0x00000000, 0x00000000 },
|
||||
{ TVM_GETUNICODEFORMAT, sent|wparam|lparam, 0x00000000, 0x00000000 },
|
||||
{ TVM_SETUNICODEFORMAT, sent|wparam|lparam, 0x00000000, 0x00000000 },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static HWND hMainWnd;
|
||||
|
||||
static HWND hTree;
|
||||
static HWND hTree, hEdit;
|
||||
static HTREEITEM hRoot, hChild;
|
||||
|
||||
static int pos = 0;
|
||||
|
@ -70,6 +225,7 @@ static void IdentifyItem(HTREEITEM hItem)
|
|||
static void FillRoot(void)
|
||||
{
|
||||
TVINSERTSTRUCTA ins;
|
||||
TVITEM tvi;
|
||||
static CHAR root[] = "Root",
|
||||
child[] = "Child";
|
||||
|
||||
|
@ -82,6 +238,13 @@ static void FillRoot(void)
|
|||
hRoot = TreeView_InsertItem(hTree, &ins);
|
||||
assert(hRoot);
|
||||
|
||||
/* UMLPad 1.15 depends on this being not -1 (I_IMAGECALLBACK) */
|
||||
tvi.hItem = hRoot;
|
||||
tvi.mask = TVIF_IMAGE | TVIF_SELECTEDIMAGE;
|
||||
SendMessage( hTree, TVM_GETITEM, 0, (LPARAM)&tvi );
|
||||
ok(tvi.iImage == 0, "tvi.iImage=%d\n", tvi.iImage);
|
||||
ok(tvi.iSelectedImage == 0, "tvi.iSelectedImage=%d\n", tvi.iSelectedImage);
|
||||
|
||||
AddItem('B');
|
||||
ins.hParent = hRoot;
|
||||
ins.hInsertAfter = TVI_FIRST;
|
||||
|
@ -132,23 +295,326 @@ static void DoTest2(void)
|
|||
ok(!strcmp(sequence, "1(nR)nR23(RC)RC45(CR)CR."), "root-child select test\n");
|
||||
}
|
||||
|
||||
LRESULT CALLBACK MyWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
static void DoFocusTest(void)
|
||||
{
|
||||
TVINSERTSTRUCTA ins;
|
||||
static CHAR child1[] = "Edit",
|
||||
child2[] = "A really long string";
|
||||
HTREEITEM hChild1, hChild2;
|
||||
|
||||
/* This test verifies that when a label is being edited, scrolling
|
||||
* the treeview does not cause the label to lose focus. To test
|
||||
* this, first some additional entries are added to generate
|
||||
* scrollbars.
|
||||
*/
|
||||
ins.hParent = hRoot;
|
||||
ins.hInsertAfter = hChild;
|
||||
U(ins).item.mask = TVIF_TEXT;
|
||||
U(ins).item.pszText = child1;
|
||||
hChild1 = TreeView_InsertItem(hTree, &ins);
|
||||
assert(hChild1);
|
||||
ins.hInsertAfter = hChild1;
|
||||
U(ins).item.mask = TVIF_TEXT;
|
||||
U(ins).item.pszText = child2;
|
||||
hChild2 = TreeView_InsertItem(hTree, &ins);
|
||||
assert(hChild2);
|
||||
|
||||
ShowWindow(hMainWnd,SW_SHOW);
|
||||
/* Using SendMessageA since Win98 doesn't have default unicode support */
|
||||
SendMessageA(hTree, TVM_SELECTITEM, TVGN_CARET, (LPARAM)hChild);
|
||||
hEdit = TreeView_EditLabel(hTree, hChild);
|
||||
ScrollWindowEx(hTree, -10, 0, NULL, NULL, NULL, NULL, SW_SCROLLCHILDREN);
|
||||
ok(GetFocus() == hEdit, "Edit control should have focus\n");
|
||||
}
|
||||
|
||||
static void TestGetSetBkColor(void)
|
||||
{
|
||||
COLORREF crColor = RGB(0,0,0);
|
||||
|
||||
todo_wine{
|
||||
/* If the value is -1, the control is using the system color for the background color. */
|
||||
crColor = (COLORREF)SendMessage( hTree, TVM_GETBKCOLOR, 0, 0 );
|
||||
ok(crColor == -1, "Default background color reported as 0x%.8x\n", crColor);
|
||||
}
|
||||
|
||||
/* Test for black background */
|
||||
SendMessage( hTree, TVM_SETBKCOLOR, 0, (LPARAM)RGB(0,0,0) );
|
||||
crColor = (COLORREF)SendMessage( hTree, TVM_GETBKCOLOR, 0, 0 );
|
||||
ok(crColor == RGB(0,0,0), "Black background color reported as 0x%.8x\n", crColor);
|
||||
|
||||
/* Test for white background */
|
||||
SendMessage( hTree, TVM_SETBKCOLOR, 0, (LPARAM)RGB(255,255,255) );
|
||||
crColor = (COLORREF)SendMessage( hTree, TVM_GETBKCOLOR, 0, 0 );
|
||||
ok(crColor == RGB(255,255,255), "White background color reported as 0x%.8x\n", crColor);
|
||||
|
||||
/* Reset the default background */
|
||||
SendMessage( hTree, TVM_SETBKCOLOR, 0, -1 );
|
||||
}
|
||||
|
||||
static void TestGetSetImageList(void)
|
||||
{
|
||||
HIMAGELIST hImageList = NULL;
|
||||
|
||||
/* Test a NULL HIMAGELIST */
|
||||
SendMessage( hTree, TVM_SETIMAGELIST, TVSIL_NORMAL, (LPARAM)hImageList );
|
||||
hImageList = (HIMAGELIST)SendMessage( hTree, TVM_GETIMAGELIST, TVSIL_NORMAL, 0 );
|
||||
ok(hImageList == NULL, "NULL image list, reported as 0x%p, expected 0.\n", hImageList);
|
||||
|
||||
/* TODO: Test an actual image list */
|
||||
}
|
||||
|
||||
static void TestGetSetIndent(void)
|
||||
{
|
||||
int ulIndent = -1;
|
||||
int ulMinIndent = -1;
|
||||
int ulMoreThanTwiceMin = -1;
|
||||
|
||||
/* Finding the minimum indent */
|
||||
SendMessage( hTree, TVM_SETINDENT, 0, 0 );
|
||||
ulMinIndent = (int)SendMessage( hTree, TVM_GETINDENT, 0, 0 );
|
||||
|
||||
/* Checking an indent that is more than twice the default indent */
|
||||
ulMoreThanTwiceMin = 2*ulMinIndent+1;
|
||||
SendMessage( hTree, TVM_SETINDENT, ulMoreThanTwiceMin, 0 );
|
||||
ulIndent = (DWORD)SendMessage( hTree, TVM_GETINDENT, 0, 0 );
|
||||
ok(ulIndent == ulMoreThanTwiceMin, "Indent reported as %d, expected %d\n", ulIndent, ulMoreThanTwiceMin);
|
||||
}
|
||||
|
||||
static void TestGetSetInsertMarkColor(void)
|
||||
{
|
||||
COLORREF crColor = RGB(0,0,0);
|
||||
SendMessage( hTree, TVM_SETINSERTMARKCOLOR, 0, crColor );
|
||||
crColor = (COLORREF)SendMessage( hTree, TVM_GETINSERTMARKCOLOR, 0, 0 );
|
||||
ok(crColor == RGB(0,0,0), "Insert mark color reported as 0x%.8x, expected 0x00000000\n", crColor);
|
||||
}
|
||||
|
||||
static void TestGetSetItem(void)
|
||||
{
|
||||
TVITEM tviRoot = {0};
|
||||
int nBufferSize = 80;
|
||||
char szBuffer[80] = {0};
|
||||
|
||||
/* Test the root item */
|
||||
tviRoot.hItem = hRoot;
|
||||
tviRoot.mask = TVIF_TEXT;
|
||||
tviRoot.cchTextMax = nBufferSize;
|
||||
tviRoot.pszText = szBuffer;
|
||||
SendMessage( hTree, TVM_GETITEM, 0, (LPARAM)&tviRoot );
|
||||
ok(!strcmp("Root", szBuffer), "GetItem: szBuffer=\"%s\", expected \"Root\"\n", szBuffer);
|
||||
|
||||
/* Change the root text */
|
||||
strncpy(szBuffer, "Testing123", nBufferSize);
|
||||
SendMessage( hTree, TVM_SETITEM, 0, (LPARAM)&tviRoot );
|
||||
memset(szBuffer, 0, nBufferSize);
|
||||
SendMessage( hTree, TVM_GETITEM, 0, (LPARAM)&tviRoot );
|
||||
ok(!strcmp("Testing123", szBuffer), "GetItem: szBuffer=\"%s\", expected \"Testing123\"\n", szBuffer);
|
||||
|
||||
/* Reset the root text */
|
||||
memset(szBuffer, 0, nBufferSize);
|
||||
strncpy(szBuffer, "Root", nBufferSize);
|
||||
SendMessage( hTree, TVM_SETITEM, 0, (LPARAM)&tviRoot );
|
||||
}
|
||||
|
||||
static void TestGetSetItemHeight(void)
|
||||
{
|
||||
int ulOldHeight = 0;
|
||||
int ulNewHeight = 0;
|
||||
|
||||
/* Assuming default height to begin with */
|
||||
ulOldHeight = (int) SendMessage( hTree, TVM_GETITEMHEIGHT, 0, 0 );
|
||||
|
||||
/* Explicitly setting and getting the default height */
|
||||
SendMessage( hTree, TVM_SETITEMHEIGHT, -1, 0 );
|
||||
ulNewHeight = (int) SendMessage( hTree, TVM_GETITEMHEIGHT, 0, 0 );
|
||||
ok(ulNewHeight == ulOldHeight, "Default height not set properly, reported %d, expected %d\n", ulNewHeight, ulOldHeight);
|
||||
|
||||
/* Explicitly setting and getting the height of twice the normal */
|
||||
SendMessage( hTree, TVM_SETITEMHEIGHT, 2*ulOldHeight, 0 );
|
||||
ulNewHeight = (int) SendMessage( hTree, TVM_GETITEMHEIGHT, 0, 0 );
|
||||
ok(ulNewHeight == 2*ulOldHeight, "New height not set properly, reported %d, expected %d\n", ulNewHeight, 2*ulOldHeight);
|
||||
|
||||
/* Assuming tree doesn't have TVS_NONEVENHEIGHT set, so a set of 9 will round down to 8 */
|
||||
SendMessage( hTree, TVM_SETITEMHEIGHT, 9, 0 );
|
||||
ulNewHeight = (int) SendMessage( hTree, TVM_GETITEMHEIGHT, 0, 0 );
|
||||
ok(ulNewHeight == 8, "Uneven height not set properly, reported %d, expected %d\n", ulNewHeight, 8);
|
||||
}
|
||||
|
||||
static void TestGetSetScrollTime(void)
|
||||
{
|
||||
int ulExpectedTime = 20;
|
||||
int ulTime = 0;
|
||||
SendMessage( hTree, TVM_SETSCROLLTIME, ulExpectedTime, 0 );
|
||||
ulTime = (int)SendMessage( hTree, TVM_GETSCROLLTIME, 0, 0 );
|
||||
ok(ulTime == ulExpectedTime, "Scroll time reported as %d, expected %d\n", ulTime, ulExpectedTime);
|
||||
}
|
||||
|
||||
static void TestGetSetTextColor(void)
|
||||
{
|
||||
/* If the value is -1, the control is using the system color for the text color. */
|
||||
COLORREF crColor = RGB(0,0,0);
|
||||
crColor = (COLORREF)SendMessage( hTree, TVM_GETTEXTCOLOR, 0, 0 );
|
||||
ok(crColor == -1, "Default text color reported as 0x%.8x\n", crColor);
|
||||
|
||||
/* Test for black text */
|
||||
SendMessage( hTree, TVM_SETTEXTCOLOR, 0, (LPARAM)RGB(0,0,0) );
|
||||
crColor = (COLORREF)SendMessage( hTree, TVM_GETTEXTCOLOR, 0, 0 );
|
||||
ok(crColor == RGB(0,0,0), "Black text color reported as 0x%.8x\n", crColor);
|
||||
|
||||
/* Test for white text */
|
||||
SendMessage( hTree, TVM_SETTEXTCOLOR, 0, (LPARAM)RGB(255,255,255) );
|
||||
crColor = (COLORREF)SendMessage( hTree, TVM_GETTEXTCOLOR, 0, 0 );
|
||||
ok(crColor == RGB(255,255,255), "White text color reported as 0x%.8x\n", crColor);
|
||||
|
||||
/* Reset the default text color */
|
||||
SendMessage( hTree, TVM_SETTEXTCOLOR, 0, -1 );
|
||||
}
|
||||
|
||||
static void TestGetSetToolTips(void)
|
||||
{
|
||||
HWND hwndLastToolTip = NULL;
|
||||
HWND hPopupTreeView;
|
||||
|
||||
/* show even WS_POPUP treeview don't send NM_TOOLTIPSCREATED */
|
||||
hPopupTreeView = CreateWindow(WC_TREEVIEW, NULL, WS_POPUP|WS_VISIBLE, 0, 0, 100, 100, hMainWnd, NULL, NULL, NULL);
|
||||
DestroyWindow(hPopupTreeView);
|
||||
|
||||
/* Testing setting a NULL ToolTip */
|
||||
SendMessage( hTree, TVM_SETTOOLTIPS, 0, 0 );
|
||||
hwndLastToolTip = (HWND)SendMessage( hTree, TVM_GETTOOLTIPS, 0, 0 );
|
||||
ok(hwndLastToolTip == NULL, "NULL tool tip, reported as 0x%p, expected 0.\n", hwndLastToolTip);
|
||||
|
||||
/* TODO: Add a test of an actual tooltip */
|
||||
}
|
||||
|
||||
static void TestGetSetUnicodeFormat(void)
|
||||
{
|
||||
BOOL bPreviousSetting = 0;
|
||||
BOOL bNewSetting = 0;
|
||||
|
||||
/* Set to Unicode */
|
||||
bPreviousSetting = (BOOL)SendMessage( hTree, TVM_SETUNICODEFORMAT, 1, 0 );
|
||||
bNewSetting = (BOOL)SendMessage( hTree, TVM_GETUNICODEFORMAT, 0, 0 );
|
||||
ok(bNewSetting == 1, "Unicode setting did not work.\n");
|
||||
|
||||
/* Set to ANSI */
|
||||
SendMessage( hTree, TVM_SETUNICODEFORMAT, 0, 0 );
|
||||
bNewSetting = (BOOL)SendMessage( hTree, TVM_GETUNICODEFORMAT, 0, 0 );
|
||||
ok(bNewSetting == 0, "ANSI setting did not work.\n");
|
||||
|
||||
/* Revert to original setting */
|
||||
SendMessage( hTree, TVM_SETUNICODEFORMAT, (LPARAM)bPreviousSetting, 0 );
|
||||
}
|
||||
|
||||
static void TestGetSet(void)
|
||||
{
|
||||
/* TVM_GETBKCOLOR and TVM_SETBKCOLOR */
|
||||
flush_sequences(MsgSequences, NUM_MSG_SEQUENCES);
|
||||
TestGetSetBkColor();
|
||||
ok_sequence(MsgSequences, LISTVIEW_SEQ_INDEX, TestGetSetBkColorSeq,
|
||||
"TestGetSetBkColor", FALSE);
|
||||
|
||||
/* TVM_GETIMAGELIST and TVM_SETIMAGELIST */
|
||||
flush_sequences(MsgSequences, NUM_MSG_SEQUENCES);
|
||||
TestGetSetImageList();
|
||||
ok_sequence(MsgSequences, LISTVIEW_SEQ_INDEX, TestGetSetImageListSeq,
|
||||
"TestGetImageList", FALSE);
|
||||
|
||||
/* TVM_SETINDENT and TVM_GETINDENT */
|
||||
flush_sequences(MsgSequences, NUM_MSG_SEQUENCES);
|
||||
TestGetSetIndent();
|
||||
ok_sequence(MsgSequences, LISTVIEW_SEQ_INDEX, TestGetSetIndentSeq,
|
||||
"TestGetSetIndent", FALSE);
|
||||
|
||||
/* TVM_GETINSERTMARKCOLOR and TVM_GETINSERTMARKCOLOR */
|
||||
flush_sequences(MsgSequences, NUM_MSG_SEQUENCES);
|
||||
TestGetSetInsertMarkColor();
|
||||
ok_sequence(MsgSequences, LISTVIEW_SEQ_INDEX, TestGetSetInsertMarkColorSeq,
|
||||
"TestGetSetInsertMarkColor", FALSE);
|
||||
|
||||
/* TVM_GETITEM and TVM_SETITEM */
|
||||
flush_sequences(MsgSequences, NUM_MSG_SEQUENCES);
|
||||
TestGetSetItem();
|
||||
ok_sequence(MsgSequences, LISTVIEW_SEQ_INDEX, TestGetSetItemSeq,
|
||||
"TestGetSetItem", FALSE);
|
||||
|
||||
/* TVM_GETITEMHEIGHT and TVM_SETITEMHEIGHT */
|
||||
flush_sequences(MsgSequences, NUM_MSG_SEQUENCES);
|
||||
TestGetSetItemHeight();
|
||||
ok_sequence(MsgSequences, LISTVIEW_SEQ_INDEX, TestGetSetItemHeightSeq,
|
||||
"TestGetSetItemHeight", FALSE);
|
||||
|
||||
/* TVM_GETSCROLLTIME and TVM_SETSCROLLTIME */
|
||||
flush_sequences(MsgSequences, NUM_MSG_SEQUENCES);
|
||||
TestGetSetScrollTime();
|
||||
ok_sequence(MsgSequences, LISTVIEW_SEQ_INDEX, TestGetSetScrollTimeSeq,
|
||||
"TestGetSetScrollTime", FALSE);
|
||||
|
||||
/* TVM_GETTEXTCOLOR and TVM_SETTEXTCOLOR */
|
||||
flush_sequences(MsgSequences, NUM_MSG_SEQUENCES);
|
||||
TestGetSetTextColor();
|
||||
ok_sequence(MsgSequences, LISTVIEW_SEQ_INDEX, TestGetSetTextColorSeq,
|
||||
"TestGetSetTextColor", FALSE);
|
||||
|
||||
/* TVM_GETTOOLTIPS and TVM_SETTOOLTIPS */
|
||||
flush_sequences(MsgSequences, NUM_MSG_SEQUENCES);
|
||||
TestGetSetToolTips();
|
||||
ok_sequence(MsgSequences, LISTVIEW_SEQ_INDEX, TestGetSetToolTipsSeq,
|
||||
"TestGetSetToolTips", TRUE);
|
||||
|
||||
/* TVM_GETUNICODEFORMAT and TVM_SETUNICODEFORMAT */
|
||||
flush_sequences(MsgSequences, NUM_MSG_SEQUENCES);
|
||||
TestGetSetUnicodeFormat();
|
||||
ok_sequence(MsgSequences, LISTVIEW_SEQ_INDEX, TestGetSetUnicodeFormatSeq,
|
||||
"TestGetSetUnicodeFormat", FALSE);
|
||||
}
|
||||
|
||||
/* This function hooks in and records all messages to the treeview control */
|
||||
static LRESULT WINAPI TreeviewWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
static long defwndproc_counter = 0;
|
||||
LRESULT ret;
|
||||
struct message msg;
|
||||
WNDPROC lpOldProc = (WNDPROC)GetWindowLongPtrA(hwnd, GWLP_USERDATA);
|
||||
|
||||
msg.message = message;
|
||||
msg.flags = sent|wparam|lparam;
|
||||
if (defwndproc_counter) msg.flags |= defwinproc;
|
||||
msg.wParam = wParam;
|
||||
msg.lParam = lParam;
|
||||
add_message(MsgSequences, LISTVIEW_SEQ_INDEX, &msg);
|
||||
|
||||
defwndproc_counter++;
|
||||
ret = CallWindowProcA(lpOldProc, hwnd, message, wParam, lParam);
|
||||
defwndproc_counter--;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static LRESULT CALLBACK MyWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
WNDPROC pOldWndProc;
|
||||
|
||||
switch(msg) {
|
||||
|
||||
case WM_CREATE:
|
||||
{
|
||||
hTree = CreateWindowExA(WS_EX_CLIENTEDGE, WC_TREEVIEWA, NULL, WS_CHILD|WS_VISIBLE|
|
||||
TVS_LINESATROOT|TVS_HASLINES|TVS_HASBUTTONS,
|
||||
0, 0, 300, 50, hWnd, (HMENU)100, GetModuleHandleA(0), 0);
|
||||
TVS_LINESATROOT|TVS_HASLINES|TVS_HASBUTTONS|TVS_EDITLABELS,
|
||||
0, 0, 120, 100, hWnd, (HMENU)100, GetModuleHandleA(0), 0);
|
||||
|
||||
SetFocus(hTree);
|
||||
|
||||
/* Record the old WNDPROC so we can call it after recording the messages */
|
||||
pOldWndProc = (WNDPROC)SetWindowLongPtrA(hTree, GWLP_WNDPROC, (LONG_PTR)TreeviewWndProc);
|
||||
SetWindowLongPtrA(hTree, GWLP_USERDATA, (LONG_PTR)pOldWndProc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
case WM_NOTIFY:
|
||||
{
|
||||
NMHDR *pHdr = (NMHDR *)lParam;
|
||||
|
||||
|
||||
ok(pHdr->code != NM_FIRST - 19, "Treeview should not send NM_TOOLTIPSCREATED\n");
|
||||
if (pHdr->idFrom == 100) {
|
||||
NMTREEVIEWA *pTreeView = (LPNMTREEVIEWA) lParam;
|
||||
switch(pHdr->code) {
|
||||
|
@ -166,15 +632,15 @@ LRESULT CALLBACK MyWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
case WM_SIZE:
|
||||
MoveWindow(hTree, 0, 0, LOWORD(lParam), HIWORD(lParam), TRUE);
|
||||
break;
|
||||
|
||||
|
||||
case WM_DESTROY:
|
||||
PostQuitMessage(0);
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
return DefWindowProcA(hWnd, msg, wParam, lParam);
|
||||
}
|
||||
|
@ -186,18 +652,18 @@ START_TEST(treeview)
|
|||
WNDCLASSA wc;
|
||||
MSG msg;
|
||||
INITCOMMONCONTROLSEX icex;
|
||||
RECT rc;
|
||||
|
||||
|
||||
icex.dwSize = sizeof(INITCOMMONCONTROLSEX);
|
||||
icex.dwICC = ICC_TREEVIEW_CLASSES;
|
||||
InitCommonControlsEx(&icex);
|
||||
|
||||
init_msg_sequences(MsgSequences, NUM_MSG_SEQUENCES);
|
||||
|
||||
wc.style = CS_HREDRAW | CS_VREDRAW;
|
||||
wc.cbClsExtra = 0;
|
||||
wc.cbWndExtra = 0;
|
||||
wc.hInstance = GetModuleHandleA(NULL);
|
||||
wc.hIcon = NULL;
|
||||
wc.hCursor = LoadCursorA(NULL, MAKEINTRESOURCEA(IDC_IBEAM));
|
||||
wc.hCursor = LoadCursorA(NULL, IDC_IBEAM);
|
||||
wc.hbrBackground = GetSysColorBrush(COLOR_WINDOW);
|
||||
wc.lpszMenuName = NULL;
|
||||
wc.lpszClassName = "MyTestWnd";
|
||||
|
@ -206,12 +672,29 @@ START_TEST(treeview)
|
|||
|
||||
|
||||
hMainWnd = CreateWindowExA(0, "MyTestWnd", "Blah", WS_OVERLAPPEDWINDOW,
|
||||
CW_USEDEFAULT, CW_USEDEFAULT, 680, 260, NULL, NULL, GetModuleHandleA(NULL), 0);
|
||||
GetClientRect(hMainWnd, &rc);
|
||||
CW_USEDEFAULT, CW_USEDEFAULT, 130, 105, NULL, NULL, GetModuleHandleA(NULL), 0);
|
||||
|
||||
if ( !ok(hMainWnd != NULL, "Failed to create parent window. Tests aborted.\n") )
|
||||
return;
|
||||
|
||||
flush_sequences(MsgSequences, NUM_MSG_SEQUENCES);
|
||||
FillRoot();
|
||||
ok_sequence(MsgSequences, LISTVIEW_SEQ_INDEX, FillRootSeq, "FillRoot", FALSE);
|
||||
|
||||
flush_sequences(MsgSequences, NUM_MSG_SEQUENCES);
|
||||
DoTest1();
|
||||
ok_sequence(MsgSequences, LISTVIEW_SEQ_INDEX, DoTest1Seq, "DoTest1", FALSE);
|
||||
|
||||
flush_sequences(MsgSequences, NUM_MSG_SEQUENCES);
|
||||
DoTest2();
|
||||
ok_sequence(MsgSequences, LISTVIEW_SEQ_INDEX, DoTest2Seq, "DoTest2", FALSE);
|
||||
|
||||
flush_sequences(MsgSequences, NUM_MSG_SEQUENCES);
|
||||
DoFocusTest();
|
||||
ok_sequence(MsgSequences, LISTVIEW_SEQ_INDEX, DoFocusTestSeq, "DoFocusTest", TRUE);
|
||||
|
||||
/* Sequences tested inside due to number */
|
||||
TestGetSet();
|
||||
|
||||
PostMessageA(hMainWnd, WM_CLOSE, 0, 0);
|
||||
while(GetMessageA(&msg,0,0,0)) {
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
/* Unit test suite for updown control.
|
||||
/* Unit tests for the up-down control
|
||||
*
|
||||
* Copyright 2005 C. Scott Ananian
|
||||
* Copyright (C) 2007 James Hawkins
|
||||
* Copyright (C) 2007 Leslie Choong
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -17,82 +19,574 @@
|
|||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
/* TO TEST:
|
||||
* - send click messages to the up-down control, check the current position
|
||||
* - up-down control automatically positions itself next to its buddy window
|
||||
* - up-down control sets the caption of the buddy window
|
||||
* - test CreateUpDownControl API
|
||||
* - check UDS_AUTOBUDDY style, up-down control selects previous window in z-order
|
||||
* - check UDM_SETBUDDY message
|
||||
* - check UDM_GETBUDDY message
|
||||
* - up-down control and buddy control must have the same parent
|
||||
* - up-down control notifies its parent window when its position changes with UDN_DELTAPOS + WM_VSCROLL or WM_HSCROLL
|
||||
* - check UDS_ALIGN[LEFT,RIGHT]...check that width of buddy window is decreased
|
||||
* - check that UDS_SETBUDDYINT sets the caption of the buddy window when it is changed
|
||||
* - check that the thousands operator is set for large numbers
|
||||
* - check that the thousands operator is not set with UDS_NOTHOUSANDS
|
||||
* - check UDS_ARROWKEYS, control subclasses the buddy window so that it processes the keys when it has focus
|
||||
* - check UDS_HORZ
|
||||
* - check changing past min/max values
|
||||
* - check UDS_WRAP wraps values past min/max, incrementing past upper value wraps position to lower value
|
||||
* - can change control's position, min/max pos, radix
|
||||
* - check UDM_GETPOS, for up-down control with a buddy window, position is the caption of the buddy window, so change the
|
||||
* caption of the buddy window then call UDM_GETPOS
|
||||
* - check UDM_SETRANGE, max can be less than min, so clicking the up arrow decreases the current position
|
||||
* - more stuff to test
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <windows.h>
|
||||
#include <commctrl.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "wine/test.h"
|
||||
#include "msg.h"
|
||||
|
||||
static HDC desktopDC;
|
||||
static HINSTANCE hinst;
|
||||
#define expect(EXPECTED,GOT) ok((GOT)==(EXPECTED), "Expected %d, got %d\n", (EXPECTED), (GOT))
|
||||
|
||||
static HWND create_edit_control (DWORD style, DWORD exstyle)
|
||||
#define NUM_MSG_SEQUENCES 3
|
||||
#define PARENT_SEQ_INDEX 0
|
||||
#define EDIT_SEQ_INDEX 1
|
||||
#define UPDOWN_SEQ_INDEX 2
|
||||
|
||||
static HWND parent_wnd, edit, updown;
|
||||
|
||||
static struct msg_sequence *sequences[NUM_MSG_SEQUENCES];
|
||||
|
||||
static const struct message create_parent_wnd_seq[] = {
|
||||
{ WM_GETMINMAXINFO, sent },
|
||||
{ WM_NCCREATE, sent },
|
||||
{ WM_NCCALCSIZE, sent|wparam, 0 },
|
||||
{ WM_CREATE, sent },
|
||||
{ WM_SHOWWINDOW, sent|wparam, 1 },
|
||||
{ WM_WINDOWPOSCHANGING, sent|wparam, 0 },
|
||||
{ WM_WINDOWPOSCHANGING, sent|wparam, 0 },
|
||||
{ WM_ACTIVATEAPP, sent|wparam, 1 },
|
||||
{ WM_NCACTIVATE, sent|wparam, 1 },
|
||||
{ WM_ACTIVATE, sent|wparam, 1 },
|
||||
{ WM_IME_SETCONTEXT, sent|wparam|defwinproc|optional, 1 },
|
||||
{ WM_IME_NOTIFY, sent|defwinproc|optional },
|
||||
{ WM_SETFOCUS, sent|wparam|defwinproc, 0 },
|
||||
/* Win9x adds SWP_NOZORDER below */
|
||||
{ WM_WINDOWPOSCHANGED, sent, /*|wparam, SWP_SHOWWINDOW|SWP_NOSIZE|SWP_NOMOVE|SWP_NOCLIENTSIZE|SWP_NOCLIENTMOVE*/ },
|
||||
{ WM_NCCALCSIZE, sent|wparam|optional, 1 },
|
||||
{ WM_SIZE, sent },
|
||||
{ WM_MOVE, sent },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message add_edit_to_parent_seq[] = {
|
||||
{ WM_PARENTNOTIFY, sent|wparam, WM_CREATE },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message add_updown_with_edit_seq[] = {
|
||||
{ WM_WINDOWPOSCHANGING, sent },
|
||||
{ WM_NCCALCSIZE, sent|wparam, TRUE },
|
||||
{ WM_WINDOWPOSCHANGED, sent },
|
||||
{ WM_SIZE, sent|wparam|defwinproc, SIZE_RESTORED /*, MAKELONG(91, 75) exact size depends on font */ },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message add_updown_to_parent_seq[] = {
|
||||
{ WM_NOTIFYFORMAT, sent|lparam, 0, NF_QUERY },
|
||||
{ WM_QUERYUISTATE, sent },
|
||||
{ WM_PARENTNOTIFY, sent|wparam, MAKELONG(WM_CREATE, WM_CREATE) },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message get_edit_text_seq[] = {
|
||||
{ WM_GETTEXT, sent },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message test_updown_pos_seq[] = {
|
||||
{ UDM_SETRANGE, sent|lparam, 0, MAKELONG(100,0) },
|
||||
{ UDM_GETRANGE, sent},
|
||||
{ UDM_SETPOS, sent|lparam, 0, 5},
|
||||
{ UDM_GETPOS, sent},
|
||||
{ UDM_SETPOS, sent|lparam, 0, 0},
|
||||
{ UDM_GETPOS, sent},
|
||||
{ UDM_SETPOS, sent|lparam, 0, MAKELONG(-1,0)},
|
||||
{ UDM_GETPOS, sent},
|
||||
{ UDM_SETPOS, sent|lparam, 0, 100},
|
||||
{ UDM_GETPOS, sent},
|
||||
{ UDM_SETPOS, sent|lparam, 0, 101},
|
||||
{ UDM_GETPOS, sent},
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message test_updown_pos32_seq[] = {
|
||||
{ UDM_SETRANGE32, sent|lparam, 0, 1000 },
|
||||
{ UDM_GETRANGE32, sent}, /* Cannot check wparam and lparam as they are ptrs */
|
||||
{ UDM_SETPOS32, sent|lparam, 0, 500 },
|
||||
{ UDM_GETPOS32, sent},
|
||||
{ UDM_SETPOS32, sent|lparam, 0, 0 },
|
||||
{ UDM_GETPOS32, sent},
|
||||
{ UDM_SETPOS32, sent|lparam, 0, -1 },
|
||||
{ UDM_GETPOS32, sent},
|
||||
{ UDM_SETPOS32, sent|lparam, 0, 1000 },
|
||||
{ UDM_GETPOS32, sent},
|
||||
{ UDM_SETPOS32, sent|lparam, 0, 1001 },
|
||||
{ UDM_GETPOS32, sent},
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message test_updown_buddy_seq[] = {
|
||||
{ UDM_GETBUDDY, sent },
|
||||
{ UDM_SETBUDDY, sent },
|
||||
{ WM_STYLECHANGING, sent|defwinproc },
|
||||
{ WM_STYLECHANGED, sent|defwinproc },
|
||||
{ WM_STYLECHANGING, sent|defwinproc },
|
||||
{ WM_STYLECHANGED, sent|defwinproc },
|
||||
{ WM_WINDOWPOSCHANGING, sent|defwinproc },
|
||||
{ WM_NCCALCSIZE, sent|wparam|optional|defwinproc, 1 },
|
||||
{ WM_WINDOWPOSCHANGED, sent|defwinproc },
|
||||
{ WM_MOVE, sent|defwinproc },
|
||||
{ UDM_GETBUDDY, sent },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message test_updown_base_seq[] = {
|
||||
{ UDM_SETBASE, sent|wparam, 10 },
|
||||
{ UDM_GETBASE, sent },
|
||||
{ UDM_SETBASE, sent|wparam, 80 },
|
||||
{ UDM_GETBASE, sent },
|
||||
{ UDM_SETBASE, sent|wparam, 16 },
|
||||
{ UDM_GETBASE, sent },
|
||||
{ UDM_SETBASE, sent|wparam, 80 },
|
||||
{ UDM_GETBASE, sent },
|
||||
{ UDM_SETBASE, sent|wparam, 10 },
|
||||
{ UDM_GETBASE, sent },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message test_updown_unicode_seq[] = {
|
||||
{ UDM_SETUNICODEFORMAT, sent|wparam, 0 },
|
||||
{ UDM_GETUNICODEFORMAT, sent },
|
||||
{ UDM_SETUNICODEFORMAT, sent|wparam, 1 },
|
||||
{ UDM_GETUNICODEFORMAT, sent },
|
||||
{ UDM_SETUNICODEFORMAT, sent|wparam, 0 },
|
||||
{ UDM_GETUNICODEFORMAT, sent },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message test_updown_destroy_seq[] = {
|
||||
{ WM_SHOWWINDOW, sent|wparam|lparam, 0, 0 },
|
||||
{ WM_WINDOWPOSCHANGING, sent},
|
||||
{ WM_WINDOWPOSCHANGED, sent},
|
||||
{ WM_DESTROY, sent},
|
||||
{ WM_NCDESTROY, sent},
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static LRESULT WINAPI parent_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
HWND handle;
|
||||
static long defwndproc_counter = 0;
|
||||
LRESULT ret;
|
||||
struct message msg;
|
||||
|
||||
handle = CreateWindowEx(exstyle,
|
||||
"EDIT",
|
||||
NULL,
|
||||
ES_AUTOHSCROLL | ES_AUTOVSCROLL | style,
|
||||
10, 10, 300, 300,
|
||||
NULL, NULL, hinst, NULL);
|
||||
assert (handle);
|
||||
if (winetest_interactive)
|
||||
ShowWindow (handle, SW_SHOW);
|
||||
return handle;
|
||||
/* do not log painting messages */
|
||||
if (message != WM_PAINT &&
|
||||
message != WM_ERASEBKGND &&
|
||||
message != WM_NCPAINT &&
|
||||
message != WM_NCHITTEST &&
|
||||
message != WM_GETTEXT &&
|
||||
message != WM_GETICON &&
|
||||
message != WM_DEVICECHANGE)
|
||||
{
|
||||
trace("parent: %p, %04x, %08lx, %08lx\n", hwnd, message, wParam, lParam);
|
||||
|
||||
msg.message = message;
|
||||
msg.flags = sent|wparam|lparam;
|
||||
if (defwndproc_counter) msg.flags |= defwinproc;
|
||||
msg.wParam = wParam;
|
||||
msg.lParam = lParam;
|
||||
add_message(sequences, PARENT_SEQ_INDEX, &msg);
|
||||
}
|
||||
|
||||
defwndproc_counter++;
|
||||
ret = DefWindowProcA(hwnd, message, wParam, lParam);
|
||||
defwndproc_counter--;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static HWND create_updown_control (HWND hWndEdit)
|
||||
static BOOL register_parent_wnd_class(void)
|
||||
{
|
||||
HWND hWndUpDown;
|
||||
WNDCLASSA cls;
|
||||
|
||||
/* make the control */
|
||||
hWndUpDown = CreateWindowEx
|
||||
(0L, UPDOWN_CLASS, NULL,
|
||||
/* window styles */
|
||||
UDS_SETBUDDYINT | UDS_ALIGNRIGHT |
|
||||
UDS_ARROWKEYS | UDS_NOTHOUSANDS,
|
||||
/* placement */
|
||||
0, 0, 8, 8,
|
||||
/* parent, etc */
|
||||
NULL, NULL, hinst, NULL);
|
||||
assert (hWndUpDown);
|
||||
/* set the buddy. */
|
||||
SendMessage (hWndUpDown, UDM_SETBUDDY, (WPARAM)hWndEdit, 0L );
|
||||
/* set the range. */
|
||||
SendMessage (hWndUpDown, UDM_SETRANGE, 0L, (LPARAM) MAKELONG(32000, 0));
|
||||
/* maybe show it. */
|
||||
if (winetest_interactive)
|
||||
ShowWindow (hWndUpDown, SW_SHOW);
|
||||
return hWndUpDown;
|
||||
cls.style = 0;
|
||||
cls.lpfnWndProc = parent_wnd_proc;
|
||||
cls.cbClsExtra = 0;
|
||||
cls.cbWndExtra = 0;
|
||||
cls.hInstance = GetModuleHandleA(NULL);
|
||||
cls.hIcon = 0;
|
||||
cls.hCursor = LoadCursorA(0, (LPSTR)IDC_ARROW);
|
||||
cls.hbrBackground = GetStockObject(WHITE_BRUSH);
|
||||
cls.lpszMenuName = NULL;
|
||||
cls.lpszClassName = "Up-Down test parent class";
|
||||
return RegisterClassA(&cls);
|
||||
}
|
||||
|
||||
static void test_updown_control (void)
|
||||
static HWND create_parent_window(void)
|
||||
{
|
||||
HWND hWndUpDown, hWndEdit;
|
||||
int num;
|
||||
if (!register_parent_wnd_class())
|
||||
return NULL;
|
||||
|
||||
hWndEdit = create_edit_control (ES_AUTOHSCROLL | ES_NUMBER, 0);
|
||||
hWndUpDown = create_updown_control (hWndEdit);
|
||||
/* before we set a value, it should be '0' */
|
||||
num = SendMessage(hWndUpDown, UDM_GETPOS, 0, 0L);
|
||||
ok(num == 0, "Expected 0 got %d\n", num);
|
||||
/* set a value, check it. */
|
||||
SendMessage(hWndUpDown, UDM_SETPOS, 0L, MAKELONG( 1, 0));
|
||||
num = SendMessage(hWndUpDown, UDM_GETPOS, 0, 0L);
|
||||
ok(num == 1, "Expected 1 got %d\n", num);
|
||||
/* okay, done (short set of tests!) */
|
||||
DestroyWindow(hWndUpDown);
|
||||
DestroyWindow(hWndEdit);
|
||||
return CreateWindowEx(0, "Up-Down test parent class",
|
||||
"Up-Down test parent window",
|
||||
WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX |
|
||||
WS_MAXIMIZEBOX | WS_VISIBLE,
|
||||
0, 0, 100, 100,
|
||||
GetDesktopWindow(), NULL, GetModuleHandleA(NULL), NULL);
|
||||
}
|
||||
|
||||
struct subclass_info
|
||||
{
|
||||
WNDPROC oldproc;
|
||||
};
|
||||
|
||||
static LRESULT WINAPI edit_subclass_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
struct subclass_info *info = (struct subclass_info *)GetWindowLongPtrA(hwnd, GWLP_USERDATA);
|
||||
static long defwndproc_counter = 0;
|
||||
LRESULT ret;
|
||||
struct message msg;
|
||||
|
||||
trace("edit: %p, %04x, %08lx, %08lx\n", hwnd, message, wParam, lParam);
|
||||
|
||||
msg.message = message;
|
||||
msg.flags = sent|wparam|lparam;
|
||||
if (defwndproc_counter) msg.flags |= defwinproc;
|
||||
msg.wParam = wParam;
|
||||
msg.lParam = lParam;
|
||||
add_message(sequences, EDIT_SEQ_INDEX, &msg);
|
||||
|
||||
defwndproc_counter++;
|
||||
ret = CallWindowProcA(info->oldproc, hwnd, message, wParam, lParam);
|
||||
defwndproc_counter--;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static HWND create_edit_control(void)
|
||||
{
|
||||
struct subclass_info *info;
|
||||
RECT rect;
|
||||
|
||||
info = HeapAlloc(GetProcessHeap(), 0, sizeof(struct subclass_info));
|
||||
if (!info)
|
||||
return NULL;
|
||||
|
||||
GetClientRect(parent_wnd, &rect);
|
||||
edit = CreateWindowExA(0, "EDIT", NULL, WS_CHILD | WS_BORDER | WS_VISIBLE,
|
||||
0, 0, rect.right, rect.bottom,
|
||||
parent_wnd, NULL, GetModuleHandleA(NULL), NULL);
|
||||
if (!edit)
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, info);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
info->oldproc = (WNDPROC)SetWindowLongPtrA(edit, GWLP_WNDPROC,
|
||||
(LONG_PTR)edit_subclass_proc);
|
||||
SetWindowLongPtrA(edit, GWLP_USERDATA, (LONG_PTR)info);
|
||||
|
||||
return edit;
|
||||
}
|
||||
|
||||
static LRESULT WINAPI updown_subclass_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
struct subclass_info *info = (struct subclass_info *)GetWindowLongPtrA(hwnd, GWLP_USERDATA);
|
||||
static long defwndproc_counter = 0;
|
||||
LRESULT ret;
|
||||
struct message msg;
|
||||
|
||||
trace("updown: %p, %04x, %08lx, %08lx\n", hwnd, message, wParam, lParam);
|
||||
|
||||
msg.message = message;
|
||||
msg.flags = sent|wparam|lparam;
|
||||
if (defwndproc_counter) msg.flags |= defwinproc;
|
||||
msg.wParam = wParam;
|
||||
msg.lParam = lParam;
|
||||
add_message(sequences, UPDOWN_SEQ_INDEX, &msg);
|
||||
|
||||
defwndproc_counter++;
|
||||
ret = CallWindowProcA(info->oldproc, hwnd, message, wParam, lParam);
|
||||
defwndproc_counter--;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static HWND create_updown_control(void)
|
||||
{
|
||||
struct subclass_info *info;
|
||||
HWND updown;
|
||||
RECT rect;
|
||||
|
||||
info = HeapAlloc(GetProcessHeap(), 0, sizeof(struct subclass_info));
|
||||
if (!info)
|
||||
return NULL;
|
||||
|
||||
GetClientRect(parent_wnd, &rect);
|
||||
updown = CreateUpDownControl(WS_CHILD | WS_BORDER | WS_VISIBLE | UDS_ALIGNRIGHT,
|
||||
0, 0, rect.right, rect.bottom, parent_wnd, 1, GetModuleHandleA(NULL), edit,
|
||||
100, 0, 50);
|
||||
if (!updown)
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, info);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
info->oldproc = (WNDPROC)SetWindowLongPtrA(updown, GWLP_WNDPROC,
|
||||
(LONG_PTR)updown_subclass_proc);
|
||||
SetWindowLongPtrA(updown, GWLP_USERDATA, (LONG_PTR)info);
|
||||
|
||||
return updown;
|
||||
}
|
||||
|
||||
static void test_updown_pos(void)
|
||||
{
|
||||
int r;
|
||||
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
|
||||
/* Set Range from 0 to 100 */
|
||||
SendMessage(updown, UDM_SETRANGE, 0 , MAKELONG(100,0) );
|
||||
r = SendMessage(updown, UDM_GETRANGE, 0,0);
|
||||
expect(100,LOWORD(r));
|
||||
expect(0,HIWORD(r));
|
||||
|
||||
/* Set the position to 5, return is not checked as it was set before func call */
|
||||
SendMessage(updown, UDM_SETPOS, 0 , MAKELONG(5,0) );
|
||||
/* Since UDM_SETBUDDYINT was not set at creation HIWORD(r) will always be 1 as a return from UDM_GETPOS */
|
||||
/* Get the position, which should be 5 */
|
||||
r = SendMessage(updown, UDM_GETPOS, 0 , 0 );
|
||||
expect(5,LOWORD(r));
|
||||
expect(1,HIWORD(r));
|
||||
|
||||
/* Set the position to 0, return should be 5 */
|
||||
r = SendMessage(updown, UDM_SETPOS, 0 , MAKELONG(0,0) );
|
||||
expect(5,r);
|
||||
/* Get the position, which should be 0 */
|
||||
r = SendMessage(updown, UDM_GETPOS, 0 , 0 );
|
||||
expect(0,LOWORD(r));
|
||||
expect(1,HIWORD(r));
|
||||
|
||||
/* Set the position to -1, return should be 0 */
|
||||
r = SendMessage(updown, UDM_SETPOS, 0 , MAKELONG(-1,0) );
|
||||
expect(0,r);
|
||||
/* Get the position, which should be 0 */
|
||||
r = SendMessage(updown, UDM_GETPOS, 0 , 0 );
|
||||
expect(0,LOWORD(r));
|
||||
expect(1,HIWORD(r));
|
||||
|
||||
/* Set the position to 100, return should be 0 */
|
||||
r = SendMessage(updown, UDM_SETPOS, 0 , MAKELONG(100,0) );
|
||||
expect(0,r);
|
||||
/* Get the position, which should be 100 */
|
||||
r = SendMessage(updown, UDM_GETPOS, 0 , 0 );
|
||||
expect(100,LOWORD(r));
|
||||
expect(1,HIWORD(r));
|
||||
|
||||
/* Set the position to 101, return should be 100 */
|
||||
r = SendMessage(updown, UDM_SETPOS, 0 , MAKELONG(101,0) );
|
||||
expect(100,r);
|
||||
/* Get the position, which should be 100 */
|
||||
r = SendMessage(updown, UDM_GETPOS, 0 , 0 );
|
||||
expect(100,LOWORD(r));
|
||||
expect(1,HIWORD(r));
|
||||
|
||||
ok_sequence(sequences, UPDOWN_SEQ_INDEX, test_updown_pos_seq , "test updown pos", FALSE);
|
||||
}
|
||||
|
||||
static void test_updown_pos32(void)
|
||||
{
|
||||
int r;
|
||||
int low, high;
|
||||
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
|
||||
/* Set the position to 0 to 1000 */
|
||||
SendMessage(updown, UDM_SETRANGE32, 0 , 1000 );
|
||||
|
||||
r = SendMessage(updown, UDM_GETRANGE32, (WPARAM) &low , (LPARAM) &high );
|
||||
expect(0,low);
|
||||
expect(1000,high);
|
||||
|
||||
/* Set position to 500, don't check return since it is unset*/
|
||||
SendMessage(updown, UDM_SETPOS32, 0 , 500 );
|
||||
|
||||
/* Since UDM_SETBUDDYINT was not set at creation bRet will always be true as a return from UDM_GETPOS32 */
|
||||
|
||||
r = SendMessage(updown, UDM_GETPOS32, 0 , (LPARAM) &high );
|
||||
expect(500,r);
|
||||
expect(1,high);
|
||||
|
||||
/* Set position to 0, return should be 500 */
|
||||
r = SendMessage(updown, UDM_SETPOS32, 0 , 0 );
|
||||
expect(500,r);
|
||||
r = SendMessage(updown, UDM_GETPOS32, 0 , (LPARAM) &high );
|
||||
expect(0,r);
|
||||
expect(1,high);
|
||||
|
||||
/* Set position to -1 which should become 0, return should be 0 */
|
||||
r = SendMessage(updown, UDM_SETPOS32, 0 , -1 );
|
||||
expect(0,r);
|
||||
r = SendMessage(updown, UDM_GETPOS32, 0 , (LPARAM) &high );
|
||||
expect(0,r);
|
||||
expect(1,high);
|
||||
|
||||
/* Set position to 1000, return should be 0 */
|
||||
r = SendMessage(updown, UDM_SETPOS32, 0 , 1000 );
|
||||
expect(0,r);
|
||||
r = SendMessage(updown, UDM_GETPOS32, 0 , (LPARAM) &high );
|
||||
expect(1000,r);
|
||||
expect(1,high);
|
||||
|
||||
/* Set position to 1001 which should become 1000, return should be 1000 */
|
||||
r = SendMessage(updown, UDM_SETPOS32, 0 , 1001 );
|
||||
expect(1000,r);
|
||||
r = SendMessage(updown, UDM_GETPOS32, 0 , (LPARAM) &high );
|
||||
expect(1000,r);
|
||||
expect(1,high);
|
||||
|
||||
ok_sequence(sequences, UPDOWN_SEQ_INDEX, test_updown_pos32_seq, "test updown pos32", FALSE);
|
||||
}
|
||||
|
||||
static void test_updown_buddy(void)
|
||||
{
|
||||
HWND buddyReturn;
|
||||
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
|
||||
buddyReturn = (HWND)SendMessage(updown, UDM_GETBUDDY, 0 , 0 );
|
||||
ok(buddyReturn == edit, "Expected edit handle\n");
|
||||
|
||||
buddyReturn = (HWND)SendMessage(updown, UDM_SETBUDDY, (WPARAM) edit, 0);
|
||||
ok(buddyReturn == edit, "Expected edit handle\n");
|
||||
|
||||
buddyReturn = (HWND)SendMessage(updown, UDM_GETBUDDY, 0 , 0 );
|
||||
ok(buddyReturn == edit, "Expected edit handle\n");
|
||||
|
||||
ok_sequence(sequences, UPDOWN_SEQ_INDEX, test_updown_buddy_seq, "test updown buddy", TRUE);
|
||||
ok_sequence(sequences, EDIT_SEQ_INDEX, add_updown_with_edit_seq, "test updown buddy_edit", FALSE);
|
||||
}
|
||||
|
||||
static void test_updown_base(void)
|
||||
{
|
||||
int r;
|
||||
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
|
||||
SendMessage(updown, UDM_SETBASE, 10 , 0);
|
||||
r = SendMessage(updown, UDM_GETBASE, 0 , 0);
|
||||
expect(10,r);
|
||||
|
||||
/* Set base to an invalid value, should return 0 and stay at 10 */
|
||||
r = SendMessage(updown, UDM_SETBASE, 80 , 0);
|
||||
expect(0,r);
|
||||
r = SendMessage(updown, UDM_GETBASE, 0 , 0);
|
||||
expect(10,r);
|
||||
|
||||
/* Set base to 16 now, should get 16 as the return */
|
||||
r = SendMessage(updown, UDM_SETBASE, 16 , 0);
|
||||
expect(10,r);
|
||||
r = SendMessage(updown, UDM_GETBASE, 0 , 0);
|
||||
expect(16,r);
|
||||
|
||||
/* Set base to an invalid value, should return 0 and stay at 16 */
|
||||
r = SendMessage(updown, UDM_SETBASE, 80 , 0);
|
||||
expect(0,r);
|
||||
r = SendMessage(updown, UDM_GETBASE, 0 , 0);
|
||||
expect(16,r);
|
||||
|
||||
/* Set base back to 10, return should be 16 */
|
||||
r = SendMessage(updown, UDM_SETBASE, 10 , 0);
|
||||
expect(16,r);
|
||||
r = SendMessage(updown, UDM_GETBASE, 0 , 0);
|
||||
expect(10,r);
|
||||
|
||||
ok_sequence(sequences, UPDOWN_SEQ_INDEX, test_updown_base_seq, "test updown base", FALSE);
|
||||
}
|
||||
|
||||
static void test_updown_unicode(void)
|
||||
{
|
||||
int r;
|
||||
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
|
||||
/* Set it to ANSI, don't check return as we don't know previous state */
|
||||
SendMessage(updown, UDM_SETUNICODEFORMAT, 0 , 0);
|
||||
r = SendMessage(updown, UDM_GETUNICODEFORMAT, 0 , 0);
|
||||
expect(0,r);
|
||||
|
||||
/* Now set it to Unicode format */
|
||||
r = SendMessage(updown, UDM_SETUNICODEFORMAT, 1 , 0);
|
||||
expect(0,r);
|
||||
r = SendMessage(updown, UDM_GETUNICODEFORMAT, 0 , 0);
|
||||
expect(1,r);
|
||||
|
||||
/* And now set it back to ANSI */
|
||||
r = SendMessage(updown, UDM_SETUNICODEFORMAT, 0 , 0);
|
||||
expect(1,r);
|
||||
r = SendMessage(updown, UDM_GETUNICODEFORMAT, 0 , 0);
|
||||
expect(0,r);
|
||||
|
||||
ok_sequence(sequences, UPDOWN_SEQ_INDEX, test_updown_unicode_seq, "test updown unicode", FALSE);
|
||||
}
|
||||
|
||||
|
||||
static void test_create_updown_control(void)
|
||||
{
|
||||
CHAR text[MAX_PATH];
|
||||
|
||||
parent_wnd = create_parent_window();
|
||||
ok(parent_wnd != NULL, "Failed to create parent window!\n");
|
||||
ok_sequence(sequences, PARENT_SEQ_INDEX, create_parent_wnd_seq, "create parent window", TRUE);
|
||||
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
|
||||
edit = create_edit_control();
|
||||
ok(edit != NULL, "Failed to create edit control\n");
|
||||
ok_sequence(sequences, PARENT_SEQ_INDEX, add_edit_to_parent_seq, "add edit control to parent", FALSE);
|
||||
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
|
||||
updown = create_updown_control();
|
||||
ok(updown != NULL, "Failed to create updown control\n");
|
||||
ok_sequence(sequences, PARENT_SEQ_INDEX, add_updown_to_parent_seq, "add updown control to parent", TRUE);
|
||||
ok_sequence(sequences, EDIT_SEQ_INDEX, add_updown_with_edit_seq, "add updown control with edit", FALSE);
|
||||
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
|
||||
GetWindowTextA(edit, text, MAX_PATH);
|
||||
ok(lstrlenA(text) == 0, "Expected empty string\n");
|
||||
ok_sequence(sequences, EDIT_SEQ_INDEX, get_edit_text_seq, "get edit text", FALSE);
|
||||
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
|
||||
test_updown_pos();
|
||||
test_updown_pos32();
|
||||
test_updown_buddy();
|
||||
test_updown_base();
|
||||
test_updown_unicode();
|
||||
}
|
||||
|
||||
START_TEST(updown)
|
||||
{
|
||||
desktopDC=GetDC(NULL);
|
||||
hinst = GetModuleHandleA(NULL);
|
||||
|
||||
InitCommonControls();
|
||||
init_msg_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
|
||||
test_updown_control();
|
||||
test_create_updown_control();
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue