[COMCTL32_WINETEST] Sync with Wine 3.0. CORE-14225

This commit is contained in:
Amine Khaldi 2018-01-18 23:49:50 +01:00
parent edd99e8ccc
commit 0d320bc25f
18 changed files with 7665 additions and 1221 deletions

View file

@ -1,16 +1,18 @@
remove_definitions(-D_WIN32_WINNT=0x502 -D_WIN32_IE=0x600)
add_definitions(-DUSE_WINE_TODOS)
add_definitions(-DUSE_WINE_TODOS -DWINETEST_USE_DBGSTR_LONGLONG)
list(APPEND SOURCE
animate.c
comboex.c
combo.c
datetime.c
dpa.c
edit.c
header.c
imagelist.c
ipaddress.c
listbox.c
listview.c
misc.c
monthcal.c
@ -19,6 +21,7 @@ list(APPEND SOURCE
progress.c
propsheet.c
rebar.c
static.c
status.c
syslink.c
tab.c
@ -43,5 +46,10 @@ endif()
set_module_type(comctl32_winetest win32cui)
add_importlibs(comctl32_winetest comctl32 ole32 user32 gdi32 advapi32 msvcrt kernel32)
if(MSVC)
add_importlibs(comctl32_winetest ntdll)
endif()
add_pch(comctl32_winetest precomp.h SOURCE)
add_rostests_file(TARGET comctl32_winetest)

File diff suppressed because it is too large Load diff

View file

@ -1,608 +0,0 @@
/* Unit test suite for comboex control.
*
* Copyright 2005 Jason Edmeades
*
* 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 "precomp.h"
#define EDITBOX_SEQ_INDEX 0
#define NUM_MSG_SEQUENCES 1
#define EDITBOX_ID 0
#define expect(expected, got) ok(got == expected, "Expected %d, got %d\n", expected, got)
static struct msg_sequence *sequences[NUM_MSG_SEQUENCES];
static HWND hComboExParentWnd;
static HINSTANCE hMainHinst;
static const char ComboExTestClass[] = "ComboExTestClass";
static BOOL (WINAPI *pSetWindowSubclass)(HWND, SUBCLASSPROC, UINT_PTR, DWORD_PTR);
#define MAX_CHARS 100
static char *textBuffer = NULL;
static BOOL received_end_edit = FALSE;
static HWND createComboEx(DWORD style) {
return CreateWindowExA(0, WC_COMBOBOXEXA, NULL, style, 0, 0, 300, 300,
hComboExParentWnd, NULL, hMainHinst, NULL);
}
static LONG addItem(HWND cbex, int idx, const char *text) {
COMBOBOXEXITEMA cbexItem;
memset(&cbexItem, 0x00, sizeof(cbexItem));
cbexItem.mask = CBEIF_TEXT;
cbexItem.iItem = idx;
cbexItem.pszText = (char*)text;
cbexItem.cchTextMax = 0;
return SendMessageA(cbex, CBEM_INSERTITEMA, 0, (LPARAM)&cbexItem);
}
static LONG setItem(HWND cbex, int idx, const char *text) {
COMBOBOXEXITEMA cbexItem;
memset(&cbexItem, 0x00, sizeof(cbexItem));
cbexItem.mask = CBEIF_TEXT;
cbexItem.iItem = idx;
cbexItem.pszText = (char*)text;
cbexItem.cchTextMax = 0;
return SendMessageA(cbex, CBEM_SETITEMA, 0, (LPARAM)&cbexItem);
}
static LONG delItem(HWND cbex, int idx) {
return SendMessageA(cbex, CBEM_DELETEITEM, idx, 0);
}
static LONG getItem(HWND cbex, int idx, COMBOBOXEXITEMA *cbItem) {
memset(cbItem, 0x00, sizeof(COMBOBOXEXITEMA));
cbItem->mask = CBEIF_TEXT;
cbItem->pszText = textBuffer;
cbItem->iItem = idx;
cbItem->cchTextMax = 100;
return SendMessageA(cbex, CBEM_GETITEMA, 0, (LPARAM)cbItem);
}
static LRESULT WINAPI editbox_subclass_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
WNDPROC oldproc = (WNDPROC)GetWindowLongPtrA(hwnd, GWLP_USERDATA);
static LONG defwndproc_counter = 0;
struct message msg = { 0 };
LRESULT ret;
msg.message = message;
msg.flags = sent|wparam|lparam;
if (defwndproc_counter) msg.flags |= defwinproc;
msg.wParam = wParam;
msg.lParam = lParam;
msg.id = EDITBOX_ID;
if (message != WM_PAINT &&
message != WM_ERASEBKGND &&
message != WM_NCPAINT &&
message != WM_NCHITTEST &&
message != WM_GETTEXT &&
message != WM_GETICON &&
message != WM_DEVICECHANGE)
{
add_message(sequences, EDITBOX_SEQ_INDEX, &msg);
}
defwndproc_counter++;
ret = CallWindowProcA(oldproc, hwnd, message, wParam, lParam);
defwndproc_counter--;
return ret;
}
static HWND subclass_editbox(HWND hwndComboEx)
{
WNDPROC oldproc;
HWND hwnd;
hwnd = (HWND)SendMessageA(hwndComboEx, CBEM_GETEDITCONTROL, 0, 0);
oldproc = (WNDPROC)SetWindowLongPtrA(hwnd, GWLP_WNDPROC,
(LONG_PTR)editbox_subclass_proc);
SetWindowLongPtrA(hwnd, GWLP_USERDATA, (LONG_PTR)oldproc);
return hwnd;
}
static void test_comboboxex(void) {
HWND myHwnd = 0;
LONG res;
COMBOBOXEXITEMA cbexItem;
static const char *first_item = "First Item",
*second_item = "Second Item",
*third_item = "Third Item",
*middle_item = "Between First and Second Items",
*replacement_item = "Between First and Second Items",
*out_of_range_item = "Out of Range Item";
/* Allocate space for result */
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 (%d)\n", res);
res = addItem(myHwnd, -1, second_item);
ok(res == 1, "Adding simple item failed (%d)\n", res);
res = addItem(myHwnd, 2, third_item);
ok(res == 2, "Adding simple item failed (%d)\n", res);
res = addItem(myHwnd, 1, middle_item);
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 (%d)\n", res);
res = addItem(myHwnd, 5, out_of_range_item);
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 (%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 (%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 (%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 (%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 (%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 (%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 */
res = setItem(myHwnd, 0, replacement_item);
ok(res != 0, "Setting first item failed (%d)\n", res);
res = setItem(myHwnd, 3, replacement_item);
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 (%d)\n", res);
res = delItem(myHwnd, 4);
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 (%d)\n", res);
res = delItem(myHwnd, 0);
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 (%d)\n", res);
res = delItem(myHwnd, 0);
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 (%d)\n", res);
/* Cleanup */
HeapFree(GetProcessHeap(), 0, textBuffer);
DestroyWindow(myHwnd);
}
static void test_WM_LBUTTONDOWN(void)
{
HWND hComboEx, hCombo, hEdit, hList;
COMBOBOXINFO cbInfo;
UINT x, y, item_height;
LRESULT result;
UINT i;
int idx;
RECT rect;
WCHAR buffer[3];
static const UINT choices[] = {8,9,10,11,12,14,16,18,20,22,24,26,28,36,48,72};
static const WCHAR stringFormat[] = {'%','2','d','\0'};
BOOL (WINAPI *pGetComboBoxInfo)(HWND, PCOMBOBOXINFO);
pGetComboBoxInfo = (void*)GetProcAddress(GetModuleHandleA("user32.dll"), "GetComboBoxInfo");
if (!pGetComboBoxInfo){
win_skip("GetComboBoxInfo is not available\n");
return;
}
hComboEx = CreateWindowExA(0, WC_COMBOBOXEXA, NULL,
WS_VISIBLE|WS_CHILD|CBS_DROPDOWN, 0, 0, 200, 150,
hComboExParentWnd, NULL, hMainHinst, NULL);
for (i = 0; i < sizeof(choices)/sizeof(UINT); i++){
COMBOBOXEXITEMW cbexItem;
wsprintfW(buffer, stringFormat, choices[i]);
memset(&cbexItem, 0x00, sizeof(cbexItem));
cbexItem.mask = CBEIF_TEXT;
cbexItem.iItem = i;
cbexItem.pszText = buffer;
cbexItem.cchTextMax = 0;
ok(SendMessageW(hComboEx, CBEM_INSERTITEMW, 0, (LPARAM)&cbexItem) >= 0,
"Failed to add item %d\n", i);
}
hCombo = (HWND)SendMessageA(hComboEx, CBEM_GETCOMBOCONTROL, 0, 0);
hEdit = (HWND)SendMessageA(hComboEx, CBEM_GETEDITCONTROL, 0, 0);
cbInfo.cbSize = sizeof(COMBOBOXINFO);
result = pGetComboBoxInfo(hCombo, &cbInfo);
ok(result, "Failed to get combobox info structure. LastError=%d\n",
GetLastError());
hList = cbInfo.hwndList;
ok(GetFocus() == hComboExParentWnd,
"Focus not on Main Window, instead on %p\n", GetFocus());
/* Click on the button to drop down the list */
x = cbInfo.rcButton.left + (cbInfo.rcButton.right-cbInfo.rcButton.left)/2;
y = cbInfo.rcButton.top + (cbInfo.rcButton.bottom-cbInfo.rcButton.top)/2;
result = SendMessageA(hCombo, WM_LBUTTONDOWN, 0, MAKELPARAM(x, y));
ok(result, "WM_LBUTTONDOWN was not processed. LastError=%d\n",
GetLastError());
ok(GetFocus() == hCombo ||
broken(GetFocus() != hCombo), /* win98 */
"Focus not on ComboBoxEx's ComboBox Control, instead on %p\n",
GetFocus());
ok(SendMessageA(hComboEx, CB_GETDROPPEDSTATE, 0, 0),
"The dropdown list should have appeared after clicking the button.\n");
idx = SendMessageA(hCombo, CB_GETTOPINDEX, 0, 0);
ok(idx == 0, "For TopIndex expected %d, got %d\n", 0, idx);
result = SendMessageA(hCombo, WM_LBUTTONUP, 0, MAKELPARAM(x, y));
ok(result, "WM_LBUTTONUP was not processed. LastError=%d\n",
GetLastError());
ok(GetFocus() == hCombo ||
broken(GetFocus() != hCombo), /* win98 */
"Focus not on ComboBoxEx's ComboBox Control, instead on %p\n",
GetFocus());
/* Click on the 5th item in the list */
item_height = SendMessageA(hCombo, CB_GETITEMHEIGHT, 0, 0);
ok(GetClientRect(hList, &rect), "Failed to get list's client rect.\n");
x = rect.left + (rect.right-rect.left)/2;
y = item_height/2 + item_height*4;
result = SendMessageA(hList, WM_MOUSEMOVE, 0, MAKELPARAM(x, y));
ok(!result, "WM_MOUSEMOVE was not processed. LastError=%d\n",
GetLastError());
ok(GetFocus() == hCombo ||
broken(GetFocus() != hCombo), /* win98 */
"Focus not on ComboBoxEx's ComboBox Control, instead on %p\n",
GetFocus());
result = SendMessageA(hList, WM_LBUTTONDOWN, 0, MAKELPARAM(x, y));
ok(!result, "WM_LBUTTONDOWN was not processed. LastError=%d\n",
GetLastError());
ok(GetFocus() == hCombo ||
broken(GetFocus() != hCombo), /* win98 */
"Focus not on ComboBoxEx's ComboBox Control, instead on %p\n",
GetFocus());
ok(SendMessageA(hComboEx, CB_GETDROPPEDSTATE, 0, 0),
"The dropdown list should still be visible.\n");
result = SendMessageA(hList, WM_LBUTTONUP, 0, MAKELPARAM(x, y));
ok(!result, "WM_LBUTTONUP was not processed. LastError=%d\n",
GetLastError());
todo_wine ok(GetFocus() == hEdit ||
broken(GetFocus() == hCombo), /* win98 */
"Focus not on ComboBoxEx's Edit Control, instead on %p\n",
GetFocus());
result = SendMessageA(hCombo, CB_GETDROPPEDSTATE, 0, 0);
ok(!result ||
broken(result != 0), /* win98 */
"The dropdown list should have been rolled up.\n");
idx = SendMessageA(hComboEx, CB_GETCURSEL, 0, 0);
ok(idx == 4 ||
broken(idx == -1), /* win98 */
"Current Selection: expected %d, got %d\n", 4, idx);
ok(received_end_edit, "Expected to receive a CBEN_ENDEDIT message\n");
SetFocus( hComboExParentWnd );
ok( GetFocus() == hComboExParentWnd, "got %p\n", GetFocus() );
SetFocus( hComboEx );
ok( GetFocus() == hEdit, "got %p\n", GetFocus() );
DestroyWindow(hComboEx);
}
static void test_CB_GETLBTEXT(void)
{
HWND hCombo;
CHAR buff[1];
COMBOBOXEXITEMA item;
LRESULT ret;
hCombo = createComboEx(WS_BORDER | WS_VISIBLE | WS_CHILD | CBS_DROPDOWN);
/* set text to null */
addItem(hCombo, 0, NULL);
buff[0] = 'a';
item.mask = CBEIF_TEXT;
item.iItem = 0;
item.pszText = buff;
item.cchTextMax = 1;
ret = SendMessageA(hCombo, CBEM_GETITEMA, 0, (LPARAM)&item);
ok(ret != 0, "CBEM_GETITEM failed\n");
ok(buff[0] == 0, "\n");
ret = SendMessageA(hCombo, CB_GETLBTEXTLEN, 0, 0);
ok(ret == 0, "Expected zero length\n");
ret = SendMessageA(hCombo, CB_GETLBTEXTLEN, 0, 0);
ok(ret == 0, "Expected zero length\n");
buff[0] = 'a';
ret = SendMessageA(hCombo, CB_GETLBTEXT, 0, (LPARAM)buff);
ok(ret == 0, "Expected zero length\n");
ok(buff[0] == 0, "Expected null terminator as a string, got %s\n", buff);
DestroyWindow(hCombo);
}
static void test_WM_WINDOWPOSCHANGING(void)
{
HWND hCombo;
WINDOWPOS wp;
RECT rect;
int combo_height;
int ret;
hCombo = createComboEx(WS_BORDER | WS_VISIBLE | WS_CHILD | CBS_DROPDOWN);
ok(hCombo != NULL, "createComboEx failed\n");
ret = GetWindowRect(hCombo, &rect);
ok(ret, "GetWindowRect failed\n");
combo_height = rect.bottom - rect.top;
ok(combo_height > 0, "wrong combo height\n");
/* Test height > combo_height */
wp.x = rect.left;
wp.y = rect.top;
wp.cx = (rect.right - rect.left);
wp.cy = combo_height * 2;
wp.flags = 0;
wp.hwnd = hCombo;
wp.hwndInsertAfter = NULL;
ret = SendMessageA(hCombo, WM_WINDOWPOSCHANGING, 0, (LPARAM)&wp);
ok(ret == 0, "expected 0, got %x\n", ret);
ok(wp.cy == combo_height,
"Expected height %d, got %d\n", combo_height, wp.cy);
/* Test height < combo_height */
wp.x = rect.left;
wp.y = rect.top;
wp.cx = (rect.right - rect.left);
wp.cy = combo_height / 2;
wp.flags = 0;
wp.hwnd = hCombo;
wp.hwndInsertAfter = NULL;
ret = SendMessageA(hCombo, WM_WINDOWPOSCHANGING, 0, (LPARAM)&wp);
ok(ret == 0, "expected 0, got %x\n", ret);
ok(wp.cy == combo_height,
"Expected height %d, got %d\n", combo_height, wp.cy);
ret = DestroyWindow(hCombo);
ok(ret, "DestroyWindow failed\n");
}
static LRESULT ComboExTestOnNotify(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
NMHDR *hdr = (NMHDR*)lParam;
switch(hdr->code){
case CBEN_ENDEDITA:
{
NMCBEENDEDITA *edit_info = (NMCBEENDEDITA*)hdr;
if(edit_info->iWhy==CBENF_DROPDOWN){
received_end_edit = TRUE;
}
break;
}
case CBEN_ENDEDITW:
{
NMCBEENDEDITW *edit_info = (NMCBEENDEDITW*)hdr;
if(edit_info->iWhy==CBENF_DROPDOWN){
received_end_edit = TRUE;
}
break;
}
}
return 0;
}
static LRESULT CALLBACK ComboExTestWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg) {
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_NOTIFY:
return ComboExTestOnNotify(hWnd,msg,wParam,lParam);
default:
return DefWindowProcA(hWnd, msg, wParam, lParam);
}
return 0L;
}
static BOOL init(void)
{
HMODULE hComctl32;
BOOL (WINAPI *pInitCommonControlsEx)(const INITCOMMONCONTROLSEX*);
WNDCLASSA wc;
INITCOMMONCONTROLSEX iccex;
hComctl32 = GetModuleHandleA("comctl32.dll");
pInitCommonControlsEx = (void*)GetProcAddress(hComctl32, "InitCommonControlsEx");
if (!pInitCommonControlsEx)
{
win_skip("InitCommonControlsEx() is missing. Skipping the tests\n");
return FALSE;
}
iccex.dwSize = sizeof(iccex);
iccex.dwICC = ICC_USEREX_CLASSES;
pInitCommonControlsEx(&iccex);
pSetWindowSubclass = (void*)GetProcAddress(hComctl32, (LPSTR)410);
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = GetModuleHandleA(NULL);
wc.hIcon = NULL;
wc.hCursor = LoadCursorA(NULL, (LPCSTR)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|WS_VISIBLE,
CW_USEDEFAULT, CW_USEDEFAULT, 680, 260, NULL, NULL, GetModuleHandleA(NULL), 0);
ok(hComboExParentWnd != NULL, "failed to create parent window\n");
hMainHinst = GetModuleHandleA(NULL);
return hComboExParentWnd != NULL;
}
static void cleanup(void)
{
MSG msg;
PostMessageA(hComboExParentWnd, WM_CLOSE, 0, 0);
while (GetMessageA(&msg,0,0,0)) {
TranslateMessage(&msg);
DispatchMessageA(&msg);
}
DestroyWindow(hComboExParentWnd);
UnregisterClassA(ComboExTestClass, GetModuleHandleA(NULL));
}
static void test_comboboxex_subclass(void)
{
HWND hComboEx, hCombo, hEdit;
hComboEx = createComboEx(WS_BORDER | WS_VISIBLE | WS_CHILD | CBS_DROPDOWN);
hCombo = (HWND)SendMessageA(hComboEx, CBEM_GETCOMBOCONTROL, 0, 0);
ok(hCombo != NULL, "Failed to get internal combo\n");
hEdit = (HWND)SendMessageA(hComboEx, CBEM_GETEDITCONTROL, 0, 0);
ok(hEdit != NULL, "Failed to get internal edit\n");
if (pSetWindowSubclass)
{
ok(GetPropA(hCombo, "CC32SubclassInfo") != NULL, "Expected CC32SubclassInfo property\n");
ok(GetPropA(hEdit, "CC32SubclassInfo") != NULL, "Expected CC32SubclassInfo property\n");
}
DestroyWindow(hComboEx);
}
static const struct message test_setitem_edit_seq[] = {
{ WM_SETTEXT, sent|id, 0, 0, EDITBOX_ID },
{ EM_SETSEL, sent|id|wparam|lparam, 0, 0, EDITBOX_ID },
{ EM_SETSEL, sent|id|wparam|lparam, 0, -1, EDITBOX_ID },
{ 0 }
};
static void test_get_set_item(void)
{
char textA[] = "test";
HWND hComboEx;
COMBOBOXEXITEMA item;
BOOL ret;
hComboEx = createComboEx(WS_BORDER | WS_VISIBLE | WS_CHILD | CBS_DROPDOWN);
subclass_editbox(hComboEx);
flush_sequences(sequences, NUM_MSG_SEQUENCES);
memset(&item, 0, sizeof(item));
item.mask = CBEIF_TEXT;
item.pszText = textA;
item.iItem = -1;
ret = SendMessageA(hComboEx, CBEM_SETITEMA, 0, (LPARAM)&item);
expect(TRUE, ret);
ok_sequence(sequences, EDITBOX_SEQ_INDEX, test_setitem_edit_seq, "set item data for edit", FALSE);
/* get/set lParam */
item.mask = CBEIF_LPARAM;
item.iItem = -1;
item.lParam = 0xdeadbeef;
ret = SendMessageA(hComboEx, CBEM_GETITEMA, 0, (LPARAM)&item);
expect(TRUE, ret);
ok(item.lParam == 0, "Expected zero, got %lx\n", item.lParam);
item.lParam = 0x1abe11ed;
ret = SendMessageA(hComboEx, CBEM_SETITEMA, 0, (LPARAM)&item);
expect(TRUE, ret);
item.lParam = 0;
ret = SendMessageA(hComboEx, CBEM_GETITEMA, 0, (LPARAM)&item);
expect(TRUE, ret);
ok(item.lParam == 0x1abe11ed, "Expected 0x1abe11ed, got %lx\n", item.lParam);
DestroyWindow(hComboEx);
}
START_TEST(comboex)
{
if (!init())
return;
init_msg_sequences(sequences, NUM_MSG_SEQUENCES);
test_comboboxex();
test_WM_LBUTTONDOWN();
test_CB_GETLBTEXT();
test_WM_WINDOWPOSCHANGING();
test_comboboxex_subclass();
test_get_set_item();
cleanup();
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -187,6 +187,12 @@ static const struct message empty_seq[] = {
{ 0 }
};
static const struct message parent_focus_change_ownerdata_seq[] = {
{ WM_NOTIFY, sent|id, 0, 0, LVN_ITEMCHANGED },
{ WM_NOTIFY, sent|id, 0, 0, LVN_GETDISPINFOA },
{ 0 }
};
static const struct message forward_erasebkgnd_parent_seq[] = {
{ WM_ERASEBKGND, sent },
{ 0 }
@ -628,14 +634,6 @@ static LRESULT WINAPI listview_subclass_proc(HWND hwnd, UINT message, WPARAM wPa
LRESULT ret;
struct message msg;
/* some debug output for style changing */
if ((message == WM_STYLECHANGING ||
message == WM_STYLECHANGED) && lParam)
{
STYLESTRUCT *style = (STYLESTRUCT*)lParam;
trace("\told style: 0x%08x, new style: 0x%08x\n", style->styleOld, style->styleNew);
}
msg.message = message;
msg.flags = sent|wparam|lparam;
if (defwndproc_counter) msg.flags |= defwinproc;
@ -1517,6 +1515,8 @@ static LRESULT CALLBACK create_test_wndproc(HWND hwnd, UINT uMsg, WPARAM wParam,
static void test_create(void)
{
static const WCHAR testtextW[] = {'t','e','s','t',' ','t','e','x','t',0};
char buff[16];
HWND hList;
HWND hHeader;
LONG_PTR ret;
@ -1537,15 +1537,6 @@ static void test_create(void)
hList = CreateWindowA("MyListView32", "Test", WS_VISIBLE, 0, 0, 100, 100, NULL, NULL, GetModuleHandleA(NULL), 0);
ok((HIMAGELIST)SendMessageA(hList, LVM_GETIMAGELIST, 0, 0) == test_create_imagelist, "Image list not obtained\n");
hHeader = (HWND)SendMessageA(hList, LVM_GETHEADER, 0, 0);
if (!IsWindow(hHeader))
{
/* version 4.0 */
win_skip("LVM_GETHEADER not implemented. Skipping.\n");
DestroyWindow(hList);
return;
}
ok(IsWindow(hHeader) && IsWindowVisible(hHeader), "Listview not in report mode\n");
ok(hHeader == GetDlgItem(hList, 0), "Expected header as dialog item\n");
DestroyWindow(hList);
@ -1728,6 +1719,23 @@ static void test_create(void)
ok_sequence(sequences, PARENT_SEQ_INDEX, create_ownerdrawfixed_parent_seq,
"created with LVS_OWNERDRAWFIXED|LVS_REPORT - parent seq", FALSE);
DestroyWindow(hList);
/* Test that window text is preserved. */
hList = CreateWindowExA(0, WC_LISTVIEWA, "test text", WS_CHILD | WS_BORDER | WS_VISIBLE,
0, 0, 100, 100, hwndparent, NULL, GetModuleHandleA(NULL), NULL);
ok(hList != NULL, "Failed to create ListView window.\n");
*buff = 0;
GetWindowTextA(hList, buff, sizeof(buff));
ok(!strcmp(buff, "test text"), "Unexpected window text %s.\n", buff);
DestroyWindow(hList);
hList = CreateWindowExW(0, WC_LISTVIEWW, testtextW, WS_CHILD | WS_BORDER | WS_VISIBLE,
0, 0, 100, 100, hwndparent, NULL, GetModuleHandleA(NULL), NULL);
ok(hList != NULL, "Failed to create ListView window.\n");
*buff = 0;
GetWindowTextA(hList, buff, sizeof(buff));
ok(!strcmp(buff, "test text"), "Unexpected window text %s.\n", buff);
DestroyWindow(hList);
}
static void test_redraw(void)
@ -1826,16 +1834,12 @@ static LRESULT WINAPI cd_wndproc(HWND hwnd, UINT message, WPARAM wParam, LPARAM
clr = GetBkColor(nmlvcd->nmcd.hdc);
ok(nmlvcd->clrTextBk == CLR_DEFAULT, "got 0x%x\n", nmlvcd->clrTextBk);
ok(nmlvcd->clrText == RGB(0, 255, 0), "got 0x%x\n", nmlvcd->clrText);
if (!(GetWindowLongW(nmhdr->hwndFrom, GWL_STYLE) & LVS_SHOWSELALWAYS))
{
todo_wine_if(nmlvcd->iSubItem)
ok(clr == c0ffee, "clr=%.8x\n", clr);
}
todo_wine_if(nmlvcd->iSubItem)
ok(clr == c0ffee, "clr=%.8x\n", clr);
return CDRF_NOTIFYPOSTPAINT;
case CDDS_ITEMPOSTPAINT | CDDS_SUBITEM:
clr = GetBkColor(nmlvcd->nmcd.hdc);
if (!(GetWindowLongW(nmhdr->hwndFrom, GWL_STYLE) & LVS_SHOWSELALWAYS))
todo_wine ok(clr == c0ffee, "clr=%.8x\n", clr);
todo_wine ok(clr == c0ffee, "clr=%.8x\n", clr);
ok(nmlvcd->clrTextBk == CLR_DEFAULT, "got 0x%x\n", nmlvcd->clrTextBk);
ok(nmlvcd->clrText == RGB(0, 255, 0), "got 0x%x\n", nmlvcd->clrText);
return CDRF_DODEFAULT;
@ -1851,7 +1855,6 @@ static void test_customdraw(void)
{
HWND hwnd;
WNDPROC oldwndproc;
LVITEMA item;
hwnd = create_listview_control(LVS_REPORT);
@ -1871,18 +1874,6 @@ static void test_customdraw(void)
UpdateWindow(hwnd);
ok_sequence(sequences, PARENT_CD_SEQ_INDEX, parent_report_cd_seq, "parent customdraw, LVS_REPORT", FALSE);
/* check colors when item is selected */
SetWindowLongW(hwnd, GWL_STYLE, GetWindowLongW(hwnd, GWL_STYLE) | LVS_SHOWSELALWAYS);
item.mask = LVIF_STATE;
item.stateMask = LVIS_SELECTED;
item.state = LVIS_SELECTED;
SendMessageA(hwnd, LVM_SETITEMSTATE, 0, (LPARAM)&item);
flush_sequences(sequences, NUM_MSG_SEQUENCES);
InvalidateRect(hwnd, NULL, TRUE);
UpdateWindow(hwnd);
ok_sequence(sequences, PARENT_CD_SEQ_INDEX, parent_report_cd_seq, "parent customdraw, LVS_REPORT, selection", FALSE);
DestroyWindow(hwnd);
hwnd = create_listview_control(LVS_LIST);
@ -1931,13 +1922,6 @@ static void test_icon_spacing(void)
"Expected %d, got %d\n", MAKELONG(w, h), r);
r = SendMessageA(hwnd, LVM_SETICONSPACING, 0, MAKELPARAM(25, 35));
if (r == 0)
{
/* version 4.0 */
win_skip("LVM_SETICONSPACING unimplemented. Skipping.\n");
DestroyWindow(hwnd);
return;
}
expect(MAKELONG(20,30), r);
r = SendMessageA(hwnd, LVM_SETICONSPACING, 0, MAKELPARAM(-1,-1));
@ -4386,19 +4370,11 @@ static void test_notifyformat(void)
r = SendMessageA(hwnd, LVM_SETUNICODEFORMAT, 1, 0);
expect(0, r);
r = SendMessageA(hwnd, LVM_GETUNICODEFORMAT, 0, 0);
if (r == 1)
{
r = SendMessageA(hwnd, LVM_SETUNICODEFORMAT, 0, 0);
expect(1, r);
r = SendMessageA(hwnd, LVM_GETUNICODEFORMAT, 0, 0);
expect(0, r);
}
else
{
win_skip("LVM_GETUNICODEFORMAT is unsupported\n");
DestroyWindow(hwnd);
return;
}
ok(r == 1, "Unexpected return value %d.\n", r);
r = SendMessageA(hwnd, LVM_SETUNICODEFORMAT, 0, 0);
expect(1, r);
r = SendMessageA(hwnd, LVM_GETUNICODEFORMAT, 0, 0);
expect(0, r);
DestroyWindow(hwnd);
@ -4978,13 +4954,18 @@ static void test_LVS_EX_TRANSPARENTBKGND(void)
static void test_approximate_viewrect(void)
{
HWND hwnd;
DWORD ret;
HIMAGELIST himl;
HBITMAP hbmp;
LVITEMA itema;
static CHAR test[] = "abracadabra, a very long item label";
DWORD item_width, item_height, header_height;
static CHAR column_header[] = "Header";
unsigned const column_width = 100;
DWORD ret, item_count;
HIMAGELIST himl;
LVITEMA itema;
LVCOLUMNA col;
HBITMAP hbmp;
HWND hwnd;
/* LVS_ICON */
hwnd = create_listview_control(LVS_ICON);
himl = ImageList_Create(40, 40, 0, 4, 4);
ok(himl != NULL, "failed to create imagelist\n");
@ -5003,12 +4984,7 @@ static void test_approximate_viewrect(void)
expect(0, ret);
ret = SendMessageA(hwnd, LVM_SETICONSPACING, 0, MAKELPARAM(75, 75));
if (ret == 0)
{
/* version 4.0 */
win_skip("LVM_SETICONSPACING unimplemented. Skipping.\n");
return;
}
ok(ret != 0, "Unexpected return value %#x.\n", ret);
ret = SendMessageA(hwnd, LVM_APPROXIMATEVIEWRECT, 11, MAKELPARAM(100,100));
expect(MAKELONG(77,827), ret);
@ -5046,6 +5022,129 @@ static void test_approximate_viewrect(void)
expect(MAKELONG(152,152), ret);
DestroyWindow(hwnd);
/* LVS_REPORT */
hwnd = create_listview_control(LVS_REPORT);
/* Empty control without columns */
ret = SendMessageA(hwnd, LVM_APPROXIMATEVIEWRECT, 0, MAKELPARAM(100, 100));
todo_wine
ok(LOWORD(ret) == 0, "Unexpected width %d.\n", LOWORD(ret));
ok(HIWORD(ret) != 0, "Unexpected height %d.\n", HIWORD(ret));
ret = SendMessageA(hwnd, LVM_APPROXIMATEVIEWRECT, 0, 0);
ok(LOWORD(ret) == 0, "Unexpected width %d.\n", LOWORD(ret));
todo_wine
ok(HIWORD(ret) != 0, "Unexpected height %d.\n", HIWORD(ret));
header_height = HIWORD(ret);
ret = SendMessageA(hwnd, LVM_APPROXIMATEVIEWRECT, 1, 0);
ok(LOWORD(ret) == 0, "Unexpected width %d.\n", LOWORD(ret));
todo_wine
ok(HIWORD(ret) > header_height, "Unexpected height %d.\n", HIWORD(ret));
item_height = HIWORD(ret) - header_height;
ret = SendMessageA(hwnd, LVM_APPROXIMATEVIEWRECT, -2, 0);
ok(LOWORD(ret) == 0, "Unexpected width %d.\n", LOWORD(ret));
ok(HIWORD(ret) == (header_height - 2 * item_height), "Unexpected height %d.\n", HIWORD(ret)) ;
ret = SendMessageA(hwnd, LVM_APPROXIMATEVIEWRECT, -1, 0);
ok(LOWORD(ret) == 0, "Unexpected width %d.\n", LOWORD(ret));
ok(HIWORD(ret) == header_height, "Unexpected height.\n");
ret = SendMessageA(hwnd, LVM_APPROXIMATEVIEWRECT, 2, 0);
ok(LOWORD(ret) == 0, "Unexpected width %d.\n", LOWORD(ret));
ok(HIWORD(ret) == header_height + 2 * item_height, "Unexpected height %d.\n", HIWORD(ret));
/* Insert column */
col.mask = LVCF_TEXT | LVCF_WIDTH;
col.pszText = column_header;
col.cx = column_width;
ret = SendMessageA(hwnd, LVM_INSERTCOLUMNA, 0, (LPARAM)&col);
ok(ret == 0, "Unexpected return value %d.\n", ret);
/* Empty control with column */
ret = SendMessageA(hwnd, LVM_APPROXIMATEVIEWRECT, 0, 0);
todo_wine {
ok(LOWORD(ret) >= column_width, "Unexpected width %d.\n", LOWORD(ret));
ok(HIWORD(ret) != 0, "Unexpected height %d.\n", HIWORD(ret));
}
header_height = HIWORD(ret);
item_width = LOWORD(ret);
ret = SendMessageA(hwnd, LVM_APPROXIMATEVIEWRECT, 1, 0);
ok(LOWORD(ret) == item_width, "Unexpected width %d.\n", LOWORD(ret));
todo_wine
ok(HIWORD(ret) > header_height, "Unexpected height %d.\n", HIWORD(ret));
item_height = HIWORD(ret) - header_height;
ret = SendMessageA(hwnd, LVM_APPROXIMATEVIEWRECT, -2, 0);
ok(LOWORD(ret) == item_width, "Unexpected width %d.\n", LOWORD(ret));
ok(HIWORD(ret) == header_height - 2 * item_height, "Unexpected height %d.\n", HIWORD(ret));
ret = SendMessageA(hwnd, LVM_APPROXIMATEVIEWRECT, -1, 0);
ok(LOWORD(ret) == item_width, "Unexpected width %d.\n", LOWORD(ret));
ok(HIWORD(ret) == header_height, "Unexpected height %d.\n", HIWORD(ret));
ret = SendMessageA(hwnd, LVM_APPROXIMATEVIEWRECT, 2, 0);
ok(LOWORD(ret) == item_width, "Unexpected width %d.\n", LOWORD(ret));
ok(HIWORD(ret) == header_height + 2 * item_height, "Unexpected height %d.\n", HIWORD(ret));
for (item_count = 1; item_count <= 2; ++item_count)
{
itema.mask = LVIF_TEXT;
itema.iItem = 0;
itema.iSubItem = 0;
itema.pszText = test;
ret = SendMessageA(hwnd, LVM_INSERTITEMA, 0, (LPARAM)&itema);
ok(ret == 0, "Unexpected return value %d.\n", ret);
ret = SendMessageA(hwnd, LVM_APPROXIMATEVIEWRECT, 0, 0);
ok(LOWORD(ret) >= column_width, "Unexpected width %d.\n", LOWORD(ret));
todo_wine
ok(HIWORD(ret) != 0, "Unexpected height %d.\n", HIWORD(ret));
header_height = HIWORD(ret);
item_width = LOWORD(ret);
ret = SendMessageA(hwnd, LVM_APPROXIMATEVIEWRECT, 1, 0);
ok(LOWORD(ret) == item_width, "Unexpected width %d, item %d\n", LOWORD(ret), item_count - 1);
ok(HIWORD(ret) > header_height, "Unexpected height %d. item %d.\n", HIWORD(ret), item_count - 1);
item_height = HIWORD(ret) - header_height;
ret = SendMessageA(hwnd, LVM_APPROXIMATEVIEWRECT, -2, 0);
ok(LOWORD(ret) == item_width, "Unexpected width %d.\n", LOWORD(ret));
todo_wine
ok(HIWORD(ret) == header_height - 2 * item_height, "Unexpected height %d.\n", HIWORD(ret));
ret = SendMessageA(hwnd, LVM_APPROXIMATEVIEWRECT, -1, 0);
ok(LOWORD(ret) == item_width, "Unexpected width %d.\n", LOWORD(ret));
ok(HIWORD(ret) == header_height + item_count * item_height, "Unexpected height %d.\n", HIWORD(ret));
ret = SendMessageA(hwnd, LVM_APPROXIMATEVIEWRECT, 2, 0);
ok(LOWORD(ret) == item_width, "Unexpected width %d.\n", LOWORD(ret));
ok(HIWORD(ret) == header_height + 2 * item_height, "Unexpected height %d.\n", HIWORD(ret));
ret = SendMessageA(hwnd, LVM_APPROXIMATEVIEWRECT, 2, MAKELONG(item_width * 2, header_height + 3 * item_height));
ok(LOWORD(ret) == item_width, "Unexpected width %d.\n", LOWORD(ret));
ok(HIWORD(ret) == header_height + 2 * item_height, "Unexpected height %d.\n", HIWORD(ret));
ret = SendMessageA(hwnd, LVM_APPROXIMATEVIEWRECT, -2, MAKELONG(item_width * 2, 0));
ok(LOWORD(ret) == item_width, "Unexpected width %d.\n", LOWORD(ret));
todo_wine
ok(HIWORD(ret) == header_height - 2 * item_height, "Unexpected height %d.\n", HIWORD(ret));
ret = SendMessageA(hwnd, LVM_APPROXIMATEVIEWRECT, -2, MAKELONG(-1, -1));
ok(LOWORD(ret) == item_width, "Unexpected width %d.\n", LOWORD(ret));
todo_wine
ok(HIWORD(ret) == header_height - 2 * item_height, "Unexpected height %d.\n", HIWORD(ret));
}
DestroyWindow(hwnd);
}
static void test_finditem(void)
@ -5102,12 +5201,6 @@ static void test_finditem(void)
fi.flags = LVFI_SUBSTRING;
fi.psz = f;
r = SendMessageA(hwnd, LVM_FINDITEMA, -1, (LPARAM)&fi);
if (r == -1)
{
win_skip("LVFI_SUBSTRING not supported\n");
DestroyWindow(hwnd);
return;
}
expect(0, r);
strcpy(f, "f");
fi.flags = LVFI_SUBSTRING;
@ -5895,6 +5988,7 @@ static void test_oneclickactivate(void)
static void test_callback_mask(void)
{
LVITEMA item;
DWORD mask;
HWND hwnd;
BOOL ret;
@ -5911,6 +6005,209 @@ static void test_callback_mask(void)
ok(mask == ~0u, "got 0x%08x\n", mask);
DestroyWindow(hwnd);
/* LVS_OWNERDATA, mask LVIS_FOCUSED */
hwnd = create_listview_control(LVS_REPORT | LVS_OWNERDATA);
mask = SendMessageA(hwnd, LVM_GETCALLBACKMASK, 0, 0);
ok(mask == 0, "Unexpected callback mask %#x.\n", mask);
ret = SendMessageA(hwnd, LVM_SETCALLBACKMASK, LVIS_FOCUSED, 0);
ok(ret, "Failed to set callback mask, %d\n", ret);
mask = SendMessageA(hwnd, LVM_GETCALLBACKMASK, 0, 0);
ok(mask == LVIS_FOCUSED, "Unexpected callback mask %#x.\n", mask);
ret = SendMessageA(hwnd, LVM_SETITEMCOUNT, 1, 0);
ok(ret, "Failed to set item count.\n");
ret = SendMessageA(hwnd, LVM_GETSELECTIONMARK, 0, 0);
ok(ret == -1, "Unexpected selection mark, %d\n", ret);
item.stateMask = LVIS_FOCUSED;
item.state = LVIS_FOCUSED;
ret = SendMessageA(hwnd, LVM_SETITEMSTATE, 0, (LPARAM)&item);
ok(ret, "Failed to set item state.\n");
flush_sequences(sequences, NUM_MSG_SEQUENCES);
ret = SendMessageA(hwnd, LVM_GETNEXTITEM, -1, LVNI_FOCUSED);
todo_wine
ok(ret == 0, "Unexpected focused item, ret %d\n", ret);
ret = SendMessageA(hwnd, LVM_GETSELECTIONMARK, 0, 0);
todo_wine
ok(ret == 0, "Unexpected selection mark, %d\n", ret);
ret = SendMessageA(hwnd, LVM_SETITEMCOUNT, 0, 0);
ok(ret, "Failed to set item count.\n");
ret = SendMessageA(hwnd, LVM_GETNEXTITEM, -1, LVNI_FOCUSED);
ok(ret == -1, "Unexpected focused item, ret %d\n", ret);
ret = SendMessageA(hwnd, LVM_GETSELECTIONMARK, 0, 0);
ok(ret == -1, "Unexpected selection mark, %d\n", ret);
ret = SendMessageA(hwnd, LVM_SETITEMCOUNT, 1, 0);
ok(ret, "Failed to set item count.\n");
ret = SendMessageA(hwnd, LVM_GETNEXTITEM, -1, LVNI_FOCUSED);
ok(ret == -1, "Unexpected focused item, ret %d\n", ret);
ok_sequence(sequences, PARENT_SEQ_INDEX, empty_seq, "parent seq, owner data/focus 1", FALSE);
/* LVS_OWNDERDATA, empty mask */
ret = SendMessageA(hwnd, LVM_SETCALLBACKMASK, 0, 0);
ok(ret, "Failed to set callback mask, %d\n", ret);
ret = SendMessageA(hwnd, LVM_SETITEMCOUNT, 1, 0);
ok(ret, "Failed to set item count.\n");
ret = SendMessageA(hwnd, LVM_GETSELECTIONMARK, 0, 0);
ok(ret == -1, "Unexpected selection mark, %d\n", ret);
item.stateMask = LVIS_FOCUSED;
item.state = LVIS_FOCUSED;
ret = SendMessageA(hwnd, LVM_SETITEMSTATE, 0, (LPARAM)&item);
ok(ret, "Failed to set item state.\n");
ret = SendMessageA(hwnd, LVM_GETSELECTIONMARK, 0, 0);
ok(ret == 0, "Unexpected selection mark, %d\n", ret);
flush_sequences(sequences, NUM_MSG_SEQUENCES);
ret = SendMessageA(hwnd, LVM_GETNEXTITEM, -1, LVNI_FOCUSED);
ok(ret == 0, "Unexpected focused item, ret %d\n", ret);
ret = SendMessageA(hwnd, LVM_SETITEMCOUNT, 0, 0);
ok(ret, "Failed to set item count.\n");
ret = SendMessageA(hwnd, LVM_GETNEXTITEM, -1, LVNI_FOCUSED);
ok(ret == -1, "Unexpected focused item, ret %d\n", ret);
ret = SendMessageA(hwnd, LVM_GETSELECTIONMARK, 0, 0);
todo_wine
ok(ret == -1, "Unexpected selection mark, %d\n", ret);
ret = SendMessageA(hwnd, LVM_SETITEMCOUNT, 1, 0);
ok(ret, "Failed to set item count.\n");
ret = SendMessageA(hwnd, LVM_GETNEXTITEM, -1, LVNI_FOCUSED);
ok(ret == -1, "Unexpected focused item, ret %d\n", ret);
ok_sequence(sequences, PARENT_SEQ_INDEX, empty_seq, "parent seq, owner data/focus 2", FALSE);
/* 2 items, focus on index 0, reduce to 1 item. */
flush_sequences(sequences, NUM_MSG_SEQUENCES);
ret = SendMessageA(hwnd, LVM_SETITEMCOUNT, 2, 0);
ok(ret, "Failed to set item count.\n");
ret = SendMessageA(hwnd, LVM_SETITEMSTATE, 0, (LPARAM)&item);
ok(ret, "Failed to set item state.\n");
ret = SendMessageA(hwnd, LVM_GETNEXTITEM, -1, LVNI_FOCUSED);
ok(ret == 0, "Unexpected focused item, ret %d\n", ret);
ret = SendMessageA(hwnd, LVM_SETITEMCOUNT, 1, 0);
ok(ret, "Failed to set item count.\n");
ret = SendMessageA(hwnd, LVM_GETNEXTITEM, -1, LVNI_FOCUSED);
ok(ret == 0, "Unexpected focused item, ret %d\n", ret);
ok_sequence(sequences, PARENT_SEQ_INDEX, parent_focus_change_ownerdata_seq,
"parent seq, owner data/focus 3", TRUE);
DestroyWindow(hwnd);
}
static void test_state_image(void)
{
static const DWORD styles[] =
{
LVS_ICON,
LVS_REPORT,
LVS_SMALLICON,
LVS_LIST,
};
int i;
for (i = 0; i < sizeof(styles)/sizeof(styles[0]); i++)
{
static char text[] = "Item";
static char subtext[] = "Subitem";
char buff[16];
LVITEMA item;
HWND hwnd;
int r;
hwnd = create_listview_control(styles[i]);
insert_column(hwnd, 0);
insert_column(hwnd, 1);
item.mask = LVIF_TEXT;
item.iItem = 0;
item.iSubItem = 0;
item.pszText = text;
r = SendMessageA(hwnd, LVM_INSERTITEMA, 0, (LPARAM)&item);
ok(r == 0, "Failed to insert an item.\n");
item.mask = LVIF_STATE;
item.state = INDEXTOSTATEIMAGEMASK(1) | LVIS_SELECTED;
item.stateMask = LVIS_STATEIMAGEMASK | LVIS_SELECTED;
item.iItem = 0;
item.iSubItem = 0;
r = SendMessageA(hwnd, LVM_SETITEMA, 0, (LPARAM)&item);
ok(r, "Failed to set item state.\n");
item.mask = LVIF_TEXT;
item.iItem = 0;
item.iSubItem = 1;
item.pszText = subtext;
r = SendMessageA(hwnd, LVM_SETITEMA, 0, (LPARAM)&item);
ok(r, "Failed to set subitem text.\n");
item.mask = LVIF_STATE;
item.stateMask = LVIS_STATEIMAGEMASK | LVIS_SELECTED;
item.state = 0;
item.iItem = 0;
item.iSubItem = 0;
r = SendMessageA(hwnd, LVM_GETITEMA, 0, (LPARAM)&item);
ok(r, "Failed to get item state.\n");
ok(item.state == (INDEXTOSTATEIMAGEMASK(1) | LVIS_SELECTED), "Unexpected item state %#x.\n", item.state);
item.mask = LVIF_STATE;
item.stateMask = LVIS_STATEIMAGEMASK | LVIS_SELECTED;
item.state = INDEXTOSTATEIMAGEMASK(2);
item.iItem = 0;
item.iSubItem = 1;
r = SendMessageA(hwnd, LVM_GETITEMA, 0, (LPARAM)&item);
ok(r, "Failed to get subitem state.\n");
todo_wine
ok(item.state == 0, "Unexpected state %#x.\n", item.state);
item.mask = LVIF_STATE;
item.stateMask = LVIS_STATEIMAGEMASK | LVIS_SELECTED;
item.state = INDEXTOSTATEIMAGEMASK(2);
item.iItem = 0;
item.iSubItem = 2;
r = SendMessageA(hwnd, LVM_GETITEMA, 0, (LPARAM)&item);
ok(r, "Failed to get subitem state.\n");
todo_wine
ok(item.state == 0, "Unexpected state %#x.\n", item.state);
item.mask = LVIF_TEXT;
item.iItem = 0;
item.iSubItem = 1;
item.pszText = buff;
item.cchTextMax = sizeof(buff);
r = SendMessageA(hwnd, LVM_GETITEMA, 0, (LPARAM)&item);
ok(r, "Failed to get subitem text %d.\n", r);
ok(!strcmp(buff, subtext), "Unexpected subitem text %s.\n", buff);
DestroyWindow(hwnd);
}
}
START_TEST(listview)
@ -5985,6 +6282,7 @@ START_TEST(listview)
test_header_proc();
test_oneclickactivate();
test_callback_mask();
test_state_image();
if (!load_v6_module(&ctx_cookie, &hCtx))
{
@ -6003,6 +6301,26 @@ START_TEST(listview)
test_multiselect();
test_insertitem();
test_header_proc();
test_images();
test_checkboxes();
test_items();
test_color();
test_columns();
test_sorting();
test_ownerdata();
test_norecompute();
test_nosortheader();
test_columnscreation();
test_indentation();
test_finditem();
test_hover();
test_destroynotify();
test_createdragimage();
test_dispinfo();
test_LVM_SETITEMTEXT();
test_LVM_REDRAWITEMS();
test_oneclickactivate();
test_state_image();
unload_v6_module(ctx_cookie, hCtx);

View file

@ -189,7 +189,7 @@ static void test_Alloc(void)
/* reallocate a NULL ptr */
p = pReAlloc(NULL, 2);
ok(p != NULL, "Expectd non-NULL ptr\n");
ok(p != NULL, "Expected non-NULL ptr\n");
res = pFree(p);
ok(res == TRUE, "Expected TRUE, got %d\n", res);

View file

@ -163,11 +163,12 @@ static void dump_sequence( struct msg_sequence **seq, int sequence_index,
}
static inline void ok_sequence_(struct msg_sequence **seq, int sequence_index,
const struct message *expected, const char *context, BOOL todo,
const struct message *expected_list, const char *context, BOOL 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};
struct msg_sequence *msg_seq = seq[sequence_index];
const struct message *expected = expected_list;
const struct message *actual, *sequence;
int failcount = 0, dump = 0;
@ -377,7 +378,7 @@ static inline void ok_sequence_(struct msg_sequence **seq, int sequence_index,
}
done:
if (dump) dump_sequence( seq, sequence_index, expected, context, file, line );
if (dump) dump_sequence( seq, sequence_index, expected_list, context, file, line );
flush_sequence(seq, sequence_index);
}

View file

@ -25,11 +25,19 @@
static HWND parenthwnd;
static HWND sheethwnd;
static BOOL rtl;
static LONG active_page = -1;
#define IDC_APPLY_BUTTON 12321
static void detect_locale(void)
{
DWORD reading_layout;
rtl = GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_IREADINGLAYOUT | LOCALE_RETURN_NUMBER,
(void *)&reading_layout, sizeof(reading_layout)) && reading_layout == 1;
}
/* try to make sure pending X events have been processed before continuing */
static void flush_events(void)
{
@ -492,19 +500,28 @@ static void test_buttons(void)
button = GetDlgItem(hdlg, IDCANCEL);
GetWindowRect(button, &rc);
ok(rc.top == top, "Cancel button should have same top as OK button\n");
ok(rc.left > prevRight, "Cancel button should be to the right of OK button\n");
if (rtl)
ok(rc.left < prevRight, "Cancel button should be to the left of OK button\n");
else
ok(rc.left > prevRight, "Cancel button should be to the right of OK button\n");
prevRight = rc.right;
button = GetDlgItem(hdlg, IDC_APPLY_BUTTON);
GetWindowRect(button, &rc);
ok(rc.top == top, "Apply button should have same top as OK button\n");
ok(rc.left > prevRight, "Apply button should be to the right of Cancel button\n");
if (rtl)
ok(rc.left < prevRight, "Apply button should be to the left of Cancel button\n");
else
ok(rc.left > prevRight, "Apply button should be to the right of Cancel button\n");
prevRight = rc.right;
button = GetDlgItem(hdlg, IDHELP);
GetWindowRect(button, &rc);
ok(rc.top == top, "Help button should have same top as OK button\n");
ok(rc.left > prevRight, "Help button should be to the right of Apply button\n");
if (rtl)
ok(rc.left < prevRight, "Help button should be to the left of Apply button\n");
else
ok(rc.left > prevRight, "Help button should be to the right of Apply button\n");
DestroyWindow(hdlg);
}
@ -1120,6 +1137,15 @@ static void test_CreatePropertySheetPage(void)
START_TEST(propsheet)
{
detect_locale();
if (rtl)
{
/* use locale-specific RTL resources when on an RTL locale */
/* without this, propsheets on RTL locales use English LTR resources */
trace("RTL locale detected\n");
SetProcessDefaultLayout(LAYOUT_RTL);
}
test_title();
test_nopage();
test_disableowner();

View file

@ -18,7 +18,7 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
//#include "windef.h"
#include "windef.h"
#include "winuser.h"
#include "resources.h"
@ -101,3 +101,63 @@ FONT 8, "MS Shell Dlg"
COMBOBOX IDC_PS_COMBO1, 16, 68, 140, 60, CBS_DROPDOWN | WS_VSCROLL | WS_TABSTOP
PUSHBUTTON "Add", IDC_PS_PUSHBUTTON1, 164, 68, 40, 13
}
MULTI_EDIT_DIALOG DIALOG 0, 0, 160, 75
STYLE WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | DS_CENTER
CAPTION "Multiple Edit Test"
FONT 8, "MS Shell Dlg"
{
EDITTEXT 1000, 5, 5, 150, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_MULTILINE | ES_WANTRETURN
EDITTEXT 1001, 5, 25, 150, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
EDITTEXT 1002, 5, 45, 150, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
}
EDIT_DIALOG DIALOG 0, 0, 160, 80
STYLE WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | DS_CENTER
CAPTION "Edit Test"
FONT 8, "MS Shell Dlg"
{
PUSHBUTTON "OK", IDOK, 20, 60, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
PUSHBUTTON "Cancel", IDCANCEL, 100, 60, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
EDITTEXT 1000, 5, 5, 150, 50, WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_MULTILINE | WS_VSCROLL | ES_AUTOVSCROLL
}
EDIT_READONLY_DIALOG DIALOG 0, 0, 160, 80
STYLE WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | DS_CENTER
CAPTION "Edit Readonly Test"
FONT 8, "MS Shell Dlg"
{
PUSHBUTTON "OK", IDOK, 20, 60, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
PUSHBUTTON "Cancel", IDCANCEL, 100, 60, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
EDITTEXT 1000, 5, 5, 150, 50, WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_MULTILINE | WS_VSCROLL | ES_AUTOVSCROLL | ES_READONLY
}
EDIT_WANTRETURN_DIALOG DIALOG 0, 0, 160, 80
STYLE WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | DS_CENTER
CAPTION "Edit Test"
FONT 8, "MS Shell Dlg"
{
PUSHBUTTON "OK", IDOK, 20, 60, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
PUSHBUTTON "Cancel", IDCANCEL, 100, 60, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
EDITTEXT 1000, 5, 5, 150, 50, WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_MULTILINE | WS_VSCROLL | ES_AUTOVSCROLL | ES_WANTRETURN
}
EDIT_SINGLELINE_DIALOG DIALOG 0, 0, 160, 80
STYLE WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | DS_CENTER
CAPTION "Edit Test"
FONT 8, "MS Shell Dlg"
{
PUSHBUTTON "OK", IDOK, 20, 60, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
PUSHBUTTON "Cancel", IDCANCEL, 100, 60, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
EDITTEXT 1000, 5, 5, 150, 50, WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_VSCROLL | ES_AUTOVSCROLL
}
EDIT_SINGLELINE_WANTRETURN_DIALOG DIALOG 0, 0, 160, 80
STYLE WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | DS_CENTER
CAPTION "Edit Test"
FONT 8, "MS Shell Dlg"
{
PUSHBUTTON "OK", IDOK, 20, 60, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
PUSHBUTTON "Cancel", IDCANCEL, 100, 60, 50, 14, WS_CHILD | WS_VISIBLE | WS_TABSTOP
EDITTEXT 1000, 5, 5, 150, 50, WS_CHILD | WS_VISIBLE | WS_TABSTOP | WS_VSCROLL | ES_AUTOVSCROLL | ES_WANTRETURN
}

View file

@ -0,0 +1,168 @@
/* Unit test suite for static controls.
*
* Copyright 2007 Google (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 "precomp.h"
#define TODO_COUNT 1
#define CTRL_ID 1995
static HWND hMainWnd;
static int g_nReceivedColorStatic;
/* try to make sure pending X events have been processed before continuing */
static void flush_events(void)
{
MSG msg;
int diff = 200;
int min_timeout = 100;
DWORD time = GetTickCount() + diff;
while (diff > 0)
{
if (MsgWaitForMultipleObjects( 0, NULL, FALSE, min_timeout, QS_ALLINPUT ) == WAIT_TIMEOUT) break;
while (PeekMessageA( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessageA( &msg );
diff = time - GetTickCount();
}
}
static HWND create_static(DWORD style)
{
return CreateWindowA("static", "Test", WS_VISIBLE|WS_CHILD|style, 5, 5, 100, 100, hMainWnd, (HMENU)CTRL_ID, NULL, 0);
}
static LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
switch (msg)
{
case WM_CTLCOLORSTATIC:
{
HDC hdc = (HDC)wparam;
HRGN hrgn = CreateRectRgn(0, 0, 1, 1);
ok(GetClipRgn(hdc, hrgn) == 1, "Static controls during a WM_CTLCOLORSTATIC must have a clipping region\n");
DeleteObject(hrgn);
g_nReceivedColorStatic++;
return (LRESULT) GetStockObject(BLACK_BRUSH);
}
break;
}
return DefWindowProcA(hwnd, msg, wparam, lparam);
}
static void test_updates(int style, int flags)
{
HWND hStatic = create_static(style);
RECT r1 = {20, 20, 30, 30};
int exp;
flush_events();
g_nReceivedColorStatic = 0;
/* during each update parent WndProc will test the WM_CTLCOLORSTATIC message */
InvalidateRect(hMainWnd, NULL, FALSE);
UpdateWindow(hMainWnd);
InvalidateRect(hMainWnd, &r1, FALSE);
UpdateWindow(hMainWnd);
InvalidateRect(hStatic, &r1, FALSE);
UpdateWindow(hStatic);
InvalidateRect(hStatic, NULL, FALSE);
UpdateWindow(hStatic);
if ((style & SS_TYPEMASK) == SS_BITMAP)
{
HDC hdc = GetDC(hStatic);
COLORREF colour = GetPixel(hdc, 10, 10);
todo_wine
ok(colour == 0, "Unexpected pixel color.\n");
ReleaseDC(hStatic, hdc);
}
if (style != SS_ETCHEDHORZ && style != SS_ETCHEDVERT)
exp = 4;
else
exp = 1; /* SS_ETCHED* seems to send WM_CTLCOLORSTATIC only sometimes */
if (flags & TODO_COUNT)
todo_wine
ok(g_nReceivedColorStatic == exp, "Unexpected WM_CTLCOLORSTATIC value %d\n", g_nReceivedColorStatic);
else if ((style & SS_TYPEMASK) == SS_ICON || (style & SS_TYPEMASK) == SS_BITMAP)
ok(g_nReceivedColorStatic == exp, "Unexpected %u got %u\n", exp, g_nReceivedColorStatic);
else
ok(g_nReceivedColorStatic == exp, "Unexpected WM_CTLCOLORSTATIC value %d\n", g_nReceivedColorStatic);
DestroyWindow(hStatic);
}
static void test_set_text(void)
{
HWND hStatic = create_static(SS_SIMPLE);
char buffA[10];
GetWindowTextA(hStatic, buffA, sizeof(buffA));
ok(!strcmp(buffA, "Test"), "got wrong text %s\n", buffA);
SetWindowTextA(hStatic, NULL);
GetWindowTextA(hStatic, buffA, sizeof(buffA));
ok(buffA[0] == 0, "got wrong text %s\n", buffA);
DestroyWindow(hStatic);
}
START_TEST(static)
{
static const char classname[] = "testclass";
WNDCLASSEXA wndclass;
ULONG_PTR ctx_cookie;
HANDLE hCtx;
if (!load_v6_module(&ctx_cookie, &hCtx))
return;
wndclass.cbSize = sizeof(wndclass);
wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = WndProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hInstance = GetModuleHandleA(NULL);
wndclass.hIcon = LoadIconA(NULL, (LPCSTR)IDI_APPLICATION);
wndclass.hIconSm = LoadIconA(NULL, (LPCSTR)IDI_APPLICATION);
wndclass.hCursor = LoadCursorA(NULL, (LPCSTR)IDC_ARROW);
wndclass.hbrBackground = GetStockObject(WHITE_BRUSH);
wndclass.lpszClassName = classname;
wndclass.lpszMenuName = NULL;
RegisterClassExA(&wndclass);
hMainWnd = CreateWindowA(classname, "Test", WS_OVERLAPPEDWINDOW, 0, 0, 500, 500, NULL, NULL,
GetModuleHandleA(NULL), NULL);
ShowWindow(hMainWnd, SW_SHOW);
test_updates(0, 0);
test_updates(SS_SIMPLE, 0);
test_updates(SS_ICON, 0);
test_updates(SS_BITMAP, 0);
test_updates(SS_BITMAP | SS_CENTERIMAGE, 0);
test_updates(SS_BLACKRECT, TODO_COUNT);
test_updates(SS_WHITERECT, TODO_COUNT);
test_updates(SS_ETCHEDHORZ, TODO_COUNT);
test_updates(SS_ETCHEDVERT, TODO_COUNT);
test_set_text();
DestroyWindow(hMainWnd);
unload_v6_module(ctx_cookie, hCtx);
}

View file

@ -175,65 +175,15 @@ static HWND create_syslink(DWORD style, HWND parent)
return hWndSysLink;
}
START_TEST(syslink)
static void test_create_syslink(void)
{
ULONG_PTR ctx_cookie;
HANDLE hCtx;
HMODULE hComctl32;
BOOL (WINAPI *pInitCommonControlsEx)(const INITCOMMONCONTROLSEX*);
INITCOMMONCONTROLSEX iccex;
BOOL rc;
HWND hWndSysLink;
LONG oldstyle;
POINT orig_pos;
if (!load_v6_module(&ctx_cookie, &hCtx))
return;
/* LoadLibrary is needed. This file has no reference to functions in comctl32 */
hComctl32 = LoadLibraryA("comctl32.dll");
pInitCommonControlsEx = (void*)GetProcAddress(hComctl32, "InitCommonControlsEx");
if (!pInitCommonControlsEx)
{
win_skip("InitCommonControlsEx() is missing. Skipping the tests\n");
return;
}
iccex.dwSize = sizeof(iccex);
iccex.dwICC = ICC_LINK_CLASS;
rc = pInitCommonControlsEx(&iccex);
ok(rc, "InitCommonControlsEx failed (le %u)\n", GetLastError());
if (!rc)
{
skip("Could not register ICC_LINK_CLASS\n");
return;
}
/* Move the cursor off the parent window */
GetCursorPos(&orig_pos);
SetCursorPos(400, 400);
init_msg_sequences(sequences, NUM_MSG_SEQUENCE);
/* Create parent window */
hWndParent = create_parent_window();
ok(hWndParent != NULL, "Failed to create parent Window!\n");
if (!hWndParent)
{
skip("Parent window not present\n");
return;
}
flush_events();
/* Create an invisible SysLink control */
flush_sequences(sequences, NUM_MSG_SEQUENCE);
hWndSysLink = create_syslink(WS_CHILD | WS_TABSTOP, hWndParent);
ok(hWndSysLink != NULL, "Expected non NULL value (le %u)\n", GetLastError());
if (!hWndSysLink)
{
skip("SysLink control not present?\n");
return;
}
flush_events();
ok_sequence(sequences, SYSLINK_SEQ_INDEX, empty_wnd_seq, "create SysLink", FALSE);
ok_sequence(sequences, PARENT_SEQ_INDEX, parent_create_syslink_wnd_seq, "create SysLink (parent)", TRUE);
@ -248,6 +198,74 @@ START_TEST(syslink)
ok_sequence(sequences, PARENT_SEQ_INDEX, parent_visible_syslink_wnd_seq, "visible SysLink (parent)", TRUE);
DestroyWindow(hWndSysLink);
}
static void test_LM_GETIDEALHEIGHT(void)
{
HWND hwnd;
LONG ret;
hwnd = create_syslink(WS_CHILD | WS_TABSTOP | WS_VISIBLE, hWndParent);
ok(hwnd != NULL, "Failed to create SysLink window.\n");
ret = SendMessageA(hwnd, LM_GETIDEALHEIGHT, 0, 0);
ok(ret > 0, "Unexpected ideal height, %d.\n", ret);
DestroyWindow(hwnd);
}
static void test_LM_GETIDEALSIZE(void)
{
HWND hwnd;
LONG ret;
SIZE sz;
hwnd = create_syslink(WS_CHILD | WS_TABSTOP | WS_VISIBLE, hWndParent);
ok(hwnd != NULL, "Failed to create SysLink window.\n");
memset(&sz, 0, sizeof(sz));
ret = SendMessageA(hwnd, LM_GETIDEALSIZE, 0, (LPARAM)&sz);
ok(ret > 0, "Unexpected return value, %d.\n", ret);
if (sz.cy == 0)
win_skip("LM_GETIDEALSIZE is not supported.\n");
else
{
ok(sz.cx > 5, "Unexpected ideal width, %d.\n", sz.cx);
ok(sz.cy == ret, "Unexpected ideal height, %d.\n", sz.cy);
}
DestroyWindow(hwnd);
}
START_TEST(syslink)
{
ULONG_PTR ctx_cookie;
HMODULE hComctl32;
POINT orig_pos;
HANDLE hCtx;
if (!load_v6_module(&ctx_cookie, &hCtx))
return;
/* LoadLibrary is needed. This file has no reference to functions in comctl32 */
hComctl32 = LoadLibraryA("comctl32.dll");
ok(hComctl32 != NULL, "Failed to load comctl32.dll.\n");
/* Move the cursor off the parent window */
GetCursorPos(&orig_pos);
SetCursorPos(400, 400);
init_msg_sequences(sequences, NUM_MSG_SEQUENCE);
/* Create parent window */
hWndParent = create_parent_window();
ok(hWndParent != NULL, "Failed to create parent Window!\n");
flush_events();
test_create_syslink();
test_LM_GETIDEALHEIGHT();
test_LM_GETIDEALSIZE();
DestroyWindow(hWndParent);
unload_v6_module(ctx_cookie, hCtx);
SetCursorPos(orig_pos.x, orig_pos.y);

View file

@ -19,10 +19,268 @@
#include "precomp.h"
#define WM_TD_CALLBACK (WM_APP) /* Custom dummy message to wrap callback notifications */
#define NUM_MSG_SEQUENCES 1
#define TASKDIALOG_SEQ_INDEX 0
#define TEST_NUM_BUTTONS 10 /* Number of custom buttons to test with */
#define ID_START 20 /* Lower IDs might be used by the system */
#define ID_START_BUTTON (ID_START + 0)
static HRESULT (WINAPI *pTaskDialogIndirect)(const TASKDIALOGCONFIG *, int *, int *, BOOL *);
static HRESULT (WINAPI *pTaskDialog)(HWND, HINSTANCE, const WCHAR *, const WCHAR *, const WCHAR *,
TASKDIALOG_COMMON_BUTTON_FLAGS, const WCHAR *, int *);
static struct msg_sequence *sequences[NUM_MSG_SEQUENCES];
struct message_info
{
UINT message;
WPARAM wparam;
LPARAM lparam;
HRESULT callback_retval;
const struct message_info *send; /* Message to send to trigger the next callback message */
};
static const struct message_info *current_message_info;
/* Messages to send */
static const struct message_info msg_send_return[] =
{
{ WM_KEYDOWN, VK_RETURN, 0 },
{ 0 }
};
/* Messages to test against */
static const struct message_info msg_return_press_ok[] =
{
{ TDN_CREATED, 0, 0, S_OK, msg_send_return },
{ TDN_BUTTON_CLICKED, IDOK, 0, S_OK, NULL },
{ 0 }
};
static const struct message_info msg_return_press_yes[] =
{
{ TDN_CREATED, 0, 0, S_OK, msg_send_return },
{ TDN_BUTTON_CLICKED, IDYES, 0, S_OK, NULL },
{ 0 }
};
static const struct message_info msg_return_press_no[] =
{
{ TDN_CREATED, 0, 0, S_OK, msg_send_return },
{ TDN_BUTTON_CLICKED, IDNO, 0, S_OK, NULL },
{ 0 }
};
static const struct message_info msg_return_press_cancel[] =
{
{ TDN_CREATED, 0, 0, S_OK, msg_send_return },
{ TDN_BUTTON_CLICKED, IDCANCEL, 0, S_OK, NULL },
{ 0 }
};
static const struct message_info msg_return_press_retry[] =
{
{ TDN_CREATED, 0, 0, S_OK, msg_send_return },
{ TDN_BUTTON_CLICKED, IDRETRY, 0, S_OK, NULL },
{ 0 }
};
static const struct message_info msg_return_press_custom1[] =
{
{ TDN_CREATED, 0, 0, S_OK, msg_send_return },
{ TDN_BUTTON_CLICKED, ID_START_BUTTON, 0, S_OK, NULL },
{ 0 }
};
static const struct message_info msg_return_press_custom4[] =
{
{ TDN_CREATED, 0, 0, S_OK, msg_send_return },
{ TDN_BUTTON_CLICKED, ID_START_BUTTON + 3, 0, S_OK, NULL },
{ 0 }
};
static const struct message_info msg_return_press_custom10[] =
{
{ TDN_CREATED, 0, 0, S_OK, msg_send_return },
{ TDN_BUTTON_CLICKED, -1, 0, S_OK, NULL },
{ 0 }
};
static void init_test_message(UINT message, WPARAM wParam, LPARAM lParam, struct message *msg)
{
msg->message = WM_TD_CALLBACK;
msg->flags = sent|wparam|lparam|id;
msg->wParam = wParam;
msg->lParam = lParam;
msg->id = message;
msg->stage = 0;
}
#define run_test(info, expect_button, seq, context) \
run_test_(info, expect_button, seq, context, \
sizeof(seq)/sizeof(seq[0]) - 1, __FILE__, __LINE__)
static void run_test_(TASKDIALOGCONFIG *info, int expect_button, const struct message_info *test_messages,
const char *context, int test_messages_len, const char *file, int line)
{
struct message *msg, *msg_start;
int ret_button = 0;
int ret_radio = 0;
HRESULT hr;
int i;
/* Allocate messages to test against, plus 2 implicit and 1 empty */
msg_start = msg = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*msg) * (test_messages_len + 3));
/* Always needed, thus made implicit */
init_test_message(TDN_DIALOG_CONSTRUCTED, 0, 0, msg++);
for (i = 0; i < test_messages_len; i++)
init_test_message(test_messages[i].message, test_messages[i].wparam, test_messages[i].lparam, msg++);
/* Always needed, thus made implicit */
init_test_message(TDN_DESTROYED, 0, 0, msg++);
current_message_info = test_messages;
flush_sequences(sequences, NUM_MSG_SEQUENCES);
hr = pTaskDialogIndirect(info, &ret_button, &ret_radio, NULL);
ok_(file, line)(hr == S_OK, "TaskDialogIndirect() failed, got %#x.\n", hr);
ok_sequence_(sequences, TASKDIALOG_SEQ_INDEX, msg_start, context, FALSE, file, line);
ok_(file, line)(ret_button == expect_button,
"Wrong button. Expected %d, got %d\n", expect_button, ret_button);
HeapFree(GetProcessHeap(), 0, msg_start);
}
static const LONG_PTR test_ref_data = 123456;
static HRESULT CALLBACK taskdialog_callback_proc(HWND hwnd, UINT notification,
WPARAM wParam, LPARAM lParam, LONG_PTR ref_data)
{
int msg_pos = sequences[TASKDIALOG_SEQ_INDEX]->count - 1; /* Skip implicit message */
const struct message_info *msg_send;
struct message msg;
ok(test_ref_data == ref_data, "Unexpected ref data %lu.\n", ref_data);
init_test_message(notification, (short)wParam, lParam, &msg);
add_message(sequences, TASKDIALOG_SEQ_INDEX, &msg);
if (notification == TDN_DIALOG_CONSTRUCTED || notification == TDN_DESTROYED) /* Skip implicit messages */
return S_OK;
msg_send = current_message_info[msg_pos].send;
for(; msg_send && msg_send->message; msg_send++)
PostMessageW(hwnd, msg_send->message, msg_send->wparam, msg_send->lparam);
return current_message_info[msg_pos].callback_retval;
}
static void test_invalid_parameters(void)
{
TASKDIALOGCONFIG info = { 0 };
HRESULT hr;
hr = pTaskDialogIndirect(NULL, NULL, NULL, NULL);
ok(hr == E_INVALIDARG, "Unexpected return value %#x.\n", hr);
info.cbSize = 0;
hr = pTaskDialogIndirect(&info, NULL, NULL, NULL);
ok(hr == E_INVALIDARG, "Unexpected return value %#x.\n", hr);
info.cbSize = sizeof(TASKDIALOGCONFIG) - 1;
hr = pTaskDialogIndirect(&info, NULL, NULL, NULL);
ok(hr == E_INVALIDARG, "Unexpected return value %#x.\n", hr);
info.cbSize = sizeof(TASKDIALOGCONFIG) + 1;
hr = pTaskDialogIndirect(&info, NULL, NULL, NULL);
ok(hr == E_INVALIDARG, "Unexpected return value %#x.\n", hr);
}
static void test_callback(void)
{
TASKDIALOGCONFIG info = {0};
info.cbSize = sizeof(TASKDIALOGCONFIG);
info.pfCallback = taskdialog_callback_proc;
info.lpCallbackData = test_ref_data;
run_test(&info, IDOK, msg_return_press_ok, "Press VK_RETURN.");
}
static void test_buttons(void)
{
TASKDIALOGCONFIG info = {0};
TASKDIALOG_BUTTON custom_buttons[TEST_NUM_BUTTONS];
const WCHAR button_format[] = {'%','0','2','d',0};
WCHAR button_titles[TEST_NUM_BUTTONS * 3]; /* Each button has two digits as title, plus null-terminator */
int i;
info.cbSize = sizeof(TASKDIALOGCONFIG);
info.pfCallback = taskdialog_callback_proc;
info.lpCallbackData = test_ref_data;
/* Init custom buttons */
for (i = 0; i < TEST_NUM_BUTTONS; i++)
{
WCHAR *text = &button_titles[i * 3];
wsprintfW(text, button_format, i);
custom_buttons[i].pszButtonText = text;
custom_buttons[i].nButtonID = ID_START_BUTTON + i;
}
custom_buttons[TEST_NUM_BUTTONS - 1].nButtonID = -1;
/* Test nDefaultButton */
/* Test common buttons with invalid default ID */
info.nDefaultButton = 0; /* Should default to first created button */
info.dwCommonButtons = TDCBF_OK_BUTTON | TDCBF_YES_BUTTON | TDCBF_NO_BUTTON
| TDCBF_CANCEL_BUTTON | TDCBF_RETRY_BUTTON | TDCBF_CLOSE_BUTTON;
run_test(&info, IDOK, msg_return_press_ok, "default button: unset default");
info.dwCommonButtons = TDCBF_YES_BUTTON | TDCBF_NO_BUTTON
| TDCBF_CANCEL_BUTTON | TDCBF_RETRY_BUTTON | TDCBF_CLOSE_BUTTON;
run_test(&info, IDYES, msg_return_press_yes, "default button: unset default");
info.dwCommonButtons = TDCBF_NO_BUTTON | TDCBF_CANCEL_BUTTON | TDCBF_RETRY_BUTTON | TDCBF_CLOSE_BUTTON;
run_test(&info, IDNO, msg_return_press_no, "default button: unset default");
info.dwCommonButtons = TDCBF_CANCEL_BUTTON | TDCBF_RETRY_BUTTON | TDCBF_CLOSE_BUTTON;
run_test(&info, IDRETRY, msg_return_press_retry, "default button: unset default");
info.dwCommonButtons = TDCBF_CANCEL_BUTTON | TDCBF_CLOSE_BUTTON;
run_test(&info, IDCANCEL, msg_return_press_cancel, "default button: unset default");
/* Test with all common and custom buttons and invalid default ID */
info.nDefaultButton = 0xff; /* Random ID, should also default to first created button */
info.cButtons = TEST_NUM_BUTTONS;
info.pButtons = custom_buttons;
run_test(&info, ID_START_BUTTON, msg_return_press_custom1, "default button: invalid default, with common buttons - 1");
info.nDefaultButton = -1; /* Should work despite button ID -1 */
run_test(&info, -1, msg_return_press_custom10, "default button: invalid default, with common buttons - 2");
info.nDefaultButton = -2; /* Should also default to first created button */
run_test(&info, ID_START_BUTTON, msg_return_press_custom1, "default button: invalid default, with common buttons - 3");
/* Test with only custom buttons and invalid default ID */
info.dwCommonButtons = 0;
run_test(&info, ID_START_BUTTON, msg_return_press_custom1, "default button: invalid default, no common buttons");
/* Test with common and custom buttons and valid default ID */
info.dwCommonButtons = TDCBF_OK_BUTTON | TDCBF_YES_BUTTON | TDCBF_NO_BUTTON
| TDCBF_CANCEL_BUTTON | TDCBF_RETRY_BUTTON | TDCBF_CLOSE_BUTTON;
info.nDefaultButton = IDRETRY;
run_test(&info, IDRETRY, msg_return_press_retry, "default button: valid default - 1");
/* Test with common and custom buttons and valid default ID */
info.nDefaultButton = ID_START_BUTTON + 3;
run_test(&info, ID_START_BUTTON + 3, msg_return_press_custom4, "default button: valid default - 2");
}
START_TEST(taskdialog)
{
ULONG_PTR ctx_cookie;
@ -54,5 +312,11 @@ START_TEST(taskdialog)
ok(pTaskDialogIndirect == ptr_ordinal, "got wrong pointer for ordinal 345, %p expected %p\n",
ptr_ordinal, pTaskDialogIndirect);
init_msg_sequences(sequences, NUM_MSG_SEQUENCES);
test_invalid_parameters();
test_callback();
test_buttons();
unload_v6_module(ctx_cookie, hCtx);
}

View file

@ -5,12 +5,14 @@
extern void func_animate(void);
extern void func_button(void);
extern void func_comboex(void);
extern void func_combo(void);
extern void func_datetime(void);
extern void func_dpa(void);
extern void func_edit(void);
extern void func_header(void);
extern void func_imagelist(void);
extern void func_ipaddress(void);
extern void func_listbox(void);
extern void func_listview(void);
extern void func_misc(void);
extern void func_monthcal(void);
@ -19,6 +21,7 @@ extern void func_pager(void);
extern void func_progress(void);
extern void func_propsheet(void);
extern void func_rebar(void);
extern void func_static(void);
extern void func_status(void);
extern void func_subclass(void);
extern void func_syslink(void);
@ -34,12 +37,14 @@ const struct test winetest_testlist[] =
{
{ "animate", func_animate },
{ "button", func_button },
{ "comboex", func_comboex },
{ "combo", func_combo },
{ "datetime", func_datetime },
{ "dpa", func_dpa },
{ "edit", func_edit },
{ "header", func_header },
{ "imagelist", func_imagelist },
{ "ipaddress", func_ipaddress },
{ "listbox", func_listbox },
{ "listview", func_listview },
{ "misc", func_misc },
{ "monthcal", func_monthcal },
@ -48,6 +53,7 @@ const struct test winetest_testlist[] =
{ "progress", func_progress },
{ "propsheet", func_propsheet },
{ "rebar", func_rebar },
{ "static", func_static },
{ "status", func_status },
{ "subclass", func_subclass },
{ "syslink", func_syslink },

View file

@ -146,8 +146,8 @@ static void test_customdraw(void) {
DWORD iterationNumber;
WNDCLASSA wc;
LRESULT lResult;
POINT orig_pos;
LRESULT ret;
/* Create a class to use the custom draw wndproc */
wc.style = CS_HREDRAW | CS_VREDRAW;
@ -211,8 +211,8 @@ static void test_customdraw(void) {
toolInfo.lpszText = (LPSTR)"This is a test tooltip";
toolInfo.lParam = 0xdeadbeef;
GetClientRect (parent, &toolInfo.rect);
lResult = SendMessageA(hwndTip, TTM_ADDTOOLA, 0, (LPARAM)&toolInfo);
ok(lResult, "Adding the tool to the tooltip failed\n");
ret = SendMessageA(hwndTip, TTM_ADDTOOLA, 0, (LPARAM)&toolInfo);
ok(ret, "Failed to add the tool.\n");
/* Make tooltip appear quickly */
SendMessageA(hwndTip, TTM_SETDELAYTIME, TTDT_INITIAL, MAKELPARAM(1,0));
@ -231,6 +231,20 @@ static void test_customdraw(void) {
expectedResults[iterationNumber].ExpectedCalls);
}
ret = SendMessageA(hwndTip, TTM_GETCURRENTTOOLA, 0, 0);
ok(ret, "Failed to get current tool %#lx.\n", ret);
memset(&toolInfo, 0xcc, sizeof(toolInfo));
toolInfo.cbSize = sizeof(toolInfo);
toolInfo.lpszText = NULL;
toolInfo.lpReserved = (void *)0xdeadbeef;
SendMessageA(hwndTip, TTM_GETCURRENTTOOLA, 0, (LPARAM)&toolInfo);
ok(toolInfo.hwnd == parent, "Unexpected hwnd %p.\n", toolInfo.hwnd);
ok(toolInfo.hinst == GetModuleHandleA(NULL), "Unexpected hinst %p.\n", toolInfo.hinst);
ok(toolInfo.uId == 0x1234abcd, "Unexpected uId %lx.\n", toolInfo.uId);
ok(toolInfo.lParam == 0, "Unexpected lParam %lx.\n", toolInfo.lParam);
ok(toolInfo.lpReserved == (void *)0xdeadbeef, "Unexpected lpReserved %p.\n", toolInfo.lpReserved);
/* Clean up */
DestroyWindow(hwndTip);
DestroyWindow(parent);
@ -436,33 +450,6 @@ todo_wine
r = SendMessageW(hwnd, TTM_ADDTOOLW, 0, (LPARAM)&toolinfoW);
ok(!r, "Adding the tool to the tooltip succeeded!\n");
/* lpszText with an invalid address */
toolinfoW.cbSize = sizeof(TTTOOLINFOW);
toolinfoW.hwnd = notify;
toolinfoW.hinst = GetModuleHandleA(NULL);
toolinfoW.uFlags = 0;
toolinfoW.uId = 0;
toolinfoW.lpszText = (LPWSTR)0xdeadbeef;
toolinfoW.lParam = 0;
GetClientRect(hwnd, &toolinfoW.rect);
r = SendMessageA(hwnd, TTM_ADDTOOLW, 0, (LPARAM)&toolinfoW);
ok(!r, "Adding the tool to the tooltip succeeded!\n");
/* lpszText with an invalid address. Crashes using TTTOOLINFOA message */
if(0)
{
toolinfoA.cbSize = sizeof(TTTOOLINFOA);
toolinfoA.hwnd = notify;
toolinfoA.hinst = GetModuleHandleA(NULL);
toolinfoA.uFlags = 0;
toolinfoA.uId = 0;
toolinfoA.lpszText = (LPSTR)0xdeadbeef;
toolinfoA.lParam = 0;
GetClientRect(hwnd, &toolinfoA.rect);
r = SendMessageA(hwnd, TTM_ADDTOOLA, 0, (LPARAM)&toolinfoA);
ok(!r, "Adding the tool to the tooltip succeeded!\n");
}
if (0) /* crashes on NT4 */
{
toolinfoW.hwnd = NULL;
@ -513,9 +500,8 @@ static void test_ttm_gettoolinfo(void)
HWND hwnd;
DWORD r;
hwnd = CreateWindowExA(0, TOOLTIPS_CLASSA, NULL, 0,
10, 10, 300, 100,
NULL, NULL, NULL, 0);
hwnd = CreateWindowExA(0, TOOLTIPS_CLASSA, NULL, 0, 10, 10, 300, 100, NULL, NULL, NULL, 0);
ok(hwnd != NULL, "Failed to create tooltip control.\n");
ti.cbSize = TTTOOLINFOA_V2_SIZE;
ti.hwnd = NULL;
@ -633,11 +619,7 @@ static void test_ttm_gettoolinfo(void)
hwnd = CreateWindowExW(0, TOOLTIPS_CLASSW, NULL, 0,
10, 10, 300, 100,
NULL, NULL, NULL, 0);
if(!hwnd)
{
win_skip("CreateWindowExW() not supported. Skipping.\n");
return;
}
ok(hwnd != NULL, "Failed to create tooltip window.\n");
tiW.cbSize = TTTOOLINFOW_V1_SIZE - 1;
tiW.hwnd = NULL;
@ -779,11 +761,7 @@ static void test_longtextW(void)
hwnd = CreateWindowExW(0, TOOLTIPS_CLASSW, NULL, 0,
10, 10, 300, 100,
NULL, NULL, NULL, 0);
if(!hwnd)
{
win_skip("CreateWindowExW() not supported. Skipping.\n");
return;
}
ok(hwnd != NULL, "Failed to create tooltip window.\n");
toolinfoW.cbSize = TTTOOLINFOW_V2_SIZE;
toolinfoW.hwnd = NULL;

View file

@ -207,6 +207,9 @@ static const struct message test_right_click_seq[] = {
{ WM_RBUTTONDOWN, sent|wparam, MK_RBUTTON },
{ WM_CAPTURECHANGED, sent|defwinproc },
{ TVM_GETNEXTITEM, sent|wparam|lparam|defwinproc, TVGN_CARET, 0 },
{ WM_NCHITTEST, sent|optional },
{ WM_SETCURSOR, sent|optional },
{ WM_MOUSEMOVE, sent|optional },
{ 0 }
};
@ -354,6 +357,8 @@ static const struct message parent_vk_return_seq[] = {
static const struct message parent_right_click_seq[] = {
{ WM_NOTIFY, sent|id, 0, 0, NM_RCLICK },
{ WM_CONTEXTMENU, sent },
{ WM_NOTIFY, sent|optional },
{ WM_SETCURSOR, sent|optional },
{ 0 }
};

View file

@ -288,11 +288,16 @@ static HWND create_updown_control(DWORD style, HWND buddy)
RECT rect;
GetClientRect(parent_wnd, &rect);
updown = CreateUpDownControl(WS_CHILD | WS_BORDER | WS_VISIBLE | style,
0, 0, rect.right, rect.bottom, parent_wnd, 1, GetModuleHandleA(NULL), buddy,
100, 0, 50);
updown = CreateWindowExA(0, UPDOWN_CLASSA, NULL, WS_CHILD | WS_BORDER | WS_VISIBLE | style,
0, 0, rect.right, rect.bottom,
parent_wnd, (HMENU)1, GetModuleHandleA(NULL), NULL);
ok(updown != NULL, "Failed to create UpDown control.\n");
if (!updown) return NULL;
SendMessageA(updown, UDM_SETBUDDY, (WPARAM)buddy, 0);
SendMessageA(updown, UDM_SETRANGE, 0, MAKELONG(100, 0));
SendMessageA(updown, UDM_SETPOS, 0, MAKELONG(50, 0));
oldproc = (WNDPROC)SetWindowLongPtrA(updown, GWLP_WNDPROC,
(LONG_PTR)updown_subclass_proc);
SetWindowLongPtrA(updown, GWLP_USERDATA, (LONG_PTR)oldproc);
@ -512,6 +517,7 @@ static void test_updown_pos32(void)
static void test_updown_buddy(void)
{
HWND updown, buddyReturn, buddy;
RECT rect, rect2;
WNDPROC proc;
DWORD style;
@ -558,8 +564,82 @@ static void test_updown_buddy(void)
}
DestroyWindow(updown);
DestroyWindow(buddy);
/* Create with buddy and UDS_HORZ, reset buddy. */
updown = create_updown_control(UDS_HORZ, g_edit);
buddyReturn = (HWND)SendMessageA(updown, UDM_GETBUDDY, 0, 0);
ok(buddyReturn == g_edit, "Unexpected buddy window.\n");
GetClientRect(updown, &rect);
buddyReturn = (HWND)SendMessageA(updown, UDM_SETBUDDY, 0, 0);
ok(buddyReturn == g_edit, "Unexpected buddy window.\n");
GetClientRect(updown, &rect2);
ok(EqualRect(&rect, &rect2), "Unexpected window rect.\n");
/* Remove UDS_HORZ, reset buddy again. */
style = GetWindowLongA(updown, GWL_STYLE);
SetWindowLongA(updown, GWL_STYLE, style & ~UDS_HORZ);
style = GetWindowLongA(updown, GWL_STYLE);
ok(!(style & UDS_HORZ), "Unexpected style.\n");
buddyReturn = (HWND)SendMessageA(updown, UDM_SETBUDDY, 0, 0);
ok(buddyReturn == NULL, "Unexpected buddy window.\n");
GetClientRect(updown, &rect2);
ok(EqualRect(&rect, &rect2), "Unexpected window rect.\n");
DestroyWindow(updown);
/* Without UDS_HORZ. */
updown = create_updown_control(0, g_edit);
buddyReturn = (HWND)SendMessageA(updown, UDM_GETBUDDY, 0, 0);
ok(buddyReturn == g_edit, "Unexpected buddy window.\n");
GetClientRect(updown, &rect);
buddyReturn = (HWND)SendMessageA(updown, UDM_SETBUDDY, 0, 0);
ok(buddyReturn == g_edit, "Unexpected buddy window.\n");
GetClientRect(updown, &rect2);
ok(EqualRect(&rect, &rect2), "Unexpected window rect.\n");
DestroyWindow(updown);
/* Create without buddy. */
GetClientRect(parent_wnd, &rect);
updown = CreateWindowExA(0, UPDOWN_CLASSA, NULL, WS_CHILD | WS_BORDER | WS_VISIBLE | UDS_HORZ,
0, 0, rect.right, rect.bottom, parent_wnd, (HMENU)1, GetModuleHandleA(NULL), NULL);
ok(updown != NULL, "Failed to create UpDown control.\n");
GetClientRect(updown, &rect);
buddyReturn = (HWND)SendMessageA(updown, UDM_SETBUDDY, 0, 0);
ok(buddyReturn == NULL, "Unexpected buddy window.\n");
GetClientRect(updown, &rect2);
ok(EqualRect(&rect, &rect2), "Unexpected window rect.\n");
style = GetWindowLongA(updown, GWL_STYLE);
SetWindowLongA(updown, GWL_STYLE, style & ~UDS_HORZ);
GetClientRect(updown, &rect2);
ok(EqualRect(&rect, &rect2), "Unexpected window rect.\n");
buddyReturn = (HWND)SendMessageA(updown, UDM_SETBUDDY, (WPARAM)g_edit, 0);
ok(buddyReturn == NULL, "Unexpected buddy window.\n");
GetClientRect(updown, &rect);
buddyReturn = (HWND)SendMessageA(updown, UDM_SETBUDDY, 0, 0);
ok(buddyReturn == g_edit, "Unexpected buddy window.\n");
GetClientRect(updown, &rect2);
todo_wine
ok(EqualRect(&rect, &rect2), "Unexpected window rect.\n");
DestroyWindow(updown);
}
static void test_updown_base(void)
@ -790,6 +870,29 @@ static void test_UDS_SETBUDDYINT(void)
DestroyWindow(updown);
}
static void test_CreateUpDownControl(void)
{
HWND updown, buddy;
DWORD range, pos;
RECT rect;
GetClientRect(parent_wnd, &rect);
updown = CreateUpDownControl(WS_CHILD | WS_BORDER | WS_VISIBLE,
0, 0, rect.right, rect.bottom, parent_wnd, 1, GetModuleHandleA(NULL), g_edit, 100, 10, 50);
ok(updown != NULL, "Failed to create control.\n");
buddy = (HWND)SendMessageA(updown, UDM_GETBUDDY, 0, 0);
ok(buddy == g_edit, "Unexpected buddy window.\n");
range = SendMessageA(updown, UDM_GETRANGE, 0, 0);
ok(range == MAKELONG(100, 10), "Unexpected range.\n");
pos = SendMessageA(updown, UDM_GETPOS, 0, 0);
ok(pos == MAKELONG(50, 1), "Unexpected position.\n");
DestroyWindow(updown);
}
START_TEST(updown)
{
HMODULE mod = GetModuleHandleA("comctl32.dll");
@ -811,6 +914,7 @@ START_TEST(updown)
test_updown_base();
test_updown_unicode();
test_UDS_SETBUDDYINT();
test_CreateUpDownControl();
DestroyWindow(g_edit);
DestroyWindow(parent_wnd);