mirror of
https://github.com/reactos/reactos.git
synced 2025-08-02 06:15:52 +00:00
[COMCTL32_WINETEST]
sync to wine 1.2 RC2 svn path=/trunk/; revision=47448
This commit is contained in:
parent
769948f75a
commit
d6fb44f0d7
29 changed files with 8176 additions and 1893 deletions
|
@ -22,11 +22,23 @@
|
|||
#include <commctrl.h>
|
||||
|
||||
#include "wine/test.h"
|
||||
#include "msg.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;
|
||||
|
||||
|
@ -42,7 +54,7 @@ static LONG addItem(HWND cbex, int idx, LPTSTR text) {
|
|||
cbexItem.iItem = idx;
|
||||
cbexItem.pszText = text;
|
||||
cbexItem.cchTextMax = 0;
|
||||
return (LONG)SendMessage(cbex, CBEM_INSERTITEM, 0,(LPARAM)&cbexItem);
|
||||
return SendMessage(cbex, CBEM_INSERTITEM, 0, (LPARAM)&cbexItem);
|
||||
}
|
||||
|
||||
static LONG setItem(HWND cbex, int idx, LPTSTR text) {
|
||||
|
@ -52,11 +64,11 @@ static LONG setItem(HWND cbex, int idx, LPTSTR text) {
|
|||
cbexItem.iItem = idx;
|
||||
cbexItem.pszText = text;
|
||||
cbexItem.cchTextMax = 0;
|
||||
return (LONG)SendMessage(cbex, CBEM_SETITEM, 0,(LPARAM)&cbexItem);
|
||||
return SendMessage(cbex, CBEM_SETITEM, 0, (LPARAM)&cbexItem);
|
||||
}
|
||||
|
||||
static LONG delItem(HWND cbex, int idx) {
|
||||
return (LONG)SendMessage(cbex, CBEM_DELETEITEM, (LPARAM)idx, 0);
|
||||
return SendMessage(cbex, CBEM_DELETEITEM, idx, 0);
|
||||
}
|
||||
|
||||
static LONG getItem(HWND cbex, int idx, COMBOBOXEXITEM *cbItem) {
|
||||
|
@ -65,7 +77,51 @@ static LONG getItem(HWND cbex, int idx, COMBOBOXEXITEM *cbItem) {
|
|||
cbItem->pszText = textBuffer;
|
||||
cbItem->iItem = idx;
|
||||
cbItem->cchTextMax = 100;
|
||||
return (LONG)SendMessage(cbex, CBEM_GETITEM, 0, (LPARAM)cbItem);
|
||||
return SendMessage(cbex, CBEM_GETITEM, 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;
|
||||
LRESULT ret;
|
||||
struct message msg;
|
||||
|
||||
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)SendMessage(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) {
|
||||
|
@ -288,6 +344,41 @@ static void test_WM_LBUTTONDOWN(void)
|
|||
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 = SendMessage(hCombo, CBEM_GETITEMA, 0, (LPARAM)&item);
|
||||
ok(ret != 0, "CBEM_GETITEM failed\n");
|
||||
ok(buff[0] == 0, "\n");
|
||||
|
||||
ret = SendMessage(hCombo, CB_GETLBTEXTLEN, 0, 0);
|
||||
ok(ret == 0, "Expected zero length\n");
|
||||
|
||||
ret = SendMessage(hCombo, CB_GETLBTEXTLEN, 0, 0);
|
||||
ok(ret == 0, "Expected zero length\n");
|
||||
|
||||
buff[0] = 'a';
|
||||
ret = SendMessage(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 LRESULT CALLBACK ComboExTestWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch(msg) {
|
||||
|
@ -321,6 +412,8 @@ static int init(void)
|
|||
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;
|
||||
|
@ -355,13 +448,87 @@ static void cleanup(void)
|
|||
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)SendMessage(hComboEx, CBEM_GETCOMBOCONTROL, 0, 0);
|
||||
ok(hCombo != NULL, "Failed to get internal combo\n");
|
||||
hEdit = (HWND)SendMessage(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 = SendMessage(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 = SendMessage(hComboEx, CBEM_GETITEMA, 0, (LPARAM)&item);
|
||||
expect(TRUE, ret);
|
||||
ok(item.lParam == 0, "Expected zero, got %ld\n", item.lParam);
|
||||
|
||||
item.lParam = 0xdeadbeef;
|
||||
ret = SendMessage(hComboEx, CBEM_SETITEMA, 0, (LPARAM)&item);
|
||||
expect(TRUE, ret);
|
||||
|
||||
item.lParam = 0;
|
||||
ret = SendMessage(hComboEx, CBEM_GETITEMA, 0, (LPARAM)&item);
|
||||
expect(TRUE, ret);
|
||||
ok(item.lParam == 0xdeadbeef, "Expected 0xdeadbeef, got %ld\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_comboboxex_subclass();
|
||||
test_get_set_item();
|
||||
|
||||
cleanup();
|
||||
}
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
<module name="comctl32_winetest" type="win32cui" installbase="bin" installname="comctl32_winetest.exe" allowwarnings="true">
|
||||
<include base="comctl32_winetest">.</include>
|
||||
<define name="__ROS_LONG64__" />
|
||||
<redefine name="_WIN32_WINNT">0x0600</redefine>
|
||||
<redefine name="_WIN32_IE">0x0500</redefine>
|
||||
<file>comboex.c</file>
|
||||
<file>datetime.c</file>
|
||||
<file>dpa.c</file>
|
||||
|
@ -14,7 +16,6 @@
|
|||
<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>
|
||||
|
|
|
@ -1,37 +0,0 @@
|
|||
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"
|
||||
Index: mru.c
|
||||
===================================================================
|
||||
--- mru.c (revision 25766)
|
||||
+++ mru.c (working copy)
|
||||
@@ -75,7 +75,7 @@
|
||||
|
||||
|
||||
/* Based on RegDeleteTreeW from dlls/advapi32/registry.c */
|
||||
-static LSTATUS mru_RegDeleteTreeA(HKEY hKey, LPCSTR lpszSubKey)
|
||||
+static LONG mru_RegDeleteTreeA(HKEY hKey, LPCSTR lpszSubKey)
|
||||
{
|
||||
LONG ret;
|
||||
DWORD dwMaxSubkeyLen, dwMaxValueLen;
|
|
@ -33,113 +33,97 @@
|
|||
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 },
|
||||
{ DTM_SETFORMATA, sent|wparam|lparam, 0, 0 },
|
||||
{ DTM_SETFORMATA, sent|wparam, 0 },
|
||||
{ 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 },
|
||||
{ DTM_SETMCCOLOR, sent|wparam|lparam, MCSC_BACKGROUND, 0 },
|
||||
{ DTM_SETMCCOLOR, sent|wparam|lparam, MCSC_BACKGROUND, RGB(255, 255, 255) },
|
||||
{ DTM_SETMCCOLOR, sent|wparam|lparam, MCSC_BACKGROUND, RGB(100, 180, 220) },
|
||||
{ DTM_GETMCCOLOR, sent|wparam|lparam, MCSC_BACKGROUND, 0 },
|
||||
{ DTM_SETMCCOLOR, sent|wparam|lparam, MCSC_MONTHBK, 0 },
|
||||
{ DTM_SETMCCOLOR, sent|wparam|lparam, MCSC_MONTHBK, RGB(255, 255, 255) },
|
||||
{ DTM_SETMCCOLOR, sent|wparam|lparam, MCSC_MONTHBK, RGB(100, 180, 220) },
|
||||
{ DTM_GETMCCOLOR, sent|wparam|lparam, MCSC_MONTHBK, 0 },
|
||||
{ DTM_SETMCCOLOR, sent|wparam|lparam, MCSC_TEXT, 0 },
|
||||
{ DTM_SETMCCOLOR, sent|wparam|lparam, MCSC_TEXT, RGB(255, 255, 255) },
|
||||
{ DTM_SETMCCOLOR, sent|wparam|lparam, MCSC_TEXT, RGB(100, 180, 220) },
|
||||
{ DTM_GETMCCOLOR, sent|wparam|lparam, MCSC_TEXT, 0 },
|
||||
{ DTM_SETMCCOLOR, sent|wparam|lparam, MCSC_TITLEBK, 0 },
|
||||
{ DTM_SETMCCOLOR, sent|wparam|lparam, MCSC_TITLEBK, RGB(255, 255, 255) },
|
||||
{ DTM_SETMCCOLOR, sent|wparam|lparam, MCSC_TITLEBK, RGB(100, 180, 220) },
|
||||
{ DTM_GETMCCOLOR, sent|wparam|lparam, MCSC_TITLEBK, 0 },
|
||||
{ DTM_SETMCCOLOR, sent|wparam|lparam, MCSC_TITLETEXT, 0 },
|
||||
{ DTM_SETMCCOLOR, sent|wparam|lparam, MCSC_TITLETEXT, RGB(255, 255, 255) },
|
||||
{ DTM_SETMCCOLOR, sent|wparam|lparam, MCSC_TITLETEXT, RGB(100, 180, 220) },
|
||||
{ DTM_GETMCCOLOR, sent|wparam|lparam, MCSC_TITLETEXT, 0 },
|
||||
{ DTM_SETMCCOLOR, sent|wparam|lparam, MCSC_TRAILINGTEXT, 0 },
|
||||
{ DTM_SETMCCOLOR, sent|wparam|lparam, MCSC_TRAILINGTEXT, RGB(255, 255, 255) },
|
||||
{ DTM_SETMCCOLOR, sent|wparam|lparam, MCSC_TRAILINGTEXT, RGB(100, 180, 220) },
|
||||
{ DTM_GETMCCOLOR, sent|wparam|lparam, MCSC_TRAILINGTEXT, 0 },
|
||||
{ 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 },
|
||||
{ DTM_SETMCFONT, sent|lparam, 0, 1 },
|
||||
{ DTM_GETMCFONT, sent|wparam|lparam, 0, 0 },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message test_dtm_get_monthcal_seq[] = {
|
||||
{ DTM_GETMONTHCAL, sent|wparam|lparam, 0x00000000, 0x00000000 },
|
||||
{ DTM_GETMONTHCAL, sent|wparam|lparam, 0, 0 },
|
||||
{ 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 },
|
||||
{ DTM_SETRANGE, sent|wparam, GDTR_MIN },
|
||||
{ DTM_GETRANGE, sent|wparam, 0 },
|
||||
{ DTM_SETRANGE, sent|wparam, GDTR_MAX },
|
||||
{ DTM_SETRANGE, sent|wparam, GDTR_MAX },
|
||||
{ DTM_GETRANGE, sent|wparam, 0 },
|
||||
{ DTM_SETRANGE, sent|wparam, GDTR_MIN },
|
||||
{ DTM_SETRANGE, sent|wparam, GDTR_MIN | GDTR_MAX },
|
||||
{ DTM_SETRANGE, sent|wparam, GDTR_MIN | GDTR_MAX },
|
||||
{ DTM_GETRANGE, sent|wparam, 0 },
|
||||
{ DTM_SETRANGE, sent|wparam, GDTR_MIN | GDTR_MAX },
|
||||
{ DTM_GETRANGE, sent|wparam, 0 },
|
||||
{ DTM_SETRANGE, sent|wparam, GDTR_MIN | GDTR_MAX },
|
||||
{ DTM_GETRANGE, sent|wparam, 0 },
|
||||
{ 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 },
|
||||
{ DTM_SETSYSTEMTIME, sent|wparam, 0 },
|
||||
{ DTM_GETSYSTEMTIME, sent|wparam, 0 },
|
||||
{ DTM_SETRANGE, sent|wparam, GDTR_MIN | GDTR_MAX },
|
||||
{ DTM_GETRANGE, sent|wparam, 0 },
|
||||
{ DTM_SETSYSTEMTIME, sent|wparam, 0 },
|
||||
{ DTM_GETSYSTEMTIME, sent|wparam, 0 },
|
||||
{ DTM_SETRANGE, sent|wparam, GDTR_MIN | GDTR_MAX },
|
||||
{ DTM_GETRANGE, sent|wparam, 0 },
|
||||
{ DTM_SETRANGE, sent|wparam, GDTR_MIN | GDTR_MAX },
|
||||
{ DTM_GETRANGE, sent|wparam, 0 },
|
||||
{ DTM_SETRANGE, sent|wparam, GDTR_MIN | GDTR_MAX },
|
||||
{ DTM_GETRANGE, sent|wparam, 0 },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message test_dtm_set_and_get_system_time_seq[] = {
|
||||
{ DTM_SETSYSTEMTIME, sent|wparam, 0x00000001 },
|
||||
{ 0x0090, sent|optional }, /* Vista */
|
||||
{ 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 },
|
||||
{ DTM_SETSYSTEMTIME, sent|wparam, GDT_NONE },
|
||||
{ DTM_GETSYSTEMTIME, sent|wparam, 0 },
|
||||
{ DTM_SETSYSTEMTIME, sent|wparam, 0 },
|
||||
{ DTM_SETSYSTEMTIME, sent|wparam, 0 },
|
||||
{ DTM_SETSYSTEMTIME, sent|wparam, 0 },
|
||||
{ DTM_GETSYSTEMTIME, sent|wparam, 0 },
|
||||
{ DTM_SETSYSTEMTIME, sent|wparam, 0 },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
static const struct message destroy_window_seq[] = {
|
||||
{ 0x0090, sent|optional }, /* Vista */
|
||||
{ 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);
|
||||
WNDPROC oldproc = (WNDPROC)GetWindowLongPtrA(hwnd, GWLP_USERDATA);
|
||||
static LONG defwndproc_counter = 0;
|
||||
LRESULT ret;
|
||||
struct message msg;
|
||||
|
@ -154,21 +138,17 @@ static LRESULT WINAPI datetime_subclass_proc(HWND hwnd, UINT message, WPARAM wPa
|
|||
add_message(sequences, DATETIME_SEQ_INDEX, &msg);
|
||||
|
||||
defwndproc_counter++;
|
||||
ret = CallWindowProcA(info->oldproc, hwnd, message, wParam, lParam);
|
||||
ret = CallWindowProcA(oldproc, hwnd, message, wParam, lParam);
|
||||
defwndproc_counter--;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static HWND create_datetime_control(DWORD style, DWORD exstyle)
|
||||
static HWND create_datetime_control(DWORD style)
|
||||
{
|
||||
struct subclass_info *info;
|
||||
WNDPROC oldproc;
|
||||
HWND hWndDateTime = NULL;
|
||||
|
||||
info = HeapAlloc(GetProcessHeap(), 0, sizeof(struct subclass_info));
|
||||
if (!info)
|
||||
return NULL;
|
||||
|
||||
hWndDateTime = CreateWindowEx(0,
|
||||
DATETIMEPICK_CLASS,
|
||||
NULL,
|
||||
|
@ -179,44 +159,47 @@ static HWND create_datetime_control(DWORD style, DWORD exstyle)
|
|||
NULL,
|
||||
NULL);
|
||||
|
||||
if (!hWndDateTime) {
|
||||
HeapFree(GetProcessHeap(), 0, info);
|
||||
return NULL;
|
||||
}
|
||||
if (!hWndDateTime) return NULL;
|
||||
|
||||
info->oldproc = (WNDPROC)SetWindowLongPtrA(hWndDateTime, GWLP_WNDPROC,
|
||||
(LONG_PTR)datetime_subclass_proc);
|
||||
SetWindowLongPtrA(hWndDateTime, GWLP_USERDATA, (LONG_PTR)info);
|
||||
oldproc = (WNDPROC)SetWindowLongPtrA(hWndDateTime, GWLP_WNDPROC,
|
||||
(LONG_PTR)datetime_subclass_proc);
|
||||
SetWindowLongPtrA(hWndDateTime, GWLP_USERDATA, (LONG_PTR)oldproc);
|
||||
|
||||
return hWndDateTime;
|
||||
}
|
||||
|
||||
static void test_dtm_set_format(HWND hWndDateTime)
|
||||
static void test_dtm_set_format(void)
|
||||
{
|
||||
HWND hWnd;
|
||||
CHAR txt[256];
|
||||
SYSTEMTIME systime;
|
||||
LRESULT r;
|
||||
|
||||
r = SendMessage(hWndDateTime, DTM_SETFORMAT, 0, 0);
|
||||
hWnd = create_datetime_control(DTS_SHOWNONE);
|
||||
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
|
||||
r = SendMessage(hWnd, DTM_SETFORMAT, 0, 0);
|
||||
expect(1, r);
|
||||
|
||||
r = SendMessage(hWndDateTime, DTM_SETFORMAT, 0,
|
||||
r = SendMessage(hWnd, 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);
|
||||
|
||||
r = SendMessage(hWndDateTime, DTM_SETFORMAT, 0,
|
||||
r = SendMessage(hWnd, DTM_SETFORMAT, 0,
|
||||
(LPARAM)"'hh' hh");
|
||||
expect(1, r);
|
||||
ZeroMemory(&systime, sizeof(systime));
|
||||
systime.wYear = 2000;
|
||||
systime.wMonth = systime.wDay = 1;
|
||||
r = SendMessage(hWndDateTime, DTM_SETSYSTEMTIME, 0, (LPARAM)&systime);
|
||||
r = SendMessage(hWnd, DTM_SETSYSTEMTIME, 0, (LPARAM)&systime);
|
||||
expect(1, r);
|
||||
GetWindowText(hWndDateTime, txt, 256);
|
||||
todo_wine ok(strcmp(txt, "hh 12") == 0, "String mismatch (\"%s\" vs \"hh 12\")\n", txt);
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
GetWindowText(hWnd, txt, 256);
|
||||
ok(strcmp(txt, "hh 12") == 0, "String mismatch (\"%s\" vs \"hh 12\")\n", txt);
|
||||
|
||||
DestroyWindow(hWnd);
|
||||
}
|
||||
|
||||
static void test_mccolor_types(HWND hWndDateTime, int mccolor_type, const char* mccolor_name)
|
||||
|
@ -239,43 +222,60 @@ static void test_mccolor_types(HWND hWndDateTime, int mccolor_type, const char*
|
|||
ok(r==theColor, "%s: GETMCCOLOR: Expected %d, got %ld\n", mccolor_name, theColor, r);
|
||||
}
|
||||
|
||||
static void test_dtm_set_and_get_mccolor(HWND hWndDateTime)
|
||||
static void test_dtm_set_and_get_mccolor(void)
|
||||
{
|
||||
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");
|
||||
HWND hWnd;
|
||||
|
||||
hWnd = create_datetime_control(DTS_SHOWNONE);
|
||||
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
|
||||
test_mccolor_types(hWnd, MCSC_BACKGROUND, "MCSC_BACKGROUND");
|
||||
test_mccolor_types(hWnd, MCSC_MONTHBK, "MCSC_MONTHBK");
|
||||
test_mccolor_types(hWnd, MCSC_TEXT, "MCSC_TEXT");
|
||||
test_mccolor_types(hWnd, MCSC_TITLEBK, "MCSC_TITLEBK");
|
||||
test_mccolor_types(hWnd, MCSC_TITLETEXT, "MCSC_TITLETEXT");
|
||||
test_mccolor_types(hWnd, 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);
|
||||
|
||||
DestroyWindow(hWnd);
|
||||
}
|
||||
|
||||
static void test_dtm_set_and_get_mcfont(HWND hWndDateTime)
|
||||
static void test_dtm_set_and_get_mcfont(void)
|
||||
{
|
||||
HFONT hFontOrig, hFontNew;
|
||||
HWND hWnd;
|
||||
|
||||
hWnd = create_datetime_control(DTS_SHOWNONE);
|
||||
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
|
||||
hFontOrig = GetStockObject(DEFAULT_GUI_FONT);
|
||||
SendMessage(hWndDateTime, DTM_SETMCFONT, (WPARAM)hFontOrig, TRUE);
|
||||
hFontNew = (HFONT)SendMessage(hWndDateTime, DTM_GETMCFONT, 0, 0);
|
||||
SendMessage(hWnd, DTM_SETMCFONT, (WPARAM)hFontOrig, TRUE);
|
||||
hFontNew = (HFONT)SendMessage(hWnd, 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);
|
||||
DestroyWindow(hWnd);
|
||||
}
|
||||
|
||||
static void test_dtm_get_monthcal(HWND hWndDateTime)
|
||||
static void test_dtm_get_monthcal(void)
|
||||
{
|
||||
LRESULT r;
|
||||
HWND hWnd;
|
||||
|
||||
hWnd = create_datetime_control(DTS_SHOWNONE);
|
||||
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
|
||||
todo_wine {
|
||||
r = SendMessage(hWndDateTime, DTM_GETMONTHCAL, 0, 0);
|
||||
r = SendMessage(hWnd, DTM_GETMONTHCAL, 0, 0);
|
||||
ok(r == 0, "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);
|
||||
DestroyWindow(hWnd);
|
||||
}
|
||||
|
||||
static void fill_systime_struct(SYSTEMTIME *st, int year, int month, int dayofweek, int day, int hour, int minute, int second, int milliseconds)
|
||||
|
@ -318,24 +318,29 @@ static LPARAM compare_systime(SYSTEMTIME *st1, SYSTEMTIME *st2)
|
|||
#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)
|
||||
static void test_dtm_set_and_get_range(void)
|
||||
{
|
||||
LRESULT r;
|
||||
SYSTEMTIME st[2];
|
||||
SYSTEMTIME getSt[2];
|
||||
HWND hWnd;
|
||||
|
||||
hWnd = create_datetime_control(DTS_SHOWNONE);
|
||||
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
|
||||
/* initialize st[0] to lowest possible value */
|
||||
fill_systime_struct(&st[0], 1601, 1, 0, 1, 0, 0, 0, 0);
|
||||
/* initialize 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);
|
||||
r = SendMessage(hWnd, DTM_SETRANGE, GDTR_MIN, (LPARAM)st);
|
||||
expect(1, r);
|
||||
r = SendMessage(hWndDateTime, DTM_GETRANGE, 0, (LPARAM)getSt);
|
||||
r = SendMessage(hWnd, 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);
|
||||
r = SendMessage(hWnd, DTM_SETRANGE, GDTR_MAX, (LPARAM)st);
|
||||
expect_unsuccess(0, r);
|
||||
|
||||
/* set st[0] to all invalid numbers */
|
||||
|
@ -343,25 +348,25 @@ static void test_dtm_set_and_get_range(HWND hWndDateTime)
|
|||
/* 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);
|
||||
r = SendMessage(hWnd, DTM_SETRANGE, GDTR_MAX, (LPARAM)st);
|
||||
expect(1, r);
|
||||
r = SendMessage(hWndDateTime, DTM_GETRANGE, 0, (LPARAM)getSt);
|
||||
r = SendMessage(hWnd, 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);
|
||||
r = SendMessage(hWnd, DTM_SETRANGE, GDTR_MIN, (LPARAM)st);
|
||||
expect_unsuccess(0, r);
|
||||
r = SendMessage(hWndDateTime, DTM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st);
|
||||
r = SendMessage(hWnd, 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);
|
||||
r = SendMessage(hWnd, DTM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st);
|
||||
expect(1, r);
|
||||
r = SendMessage(hWndDateTime, DTM_GETRANGE, 0, (LPARAM)getSt);
|
||||
r = SendMessage(hWnd, 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]);
|
||||
|
@ -371,9 +376,9 @@ static void test_dtm_set_and_get_range(HWND hWndDateTime)
|
|||
/* 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);
|
||||
r = SendMessage(hWnd, DTM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st);
|
||||
expect(1, r);
|
||||
r = SendMessage(hWndDateTime, DTM_GETRANGE, 0, (LPARAM)getSt);
|
||||
r = SendMessage(hWnd, 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]);
|
||||
|
@ -383,32 +388,37 @@ static void test_dtm_set_and_get_range(HWND hWndDateTime)
|
|||
/* 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);
|
||||
r = SendMessage(hWnd, DTM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st);
|
||||
expect(1, r);
|
||||
r = SendMessage(hWndDateTime, DTM_GETRANGE, 0, (LPARAM)getSt);
|
||||
r = SendMessage(hWnd, 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);
|
||||
|
||||
DestroyWindow(hWnd);
|
||||
}
|
||||
|
||||
/* 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)
|
||||
static void test_dtm_set_range_swap_min_max(void)
|
||||
{
|
||||
LRESULT r;
|
||||
SYSTEMTIME st[2];
|
||||
SYSTEMTIME getSt[2];
|
||||
SYSTEMTIME origSt;
|
||||
HWND hWnd;
|
||||
|
||||
hWnd = create_datetime_control(DTS_SHOWNONE);
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
|
||||
fill_systime_struct(&st[0], 2007, 2, 4, 15, 2, 2, 2, 2);
|
||||
|
||||
r = SendMessage(hWndDateTime, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st[0]);
|
||||
r = SendMessage(hWnd, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st[0]);
|
||||
expect(1, r);
|
||||
r = SendMessage(hWndDateTime, DTM_GETSYSTEMTIME, 0, (LPARAM)&origSt);
|
||||
r = SendMessage(hWnd, 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);
|
||||
|
||||
|
@ -418,28 +428,33 @@ static void test_dtm_set_range_swap_min_max(HWND hWndDateTime)
|
|||
|
||||
/* 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);
|
||||
r = SendMessage(hWnd, DTM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st);
|
||||
expect(1, r);
|
||||
r = SendMessage(hWndDateTime, DTM_GETRANGE, 0, (LPARAM)getSt);
|
||||
r = SendMessage(hWnd, 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]);
|
||||
ok(compare_systime(&st[0], &getSt[0]) == 1 ||
|
||||
broken(compare_systime(&st[0], &getSt[1]) == 1), /* comctl32 version <= 5.80 */
|
||||
"ST1 != ST2\n");
|
||||
|
||||
ok(compare_systime(&st[1], &getSt[1]) == 1 ||
|
||||
broken(compare_systime(&st[1], &getSt[0]) == 1), /* comctl32 version <= 5.80 */
|
||||
"ST1 != ST2\n");
|
||||
}
|
||||
|
||||
fill_systime_struct(&st[0], 1980, 1, 3, 23, 14, 34, 37, 465);
|
||||
|
||||
r = SendMessage(hWndDateTime, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st[0]);
|
||||
r = SendMessage(hWnd, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st[0]);
|
||||
expect(1, r);
|
||||
r = SendMessage(hWndDateTime, DTM_GETSYSTEMTIME, 0, (LPARAM)&getSt[0]);
|
||||
r = SendMessage(hWnd, 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]);
|
||||
ok(compare_systime_time(&origSt, &getSt[0]) == 1 ||
|
||||
broken(compare_systime_time(&st[0], &getSt[0]) == 1), /* comctl32 version <= 5.80 */
|
||||
"ST1.time != ST2.time\n");
|
||||
}
|
||||
|
||||
/* set st[0] to value higher than minimum */
|
||||
|
@ -447,18 +462,21 @@ static void test_dtm_set_range_swap_min_max(HWND hWndDateTime)
|
|||
/* 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);
|
||||
r = SendMessage(hWnd, 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);
|
||||
r = SendMessage(hWnd, 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]);
|
||||
ok(compare_systime(&st[0], &getSt[1]) == 1 ||
|
||||
broken(compare_systime(&st[0], &getSt[0]) == 1), /* comctl32 version <= 5.80 */
|
||||
"ST1 != ST2\n");
|
||||
|
||||
ok(compare_systime(&st[1], &getSt[0]) == 1 ||
|
||||
broken(compare_systime(&st[1], &getSt[1]) == 1), /* comctl32 version <= 5.80 */
|
||||
"ST1 != ST2\n");
|
||||
}
|
||||
|
||||
/* set st[0] to value higher than st[1] */
|
||||
|
@ -467,9 +485,9 @@ static void test_dtm_set_range_swap_min_max(HWND hWndDateTime)
|
|||
|
||||
/* 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);
|
||||
r = SendMessage(hWnd, DTM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st);
|
||||
expect(1, r);
|
||||
r = SendMessage(hWndDateTime, DTM_GETRANGE, 0, (LPARAM)getSt);
|
||||
r = SendMessage(hWnd, 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]);
|
||||
|
@ -479,25 +497,25 @@ static void test_dtm_set_range_swap_min_max(HWND hWndDateTime)
|
|||
/* 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);
|
||||
r = SendMessage(hWnd, DTM_SETRANGE, GDTR_MIN | GDTR_MAX, (LPARAM)st);
|
||||
expect(1, r);
|
||||
r = SendMessage(hWndDateTime, DTM_GETRANGE, 0, (LPARAM)getSt);
|
||||
r = SendMessage(hWnd, 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);
|
||||
|
||||
DestroyWindow(hWnd);
|
||||
}
|
||||
|
||||
static void test_dtm_set_and_get_system_time(HWND hWndDateTime)
|
||||
static void test_dtm_set_and_get_system_time(void)
|
||||
{
|
||||
LRESULT r;
|
||||
SYSTEMTIME st;
|
||||
SYSTEMTIME getSt;
|
||||
HWND hWndDateTime_test_gdt_none;
|
||||
SYSTEMTIME st, getSt, ref;
|
||||
HWND hWnd, hWndDateTime_test_gdt_none;
|
||||
|
||||
hWndDateTime_test_gdt_none = create_datetime_control(0, 0);
|
||||
hWndDateTime_test_gdt_none = create_datetime_control(0);
|
||||
|
||||
ok(hWndDateTime_test_gdt_none!=NULL, "Expected non NULL, got %p\n", hWndDateTime_test_gdt_none);
|
||||
if(hWndDateTime_test_gdt_none) {
|
||||
|
@ -513,64 +531,175 @@ static void test_dtm_set_and_get_system_time(HWND hWndDateTime)
|
|||
|
||||
DestroyWindow(hWndDateTime_test_gdt_none);
|
||||
|
||||
r = SendMessage(hWndDateTime, DTM_SETSYSTEMTIME, GDT_NONE, (LPARAM)&st);
|
||||
hWnd = create_datetime_control(DTS_SHOWNONE);
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
|
||||
r = SendMessage(hWnd, DTM_SETSYSTEMTIME, GDT_NONE, (LPARAM)&st);
|
||||
expect(1, r);
|
||||
r = SendMessage(hWndDateTime, DTM_GETSYSTEMTIME, 0, (LPARAM)&getSt);
|
||||
r = SendMessage(hWnd, 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);
|
||||
r = SendMessage(hWnd, 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);
|
||||
r = SendMessage(hWnd, 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);
|
||||
r = SendMessage(hWnd, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st);
|
||||
expect(1, r);
|
||||
r = SendMessage(hWndDateTime, DTM_GETSYSTEMTIME, 0, (LPARAM)&getSt);
|
||||
r = SendMessage(hWnd, 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);
|
||||
r = SendMessage(hWnd, 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);
|
||||
|
||||
/* set to some valid value */
|
||||
GetSystemTime(&ref);
|
||||
r = SendMessage(hWnd, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&ref);
|
||||
expect(1, r);
|
||||
r = SendMessage(hWnd, DTM_GETSYSTEMTIME, 0, (LPARAM)&getSt);
|
||||
expect(GDT_VALID, r);
|
||||
expect_systime(&ref, &getSt);
|
||||
|
||||
/* year invalid */
|
||||
st = ref;
|
||||
st.wYear = 0;
|
||||
r = SendMessage(hWnd, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st);
|
||||
todo_wine expect(1, r);
|
||||
r = SendMessage(hWnd, DTM_GETSYSTEMTIME, 0, (LPARAM)&getSt);
|
||||
expect(GDT_VALID, r);
|
||||
expect_systime(&ref, &getSt);
|
||||
/* month invalid */
|
||||
st = ref;
|
||||
st.wMonth = 13;
|
||||
r = SendMessage(hWnd, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st);
|
||||
expect(0, r);
|
||||
r = SendMessage(hWnd, DTM_GETSYSTEMTIME, 0, (LPARAM)&getSt);
|
||||
expect(GDT_VALID, r);
|
||||
expect_systime(&ref, &getSt);
|
||||
/* day invalid */
|
||||
st = ref;
|
||||
st.wDay = 32;
|
||||
r = SendMessage(hWnd, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st);
|
||||
expect(0, r);
|
||||
r = SendMessage(hWnd, DTM_GETSYSTEMTIME, 0, (LPARAM)&getSt);
|
||||
expect(GDT_VALID, r);
|
||||
expect_systime(&ref, &getSt);
|
||||
/* day of week isn't validated */
|
||||
st = ref;
|
||||
st.wDayOfWeek = 10;
|
||||
r = SendMessage(hWnd, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st);
|
||||
expect(1, r);
|
||||
r = SendMessage(hWnd, DTM_GETSYSTEMTIME, 0, (LPARAM)&getSt);
|
||||
expect(GDT_VALID, r);
|
||||
expect_systime(&ref, &getSt);
|
||||
/* hour invalid */
|
||||
st = ref;
|
||||
st.wHour = 25;
|
||||
r = SendMessage(hWnd, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st);
|
||||
expect(0, r);
|
||||
r = SendMessage(hWnd, DTM_GETSYSTEMTIME, 0, (LPARAM)&getSt);
|
||||
expect(GDT_VALID, r);
|
||||
expect_systime(&ref, &getSt);
|
||||
/* minute invalid */
|
||||
st = ref;
|
||||
st.wMinute = 60;
|
||||
r = SendMessage(hWnd, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st);
|
||||
expect(0, r);
|
||||
r = SendMessage(hWnd, DTM_GETSYSTEMTIME, 0, (LPARAM)&getSt);
|
||||
expect(GDT_VALID, r);
|
||||
expect_systime(&ref, &getSt);
|
||||
/* sec invalid */
|
||||
st = ref;
|
||||
st.wSecond = 60;
|
||||
r = SendMessage(hWnd, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st);
|
||||
expect(0, r);
|
||||
r = SendMessage(hWnd, DTM_GETSYSTEMTIME, 0, (LPARAM)&getSt);
|
||||
expect(GDT_VALID, r);
|
||||
expect_systime(&ref, &getSt);
|
||||
/* msec invalid */
|
||||
st = ref;
|
||||
st.wMilliseconds = 1000;
|
||||
r = SendMessage(hWnd, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st);
|
||||
expect(0, r);
|
||||
r = SendMessage(hWnd, DTM_GETSYSTEMTIME, 0, (LPARAM)&getSt);
|
||||
expect(GDT_VALID, r);
|
||||
expect_systime(&ref, &getSt);
|
||||
|
||||
/* day of week should be calculated automatically,
|
||||
actual day of week for this date is 4 */
|
||||
fill_systime_struct(&st, 2009, 10, 1, 1, 0, 0, 10, 200);
|
||||
r = SendMessage(hWnd, DTM_SETSYSTEMTIME, GDT_VALID, (LPARAM)&st);
|
||||
expect(1, r);
|
||||
r = SendMessage(hWnd, DTM_GETSYSTEMTIME, 0, (LPARAM)&getSt);
|
||||
expect(GDT_VALID, r);
|
||||
/* 01.10.2009 is Thursday */
|
||||
expect(4, (LRESULT)getSt.wDayOfWeek);
|
||||
st.wDayOfWeek = 4;
|
||||
expect_systime(&st, &getSt);
|
||||
|
||||
DestroyWindow(hWnd);
|
||||
}
|
||||
|
||||
static void test_datetime_control(void)
|
||||
static void test_wm_set_get_text(void)
|
||||
{
|
||||
HWND hWndDateTime;
|
||||
static const CHAR a_str[] = "a";
|
||||
char buff[16], time[16];
|
||||
HWND hWnd;
|
||||
LRESULT ret;
|
||||
|
||||
hWndDateTime = create_datetime_control(DTS_SHOWNONE, 0);
|
||||
hWnd = create_datetime_control(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");
|
||||
}
|
||||
ret = SendMessage(hWnd, WM_SETTEXT, 0, (LPARAM)a_str);
|
||||
ok(CB_ERR == ret ||
|
||||
broken(0 == ret) || /* comctl32 <= 4.72 */
|
||||
broken(1 == ret), /* comctl32 <= 4.70 */
|
||||
"Expected CB_ERR, got %ld\n", ret);
|
||||
|
||||
DestroyWindow(hWndDateTime);
|
||||
ok_sequence(sequences, DATETIME_SEQ_INDEX, destroy_window_seq, "test_dtm_set_and_get_system_time", TRUE);
|
||||
buff[0] = 0;
|
||||
ret = SendMessage(hWnd, WM_GETTEXT, sizeof(buff), (LPARAM)buff);
|
||||
ok(strcmp(buff, a_str) != 0, "Expected text not to change, got %s\n", buff);
|
||||
|
||||
GetDateFormat(LOCALE_USER_DEFAULT, 0, NULL, NULL, time, sizeof(time));
|
||||
ok(!strcmp(buff, time), "Expected %s, got %s\n", time, buff);
|
||||
|
||||
DestroyWindow(hWnd);
|
||||
}
|
||||
|
||||
static void test_dts_shownone(void)
|
||||
{
|
||||
HWND hwnd;
|
||||
DWORD style;
|
||||
|
||||
/* it isn't allowed to change DTS_SHOWNONE after creation */
|
||||
hwnd = create_datetime_control(0);
|
||||
style = GetWindowLong(hwnd, GWL_STYLE);
|
||||
SetWindowLong(hwnd, GWL_STYLE, style | DTS_SHOWNONE);
|
||||
style = GetWindowLong(hwnd, GWL_STYLE);
|
||||
ok(!(style & DTS_SHOWNONE), "Expected DTS_SHOWNONE not to be set\n");
|
||||
DestroyWindow(hwnd);
|
||||
|
||||
hwnd = create_datetime_control(DTS_SHOWNONE);
|
||||
style = GetWindowLong(hwnd, GWL_STYLE);
|
||||
SetWindowLong(hwnd, GWL_STYLE, style & ~DTS_SHOWNONE);
|
||||
style = GetWindowLong(hwnd, GWL_STYLE);
|
||||
ok(style & DTS_SHOWNONE, "Expected DTS_SHOWNONE to be set\n");
|
||||
DestroyWindow(hwnd);
|
||||
}
|
||||
|
||||
START_TEST(datetime)
|
||||
|
@ -592,5 +721,13 @@ START_TEST(datetime)
|
|||
|
||||
init_msg_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
|
||||
test_datetime_control();
|
||||
test_dtm_set_format();
|
||||
test_dtm_set_and_get_mccolor();
|
||||
test_dtm_set_and_get_mcfont();
|
||||
test_dtm_get_monthcal();
|
||||
test_dtm_set_and_get_range();
|
||||
test_dtm_set_range_swap_min_max();
|
||||
test_dtm_set_and_get_system_time();
|
||||
test_wm_set_get_text();
|
||||
test_dts_shownone();
|
||||
}
|
||||
|
|
|
@ -31,17 +31,14 @@
|
|||
|
||||
#include "wine/test.h"
|
||||
|
||||
#define DPAM_NOSORT 0x1
|
||||
#define DPAM_INSERT 0x4
|
||||
#define DPAM_DELETE 0x8
|
||||
#define expect(expected, got) ok(got == expected, "Expected %d, got %d\n", expected, got)
|
||||
|
||||
typedef struct _ITEMDATA
|
||||
typedef struct _STREAMDATA
|
||||
{
|
||||
INT iPos;
|
||||
PVOID pvData;
|
||||
} ITEMDATA, *LPITEMDATA;
|
||||
|
||||
typedef HRESULT (CALLBACK *PFNDPASTM)(LPITEMDATA,IStream*,LPARAM);
|
||||
DWORD dwSize;
|
||||
DWORD dwData2;
|
||||
DWORD dwItems;
|
||||
} STREAMDATA, *PSTREAMDATA;
|
||||
|
||||
static HDPA (WINAPI *pDPA_Clone)(const HDPA,const HDPA);
|
||||
static HDPA (WINAPI *pDPA_Create)(INT);
|
||||
|
@ -55,9 +52,9 @@ static INT (WINAPI *pDPA_GetPtr)(const HDPA,INT);
|
|||
static INT (WINAPI *pDPA_GetPtrIndex)(const HDPA,PVOID);
|
||||
static BOOL (WINAPI *pDPA_Grow)(HDPA,INT);
|
||||
static INT (WINAPI *pDPA_InsertPtr)(const HDPA,INT,PVOID);
|
||||
static HRESULT (WINAPI *pDPA_LoadStream)(HDPA*,PFNDPASTM,IStream*,LPARAM);
|
||||
static HRESULT (WINAPI *pDPA_LoadStream)(HDPA*,PFNDPASTREAM,IStream*,LPVOID);
|
||||
static BOOL (WINAPI *pDPA_Merge)(const HDPA,const HDPA,DWORD,PFNDPACOMPARE,PFNDPAMERGE,LPARAM);
|
||||
static HRESULT (WINAPI *pDPA_SaveStream)(HDPA,PFNDPASTM,IStream*,LPARAM);
|
||||
static HRESULT (WINAPI *pDPA_SaveStream)(HDPA,PFNDPASTREAM,IStream*,LPVOID);
|
||||
static INT (WINAPI *pDPA_Search)(HDPA,PVOID,INT,PFNDPACOMPARE,LPARAM,UINT);
|
||||
static BOOL (WINAPI *pDPA_SetPtr)(const HDPA,INT,PVOID);
|
||||
static BOOL (WINAPI *pDPA_Sort)(const HDPA,PFNDPACOMPARE,LPARAM);
|
||||
|
@ -109,14 +106,22 @@ static INT CALLBACK CB_CmpGT(PVOID p1, PVOID p2, LPARAM lp)
|
|||
return p1 > p2 ? -1 : p1 < p2 ? 1 : 0;
|
||||
}
|
||||
|
||||
/* merge callback messages counter
|
||||
DPAMM_MERGE 1
|
||||
DPAMM_DELETE 2
|
||||
DPAMM_INSERT 3 */
|
||||
static INT nMessages[4];
|
||||
|
||||
static PVOID CALLBACK CB_MergeInsertSrc(UINT op, PVOID p1, PVOID p2, LPARAM lp)
|
||||
{
|
||||
nMessages[op]++;
|
||||
ok(lp == 0xdeadbeef, "lp=%ld\n", lp);
|
||||
return p1;
|
||||
}
|
||||
|
||||
static PVOID CALLBACK CB_MergeDeleteOddSrc(UINT op, PVOID p1, PVOID p2, LPARAM lp)
|
||||
{
|
||||
nMessages[op]++;
|
||||
ok(lp == 0xdeadbeef, "lp=%ld\n", lp);
|
||||
return ((PCHAR)p2)+1;
|
||||
}
|
||||
|
@ -134,30 +139,30 @@ static INT CALLBACK CB_EnumFirstThree(PVOID pItem, PVOID lp)
|
|||
return pItem != (PVOID)3;
|
||||
}
|
||||
|
||||
static HRESULT CALLBACK CB_Save(LPITEMDATA pInfo, IStream *pStm, LPARAM lp)
|
||||
static HRESULT CALLBACK CB_Save(DPASTREAMINFO *pInfo, IStream *pStm, LPVOID lp)
|
||||
{
|
||||
HRESULT hRes;
|
||||
|
||||
ok(lp == 0xdeadbeef, "lp=%ld\n", lp);
|
||||
|
||||
ok(lp == (LPVOID)0xdeadbeef, "lp=%p\n", lp);
|
||||
hRes = IStream_Write(pStm, &pInfo->iPos, sizeof(INT), NULL);
|
||||
ok(hRes == S_OK, "hRes=0x%x\n", hRes);
|
||||
hRes = IStream_Write(pStm, &pInfo->pvData, sizeof(PVOID), NULL);
|
||||
ok(hRes == S_OK, "hRes=0x%x\n", hRes);
|
||||
expect(S_OK, hRes);
|
||||
hRes = IStream_Write(pStm, &pInfo->pvItem, sizeof(PVOID), NULL);
|
||||
expect(S_OK, hRes);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT CALLBACK CB_Load(LPITEMDATA pInfo, IStream *pStm, LPARAM lp)
|
||||
static HRESULT CALLBACK CB_Load(DPASTREAMINFO *pInfo, IStream *pStm, LPVOID lp)
|
||||
{
|
||||
HRESULT hRes;
|
||||
INT iOldPos;
|
||||
|
||||
iOldPos = pInfo->iPos;
|
||||
ok(lp == 0xdeadbeef, "lp=%ld\n", lp);
|
||||
ok(lp == (LPVOID)0xdeadbeef, "lp=%p\n", lp);
|
||||
hRes = IStream_Read(pStm, &pInfo->iPos, sizeof(INT), NULL);
|
||||
ok(hRes == S_OK, "hRes=0x%x\n", hRes);
|
||||
expect(S_OK, 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%x\n", hRes);
|
||||
hRes = IStream_Read(pStm, &pInfo->pvItem, sizeof(PVOID), NULL);
|
||||
expect(S_OK, hRes);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -200,7 +205,6 @@ static void test_dpa(void)
|
|||
INT ret, i;
|
||||
PVOID p;
|
||||
DWORD dw, dw2, dw3;
|
||||
HRESULT hRes;
|
||||
BOOL rc;
|
||||
|
||||
GetSystemInfo(&si);
|
||||
|
@ -209,9 +213,9 @@ static void test_dpa(void)
|
|||
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,
|
||||
ok(!ret && GetLastError() == ERROR_NOT_ENOUGH_MEMORY,
|
||||
"ret=%d error=%d\n", ret, GetLastError());
|
||||
|
||||
|
||||
dpa = pDPA_Create(0);
|
||||
ok(dpa != NULL, "\n");
|
||||
|
||||
|
@ -288,9 +292,9 @@ static void test_dpa(void)
|
|||
ok(j == DPA_ERR, "j=%d\n", j);
|
||||
/* ... but for a binary search it's ignored */
|
||||
j = pDPA_Search(dpa, (PVOID)(INT_PTR)i, i+1, CB_CmpLT, 0xdeadbeef, DPAS_SORTED);
|
||||
todo_wine ok(j+1 == i, "j=%d i=%d\n", j, i);
|
||||
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);
|
||||
|
@ -335,49 +339,6 @@ static void test_dpa(void)
|
|||
ok(j != i, "i=%d\n", i);
|
||||
}
|
||||
|
||||
if(pDPA_Merge)
|
||||
{
|
||||
/* Delete all even entries from dpa */
|
||||
p = pDPA_DeletePtr(dpa, 1);
|
||||
p = pDPA_DeletePtr(dpa, 2);
|
||||
p = pDPA_DeletePtr(dpa, 3);
|
||||
rc=CheckDPA(dpa, 0x135, &dw);
|
||||
ok(rc, "dw=0x%x\n", dw);
|
||||
|
||||
/* Delete all odd entries from dpa2 */
|
||||
pDPA_Merge(dpa2, dpa, DPAM_DELETE,
|
||||
CB_CmpLT, CB_MergeDeleteOddSrc, 0xdeadbeef);
|
||||
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,
|
||||
CB_CmpLT, CB_MergeInsertSrc, 0xdeadbeef);
|
||||
pDPA_Merge(dpa2, dpa3, DPAM_INSERT|DPAM_NOSORT,
|
||||
CB_CmpLT, CB_MergeInsertSrc, 0xdeadbeef);
|
||||
|
||||
rc=CheckDPA(dpa, 0x123456, &dw);
|
||||
ok(rc, "dw=0x%x\n", dw);
|
||||
rc=CheckDPA(dpa2, 0x123456, &dw2);
|
||||
ok(rc ||
|
||||
broken(!rc), /* win98 */
|
||||
"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, dpa2);
|
||||
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);
|
||||
|
@ -386,62 +347,397 @@ static void test_dpa(void)
|
|||
pDPA_DeleteAllPtrs(dpa2);
|
||||
rc=CheckDPA(dpa2, 0, &dw2);
|
||||
ok(rc, "dw2=0x%x\n", dw2);
|
||||
|
||||
pDPA_Destroy(dpa);
|
||||
pDPA_Destroy(dpa2);
|
||||
pDPA_Destroy(dpa3);
|
||||
}
|
||||
|
||||
if(pDPA_DestroyCallback)
|
||||
static void test_DPA_Merge(void)
|
||||
{
|
||||
HDPA dpa, dpa2, dpa3;
|
||||
INT ret, i;
|
||||
DWORD dw;
|
||||
BOOL rc;
|
||||
|
||||
if(!pDPA_Merge)
|
||||
{
|
||||
nEnum = 0;
|
||||
pDPA_DestroyCallback(dpa3, CB_EnumFirstThree, dpa3);
|
||||
ok(nEnum == 3, "nEnum=%d\n", nEnum);
|
||||
win_skip("DPA_Merge() not available\n");
|
||||
return;
|
||||
}
|
||||
else pDPA_Destroy(dpa3);
|
||||
|
||||
if(!pDPA_SaveStream)
|
||||
goto skip_stream_tests;
|
||||
dpa = pDPA_Create(0);
|
||||
dpa2 = pDPA_Create(0);
|
||||
dpa3 = pDPA_Create(0);
|
||||
|
||||
ret = pDPA_InsertPtr(dpa, 0, (PVOID)1);
|
||||
ok(ret == 0, "ret=%d\n", ret);
|
||||
ret = pDPA_InsertPtr(dpa, 1, (PVOID)3);
|
||||
ok(ret == 1, "ret=%d\n", ret);
|
||||
ret = pDPA_InsertPtr(dpa, 2, (PVOID)5);
|
||||
ok(ret == 2, "ret=%d\n", ret);
|
||||
|
||||
rc = CheckDPA(dpa, 0x135, &dw);
|
||||
ok(rc, "dw=0x%x\n", dw);
|
||||
|
||||
for (i = 0; i < 6; i++)
|
||||
{
|
||||
ret = pDPA_InsertPtr(dpa2, i, (PVOID)(INT_PTR)(6-i));
|
||||
ok(ret == i, "ret=%d\n", ret);
|
||||
ret = pDPA_InsertPtr(dpa3, i, (PVOID)(INT_PTR)(i+1));
|
||||
ok(ret == i, "ret=%d\n", ret);
|
||||
}
|
||||
|
||||
rc = CheckDPA(dpa2, 0x654321, &dw);
|
||||
ok(rc, "dw=0x%x\n", dw);
|
||||
rc = CheckDPA(dpa3, 0x123456, &dw);
|
||||
ok(rc, "dw=0x%x\n", dw);
|
||||
|
||||
/* Delete all odd entries from dpa2 */
|
||||
memset(nMessages, 0, sizeof(nMessages));
|
||||
pDPA_Merge(dpa2, dpa, DPAM_INTERSECT,
|
||||
CB_CmpLT, CB_MergeDeleteOddSrc, 0xdeadbeef);
|
||||
rc = CheckDPA(dpa2, 0x246, &dw);
|
||||
ok(rc, "dw=0x%x\n", dw);
|
||||
|
||||
expect(3, nMessages[DPAMM_MERGE]);
|
||||
expect(3, nMessages[DPAMM_DELETE]);
|
||||
expect(0, nMessages[DPAMM_INSERT]);
|
||||
|
||||
for (i = 0; i < 6; i++)
|
||||
{
|
||||
ret = pDPA_InsertPtr(dpa2, i, (PVOID)(INT_PTR)(6-i));
|
||||
ok(ret == i, "ret=%d\n", ret);
|
||||
}
|
||||
|
||||
/* DPAM_INTERSECT - returning source while merging */
|
||||
memset(nMessages, 0, sizeof(nMessages));
|
||||
pDPA_Merge(dpa2, dpa, DPAM_INTERSECT,
|
||||
CB_CmpLT, CB_MergeInsertSrc, 0xdeadbeef);
|
||||
rc = CheckDPA(dpa2, 0x135, &dw);
|
||||
ok(rc, "dw=0x%x\n", dw);
|
||||
|
||||
expect(3, nMessages[DPAMM_MERGE]);
|
||||
expect(6, nMessages[DPAMM_DELETE]);
|
||||
expect(0, nMessages[DPAMM_INSERT]);
|
||||
|
||||
/* DPAM_UNION */
|
||||
pDPA_DeleteAllPtrs(dpa);
|
||||
pDPA_InsertPtr(dpa, 0, (PVOID)1);
|
||||
pDPA_InsertPtr(dpa, 1, (PVOID)3);
|
||||
pDPA_InsertPtr(dpa, 2, (PVOID)5);
|
||||
pDPA_DeleteAllPtrs(dpa2);
|
||||
pDPA_InsertPtr(dpa2, 0, (PVOID)2);
|
||||
pDPA_InsertPtr(dpa2, 1, (PVOID)4);
|
||||
pDPA_InsertPtr(dpa2, 2, (PVOID)6);
|
||||
|
||||
memset(nMessages, 0, sizeof(nMessages));
|
||||
pDPA_Merge(dpa2, dpa, DPAM_UNION,
|
||||
CB_CmpLT, CB_MergeInsertSrc, 0xdeadbeef);
|
||||
rc = CheckDPA(dpa2, 0x123456, &dw);
|
||||
ok(rc ||
|
||||
broken(!rc && dw == 0x23456), /* 4.7x */
|
||||
"dw=0x%x\n", dw);
|
||||
|
||||
expect(0, nMessages[DPAMM_MERGE]);
|
||||
expect(0, nMessages[DPAMM_DELETE]);
|
||||
ok(nMessages[DPAMM_INSERT] == 3 ||
|
||||
broken(nMessages[DPAMM_INSERT] == 2), /* 4.7x */
|
||||
"Expected 3, got %d\n", nMessages[DPAMM_INSERT]);
|
||||
|
||||
/* Merge dpa3 into dpa2 and dpa */
|
||||
memset(nMessages, 0, sizeof(nMessages));
|
||||
pDPA_Merge(dpa, dpa3, DPAM_UNION|DPAM_SORTED,
|
||||
CB_CmpLT, CB_MergeInsertSrc, 0xdeadbeef);
|
||||
expect(3, nMessages[DPAMM_MERGE]);
|
||||
expect(0, nMessages[DPAMM_DELETE]);
|
||||
expect(3, nMessages[DPAMM_INSERT]);
|
||||
|
||||
|
||||
pDPA_DeleteAllPtrs(dpa2);
|
||||
pDPA_InsertPtr(dpa2, 0, (PVOID)2);
|
||||
pDPA_InsertPtr(dpa2, 1, (PVOID)4);
|
||||
pDPA_InsertPtr(dpa2, 2, (PVOID)6);
|
||||
|
||||
memset(nMessages, 0, sizeof(nMessages));
|
||||
pDPA_Merge(dpa2, dpa3, DPAM_UNION|DPAM_SORTED,
|
||||
CB_CmpLT, CB_MergeInsertSrc, 0xdeadbeef);
|
||||
expect(3, nMessages[DPAMM_MERGE]);
|
||||
expect(0, nMessages[DPAMM_DELETE]);
|
||||
ok(nMessages[DPAMM_INSERT] == 3 ||
|
||||
broken(nMessages[DPAMM_INSERT] == 2), /* 4.7x */
|
||||
"Expected 3, got %d\n", nMessages[DPAMM_INSERT]);
|
||||
|
||||
rc = CheckDPA(dpa, 0x123456, &dw);
|
||||
ok(rc, "dw=0x%x\n", dw);
|
||||
rc = CheckDPA(dpa2, 0x123456, &dw);
|
||||
ok(rc ||
|
||||
broken(!rc), /* win98 */
|
||||
"dw=0x%x\n", dw);
|
||||
rc = CheckDPA(dpa3, 0x123456, &dw);
|
||||
ok(rc, "dw=0x%x\n", dw);
|
||||
|
||||
pDPA_Destroy(dpa);
|
||||
pDPA_Destroy(dpa2);
|
||||
pDPA_Destroy(dpa3);
|
||||
}
|
||||
|
||||
static void test_DPA_EnumCallback(void)
|
||||
{
|
||||
HDPA dpa;
|
||||
BOOL rc;
|
||||
DWORD dw;
|
||||
INT i, ret;
|
||||
|
||||
if(!pDPA_EnumCallback)
|
||||
{
|
||||
win_skip("DPA_EnumCallback() not available\n");
|
||||
return;
|
||||
}
|
||||
|
||||
dpa = pDPA_Create(0);
|
||||
|
||||
for (i = 0; i < 6; i++)
|
||||
{
|
||||
ret = pDPA_InsertPtr(dpa, i, (PVOID)(INT_PTR)(i+1));
|
||||
ok(ret == i, "ret=%d\n", ret);
|
||||
}
|
||||
|
||||
rc = CheckDPA(dpa, 0x123456, &dw);
|
||||
ok(rc, "dw=0x%x\n", dw);
|
||||
|
||||
nEnum = 0;
|
||||
/* test callback sets first 3 items to 7 */
|
||||
pDPA_EnumCallback(dpa, CB_EnumFirstThree, dpa);
|
||||
rc = CheckDPA(dpa, 0x777456, &dw);
|
||||
ok(rc, "dw=0x%x\n", dw);
|
||||
ok(nEnum == 3, "nEnum=%d\n", nEnum);
|
||||
|
||||
pDPA_Destroy(dpa);
|
||||
}
|
||||
|
||||
static void test_DPA_DestroyCallback(void)
|
||||
{
|
||||
HDPA dpa;
|
||||
INT i, ret;
|
||||
|
||||
if(!pDPA_DestroyCallback)
|
||||
{
|
||||
win_skip("DPA_DestroyCallback() not available\n");
|
||||
return;
|
||||
}
|
||||
|
||||
dpa = pDPA_Create(0);
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
ret = pDPA_InsertPtr(dpa, i, (PVOID)(INT_PTR)(i+1));
|
||||
ok(ret == i, "ret=%d\n", ret);
|
||||
}
|
||||
|
||||
nEnum = 0;
|
||||
pDPA_DestroyCallback(dpa, CB_EnumFirstThree, dpa);
|
||||
ok(nEnum == 3, "nEnum=%d\n", nEnum);
|
||||
}
|
||||
|
||||
static void test_DPA_LoadStream(void)
|
||||
{
|
||||
static const WCHAR szStg[] = { 'S','t','g',0 };
|
||||
IStorage* pStg = NULL;
|
||||
IStream* pStm = NULL;
|
||||
LARGE_INTEGER li;
|
||||
ULARGE_INTEGER uli;
|
||||
DWORD dwMode;
|
||||
HRESULT hRes;
|
||||
STREAMDATA header;
|
||||
ULONG written, ret;
|
||||
HDPA dpa;
|
||||
|
||||
if(!pDPA_LoadStream)
|
||||
{
|
||||
win_skip("DPA_LoadStream() not available. Skipping stream tests.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
hRes = CoInitialize(NULL);
|
||||
if(hRes == S_OK)
|
||||
if (hRes != S_OK)
|
||||
{
|
||||
static const WCHAR szStg[] = { 'S','t','g',0 };
|
||||
IStorage* pStg = NULL;
|
||||
IStream* pStm = NULL;
|
||||
LARGE_INTEGER liZero;
|
||||
DWORD dwMode;
|
||||
liZero.QuadPart = 0;
|
||||
|
||||
dwMode = STGM_DIRECT|STGM_CREATE|STGM_READWRITE|STGM_SHARE_EXCLUSIVE;
|
||||
hRes = StgCreateDocfile(NULL, dwMode|STGM_DELETEONRELEASE, 0, &pStg);
|
||||
ok(hRes == S_OK, "hRes=0x%x\n", hRes);
|
||||
|
||||
hRes = IStorage_CreateStream(pStg, szStg, dwMode, 0, 0, &pStm);
|
||||
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%x\n", hRes);
|
||||
pDPA_Destroy(dpa);
|
||||
|
||||
hRes = IStream_Seek(pStm, liZero, STREAM_SEEK_SET, NULL);
|
||||
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%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();
|
||||
ok(0, "hResult: %d\n", hRes);
|
||||
return;
|
||||
}
|
||||
else ok(0, "hResult: %d\n", hRes);
|
||||
|
||||
skip_stream_tests:
|
||||
dwMode = STGM_DIRECT|STGM_CREATE|STGM_READWRITE|STGM_SHARE_EXCLUSIVE;
|
||||
hRes = StgCreateDocfile(NULL, dwMode|STGM_DELETEONRELEASE, 0, &pStg);
|
||||
expect(S_OK, hRes);
|
||||
|
||||
hRes = IStorage_CreateStream(pStg, szStg, dwMode, 0, 0, &pStm);
|
||||
expect(S_OK, hRes);
|
||||
|
||||
/* write less than header size */
|
||||
li.QuadPart = 0;
|
||||
hRes = IStream_Seek(pStm, li, STREAM_SEEK_SET, NULL);
|
||||
expect(S_OK, hRes);
|
||||
|
||||
memset(&header, 0, sizeof(header));
|
||||
written = 0;
|
||||
uli.QuadPart = sizeof(header)-1;
|
||||
hRes = IStream_SetSize(pStm, uli);
|
||||
expect(S_OK, hRes);
|
||||
hRes = IStream_Write(pStm, &header, sizeof(header)-1, &written);
|
||||
expect(S_OK, hRes);
|
||||
written -= sizeof(header)-1;
|
||||
expect(0, written);
|
||||
|
||||
li.QuadPart = 0;
|
||||
hRes = IStream_Seek(pStm, li, STREAM_SEEK_SET, NULL);
|
||||
expect(S_OK, hRes);
|
||||
|
||||
hRes = pDPA_LoadStream(&dpa, CB_Load, pStm, NULL);
|
||||
expect(E_FAIL, hRes);
|
||||
|
||||
/* check stream position after header read failed */
|
||||
li.QuadPart = 0;
|
||||
uli.QuadPart = 1;
|
||||
hRes = IStream_Seek(pStm, li, STREAM_SEEK_CUR, &uli);
|
||||
expect(S_OK, hRes);
|
||||
ok(uli.QuadPart == 0, "Expected to position reset\n");
|
||||
|
||||
/* write valid header for empty DPA */
|
||||
header.dwSize = sizeof(header);
|
||||
header.dwData2 = 1;
|
||||
header.dwItems = 0;
|
||||
written = 0;
|
||||
|
||||
li.QuadPart = 0;
|
||||
hRes = IStream_Seek(pStm, li, STREAM_SEEK_SET, NULL);
|
||||
expect(S_OK, hRes);
|
||||
|
||||
uli.QuadPart = sizeof(header);
|
||||
hRes = IStream_SetSize(pStm, uli);
|
||||
expect(S_OK, hRes);
|
||||
|
||||
hRes = IStream_Write(pStm, &header, sizeof(header), &written);
|
||||
expect(S_OK, hRes);
|
||||
written -= sizeof(header);
|
||||
expect(0, written);
|
||||
|
||||
li.QuadPart = 0;
|
||||
hRes = IStream_Seek(pStm, li, STREAM_SEEK_SET, NULL);
|
||||
expect(S_OK, hRes);
|
||||
|
||||
dpa = NULL;
|
||||
hRes = pDPA_LoadStream(&dpa, CB_Load, pStm, NULL);
|
||||
expect(S_OK, hRes);
|
||||
DPA_Destroy(dpa);
|
||||
|
||||
/* try with altered dwData2 field */
|
||||
header.dwSize = sizeof(header);
|
||||
header.dwData2 = 2;
|
||||
header.dwItems = 0;
|
||||
|
||||
li.QuadPart = 0;
|
||||
hRes = IStream_Seek(pStm, li, STREAM_SEEK_SET, NULL);
|
||||
expect(S_OK, hRes);
|
||||
hRes = IStream_Write(pStm, &header, sizeof(header), &written);
|
||||
expect(S_OK, hRes);
|
||||
written -= sizeof(header);
|
||||
expect(0, written);
|
||||
|
||||
li.QuadPart = 0;
|
||||
hRes = IStream_Seek(pStm, li, STREAM_SEEK_SET, NULL);
|
||||
expect(S_OK, hRes);
|
||||
|
||||
hRes = pDPA_LoadStream(&dpa, CB_Load, pStm, (void*)0xdeadbeef);
|
||||
expect(E_FAIL, hRes);
|
||||
|
||||
ret = IStream_Release(pStm);
|
||||
ok(!ret, "ret=%d\n", ret);
|
||||
|
||||
ret = IStorage_Release(pStg);
|
||||
ok(!ret, "ret=%d\n", ret);
|
||||
|
||||
CoUninitialize();
|
||||
}
|
||||
|
||||
static void test_DPA_SaveStream(void)
|
||||
{
|
||||
HDPA dpa;
|
||||
static const WCHAR szStg[] = { 'S','t','g',0 };
|
||||
IStorage* pStg = NULL;
|
||||
IStream* pStm = NULL;
|
||||
DWORD dwMode, dw;
|
||||
HRESULT hRes;
|
||||
ULONG ret;
|
||||
INT i;
|
||||
BOOL rc;
|
||||
LARGE_INTEGER liZero;
|
||||
|
||||
if(!pDPA_SaveStream)
|
||||
{
|
||||
win_skip("DPA_SaveStream() not available. Skipping stream tests.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
hRes = CoInitialize(NULL);
|
||||
if (hRes != S_OK)
|
||||
{
|
||||
ok(0, "hResult: %d\n", hRes);
|
||||
return;
|
||||
}
|
||||
|
||||
dwMode = STGM_DIRECT|STGM_CREATE|STGM_READWRITE|STGM_SHARE_EXCLUSIVE;
|
||||
hRes = StgCreateDocfile(NULL, dwMode|STGM_DELETEONRELEASE, 0, &pStg);
|
||||
expect(S_OK, hRes);
|
||||
|
||||
hRes = IStorage_CreateStream(pStg, szStg, dwMode, 0, 0, &pStm);
|
||||
expect(S_OK, hRes);
|
||||
|
||||
dpa = pDPA_Create(0);
|
||||
|
||||
/* simple parameter check */
|
||||
hRes = pDPA_SaveStream(dpa, NULL, pStm, NULL);
|
||||
ok(hRes == E_INVALIDARG ||
|
||||
broken(hRes == S_OK) /* XP and below */, "Wrong result, %d\n", hRes);
|
||||
if (0) {
|
||||
/* crashes on XP */
|
||||
hRes = pDPA_SaveStream(NULL, CB_Save, pStm, NULL);
|
||||
expect(E_INVALIDARG, hRes);
|
||||
|
||||
hRes = pDPA_SaveStream(dpa, CB_Save, NULL, NULL);
|
||||
expect(E_INVALIDARG, hRes);
|
||||
}
|
||||
|
||||
/* saving/loading */
|
||||
for (i = 0; i < 6; i++)
|
||||
{
|
||||
ret = pDPA_InsertPtr(dpa, i, (PVOID)(INT_PTR)(i+1));
|
||||
ok(ret == i, "ret=%d\n", ret);
|
||||
}
|
||||
|
||||
liZero.QuadPart = 0;
|
||||
hRes = IStream_Seek(pStm, liZero, STREAM_SEEK_SET, NULL);
|
||||
expect(S_OK, hRes);
|
||||
|
||||
hRes = pDPA_SaveStream(dpa, CB_Save, pStm, (void*)0xdeadbeef);
|
||||
expect(S_OK, hRes);
|
||||
pDPA_Destroy(dpa);
|
||||
|
||||
liZero.QuadPart = 0;
|
||||
hRes = IStream_Seek(pStm, liZero, STREAM_SEEK_SET, NULL);
|
||||
expect(S_OK, hRes);
|
||||
hRes = pDPA_LoadStream(&dpa, CB_Load, pStm, (void*)0xdeadbeef);
|
||||
expect(S_OK, hRes);
|
||||
rc = CheckDPA(dpa, 0x123456, &dw);
|
||||
ok(rc, "dw=0x%x\n", dw);
|
||||
pDPA_Destroy(dpa);
|
||||
|
||||
ret = IStream_Release(pStm);
|
||||
ok(!ret, "ret=%d\n", ret);
|
||||
|
||||
ret = IStorage_Release(pStg);
|
||||
ok(!ret, "ret=%d\n", ret);
|
||||
|
||||
CoUninitialize();
|
||||
}
|
||||
|
||||
START_TEST(dpa)
|
||||
|
@ -450,8 +746,16 @@ START_TEST(dpa)
|
|||
|
||||
hcomctl32 = GetModuleHandleA("comctl32.dll");
|
||||
|
||||
if(InitFunctionPtrs(hcomctl32))
|
||||
test_dpa();
|
||||
else
|
||||
if(!InitFunctionPtrs(hcomctl32))
|
||||
{
|
||||
win_skip("Needed functions are not available\n");
|
||||
return;
|
||||
}
|
||||
|
||||
test_dpa();
|
||||
test_DPA_Merge();
|
||||
test_DPA_EnumCallback();
|
||||
test_DPA_DestroyCallback();
|
||||
test_DPA_LoadStream();
|
||||
test_DPA_SaveStream();
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include <assert.h>
|
||||
|
||||
#include "wine/test.h"
|
||||
#include "v6util.h"
|
||||
#include "msg.h"
|
||||
|
||||
typedef struct tagEXPECTEDNOTIFY
|
||||
|
@ -121,7 +122,6 @@ static const struct message deleteItem_getItemCount_seq[] = {
|
|||
};
|
||||
|
||||
static const struct message orderArray_seq[] = {
|
||||
{ HDM_GETITEMCOUNT, sent },
|
||||
{ HDM_SETORDERARRAY, sent|wparam, 2 },
|
||||
{ HDM_GETORDERARRAY, sent|wparam, 2 },
|
||||
{ 0 }
|
||||
|
@ -244,7 +244,7 @@ static LONG addItem(HWND hdex, int idx, LPSTR text)
|
|||
hdItem.cxy = 100;
|
||||
hdItem.pszText = text;
|
||||
hdItem.cchTextMax = 0;
|
||||
return (LONG)SendMessage(hdex, HDM_INSERTITEMA, (WPARAM)idx, (LPARAM)&hdItem);
|
||||
return SendMessage(hdex, HDM_INSERTITEMA, idx, (LPARAM)&hdItem);
|
||||
}
|
||||
|
||||
static LONG setItem(HWND hdex, int idx, LPSTR text, BOOL fCheckNotifies)
|
||||
|
@ -259,7 +259,7 @@ static LONG setItem(HWND hdex, int idx, LPSTR text, BOOL fCheckNotifies)
|
|||
expect_notify(HDN_ITEMCHANGINGA, FALSE, &hdexItem);
|
||||
expect_notify(HDN_ITEMCHANGEDA, FALSE, &hdexItem);
|
||||
}
|
||||
ret = (LONG)SendMessage(hdex, HDM_SETITEMA, (WPARAM)idx, (LPARAM)&hdexItem);
|
||||
ret = SendMessage(hdex, HDM_SETITEMA, idx, (LPARAM)&hdexItem);
|
||||
if (fCheckNotifies)
|
||||
ok(notifies_received(), "setItem(): not all expected notifies were received\n");
|
||||
return ret;
|
||||
|
@ -279,19 +279,19 @@ static LONG setItemUnicodeNotify(HWND hdex, int idx, LPSTR text, LPWSTR wText)
|
|||
|
||||
expect_notify(HDN_ITEMCHANGINGW, TRUE, (HDITEMA*)&hdexNotify);
|
||||
expect_notify(HDN_ITEMCHANGEDW, TRUE, (HDITEMA*)&hdexNotify);
|
||||
ret = (LONG)SendMessage(hdex, HDM_SETITEMA, (WPARAM)idx, (LPARAM)&hdexItem);
|
||||
ret = SendMessage(hdex, HDM_SETITEMA, idx, (LPARAM)&hdexItem);
|
||||
ok(notifies_received(), "setItemUnicodeNotify(): not all expected notifies were received\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
static LONG delItem(HWND hdex, int idx)
|
||||
{
|
||||
return (LONG)SendMessage(hdex, HDM_DELETEITEM, (WPARAM)idx, 0);
|
||||
return SendMessage(hdex, HDM_DELETEITEM, idx, 0);
|
||||
}
|
||||
|
||||
static LONG getItemCount(HWND hdex)
|
||||
{
|
||||
return (LONG)SendMessage(hdex, HDM_GETITEMCOUNT, 0, 0);
|
||||
return SendMessage(hdex, HDM_GETITEMCOUNT, 0, 0);
|
||||
}
|
||||
|
||||
static LONG getItem(HWND hdex, int idx, LPSTR textBuffer)
|
||||
|
@ -300,7 +300,7 @@ static LONG getItem(HWND hdex, int idx, LPSTR textBuffer)
|
|||
hdItem.mask = HDI_TEXT;
|
||||
hdItem.pszText = textBuffer;
|
||||
hdItem.cchTextMax = MAX_CHARS;
|
||||
return (LONG)SendMessage(hdex, HDM_GETITEMA, (WPARAM)idx, (LPARAM)&hdItem);
|
||||
return SendMessage(hdex, HDM_GETITEMA, idx, (LPARAM)&hdItem);
|
||||
}
|
||||
|
||||
static void addReadDelItem(HWND hdex, HDITEMA *phdiCreate, int maskRead, HDITEMA *phdiRead)
|
||||
|
@ -396,14 +396,9 @@ static WCHAR pszUniTestW[] = {'T','S','T',0};
|
|||
ok(res == i, "Got Item Count as %d\n", res);\
|
||||
}
|
||||
|
||||
struct subclass_info
|
||||
{
|
||||
WNDPROC oldproc;
|
||||
};
|
||||
|
||||
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);
|
||||
WNDPROC oldproc = (WNDPROC)GetWindowLongPtrA(hwnd, GWLP_USERDATA);
|
||||
static LONG defwndproc_counter = 0;
|
||||
LRESULT ret;
|
||||
struct message msg;
|
||||
|
@ -417,7 +412,7 @@ static LRESULT WINAPI header_subclass_proc(HWND hwnd, UINT message, WPARAM wPara
|
|||
add_message(sequences, HEADER_SEQ_INDEX, &msg);
|
||||
|
||||
defwndproc_counter++;
|
||||
ret = CallWindowProcA(info->oldproc, hwnd, message, wParam, lParam);
|
||||
ret = CallWindowProcA(oldproc, hwnd, message, wParam, lParam);
|
||||
defwndproc_counter--;
|
||||
|
||||
return ret;
|
||||
|
@ -487,7 +482,7 @@ static HWND create_custom_parent_window(void)
|
|||
|
||||
static HWND create_custom_header_control(HWND hParent, BOOL preloadHeaderItems)
|
||||
{
|
||||
struct subclass_info *info;
|
||||
WNDPROC oldproc;
|
||||
HWND childHandle;
|
||||
HDLAYOUT hlayout;
|
||||
RECT rectwin;
|
||||
|
@ -505,9 +500,6 @@ static HWND create_custom_header_control(HWND hParent, BOOL preloadHeaderItems)
|
|||
|
||||
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
info = HeapAlloc(GetProcessHeap(), 0, sizeof(struct subclass_info));
|
||||
if (!info)
|
||||
return NULL;
|
||||
|
||||
childHandle = CreateWindowEx(0, WC_HEADER, NULL,
|
||||
WS_CHILD|WS_BORDER|WS_VISIBLE|HDS_BUTTONS|HDS_HORZ,
|
||||
|
@ -534,9 +526,9 @@ static HWND create_custom_header_control(HWND hParent, BOOL preloadHeaderItems)
|
|||
SetWindowPos(childHandle, winpos.hwndInsertAfter, winpos.x, winpos.y,
|
||||
winpos.cx, winpos.cy, 0);
|
||||
|
||||
info->oldproc = (WNDPROC)SetWindowLongPtrA(childHandle, GWLP_WNDPROC,
|
||||
(LONG_PTR)header_subclass_proc);
|
||||
SetWindowLongPtrA(childHandle, GWLP_USERDATA, (LONG_PTR)info);
|
||||
oldproc = (WNDPROC)SetWindowLongPtrA(childHandle, GWLP_WNDPROC,
|
||||
(LONG_PTR)header_subclass_proc);
|
||||
SetWindowLongPtrA(childHandle, GWLP_USERDATA, (LONG_PTR)oldproc);
|
||||
return childHandle;
|
||||
}
|
||||
|
||||
|
@ -756,10 +748,10 @@ static void test_header_control (void)
|
|||
TEST_GET_ITEM(i, 4);
|
||||
TEST_GET_ITEMCOUNT(6);
|
||||
}
|
||||
|
||||
SendMessageA(hWndHeader, HDM_SETUNICODEFORMAT, (WPARAM)TRUE, 0);
|
||||
|
||||
SendMessageA(hWndHeader, HDM_SETUNICODEFORMAT, TRUE, 0);
|
||||
setItemUnicodeNotify(hWndHeader, 3, pszUniTestA, pszUniTestW);
|
||||
SendMessageA(hWndHeader, WM_NOTIFYFORMAT, (WPARAM)hHeaderParentWnd, (LPARAM)NF_REQUERY);
|
||||
SendMessageA(hWndHeader, WM_NOTIFYFORMAT, (WPARAM)hHeaderParentWnd, NF_REQUERY);
|
||||
setItem(hWndHeader, 3, str_items[4], TRUE);
|
||||
|
||||
dont_expect_notify(HDN_GETDISPINFOA);
|
||||
|
@ -820,10 +812,8 @@ static void test_hdm_getitemrect(HWND hParent)
|
|||
expect(80, rect.left);
|
||||
expect(0, rect.top);
|
||||
expect(160, rect.right);
|
||||
todo_wine
|
||||
{
|
||||
expect(g_customheight, rect.bottom);
|
||||
}
|
||||
expect(g_customheight, rect.bottom);
|
||||
|
||||
retVal = SendMessage(hChild, HDM_GETITEMRECT, 0, (LPARAM) &rect);
|
||||
|
||||
ok(retVal == TRUE, "Getting item rect should TRUE, got %d\n", retVal);
|
||||
|
@ -832,10 +822,8 @@ static void test_hdm_getitemrect(HWND hParent)
|
|||
expect(0, rect.top);
|
||||
|
||||
expect(80, rect.right);
|
||||
todo_wine
|
||||
{
|
||||
expect(g_customheight, rect.bottom);
|
||||
}
|
||||
expect(g_customheight, rect.bottom);
|
||||
|
||||
retVal = SendMessage(hChild, HDM_GETITEMRECT, 10, (LPARAM) &rect);
|
||||
ok(retVal == 0, "Getting rect of nonexistent item should return 0, got %d\n", retVal);
|
||||
|
||||
|
@ -907,30 +895,25 @@ static void test_hdm_hittest(HWND hParent)
|
|||
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
retVal = SendMessage(hChild, HDM_HITTEST, 0, (LPARAM) &hdHitTestInfo);
|
||||
todo_wine
|
||||
{
|
||||
expect(0, retVal);
|
||||
expect(0, hdHitTestInfo.iItem);
|
||||
}
|
||||
expect(0, retVal);
|
||||
expect(0, hdHitTestInfo.iItem);
|
||||
expect(HHT_ONDIVIDER, hdHitTestInfo.flags);
|
||||
|
||||
pt.x = secondItemRightBoundary - 1;
|
||||
pt.y = bottomBoundary - 1;
|
||||
hdHitTestInfo.pt = pt;
|
||||
retVal = SendMessage(hChild, HDM_HITTEST, 1, (LPARAM) &hdHitTestInfo);
|
||||
todo_wine
|
||||
{
|
||||
expect(1, retVal);
|
||||
}
|
||||
expect(1, retVal);
|
||||
expect(1, hdHitTestInfo.iItem);
|
||||
expect(HHT_ONDIVIDER, hdHitTestInfo.flags);
|
||||
|
||||
pt.x = secondItemRightBoundary;
|
||||
pt.y = bottomBoundary + 1;
|
||||
hdHitTestInfo.pt = pt;
|
||||
todo_wine
|
||||
{
|
||||
retVal = SendMessage(hChild, HDM_HITTEST, 0, (LPARAM) &hdHitTestInfo);
|
||||
expect(-1, retVal);
|
||||
}
|
||||
retVal = SendMessage(hChild, HDM_HITTEST, 0, (LPARAM) &hdHitTestInfo);
|
||||
expect(-1, retVal);
|
||||
expect(-1, hdHitTestInfo.iItem);
|
||||
expect(HHT_BELOW, hdHitTestInfo.flags);
|
||||
|
||||
ok_sequence(sequences, HEADER_SEQ_INDEX, hittest_seq, "hittest sequence testing", FALSE);
|
||||
|
||||
|
@ -951,11 +934,9 @@ static void test_hdm_sethotdivider(HWND hParent)
|
|||
"adder header control to parent", FALSE);
|
||||
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
todo_wine
|
||||
{
|
||||
retVal = SendMessage(hChild, HDM_SETHOTDIVIDER, TRUE, 0X00050005);
|
||||
expect(0, retVal);
|
||||
}
|
||||
retVal = SendMessage(hChild, HDM_SETHOTDIVIDER, TRUE, MAKELPARAM(5, 5));
|
||||
expect(0, retVal);
|
||||
|
||||
retVal = SendMessage(hChild, HDM_SETHOTDIVIDER, FALSE, 100);
|
||||
expect(100, retVal);
|
||||
retVal = SendMessage(hChild, HDM_SETHOTDIVIDER, FALSE, 1);
|
||||
|
@ -973,7 +954,7 @@ static void test_hdm_sethotdivider(HWND hParent)
|
|||
static void test_hdm_imageMessages(HWND hParent)
|
||||
{
|
||||
HIMAGELIST hImageList = ImageList_Create (4, 4, 0, 1, 0);
|
||||
HIMAGELIST hImageListRetVal;
|
||||
HIMAGELIST hIml;
|
||||
HWND hChild;
|
||||
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
|
@ -983,14 +964,15 @@ static void test_hdm_imageMessages(HWND hParent)
|
|||
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
|
||||
hImageListRetVal = (HIMAGELIST) SendMessage(hChild, HDM_SETIMAGELIST, 0, (LPARAM) hImageList);
|
||||
ok(hImageListRetVal == NULL, "Expected NULL, got %p\n", hImageListRetVal);
|
||||
hIml = (HIMAGELIST) SendMessage(hChild, HDM_SETIMAGELIST, 0, (LPARAM) hImageList);
|
||||
ok(hIml == NULL, "Expected NULL, got %p\n", hIml);
|
||||
|
||||
hImageListRetVal = (HIMAGELIST) SendMessage(hChild, HDM_GETIMAGELIST, 0, 0);
|
||||
ok(hImageListRetVal != NULL, "Expected non-NULL handle, got %p\n", hImageListRetVal);
|
||||
hIml = (HIMAGELIST) SendMessage(hChild, HDM_GETIMAGELIST, 0, 0);
|
||||
ok(hIml != NULL, "Expected non-NULL handle, got %p\n", hIml);
|
||||
|
||||
hImageListRetVal = (HIMAGELIST) SendMessage(hChild, HDM_CREATEDRAGIMAGE, 0, 0);
|
||||
ok(hImageListRetVal != NULL, "Expected non-NULL handle, got %p\n", hImageListRetVal);
|
||||
hIml = (HIMAGELIST) SendMessage(hChild, HDM_CREATEDRAGIMAGE, 0, 0);
|
||||
ok(hIml != NULL, "Expected non-NULL handle, got %p\n", hIml);
|
||||
ImageList_Destroy(hIml);
|
||||
|
||||
ok_sequence(sequences, HEADER_SEQ_INDEX, imageMessages_seq, "imageMessages sequence testing", FALSE);
|
||||
|
||||
|
@ -1025,9 +1007,16 @@ static void test_hdm_filterMessages(HWND hParent)
|
|||
todo_wine
|
||||
{
|
||||
retVal = SendMessage(hChild, HDM_CLEARFILTER, 0, 1);
|
||||
expect(1, retVal);
|
||||
if (retVal == 0)
|
||||
win_skip("HDM_CLEARFILTER needs 5.80\n");
|
||||
else
|
||||
expect(1, retVal);
|
||||
|
||||
retVal = SendMessage(hChild, HDM_EDITFILTER, 1, 0);
|
||||
expect(1, retVal);
|
||||
if (retVal == 0)
|
||||
win_skip("HDM_EDITFILTER needs 5.80\n");
|
||||
else
|
||||
expect(1, retVal);
|
||||
}
|
||||
if (winetest_interactive)
|
||||
ok_sequence(sequences, HEADER_SEQ_INDEX, filterMessages_seq_interactive,
|
||||
|
@ -1076,7 +1065,10 @@ static void test_hdm_bitmapmarginMessages(HWND hParent)
|
|||
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
retVal = SendMessage(hChild, HDM_GETBITMAPMARGIN, 0, 0);
|
||||
expect(6, retVal);
|
||||
if (retVal == 0)
|
||||
win_skip("HDM_GETBITMAPMARGIN needs 5.80\n");
|
||||
else
|
||||
expect(6, retVal);
|
||||
|
||||
ok_sequence(sequences, HEADER_SEQ_INDEX, bitmapmarginMessages_seq,
|
||||
"bitmapmarginMessages sequence testing", FALSE);
|
||||
|
@ -1085,7 +1077,6 @@ static void test_hdm_bitmapmarginMessages(HWND hParent)
|
|||
|
||||
static void test_hdm_index_messages(HWND hParent)
|
||||
{
|
||||
|
||||
HWND hChild;
|
||||
int retVal;
|
||||
int loopcnt;
|
||||
|
@ -1098,6 +1089,7 @@ static void test_hdm_index_messages(HWND hParent)
|
|||
static char thirdHeaderItem[] = "Type";
|
||||
static char fourthHeaderItem[] = "Date Modified";
|
||||
static char *items[] = {firstHeaderItem, secondHeaderItem, thirdHeaderItem, fourthHeaderItem};
|
||||
RECT rect;
|
||||
HDITEM hdItem;
|
||||
hdItem.mask = HDI_TEXT | HDI_WIDTH | HDI_FORMAT;
|
||||
hdItem.fmt = HDF_LEFT;
|
||||
|
@ -1125,17 +1117,17 @@ static void test_hdm_index_messages(HWND hParent)
|
|||
|
||||
retVal = SendMessage(hChild, HDM_DELETEITEM, 3, (LPARAM) &hdItem);
|
||||
ok(retVal == TRUE, "Deleting item 3 should return TRUE, got %d\n", retVal);
|
||||
retVal = SendMessage(hChild, HDM_GETITEMCOUNT, 0, (LPARAM) &hdItem);
|
||||
retVal = SendMessage(hChild, HDM_GETITEMCOUNT, 0, 0);
|
||||
ok(retVal == 3, "Getting item count should return 3, got %d\n", retVal);
|
||||
|
||||
retVal = SendMessage(hChild, HDM_DELETEITEM, 3, (LPARAM) &hdItem);
|
||||
ok(retVal == FALSE, "Deleting already-deleted item should return FALSE, got %d\n", retVal);
|
||||
retVal = SendMessage(hChild, HDM_GETITEMCOUNT, 0, (LPARAM) &hdItem);
|
||||
retVal = SendMessage(hChild, HDM_GETITEMCOUNT, 0, 0);
|
||||
ok(retVal == 3, "Getting item count should return 3, got %d\n", retVal);
|
||||
|
||||
retVal = SendMessage(hChild, HDM_DELETEITEM, 2, (LPARAM) &hdItem);
|
||||
ok(retVal == TRUE, "Deleting item 2 should return TRUE, got %d\n", retVal);
|
||||
retVal = SendMessage(hChild, HDM_GETITEMCOUNT, 0, (LPARAM) &hdItem);
|
||||
retVal = SendMessage(hChild, HDM_GETITEMCOUNT, 0, 0);
|
||||
ok(retVal == 2, "Getting item count should return 2, got %d\n", retVal);
|
||||
|
||||
ok_sequence(sequences, HEADER_SEQ_INDEX, deleteItem_getItemCount_seq,
|
||||
|
@ -1156,9 +1148,19 @@ static void test_hdm_index_messages(HWND hParent)
|
|||
expect(0, strcmpResult);
|
||||
expect(80, hdItem.cxy);
|
||||
|
||||
iSize = SendMessage(hChild, HDM_GETITEMCOUNT, 0, 0);
|
||||
|
||||
/* item should be updated just after accepting new array */
|
||||
ShowWindow(hChild, SW_HIDE);
|
||||
retVal = SendMessage(hChild, HDM_SETORDERARRAY, iSize, (LPARAM) lpiarray);
|
||||
expect(TRUE, retVal);
|
||||
rect.left = 0;
|
||||
retVal = SendMessage(hChild, HDM_GETITEMRECT, 0, (LPARAM) &rect);
|
||||
expect(TRUE, retVal);
|
||||
ok(rect.left != 0, "Expected updated rectangle\n");
|
||||
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
|
||||
iSize = SendMessage(hChild, HDM_GETITEMCOUNT, 0, (LPARAM) &hdItem);
|
||||
retVal = SendMessage(hChild, HDM_SETORDERARRAY, iSize, (LPARAM) lpiarray);
|
||||
ok(retVal == TRUE, "Setting header items order should return TRUE, got %d\n", retVal);
|
||||
|
||||
|
@ -1187,12 +1189,156 @@ static void test_hdm_index_messages(HWND hParent)
|
|||
DestroyWindow(hChild);
|
||||
}
|
||||
|
||||
static void test_hdf_fixedwidth(HWND hParent)
|
||||
{
|
||||
HWND hChild;
|
||||
HDITEM hdItem;
|
||||
DWORD ret;
|
||||
RECT rect;
|
||||
HDHITTESTINFO ht;
|
||||
|
||||
hChild = create_custom_header_control(hParent, FALSE);
|
||||
|
||||
hdItem.mask = HDI_WIDTH | HDI_FORMAT;
|
||||
hdItem.fmt = HDF_FIXEDWIDTH;
|
||||
hdItem.cxy = 80;
|
||||
|
||||
ret = SendMessage(hChild, HDM_INSERTITEM, 0, (LPARAM)&hdItem);
|
||||
expect(0, ret);
|
||||
|
||||
/* try to change width */
|
||||
rect.right = rect.bottom = 0;
|
||||
SendMessage(hChild, HDM_GETITEMRECT, 0, (LPARAM)&rect);
|
||||
ok(rect.right != 0, "Expected not zero width\n");
|
||||
ok(rect.bottom != 0, "Expected not zero height\n");
|
||||
|
||||
SendMessage(hChild, WM_LBUTTONDOWN, 0, MAKELPARAM(rect.right, rect.bottom / 2));
|
||||
SendMessage(hChild, WM_MOUSEMOVE, 0, MAKELPARAM(rect.right + 20, rect.bottom / 2));
|
||||
SendMessage(hChild, WM_LBUTTONUP, 0, MAKELPARAM(rect.right + 20, rect.bottom / 2));
|
||||
|
||||
SendMessage(hChild, HDM_GETITEMRECT, 0, (LPARAM)&rect);
|
||||
|
||||
if (hdItem.cxy != rect.right)
|
||||
{
|
||||
win_skip("HDF_FIXEDWIDTH format not supported\n");
|
||||
DestroyWindow(hChild);
|
||||
return;
|
||||
}
|
||||
|
||||
/* try to adjust with message */
|
||||
hdItem.mask = HDI_WIDTH;
|
||||
hdItem.cxy = 90;
|
||||
|
||||
ret = SendMessage(hChild, HDM_SETITEM, 0, (LPARAM)&hdItem);
|
||||
expect(TRUE, ret);
|
||||
|
||||
rect.right = 0;
|
||||
SendMessage(hChild, HDM_GETITEMRECT, 0, (LPARAM)&rect);
|
||||
expect(90, rect.right);
|
||||
|
||||
/* hittesting doesn't report ondivider flag for HDF_FIXEDWIDTH */
|
||||
ht.pt.x = rect.right - 1;
|
||||
ht.pt.y = rect.bottom / 2;
|
||||
SendMessage(hChild, HDM_HITTEST, 0, (LPARAM)&ht);
|
||||
expect(HHT_ONHEADER, ht.flags);
|
||||
|
||||
/* try to adjust with message */
|
||||
hdItem.mask = HDI_FORMAT;
|
||||
hdItem.fmt = 0;
|
||||
|
||||
ret = SendMessage(hChild, HDM_SETITEM, 0, (LPARAM)&hdItem);
|
||||
expect(TRUE, ret);
|
||||
|
||||
ht.pt.x = 90;
|
||||
ht.pt.y = rect.bottom / 2;
|
||||
SendMessage(hChild, HDM_HITTEST, 0, (LPARAM)&ht);
|
||||
expect(HHT_ONDIVIDER, ht.flags);
|
||||
|
||||
DestroyWindow(hChild);
|
||||
}
|
||||
|
||||
static void test_hds_nosizing(HWND hParent)
|
||||
{
|
||||
HWND hChild;
|
||||
HDITEM hdItem;
|
||||
DWORD ret;
|
||||
RECT rect;
|
||||
HDHITTESTINFO ht;
|
||||
|
||||
hChild = create_custom_header_control(hParent, FALSE);
|
||||
|
||||
memset(&hdItem, 0, sizeof(hdItem));
|
||||
hdItem.mask = HDI_WIDTH;
|
||||
hdItem.cxy = 80;
|
||||
|
||||
ret = SendMessage(hChild, HDM_INSERTITEM, 0, (LPARAM)&hdItem);
|
||||
expect(0, ret);
|
||||
|
||||
/* HDS_NOSIZING only blocks hittesting */
|
||||
ret = GetWindowLong(hChild, GWL_STYLE);
|
||||
SetWindowLong(hChild, GWL_STYLE, ret | HDS_NOSIZING);
|
||||
|
||||
/* try to change width with mouse gestures */
|
||||
rect.right = rect.bottom = 0;
|
||||
SendMessage(hChild, HDM_GETITEMRECT, 0, (LPARAM)&rect);
|
||||
ok(rect.right != 0, "Expected not zero width\n");
|
||||
ok(rect.bottom != 0, "Expected not zero height\n");
|
||||
|
||||
SendMessage(hChild, WM_LBUTTONDOWN, 0, MAKELPARAM(rect.right, rect.bottom / 2));
|
||||
SendMessage(hChild, WM_MOUSEMOVE, 0, MAKELPARAM(rect.right + 20, rect.bottom / 2));
|
||||
SendMessage(hChild, WM_LBUTTONUP, 0, MAKELPARAM(rect.right + 20, rect.bottom / 2));
|
||||
|
||||
SendMessage(hChild, HDM_GETITEMRECT, 0, (LPARAM)&rect);
|
||||
|
||||
if (hdItem.cxy != rect.right)
|
||||
{
|
||||
win_skip("HDS_NOSIZING style not supported\n");
|
||||
DestroyWindow(hChild);
|
||||
return;
|
||||
}
|
||||
|
||||
/* this style doesn't set HDF_FIXEDWIDTH for items */
|
||||
hdItem.mask = HDI_FORMAT;
|
||||
ret = SendMessage(hChild, HDM_GETITEM, 0, (LPARAM)&hdItem);
|
||||
expect(TRUE, ret);
|
||||
ok(!(hdItem.fmt & HDF_FIXEDWIDTH), "Unexpected HDF_FIXEDWIDTH\n");
|
||||
|
||||
/* try to adjust with message */
|
||||
hdItem.mask = HDI_WIDTH;
|
||||
hdItem.cxy = 90;
|
||||
|
||||
ret = SendMessage(hChild, HDM_SETITEM, 0, (LPARAM)&hdItem);
|
||||
expect(TRUE, ret);
|
||||
|
||||
rect.right = 0;
|
||||
SendMessage(hChild, HDM_GETITEMRECT, 0, (LPARAM)&rect);
|
||||
expect(90, rect.right);
|
||||
|
||||
/* hittesting doesn't report ondivider flags for HDS_NOSIZING */
|
||||
ht.pt.x = rect.right - 1;
|
||||
ht.pt.y = rect.bottom / 2;
|
||||
SendMessage(hChild, HDM_HITTEST, 0, (LPARAM)&ht);
|
||||
expect(HHT_ONHEADER, ht.flags);
|
||||
|
||||
/* try to adjust with message */
|
||||
ret = GetWindowLong(hChild, GWL_STYLE);
|
||||
SetWindowLong(hChild, GWL_STYLE, ret & ~HDS_NOSIZING);
|
||||
|
||||
ht.pt.x = 90;
|
||||
ht.pt.y = rect.bottom / 2;
|
||||
SendMessage(hChild, HDM_HITTEST, 0, (LPARAM)&ht);
|
||||
expect(HHT_ONDIVIDER, ht.flags);
|
||||
|
||||
DestroyWindow(hChild);
|
||||
}
|
||||
|
||||
#define TEST_NMCUSTOMDRAW(draw_stage, item_spec, lparam, _left, _top, _right, _bottom) \
|
||||
ok(nm->dwDrawStage == draw_stage, "Invalid dwDrawStage %d vs %d\n", draw_stage, nm->dwDrawStage); \
|
||||
if (item_spec != -1) \
|
||||
ok(nm->dwItemSpec == item_spec, "Invalid dwItemSpec %d vs %ld\n", item_spec, nm->dwItemSpec); \
|
||||
ok(nm->lItemlParam == lparam, "Invalid lItemlParam %d vs %ld\n", lparam, nm->lItemlParam); \
|
||||
ok(nm->rc.top == _top && nm->rc.bottom == _bottom && nm->rc.left == _left && nm->rc.right == _right, \
|
||||
ok((nm->rc.top == _top && nm->rc.bottom == _bottom && nm->rc.left == _left && nm->rc.right == _right) || \
|
||||
broken(draw_stage != CDDS_ITEMPREPAINT), /* comctl32 < 5.80 */ \
|
||||
"Invalid rect (%d,%d) (%d,%d) vs (%d,%d) (%d,%d)\n", _left, _top, _right, _bottom, \
|
||||
nm->rc.left, nm->rc.top, nm->rc.right, nm->rc.bottom);
|
||||
|
||||
|
@ -1545,15 +1691,139 @@ static int init(void)
|
|||
return 1;
|
||||
}
|
||||
|
||||
/* maximum 8 items allowed */
|
||||
static void check_orderarray(HWND hwnd, DWORD start, DWORD set, DWORD expected,
|
||||
int todo, int line)
|
||||
{
|
||||
int count, i;
|
||||
INT order[8];
|
||||
DWORD ret, array = 0;
|
||||
|
||||
count = SendMessage(hwnd, HDM_GETITEMCOUNT, 0, 0);
|
||||
|
||||
/* initial order */
|
||||
for(i = 1; i<=count; i++)
|
||||
order[i-1] = start>>(4*(count-i)) & 0xf;
|
||||
|
||||
ret = SendMessage(hwnd, HDM_SETORDERARRAY, count, (LPARAM)order);
|
||||
ok_(__FILE__, line)(ret, "Expected HDM_SETORDERARAY to succeed, got %d\n", ret);
|
||||
|
||||
/* new order */
|
||||
for(i = 1; i<=count; i++)
|
||||
order[i-1] = set>>(4*(count-i)) & 0xf;
|
||||
ret = SendMessage(hwnd, HDM_SETORDERARRAY, count, (LPARAM)order);
|
||||
ok_(__FILE__, line)(ret, "Expected HDM_SETORDERARAY to succeed, got %d\n", ret);
|
||||
|
||||
/* check actual order */
|
||||
ret = SendMessage(hwnd, HDM_GETORDERARRAY, count, (LPARAM)order);
|
||||
ok_(__FILE__, line)(ret, "Expected HDM_GETORDERARAY to succeed, got %d\n", ret);
|
||||
for(i = 1; i<=count; i++)
|
||||
array |= order[i-1]<<(4*(count-i));
|
||||
|
||||
if (todo) {
|
||||
todo_wine
|
||||
ok_(__FILE__, line)(array == expected, "Expected %x, got %x\n", expected, array);
|
||||
}
|
||||
else
|
||||
ok_(__FILE__, line)(array == expected, "Expected %x, got %x\n", expected, array);
|
||||
}
|
||||
|
||||
static void test_hdm_orderarray(void)
|
||||
{
|
||||
HWND hwnd;
|
||||
INT order[5];
|
||||
DWORD ret;
|
||||
|
||||
hwnd = create_header_control();
|
||||
|
||||
/* three items */
|
||||
addItem(hwnd, 0, NULL);
|
||||
addItem(hwnd, 1, NULL);
|
||||
addItem(hwnd, 2, NULL);
|
||||
|
||||
ret = SendMessage(hwnd, HDM_GETORDERARRAY, 3, (LPARAM)order);
|
||||
if (!ret)
|
||||
{
|
||||
win_skip("HDM_GETORDERARRAY not implemented.\n");
|
||||
DestroyWindow(hwnd);
|
||||
return;
|
||||
}
|
||||
|
||||
expect(0, order[0]);
|
||||
expect(1, order[1]);
|
||||
expect(2, order[2]);
|
||||
|
||||
if (0)
|
||||
{
|
||||
/* null pointer, crashes native */
|
||||
ret = SendMessage(hwnd, HDM_SETORDERARRAY, 3, 0);
|
||||
expect(FALSE, ret);
|
||||
}
|
||||
/* count out of limits */
|
||||
ret = SendMessage(hwnd, HDM_SETORDERARRAY, 5, (LPARAM)order);
|
||||
expect(FALSE, ret);
|
||||
/* count out of limits */
|
||||
ret = SendMessage(hwnd, HDM_SETORDERARRAY, 2, (LPARAM)order);
|
||||
expect(FALSE, ret);
|
||||
|
||||
/* try with out of range item index */
|
||||
/* (0,1,2)->(1,0,3) => (1,0,2) */
|
||||
check_orderarray(hwnd, 0x120, 0x103, 0x102, FALSE, __LINE__);
|
||||
/* (1,0,2)->(3,0,1) => (0,2,1) */
|
||||
check_orderarray(hwnd, 0x102, 0x301, 0x021, TRUE, __LINE__);
|
||||
/* (0,2,1)->(2,3,1) => (2,0,1) */
|
||||
check_orderarray(hwnd, 0x021, 0x231, 0x201, FALSE, __LINE__);
|
||||
|
||||
/* (0,1,2)->(0,2,2) => (0,1,2) */
|
||||
check_orderarray(hwnd, 0x012, 0x022, 0x012, FALSE, __LINE__);
|
||||
|
||||
addItem(hwnd, 3, NULL);
|
||||
|
||||
/* (0,1,2,3)->(0,1,2,2) => (0,1,3,2) */
|
||||
check_orderarray(hwnd, 0x0123, 0x0122, 0x0132, FALSE, __LINE__);
|
||||
/* (0,1,2,3)->(0,1,3,3) => (0,1,2,3) */
|
||||
check_orderarray(hwnd, 0x0123, 0x0133, 0x0123, FALSE, __LINE__);
|
||||
/* (0,1,2,3)->(0,4,2,3) => (0,1,2,3) */
|
||||
check_orderarray(hwnd, 0x0123, 0x0423, 0x0123, FALSE, __LINE__);
|
||||
/* (0,1,2,3)->(4,0,1,2) => (0,1,3,2) */
|
||||
check_orderarray(hwnd, 0x0123, 0x4012, 0x0132, TRUE, __LINE__);
|
||||
/* (0,1,3,2)->(4,0,1,4) => (0,3,1,2) */
|
||||
check_orderarray(hwnd, 0x0132, 0x4014, 0x0312, TRUE, __LINE__);
|
||||
/* (0,1,2,3)->(4,1,0,2) => (1,0,3,2) */
|
||||
check_orderarray(hwnd, 0x0123, 0x4102, 0x1032, TRUE, __LINE__);
|
||||
/* (0,1,2,3)->(0,1,4,2) => (0,1,2,3) */
|
||||
check_orderarray(hwnd, 0x0123, 0x0142, 0x0132, FALSE, __LINE__);
|
||||
/* (0,1,2,3)->(4,4,4,4) => (0,1,2,3) */
|
||||
check_orderarray(hwnd, 0x0123, 0x4444, 0x0123, FALSE, __LINE__);
|
||||
/* (0,1,2,3)->(4,4,1,2) => (0,1,3,2) */
|
||||
check_orderarray(hwnd, 0x0123, 0x4412, 0x0132, TRUE, __LINE__);
|
||||
/* (0,1,2,3)->(4,4,4,1) => (0,2,3,1) */
|
||||
check_orderarray(hwnd, 0x0123, 0x4441, 0x0231, TRUE, __LINE__);
|
||||
/* (0,1,2,3)->(1,4,4,4) => (1,0,2,3) */
|
||||
check_orderarray(hwnd, 0x0123, 0x1444, 0x1023, FALSE, __LINE__);
|
||||
/* (0,1,2,3)->(4,2,4,1) => (0,2,3,1) */
|
||||
check_orderarray(hwnd, 0x0123, 0x4241, 0x0231, FALSE, __LINE__);
|
||||
/* (0,1,2,3)->(4,2,0,1) => (2,0,3,1) */
|
||||
check_orderarray(hwnd, 0x0123, 0x4201, 0x2031, TRUE, __LINE__);
|
||||
/* (3,2,1,0)->(4,2,0,1) => (3,2,0,1) */
|
||||
check_orderarray(hwnd, 0x3210, 0x4201, 0x3201, FALSE, __LINE__);
|
||||
|
||||
DestroyWindow(hwnd);
|
||||
}
|
||||
|
||||
START_TEST(header)
|
||||
{
|
||||
HWND parent_hwnd;
|
||||
ULONG_PTR ctx_cookie;
|
||||
HANDLE hCtx;
|
||||
HWND hwnd;
|
||||
|
||||
if (!init())
|
||||
return;
|
||||
|
||||
test_header_control();
|
||||
test_header_order();
|
||||
test_hdm_orderarray();
|
||||
test_customdraw();
|
||||
|
||||
DestroyWindow(hHeaderParentWnd);
|
||||
|
@ -1573,6 +1843,33 @@ START_TEST(header)
|
|||
test_hdm_unicodeformatMessages(parent_hwnd);
|
||||
test_hdm_bitmapmarginMessages(parent_hwnd);
|
||||
|
||||
DestroyWindow(parent_hwnd);
|
||||
if (!load_v6_module(&ctx_cookie, &hCtx))
|
||||
{
|
||||
DestroyWindow(parent_hwnd);
|
||||
return;
|
||||
}
|
||||
|
||||
/* this is a XP SP3 failure workaround */
|
||||
hwnd = CreateWindowExA(0, WC_HEADER, NULL,
|
||||
WS_CHILD|WS_BORDER|WS_VISIBLE|HDS_BUTTONS|HDS_HORZ,
|
||||
0, 0, 100, 100,
|
||||
parent_hwnd, NULL, GetModuleHandleA(NULL), NULL);
|
||||
|
||||
if (!IsWindow(hwnd))
|
||||
{
|
||||
win_skip("FIXME: failed to create Header window.\n");
|
||||
unload_v6_module(ctx_cookie, hCtx);
|
||||
DestroyWindow(parent_hwnd);
|
||||
return;
|
||||
}
|
||||
else
|
||||
DestroyWindow(hwnd);
|
||||
|
||||
/* comctl32 version 6 tests start here */
|
||||
test_hdf_fixedwidth(parent_hwnd);
|
||||
test_hds_nosizing(parent_hwnd);
|
||||
|
||||
unload_v6_module(ctx_cookie, hCtx);
|
||||
|
||||
DestroyWindow(parent_hwnd);
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
* Copyright 2004 Michael Stefaniuc
|
||||
* Copyright 2002 Mike McCormack for CodeWeavers
|
||||
* Copyright 2007 Dmitry Timoshkov
|
||||
* Copyright 2009 Owen Rudge for CodeWeavers
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -33,8 +34,12 @@
|
|||
#include "winuser.h"
|
||||
#include "objbase.h"
|
||||
#include "commctrl.h" /* must be included after objbase.h to get ImageList_Write */
|
||||
#include "initguid.h"
|
||||
#include "commoncontrols.h"
|
||||
#include "shellapi.h"
|
||||
|
||||
#include "wine/test.h"
|
||||
#include "v6util.h"
|
||||
|
||||
#undef VISIBLE
|
||||
|
||||
|
@ -65,10 +70,14 @@ typedef struct _ILHEAD
|
|||
} ILHEAD;
|
||||
#include "poppack.h"
|
||||
|
||||
static HIMAGELIST (WINAPI *pImageList_Create)(int, int, UINT, int, int);
|
||||
static int (WINAPI *pImageList_Add)(HIMAGELIST, HBITMAP, HBITMAP);
|
||||
static BOOL (WINAPI *pImageList_DrawIndirect)(IMAGELISTDRAWPARAMS*);
|
||||
static BOOL (WINAPI *pImageList_SetImageCount)(HIMAGELIST,UINT);
|
||||
static HRESULT (WINAPI *pImageList_CoCreateInstance)(REFCLSID,const IUnknown *,
|
||||
REFIID,void **);
|
||||
static HRESULT (WINAPI *pHIMAGELIST_QueryInterface)(HIMAGELIST,REFIID,void **);
|
||||
|
||||
static HDC desktopDC;
|
||||
static HINSTANCE hinst;
|
||||
|
||||
/* These macros build cursor/bitmap data in 4x4 pixel blocks */
|
||||
|
@ -327,7 +336,7 @@ static BOOL DoTest1(void)
|
|||
HICON hicon3 ;
|
||||
|
||||
/* create an imagelist to play with */
|
||||
himl = ImageList_Create(84,84,0x10,0,3);
|
||||
himl = ImageList_Create(84, 84, ILC_COLOR16, 0, 3);
|
||||
ok(himl!=0,"failed to create imagelist\n");
|
||||
|
||||
/* load the icons to add to the image list */
|
||||
|
@ -393,7 +402,7 @@ static BOOL DoTest2(void)
|
|||
HICON hicon3 ;
|
||||
|
||||
/* create an imagelist to play with */
|
||||
himl = ImageList_Create(84,84,0x10,0,3);
|
||||
himl = ImageList_Create(84, 84, ILC_COLOR16, 0, 3);
|
||||
ok(himl!=0,"failed to create imagelist\n");
|
||||
|
||||
/* load the icons to add to the image list */
|
||||
|
@ -442,7 +451,7 @@ static BOOL DoTest3(void)
|
|||
ok(hdc!=NULL, "couldn't get DC\n");
|
||||
|
||||
/* create an imagelist to play with */
|
||||
himl = ImageList_Create(48,48,0x10,0,3);
|
||||
himl = ImageList_Create(48, 48, ILC_COLOR16, 0, 3);
|
||||
ok(himl!=0,"failed to create imagelist\n");
|
||||
|
||||
/* load the icons to add to the image list */
|
||||
|
@ -824,7 +833,7 @@ static void check_bitmap_data(const char *bm_data, ULONG bm_data_size,
|
|||
|
||||
static void check_ilhead_data(const char *ilh_data, INT cx, INT cy, INT cur, INT max)
|
||||
{
|
||||
ILHEAD *ilh = (ILHEAD *)ilh_data;
|
||||
const ILHEAD *ilh = (const 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);
|
||||
|
@ -981,13 +990,639 @@ static void test_imagelist_storage(void)
|
|||
iml_clear_stream_data();
|
||||
}
|
||||
|
||||
static void test_shell_imagelist(void)
|
||||
{
|
||||
BOOL (WINAPI *pSHGetImageList)(INT, REFIID, void**);
|
||||
IImageList *iml = NULL;
|
||||
HMODULE hShell32;
|
||||
HRESULT hr;
|
||||
int out = 0;
|
||||
RECT rect;
|
||||
int cx, cy;
|
||||
|
||||
/* Try to load function from shell32 */
|
||||
hShell32 = LoadLibrary("shell32.dll");
|
||||
pSHGetImageList = (void*)GetProcAddress(hShell32, (LPCSTR) 727);
|
||||
|
||||
if (!pSHGetImageList)
|
||||
{
|
||||
win_skip("SHGetImageList not available, skipping test\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Get system image list */
|
||||
hr = (pSHGetImageList)(SHIL_SYSSMALL, &IID_IImageList, (void**)&iml);
|
||||
|
||||
ok(SUCCEEDED(hr), "SHGetImageList failed, hr=%x\n", hr);
|
||||
|
||||
if (hr != S_OK)
|
||||
return;
|
||||
|
||||
IImageList_GetImageCount(iml, &out);
|
||||
ok(out > 0, "IImageList_GetImageCount returned out <= 0\n");
|
||||
|
||||
/* Fetch the small icon size */
|
||||
cx = GetSystemMetrics(SM_CXSMICON);
|
||||
cy = GetSystemMetrics(SM_CYSMICON);
|
||||
|
||||
/* Check icon size matches */
|
||||
IImageList_GetImageRect(iml, 0, &rect);
|
||||
ok(((rect.right == cx) && (rect.bottom == cy)),
|
||||
"IImageList_GetImageRect returned r:%d,b:%d\n",
|
||||
rect.right, rect.bottom);
|
||||
|
||||
IImageList_Release(iml);
|
||||
FreeLibrary(hShell32);
|
||||
}
|
||||
|
||||
static HBITMAP create_test_bitmap(HDC hdc, int bpp, UINT32 pixel1, UINT32 pixel2)
|
||||
{
|
||||
HBITMAP hBitmap;
|
||||
UINT32 *buffer = NULL;
|
||||
BITMAPINFO bitmapInfo = {{sizeof(BITMAPINFOHEADER), 2, 1, 1, bpp, BI_RGB,
|
||||
0, 0, 0, 0, 0}};
|
||||
|
||||
hBitmap = CreateDIBSection(hdc, &bitmapInfo, DIB_RGB_COLORS, (void**)&buffer, NULL, 0);
|
||||
ok(hBitmap != NULL && buffer != NULL, "CreateDIBSection failed.\n");
|
||||
|
||||
if(!hBitmap || !buffer)
|
||||
{
|
||||
DeleteObject(hBitmap);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
buffer[0] = pixel1;
|
||||
buffer[1] = pixel2;
|
||||
|
||||
return hBitmap;
|
||||
}
|
||||
|
||||
static BOOL colour_match(UINT32 x, UINT32 y)
|
||||
{
|
||||
const INT32 tolerance = 8;
|
||||
|
||||
const INT32 dr = abs((INT32)(x & 0x000000FF) - (INT32)(y & 0x000000FF));
|
||||
const INT32 dg = abs((INT32)((x & 0x0000FF00) >> 8) - (INT32)((y & 0x0000FF00) >> 8));
|
||||
const INT32 db = abs((INT32)((x & 0x00FF0000) >> 16) - (INT32)((y & 0x00FF0000) >> 16));
|
||||
|
||||
return (dr <= tolerance && dg <= tolerance && db <= tolerance);
|
||||
}
|
||||
|
||||
static void check_ImageList_DrawIndirect(IMAGELISTDRAWPARAMS *ildp, UINT32 *bits,
|
||||
UINT32 expected, int line)
|
||||
{
|
||||
bits[0] = 0x00FFFFFF;
|
||||
pImageList_DrawIndirect(ildp);
|
||||
ok(colour_match(bits[0], expected),
|
||||
"ImageList_DrawIndirect: Pixel %08X, Expected a close match to %08X from line %d\n",
|
||||
bits[0] & 0x00FFFFFF, expected, line);
|
||||
}
|
||||
|
||||
|
||||
static void check_ImageList_DrawIndirect_fStyle(HDC hdc, HIMAGELIST himl, UINT32 *bits, int i,
|
||||
UINT fStyle, UINT32 expected, int line)
|
||||
{
|
||||
IMAGELISTDRAWPARAMS ildp = {sizeof(IMAGELISTDRAWPARAMS), himl, i, hdc,
|
||||
0, 0, 0, 0, 0, 0, CLR_NONE, CLR_NONE, fStyle, 0, ILS_NORMAL, 0, 0x00000000};
|
||||
check_ImageList_DrawIndirect(&ildp, bits, expected, line);
|
||||
}
|
||||
|
||||
static void check_ImageList_DrawIndirect_ILD_ROP(HDC hdc, HIMAGELIST himl, UINT32 *bits, int i,
|
||||
DWORD dwRop, UINT32 expected, int line)
|
||||
{
|
||||
IMAGELISTDRAWPARAMS ildp = {sizeof(IMAGELISTDRAWPARAMS), himl, i, hdc,
|
||||
0, 0, 0, 0, 0, 0, CLR_NONE, CLR_NONE, ILD_IMAGE | ILD_ROP, dwRop, ILS_NORMAL, 0, 0x00000000};
|
||||
check_ImageList_DrawIndirect(&ildp, bits, expected, line);
|
||||
}
|
||||
|
||||
static void check_ImageList_DrawIndirect_fState(HDC hdc, HIMAGELIST himl, UINT32 *bits, int i, UINT fStyle,
|
||||
UINT fState, DWORD Frame, UINT32 expected, int line)
|
||||
{
|
||||
IMAGELISTDRAWPARAMS ildp = {sizeof(IMAGELISTDRAWPARAMS), himl, i, hdc,
|
||||
0, 0, 0, 0, 0, 0, CLR_NONE, CLR_NONE, fStyle, 0, fState, Frame, 0x00000000};
|
||||
check_ImageList_DrawIndirect(&ildp, bits, expected, line);
|
||||
}
|
||||
|
||||
static void check_ImageList_DrawIndirect_broken(HDC hdc, HIMAGELIST himl, UINT32 *bits, int i,
|
||||
UINT fStyle, UINT fState, DWORD Frame, UINT32 expected,
|
||||
UINT32 broken_expected, int line)
|
||||
{
|
||||
IMAGELISTDRAWPARAMS ildp = {sizeof(IMAGELISTDRAWPARAMS), himl, i, hdc,
|
||||
0, 0, 0, 0, 0, 0, CLR_NONE, CLR_NONE, fStyle, 0, fState, Frame, 0x00000000};
|
||||
bits[0] = 0x00FFFFFF;
|
||||
pImageList_DrawIndirect(&ildp);
|
||||
ok(colour_match(bits[0], expected) ||
|
||||
broken(colour_match(bits[0], broken_expected)),
|
||||
"ImageList_DrawIndirect: Pixel %08X, Expected a close match to %08X from line %d\n",
|
||||
bits[0] & 0x00FFFFFF, expected, line);
|
||||
}
|
||||
|
||||
static void test_ImageList_DrawIndirect(void)
|
||||
{
|
||||
HIMAGELIST himl = NULL;
|
||||
int ret;
|
||||
HDC hdcDst = NULL;
|
||||
HBITMAP hbmOld = NULL, hbmDst = NULL;
|
||||
HBITMAP hbmMask = NULL, hbmInverseMask = NULL;
|
||||
HBITMAP hbmImage = NULL, hbmAlphaImage = NULL, hbmTransparentImage = NULL;
|
||||
int iImage = -1, iAlphaImage = -1, iTransparentImage = -1;
|
||||
UINT32 *bits = 0;
|
||||
UINT32 maskBits = 0x00000000, inverseMaskBits = 0xFFFFFFFF;
|
||||
|
||||
BITMAPINFO bitmapInfo = {{sizeof(BITMAPINFOHEADER), 2, 1, 1, 32, BI_RGB,
|
||||
0, 0, 0, 0, 0}};
|
||||
|
||||
hdcDst = CreateCompatibleDC(0);
|
||||
ok(hdcDst != 0, "CreateCompatibleDC(0) failed to return a valid DC\n");
|
||||
if (!hdcDst)
|
||||
return;
|
||||
|
||||
hbmMask = CreateBitmap(2, 1, 1, 1, &maskBits);
|
||||
ok(hbmMask != 0, "CreateBitmap failed\n");
|
||||
if(!hbmMask) goto cleanup;
|
||||
|
||||
hbmInverseMask = CreateBitmap(2, 1, 1, 1, &inverseMaskBits);
|
||||
ok(hbmInverseMask != 0, "CreateBitmap failed\n");
|
||||
if(!hbmInverseMask) goto cleanup;
|
||||
|
||||
himl = pImageList_Create(2, 1, ILC_COLOR32, 0, 1);
|
||||
ok(himl != 0, "ImageList_Create failed\n");
|
||||
if(!himl) goto cleanup;
|
||||
|
||||
/* Add a no-alpha image */
|
||||
hbmImage = create_test_bitmap(hdcDst, 32, 0x00ABCDEF, 0x00ABCDEF);
|
||||
if(!hbmImage) goto cleanup;
|
||||
|
||||
iImage = pImageList_Add(himl, hbmImage, hbmMask);
|
||||
ok(iImage != -1, "ImageList_Add failed\n");
|
||||
if(iImage == -1) goto cleanup;
|
||||
|
||||
/* Add an alpha image */
|
||||
hbmAlphaImage = create_test_bitmap(hdcDst, 32, 0x89ABCDEF, 0x89ABCDEF);
|
||||
if(!hbmAlphaImage) goto cleanup;
|
||||
|
||||
iAlphaImage = pImageList_Add(himl, hbmAlphaImage, hbmMask);
|
||||
ok(iAlphaImage != -1, "ImageList_Add failed\n");
|
||||
if(iAlphaImage == -1) goto cleanup;
|
||||
|
||||
/* Add a transparent alpha image */
|
||||
hbmTransparentImage = create_test_bitmap(hdcDst, 32, 0x00ABCDEF, 0x89ABCDEF);
|
||||
if(!hbmTransparentImage) goto cleanup;
|
||||
|
||||
iTransparentImage = pImageList_Add(himl, hbmTransparentImage, hbmMask);
|
||||
ok(iTransparentImage != -1, "ImageList_Add failed\n");
|
||||
if(iTransparentImage == -1) goto cleanup;
|
||||
|
||||
/* 32-bit Tests */
|
||||
bitmapInfo.bmiHeader.biBitCount = 32;
|
||||
hbmDst = CreateDIBSection(hdcDst, &bitmapInfo, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
|
||||
ok (hbmDst && bits, "CreateDIBSection failed to return a valid bitmap and buffer\n");
|
||||
if (!hbmDst || !bits)
|
||||
goto cleanup;
|
||||
hbmOld = SelectObject(hdcDst, hbmDst);
|
||||
|
||||
check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iImage, ILD_NORMAL, 0x00ABCDEF, __LINE__);
|
||||
check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iImage, ILD_TRANSPARENT, 0x00ABCDEF, __LINE__);
|
||||
todo_wine check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_BLEND25, ILS_NORMAL, 0, 0x00E8F1FA, 0x00D4D9DD, __LINE__);
|
||||
todo_wine check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_BLEND50, ILS_NORMAL, 0, 0x00E8F1FA, 0x00B4BDC4, __LINE__);
|
||||
check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iImage, ILD_MASK, 0x00ABCDEF, __LINE__);
|
||||
check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iImage, ILD_IMAGE, 0x00ABCDEF, __LINE__);
|
||||
check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iImage, ILD_PRESERVEALPHA, 0x00ABCDEF, __LINE__);
|
||||
|
||||
check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iAlphaImage, ILD_NORMAL, 0x00D3E5F7, __LINE__);
|
||||
check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iAlphaImage, ILD_TRANSPARENT, 0x00D3E5F7, __LINE__);
|
||||
todo_wine
|
||||
{
|
||||
check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_BLEND25, ILS_NORMAL, 0, 0x00E8F1FA, 0x009DA8B1, __LINE__);
|
||||
check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_BLEND50, ILS_NORMAL, 0, 0x00E8F1FA, 0x008C99A3, __LINE__);
|
||||
|
||||
}
|
||||
check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iAlphaImage, ILD_MASK, 0x00D3E5F7, __LINE__);
|
||||
check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iAlphaImage, ILD_IMAGE, 0x00D3E5F7, __LINE__);
|
||||
todo_wine check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iAlphaImage, ILD_PRESERVEALPHA, 0x005D6F81, __LINE__);
|
||||
|
||||
check_ImageList_DrawIndirect_fStyle(hdcDst, himl, bits, iTransparentImage, ILD_NORMAL, 0x00FFFFFF, __LINE__);
|
||||
|
||||
check_ImageList_DrawIndirect_ILD_ROP(hdcDst, himl, bits, iImage, SRCCOPY, 0x00ABCDEF, __LINE__);
|
||||
check_ImageList_DrawIndirect_ILD_ROP(hdcDst, himl, bits, iImage, SRCINVERT, 0x00543210, __LINE__);
|
||||
|
||||
/* ILD_ROP is ignored when the image has an alpha channel */
|
||||
check_ImageList_DrawIndirect_ILD_ROP(hdcDst, himl, bits, iAlphaImage, SRCCOPY, 0x00D3E5F7, __LINE__);
|
||||
check_ImageList_DrawIndirect_ILD_ROP(hdcDst, himl, bits, iAlphaImage, SRCINVERT, 0x00D3E5F7, __LINE__);
|
||||
|
||||
todo_wine check_ImageList_DrawIndirect_fState(hdcDst, himl, bits, iImage, ILD_NORMAL, ILS_SATURATE, 0, 0x00CCCCCC, __LINE__);
|
||||
todo_wine check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_NORMAL, ILS_SATURATE, 0, 0x00AFAFAF, 0x00F0F0F0, __LINE__);
|
||||
|
||||
check_ImageList_DrawIndirect_fState(hdcDst, himl, bits, iImage, ILD_NORMAL, ILS_GLOW, 0, 0x00ABCDEF, __LINE__);
|
||||
check_ImageList_DrawIndirect_fState(hdcDst, himl, bits, iImage, ILD_NORMAL, ILS_SHADOW, 0, 0x00ABCDEF, __LINE__);
|
||||
|
||||
check_ImageList_DrawIndirect_fState(hdcDst, himl, bits, iImage, ILD_NORMAL, ILS_ALPHA, 127, 0x00D5E6F7, __LINE__);
|
||||
check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_NORMAL, ILS_ALPHA, 127, 0x00E9F2FB, 0x00AEB7C0, __LINE__);
|
||||
todo_wine check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_NORMAL, ILS_NORMAL, 127, 0x00E9F2FB, 0x00D3E5F7, __LINE__);
|
||||
|
||||
cleanup:
|
||||
|
||||
if(hbmOld)
|
||||
SelectObject(hdcDst, hbmOld);
|
||||
if(hbmDst)
|
||||
DeleteObject(hbmDst);
|
||||
|
||||
if(hdcDst)
|
||||
DeleteDC(hdcDst);
|
||||
|
||||
if(hbmMask)
|
||||
DeleteObject(hbmMask);
|
||||
if(hbmInverseMask)
|
||||
DeleteObject(hbmInverseMask);
|
||||
|
||||
if(hbmImage)
|
||||
DeleteObject(hbmImage);
|
||||
if(hbmAlphaImage)
|
||||
DeleteObject(hbmAlphaImage);
|
||||
if(hbmTransparentImage)
|
||||
DeleteObject(hbmTransparentImage);
|
||||
|
||||
if(himl)
|
||||
{
|
||||
ret = ImageList_Destroy(himl);
|
||||
ok(ret, "ImageList_Destroy failed\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void test_iimagelist(void)
|
||||
{
|
||||
IImageList *imgl;
|
||||
HIMAGELIST himl;
|
||||
HRESULT hr;
|
||||
ULONG ret;
|
||||
|
||||
if (!pHIMAGELIST_QueryInterface)
|
||||
{
|
||||
win_skip("XP imagelist functions not available\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* test reference counting on destruction */
|
||||
imgl = (IImageList*)createImageList(32, 32);
|
||||
ret = IUnknown_AddRef(imgl);
|
||||
ok(ret == 2, "Expected 2, got %d\n", ret);
|
||||
ret = ImageList_Destroy((HIMAGELIST)imgl);
|
||||
ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
|
||||
ret = ImageList_Destroy((HIMAGELIST)imgl);
|
||||
ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
|
||||
ret = ImageList_Destroy((HIMAGELIST)imgl);
|
||||
ok(ret == FALSE, "Expected FALSE, got %d\n", ret);
|
||||
|
||||
imgl = (IImageList*)createImageList(32, 32);
|
||||
ret = IUnknown_AddRef(imgl);
|
||||
ok(ret == 2, "Expected 2, got %d\n", ret);
|
||||
ret = ImageList_Destroy((HIMAGELIST)imgl);
|
||||
ok(ret == TRUE, "Expected TRUE, got %d\n", ret);
|
||||
ret = IImageList_Release(imgl);
|
||||
ok(ret == 0, "Expected 0, got %d\n", ret);
|
||||
ret = ImageList_Destroy((HIMAGELIST)imgl);
|
||||
ok(ret == FALSE, "Expected FALSE, got %d\n", ret);
|
||||
|
||||
if (!pImageList_CoCreateInstance)
|
||||
{
|
||||
win_skip("Vista imagelist functions not available\n");
|
||||
return;
|
||||
}
|
||||
|
||||
hr = pImageList_CoCreateInstance(&CLSID_ImageList, NULL, &IID_IImageList, (void **) &imgl);
|
||||
ok(SUCCEEDED(hr), "ImageList_CoCreateInstance failed, hr=%x\n", hr);
|
||||
|
||||
if (hr == S_OK)
|
||||
IImageList_Release(imgl);
|
||||
|
||||
himl = createImageList(32, 32);
|
||||
|
||||
if (!himl)
|
||||
return;
|
||||
|
||||
hr = (pHIMAGELIST_QueryInterface)(himl, &IID_IImageList, (void **) &imgl);
|
||||
ok(SUCCEEDED(hr), "HIMAGELIST_QueryInterface failed, hr=%x\n", hr);
|
||||
|
||||
if (hr == S_OK)
|
||||
IImageList_Release(imgl);
|
||||
|
||||
ImageList_Destroy(himl);
|
||||
}
|
||||
|
||||
static void testHotspot_v6(void)
|
||||
{
|
||||
struct hotspot {
|
||||
int dx;
|
||||
int dy;
|
||||
};
|
||||
|
||||
#define SIZEX1 47
|
||||
#define SIZEY1 31
|
||||
#define SIZEX2 11
|
||||
#define SIZEY2 17
|
||||
#define HOTSPOTS_MAX 4 /* Number of entries in hotspots */
|
||||
static const struct hotspot hotspots[HOTSPOTS_MAX] = {
|
||||
{ 10, 7 },
|
||||
{ SIZEX1, SIZEY1 },
|
||||
{ -9, -8 },
|
||||
{ -7, 35 }
|
||||
};
|
||||
int i, j;
|
||||
HIMAGELIST himl1 = createImageList(SIZEX1, SIZEY1);
|
||||
HIMAGELIST himl2 = createImageList(SIZEX2, SIZEY2);
|
||||
IImageList *imgl1, *imgl2;
|
||||
HRESULT hr;
|
||||
|
||||
/* cast to IImageList */
|
||||
imgl1 = (IImageList *) himl1;
|
||||
imgl2 = (IImageList *) himl2;
|
||||
|
||||
for (i = 0; i < HOTSPOTS_MAX; i++) {
|
||||
for (j = 0; j < HOTSPOTS_MAX; j++) {
|
||||
int dx1 = hotspots[i].dx;
|
||||
int dy1 = hotspots[i].dy;
|
||||
int dx2 = hotspots[j].dx;
|
||||
int dy2 = hotspots[j].dy;
|
||||
int correctx, correcty, newx, newy;
|
||||
char loc[256];
|
||||
IImageList *imglNew;
|
||||
POINT ppt;
|
||||
|
||||
hr = IImageList_BeginDrag(imgl1, 0, dx1, dy1);
|
||||
ok(SUCCEEDED(hr), "BeginDrag failed for { %d, %d }\n", dx1, dy1);
|
||||
sprintf(loc, "BeginDrag (%d,%d)\n", i, j);
|
||||
|
||||
/* check merging the dragged image with a second image */
|
||||
hr = IImageList_SetDragCursorImage(imgl2, (IUnknown *) imgl2, 0, dx2, dy2);
|
||||
ok(SUCCEEDED(hr), "SetDragCursorImage failed for {%d, %d}{%d, %d}\n",
|
||||
dx1, dy1, dx2, dy2);
|
||||
sprintf(loc, "SetDragCursorImage (%d,%d)\n", i, j);
|
||||
|
||||
/* check new hotspot, it should be the same like the old one */
|
||||
hr = IImageList_GetDragImage(imgl2, NULL, &ppt, &IID_IImageList, (PVOID *) &imglNew);
|
||||
ok(SUCCEEDED(hr), "GetDragImage failed\n");
|
||||
ok(ppt.x == dx1 && ppt.y == dy1,
|
||||
"Expected drag hotspot [%d,%d] got [%d,%d]\n",
|
||||
dx1, dy1, ppt.x, ppt.y);
|
||||
/* check size of new dragged image */
|
||||
IImageList_GetIconSize(imglNew, &newx, &newy);
|
||||
correctx = max(SIZEX1, max(SIZEX2 + dx2, SIZEX1 - dx2));
|
||||
correcty = max(SIZEY1, max(SIZEY2 + dy2, SIZEY1 - dy2));
|
||||
ok(newx == correctx && newy == correcty,
|
||||
"Expected drag image size [%d,%d] got [%d,%d]\n",
|
||||
correctx, correcty, newx, newy);
|
||||
sprintf(loc, "GetDragImage (%d,%d)\n", i, j);
|
||||
IImageList_EndDrag(imgl2);
|
||||
}
|
||||
}
|
||||
#undef SIZEX1
|
||||
#undef SIZEY1
|
||||
#undef SIZEX2
|
||||
#undef SIZEY2
|
||||
#undef HOTSPOTS_MAX
|
||||
IImageList_Release(imgl2);
|
||||
IImageList_Release(imgl1);
|
||||
}
|
||||
|
||||
static void DoTest1_v6(void)
|
||||
{
|
||||
IImageList *imgl;
|
||||
HIMAGELIST himl;
|
||||
HRESULT hr;
|
||||
|
||||
HICON hicon1;
|
||||
HICON hicon2;
|
||||
HICON hicon3;
|
||||
|
||||
int ret = 0;
|
||||
|
||||
/* create an imagelist to play with */
|
||||
himl = ImageList_Create(84, 84, ILC_COLOR16, 0, 3);
|
||||
ok(himl != 0,"failed to create imagelist\n");
|
||||
|
||||
imgl = (IImageList *) himl;
|
||||
|
||||
/* load the icons to add to the image list */
|
||||
hicon1 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
|
||||
ok(hicon1 != 0, "no hicon1\n");
|
||||
hicon2 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
|
||||
ok(hicon2 != 0, "no hicon2\n");
|
||||
hicon3 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
|
||||
ok(hicon3 != 0, "no hicon3\n");
|
||||
|
||||
/* remove when nothing exists */
|
||||
hr = IImageList_Remove(imgl, 0);
|
||||
ok(!(SUCCEEDED(hr)), "removed nonexistent icon\n");
|
||||
|
||||
/* removing everything from an empty imagelist should succeed */
|
||||
hr = IImageList_Remove(imgl, -1);
|
||||
ok(SUCCEEDED(hr), "removed nonexistent icon\n");
|
||||
|
||||
/* add three */
|
||||
ok(SUCCEEDED(IImageList_ReplaceIcon(imgl, -1, hicon1, &ret)) && (ret == 0),"failed to add icon1\n");
|
||||
ok(SUCCEEDED(IImageList_ReplaceIcon(imgl, -1, hicon2, &ret)) && (ret == 1),"failed to add icon2\n");
|
||||
ok(SUCCEEDED(IImageList_ReplaceIcon(imgl, -1, hicon3, &ret)) && (ret == 2),"failed to add icon3\n");
|
||||
|
||||
/* remove an index out of range */
|
||||
ok(FAILED(IImageList_Remove(imgl, 4711)),"removed nonexistent icon\n");
|
||||
|
||||
/* remove three */
|
||||
ok(SUCCEEDED(IImageList_Remove(imgl,0)),"can't remove 0\n");
|
||||
ok(SUCCEEDED(IImageList_Remove(imgl,0)),"can't remove 0\n");
|
||||
ok(SUCCEEDED(IImageList_Remove(imgl,0)),"can't remove 0\n");
|
||||
|
||||
/* remove one extra */
|
||||
ok(FAILED(IImageList_Remove(imgl, 0)),"removed nonexistent icon\n");
|
||||
|
||||
/* check SetImageCount/GetImageCount */
|
||||
ok(SUCCEEDED(IImageList_SetImageCount(imgl, 3)), "couldn't increase image count\n");
|
||||
ok(SUCCEEDED(IImageList_GetImageCount(imgl, &ret)) && (ret == 3), "invalid image count after increase\n");
|
||||
ok(SUCCEEDED(IImageList_SetImageCount(imgl, 1)), "couldn't decrease image count\n");
|
||||
ok(SUCCEEDED(IImageList_GetImageCount(imgl, &ret)) && (ret == 1), "invalid image count after decrease to 1\n");
|
||||
ok(SUCCEEDED(IImageList_SetImageCount(imgl, 0)), "couldn't decrease image count\n");
|
||||
ok(SUCCEEDED(IImageList_GetImageCount(imgl, &ret)) && (ret == 0), "invalid image count after decrease to 0\n");
|
||||
|
||||
/* destroy it */
|
||||
ok(SUCCEEDED(IImageList_Release(imgl)),"release imagelist failed\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");
|
||||
}
|
||||
|
||||
static void DoTest3_v6(void)
|
||||
{
|
||||
IImageList *imgl;
|
||||
HIMAGELIST himl;
|
||||
|
||||
HBITMAP hbm1;
|
||||
HBITMAP hbm2;
|
||||
HBITMAP hbm3;
|
||||
|
||||
IMAGELISTDRAWPARAMS imldp;
|
||||
HWND hwndfortest;
|
||||
HDC hdc;
|
||||
int ret;
|
||||
|
||||
hwndfortest = create_a_window();
|
||||
hdc = GetDC(hwndfortest);
|
||||
ok(hdc!=NULL, "couldn't get DC\n");
|
||||
|
||||
/* create an imagelist to play with */
|
||||
himl = ImageList_Create(48, 48, ILC_COLOR16, 0, 3);
|
||||
ok(himl!=0,"failed to create imagelist\n");
|
||||
|
||||
imgl = (IImageList *) himl;
|
||||
|
||||
/* load the icons to add to the image list */
|
||||
hbm1 = CreateBitmap(48, 48, 1, 1, bitmap_bits);
|
||||
ok(hbm1 != 0, "no bitmap 1\n");
|
||||
hbm2 = CreateBitmap(48, 48, 1, 1, bitmap_bits);
|
||||
ok(hbm2 != 0, "no bitmap 2\n");
|
||||
hbm3 = CreateBitmap(48, 48, 1, 1, bitmap_bits);
|
||||
ok(hbm3 != 0, "no bitmap 3\n");
|
||||
|
||||
/* add three */
|
||||
ok(SUCCEEDED(IImageList_Add(imgl, hbm1, 0, &ret)) && (ret == 0), "failed to add bitmap 1\n");
|
||||
ok(SUCCEEDED(IImageList_Add(imgl, hbm2, 0, &ret)) && (ret == 1), "failed to add bitmap 2\n");
|
||||
|
||||
ok(SUCCEEDED(IImageList_SetImageCount(imgl, 3)), "Setimage count failed\n");
|
||||
ok(SUCCEEDED(IImageList_Replace(imgl, 2, hbm3, 0)), "failed to replace bitmap 3\n");
|
||||
|
||||
memset(&imldp, 0, sizeof (imldp));
|
||||
ok(FAILED(IImageList_Draw(imgl, &imldp)), "zero data succeeded!\n");
|
||||
|
||||
imldp.cbSize = sizeof (imldp);
|
||||
imldp.hdcDst = hdc;
|
||||
imldp.himl = himl;
|
||||
|
||||
if (FAILED(IImageList_Draw(imgl, &imldp)))
|
||||
{
|
||||
/* Earlier versions of native comctl32 use a smaller structure */
|
||||
imldp.cbSize -= 3 * sizeof(DWORD);
|
||||
ok(SUCCEEDED(IImageList_Draw(imgl, &imldp)), "should succeed\n");
|
||||
}
|
||||
|
||||
REDRAW(hwndfortest);
|
||||
WAIT;
|
||||
|
||||
imldp.fStyle = SRCCOPY;
|
||||
imldp.rgbBk = CLR_DEFAULT;
|
||||
imldp.rgbFg = CLR_DEFAULT;
|
||||
imldp.y = 100;
|
||||
imldp.x = 100;
|
||||
ok(SUCCEEDED(IImageList_Draw(imgl, &imldp)), "should succeed\n");
|
||||
imldp.i ++;
|
||||
ok(SUCCEEDED(IImageList_Draw(imgl, &imldp)), "should succeed\n");
|
||||
imldp.i ++;
|
||||
ok(SUCCEEDED(IImageList_Draw(imgl, &imldp)), "should succeed\n");
|
||||
imldp.i ++;
|
||||
ok(FAILED(IImageList_Draw(imgl, &imldp)), "should fail\n");
|
||||
|
||||
/* remove three */
|
||||
ok(SUCCEEDED(IImageList_Remove(imgl, 0)), "removing 1st bitmap\n");
|
||||
ok(SUCCEEDED(IImageList_Remove(imgl, 0)), "removing 2nd bitmap\n");
|
||||
ok(SUCCEEDED(IImageList_Remove(imgl, 0)), "removing 3rd bitmap\n");
|
||||
|
||||
/* destroy it */
|
||||
ok(SUCCEEDED(IImageList_Release(imgl)), "release imagelist failed\n");
|
||||
|
||||
/* bitmaps should not be deleted by the imagelist */
|
||||
ok(DeleteObject(hbm1),"bitmap 1 can't be deleted\n");
|
||||
ok(DeleteObject(hbm2),"bitmap 2 can't be deleted\n");
|
||||
ok(DeleteObject(hbm3),"bitmap 3 can't be deleted\n");
|
||||
|
||||
ReleaseDC(hwndfortest, hdc);
|
||||
DestroyWindow(hwndfortest);
|
||||
}
|
||||
|
||||
static void testMerge_v6(void)
|
||||
{
|
||||
HIMAGELIST himl1, himl2;
|
||||
IImageList *imgl1, *imgl2, *merge;
|
||||
HICON hicon1;
|
||||
HWND hwnd = create_a_window();
|
||||
HRESULT hr;
|
||||
int ret;
|
||||
|
||||
himl1 = ImageList_Create(32,32,0,0,3);
|
||||
ok(himl1 != NULL,"failed to create himl1\n");
|
||||
|
||||
himl2 = ImageList_Create(32,32,0,0,3);
|
||||
ok(himl2 != NULL,"failed to create himl2\n");
|
||||
|
||||
hicon1 = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits);
|
||||
ok(hicon1 != NULL, "failed to create hicon1\n");
|
||||
|
||||
if (!himl1 || !himl2 || !hicon1)
|
||||
return;
|
||||
|
||||
/* cast to IImageList */
|
||||
imgl1 = (IImageList *) himl1;
|
||||
imgl2 = (IImageList *) himl2;
|
||||
|
||||
ok(SUCCEEDED(IImageList_ReplaceIcon(imgl2, -1, hicon1, &ret)) && (ret == 0),"add icon1 to himl2 failed\n");
|
||||
|
||||
/* If himl1 has no images, merge still succeeds */
|
||||
hr = IImageList_Merge(imgl1, -1, (IUnknown *) imgl2, 0, 0, 0, &IID_IImageList, (void **) &merge);
|
||||
ok(SUCCEEDED(hr), "merge himl1,-1 failed\n");
|
||||
if (SUCCEEDED(hr)) IImageList_Release(merge);
|
||||
|
||||
hr = IImageList_Merge(imgl1, 0, (IUnknown *) imgl2, 0, 0, 0, &IID_IImageList, (void **) &merge);
|
||||
ok(SUCCEEDED(hr), "merge himl1,0 failed\n");
|
||||
if (SUCCEEDED(hr)) IImageList_Release(merge);
|
||||
|
||||
/* Same happens if himl2 is empty */
|
||||
IImageList_Release(imgl2);
|
||||
himl2 = ImageList_Create(32,32,0,0,3);
|
||||
ok(himl2 != NULL,"failed to recreate himl2\n");
|
||||
|
||||
imgl2 = (IImageList *) himl2;
|
||||
|
||||
hr = IImageList_Merge(imgl1, -1, (IUnknown *) imgl2, -1, 0, 0, &IID_IImageList, (void **) &merge);
|
||||
ok(SUCCEEDED(hr), "merge himl2,-1 failed\n");
|
||||
if (SUCCEEDED(hr)) IImageList_Release(merge);
|
||||
|
||||
hr = IImageList_Merge(imgl1, -1, (IUnknown *) imgl2, 0, 0, 0, &IID_IImageList, (void **) &merge);
|
||||
ok(SUCCEEDED(hr), "merge himl2,0 failed\n");
|
||||
if (SUCCEEDED(hr)) IImageList_Release(merge);
|
||||
|
||||
/* Now try merging an image with itself */
|
||||
ok(SUCCEEDED(IImageList_ReplaceIcon(imgl2, -1, hicon1, &ret)) && (ret == 0),"re-add icon1 to himl2 failed\n");
|
||||
|
||||
hr = IImageList_Merge(imgl2, 0, (IUnknown *) imgl2, 0, 0, 0, &IID_IImageList, (void **) &merge);
|
||||
ok(SUCCEEDED(hr), "merge himl2 with itself failed\n");
|
||||
if (SUCCEEDED(hr)) IImageList_Release(merge);
|
||||
|
||||
/* Try merging 2 different image lists */
|
||||
ok(SUCCEEDED(IImageList_ReplaceIcon(imgl1, -1, hicon1, &ret)) && (ret == 0),"add icon1 to himl1 failed\n");
|
||||
|
||||
hr = IImageList_Merge(imgl1, 0, (IUnknown *) imgl2, 0, 0, 0, &IID_IImageList, (void **) &merge);
|
||||
ok(SUCCEEDED(hr), "merge himl1 with himl2 failed\n");
|
||||
if (SUCCEEDED(hr)) IImageList_Release(merge);
|
||||
|
||||
hr = IImageList_Merge(imgl1, 0, (IUnknown *) imgl2, 0, 8, 16, &IID_IImageList, (void **) &merge);
|
||||
ok(SUCCEEDED(hr), "merge himl1 with himl2 8,16 failed\n");
|
||||
if (SUCCEEDED(hr)) IImageList_Release(merge);
|
||||
|
||||
IImageList_Release(imgl1);
|
||||
IImageList_Release(imgl2);
|
||||
|
||||
DestroyIcon(hicon1);
|
||||
DestroyWindow(hwnd);
|
||||
}
|
||||
|
||||
START_TEST(imagelist)
|
||||
{
|
||||
ULONG_PTR ctx_cookie;
|
||||
HANDLE hCtx;
|
||||
|
||||
HMODULE hComCtl32 = GetModuleHandle("comctl32.dll");
|
||||
pImageList_Create = NULL; /* These are not needed for non-v6.0 tests*/
|
||||
pImageList_Add = NULL;
|
||||
pImageList_DrawIndirect = (void*)GetProcAddress(hComCtl32, "ImageList_DrawIndirect");
|
||||
pImageList_SetImageCount = (void*)GetProcAddress(hComCtl32, "ImageList_SetImageCount");
|
||||
|
||||
desktopDC=GetDC(NULL);
|
||||
hinst = GetModuleHandleA(NULL);
|
||||
|
||||
InitCommonControls();
|
||||
|
@ -998,4 +1633,36 @@ START_TEST(imagelist)
|
|||
DoTest3();
|
||||
testMerge();
|
||||
test_imagelist_storage();
|
||||
|
||||
FreeLibrary(hComCtl32);
|
||||
|
||||
/* Now perform v6 tests */
|
||||
|
||||
if (!load_v6_module(&ctx_cookie, &hCtx))
|
||||
return;
|
||||
|
||||
/* Reload comctl32 */
|
||||
hComCtl32 = LoadLibraryA("comctl32.dll");
|
||||
pImageList_Create = (void*)GetProcAddress(hComCtl32, "ImageList_Create");
|
||||
pImageList_Add = (void*)GetProcAddress(hComCtl32, "ImageList_Add");
|
||||
pImageList_DrawIndirect = (void*)GetProcAddress(hComCtl32, "ImageList_DrawIndirect");
|
||||
pImageList_SetImageCount = (void*)GetProcAddress(hComCtl32, "ImageList_SetImageCount");
|
||||
pImageList_CoCreateInstance = (void*)GetProcAddress(hComCtl32, "ImageList_CoCreateInstance");
|
||||
pHIMAGELIST_QueryInterface = (void*)GetProcAddress(hComCtl32, "HIMAGELIST_QueryInterface");
|
||||
|
||||
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
|
||||
|
||||
/* Do v6.0 tests */
|
||||
test_ImageList_DrawIndirect();
|
||||
test_shell_imagelist();
|
||||
test_iimagelist();
|
||||
|
||||
testHotspot_v6();
|
||||
DoTest1_v6();
|
||||
DoTest3_v6();
|
||||
testMerge_v6();
|
||||
|
||||
CoUninitialize();
|
||||
|
||||
unload_v6_module(ctx_cookie, hCtx);
|
||||
}
|
||||
|
|
|
@ -33,8 +33,6 @@ static HWND create_ipaddress_control (void)
|
|||
handle = CreateWindowEx(0, WC_IPADDRESS, NULL,
|
||||
WS_BORDER|WS_VISIBLE, 0, 0, 0, 0,
|
||||
NULL, NULL, NULL, NULL);
|
||||
assert(handle);
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
|
@ -45,6 +43,11 @@ static void test_get_set_text(void)
|
|||
INT r;
|
||||
|
||||
hwnd = create_ipaddress_control();
|
||||
if (!hwnd)
|
||||
{
|
||||
win_skip("IPAddress control not implemented\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* check text just after creation */
|
||||
r = GetWindowText(hwnd, ip, sizeof(ip)/sizeof(CHAR));
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -104,7 +104,9 @@ static void test_GetPtrAW(void)
|
|||
ok (count == sourcelen ||
|
||||
broken(count == 0), /* win9x */
|
||||
"Expected count to be %d, it was %d\n", sourcelen, count);
|
||||
ok (!lstrcmp(dest, desttest), "Expected destination to not have changed\n");
|
||||
ok (!lstrcmp(dest, desttest) ||
|
||||
broken(!lstrcmp(dest, "")), /* Win7 */
|
||||
"Expected destination to not have changed\n");
|
||||
|
||||
count = 0;
|
||||
count = pStr_GetPtrA(source, NULL, destsize);
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -69,11 +69,27 @@ static HANDLE (WINAPI *pCreateMRUListA)(LPCREATEMRULISTA);
|
|||
static void (WINAPI *pFreeMRUList)(HANDLE);
|
||||
static INT (WINAPI *pAddMRUStringA)(HANDLE,LPCSTR);
|
||||
static INT (WINAPI *pEnumMRUList)(HANDLE,INT,LPVOID,DWORD);
|
||||
static INT (WINAPI *pEnumMRUListW)(HANDLE,INT,LPVOID,DWORD);
|
||||
static HANDLE (WINAPI *pCreateMRUListLazyA)(LPCREATEMRULISTA, DWORD, DWORD, DWORD);
|
||||
static INT (WINAPI *pFindMRUData)(HANDLE, LPCVOID, DWORD, LPINT);
|
||||
static INT (WINAPI *pAddMRUData)(HANDLE, LPCVOID, DWORD);
|
||||
/*
|
||||
static INT (WINAPI *pFindMRUStringA)(HANDLE,LPCSTR,LPINT);
|
||||
*/
|
||||
|
||||
|
||||
static void InitPointers(void)
|
||||
{
|
||||
pCreateMRUListA = (void*)GetProcAddress(hComctl32,(LPCSTR)151);
|
||||
pFreeMRUList = (void*)GetProcAddress(hComctl32,(LPCSTR)152);
|
||||
pAddMRUStringA = (void*)GetProcAddress(hComctl32,(LPCSTR)153);
|
||||
pEnumMRUList = (void*)GetProcAddress(hComctl32,(LPCSTR)154);
|
||||
pCreateMRUListLazyA = (void*)GetProcAddress(hComctl32,(LPCSTR)157);
|
||||
pAddMRUData = (void*)GetProcAddress(hComctl32,(LPCSTR)167);
|
||||
pFindMRUData = (void*)GetProcAddress(hComctl32,(LPCSTR)169);
|
||||
pEnumMRUListW = (void*)GetProcAddress(hComctl32,(LPCSTR)403);
|
||||
}
|
||||
|
||||
/* Based on RegDeleteTreeW from dlls/advapi32/registry.c */
|
||||
static LSTATUS mru_RegDeleteTreeA(HKEY hKey, LPCSTR lpszSubKey)
|
||||
{
|
||||
|
@ -227,11 +243,6 @@ static void test_MRUListA(void)
|
|||
HKEY hKey;
|
||||
INT iRet;
|
||||
|
||||
pCreateMRUListA = (void*)GetProcAddress(hComctl32,(LPCSTR)151);
|
||||
pFreeMRUList = (void*)GetProcAddress(hComctl32,(LPCSTR)152);
|
||||
pAddMRUStringA = (void*)GetProcAddress(hComctl32,(LPCSTR)153);
|
||||
pEnumMRUList = (void*)GetProcAddress(hComctl32,(LPCSTR)154);
|
||||
|
||||
if (!pCreateMRUListA || !pFreeMRUList || !pAddMRUStringA || !pEnumMRUList)
|
||||
{
|
||||
skip("MRU entry points not found\n");
|
||||
|
@ -374,7 +385,7 @@ static void test_MRUListA(void)
|
|||
/* check entry 0 */
|
||||
buffer[0] = 0;
|
||||
iRet = pEnumMRUList(hMRU, 0, buffer, 255);
|
||||
todo_wine ok(iRet == lstrlen(checks[3]), "EnumMRUList expected %d, got %d\n", lstrlen(checks[3]), iRet);
|
||||
ok(iRet == lstrlen(checks[3]), "EnumMRUList expected %d, got %d\n", lstrlen(checks[3]), iRet);
|
||||
ok(strcmp(buffer, checks[3]) == 0, "EnumMRUList expected %s, got %s\n", checks[3], buffer);
|
||||
|
||||
/* check entry 0 with a too small buffer */
|
||||
|
@ -383,21 +394,21 @@ static void test_MRUListA(void)
|
|||
buffer[2] = 'A'; /* unchanged */
|
||||
buffer[3] = 0; /* unchanged */
|
||||
iRet = pEnumMRUList(hMRU, 0, buffer, 2);
|
||||
todo_wine ok(iRet == lstrlen(checks[3]), "EnumMRUList expected %d, got %d\n", lstrlen(checks[3]), iRet);
|
||||
todo_wine ok(strcmp(buffer, "T") == 0, "EnumMRUList expected %s, got %s\n", "T", buffer);
|
||||
ok(iRet == lstrlen(checks[3]), "EnumMRUList expected %d, got %d\n", lstrlen(checks[3]), iRet);
|
||||
ok(strcmp(buffer, "T") == 0, "EnumMRUList expected %s, got %s\n", "T", buffer);
|
||||
/* make sure space after buffer has old values */
|
||||
ok(buffer[2] == 'A', "EnumMRUList expected %02x, got %02x\n", 'A', buffer[2]);
|
||||
|
||||
/* check entry 1 */
|
||||
buffer[0] = 0;
|
||||
iRet = pEnumMRUList(hMRU, 1, buffer, 255);
|
||||
todo_wine ok(iRet == lstrlen(checks[1]), "EnumMRUList expected %d, got %d\n", lstrlen(checks[1]), iRet);
|
||||
ok(iRet == lstrlen(checks[1]), "EnumMRUList expected %d, got %d\n", lstrlen(checks[1]), iRet);
|
||||
ok(strcmp(buffer, checks[1]) == 0, "EnumMRUList expected %s, got %s\n", checks[1], buffer);
|
||||
|
||||
/* check entry 2 */
|
||||
buffer[0] = 0;
|
||||
iRet = pEnumMRUList(hMRU, 2, buffer, 255);
|
||||
todo_wine ok(iRet == lstrlen(checks[2]), "EnumMRUList expected %d, got %d\n", lstrlen(checks[2]), iRet);
|
||||
ok(iRet == lstrlen(checks[2]), "EnumMRUList expected %d, got %d\n", lstrlen(checks[2]), iRet);
|
||||
ok(strcmp(buffer, checks[2]) == 0, "EnumMRUList expected %s, got %s\n", checks[2], buffer);
|
||||
|
||||
/* check out of bounds entry 3 */
|
||||
|
@ -413,6 +424,89 @@ static void test_MRUListA(void)
|
|||
/* FreeMRUList(NULL) crashes on Win98 OSR0 */
|
||||
}
|
||||
|
||||
static void test_CreateMRUListLazyA(void)
|
||||
{
|
||||
HANDLE hMRU;
|
||||
HKEY hKey;
|
||||
CREATEMRULISTA listA = { 0 };
|
||||
|
||||
if (!pCreateMRUListLazyA || !pFreeMRUList)
|
||||
{
|
||||
win_skip("CreateMRUListLazyA or FreeMRUList entry points not found\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* wrong size */
|
||||
listA.cbSize = sizeof(listA) + 1;
|
||||
hMRU = pCreateMRUListLazyA(&listA, 0, 0, 0);
|
||||
ok(hMRU == NULL, "Expected NULL handle, got %p\n", hMRU);
|
||||
listA.cbSize = 4;
|
||||
hMRU = pCreateMRUListLazyA(&listA, 0, 0, 0);
|
||||
ok(hMRU == NULL, "Expected NULL handle, got %p\n", hMRU);
|
||||
/* NULL hKey */
|
||||
listA.cbSize = sizeof(listA);
|
||||
listA.hKey = NULL;
|
||||
hMRU = pCreateMRUListLazyA(&listA, 0, 0, 0);
|
||||
ok(hMRU == NULL, "Expected NULL handle, got %p\n", hMRU);
|
||||
/* NULL subkey */
|
||||
ok(!RegCreateKeyA(HKEY_CURRENT_USER, REG_TEST_KEYA, &hKey),
|
||||
"Couldn't create test key \"%s\"\n", REG_TEST_KEYA);
|
||||
listA.cbSize = sizeof(listA);
|
||||
listA.hKey = hKey;
|
||||
listA.lpszSubKey = NULL;
|
||||
hMRU = pCreateMRUListLazyA(&listA, 0, 0, 0);
|
||||
ok(hMRU == NULL || broken(hMRU != NULL), /* Win9x */
|
||||
"Expected NULL handle, got %p\n", hMRU);
|
||||
if (hMRU) pFreeMRUList(hMRU);
|
||||
}
|
||||
|
||||
static void test_EnumMRUList(void)
|
||||
{
|
||||
if (!pEnumMRUList || !pEnumMRUListW)
|
||||
{
|
||||
win_skip("EnumMRUListA/EnumMRUListW entry point not found\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* NULL handle */
|
||||
if (0)
|
||||
{
|
||||
/* crashes on NT4, passed on Win2k, XP, 2k3, Vista, 2k8 */
|
||||
pEnumMRUList(NULL, 0, NULL, 0);
|
||||
pEnumMRUListW(NULL, 0, NULL, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void test_FindMRUData(void)
|
||||
{
|
||||
INT iRet;
|
||||
|
||||
if (!pFindMRUData)
|
||||
{
|
||||
win_skip("FindMRUData entry point not found\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* NULL handle */
|
||||
iRet = pFindMRUData(NULL, NULL, 0, NULL);
|
||||
ok(iRet == -1, "FindMRUData expected -1, got %d\n", iRet);
|
||||
}
|
||||
|
||||
static void test_AddMRUData(void)
|
||||
{
|
||||
INT iRet;
|
||||
|
||||
if (!pAddMRUData)
|
||||
{
|
||||
win_skip("AddMRUData entry point not found\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* NULL handle */
|
||||
iRet = pFindMRUData(NULL, NULL, 0, NULL);
|
||||
ok(iRet == -1, "AddMRUData expected -1, got %d\n", iRet);
|
||||
}
|
||||
|
||||
START_TEST(mru)
|
||||
{
|
||||
hComctl32 = GetModuleHandleA("comctl32.dll");
|
||||
|
@ -421,7 +515,13 @@ START_TEST(mru)
|
|||
if (!create_reg_entries())
|
||||
return;
|
||||
|
||||
InitPointers();
|
||||
|
||||
test_MRUListA();
|
||||
test_CreateMRUListLazyA();
|
||||
test_EnumMRUList();
|
||||
test_FindMRUData();
|
||||
test_AddMRUData();
|
||||
|
||||
delete_reg_entries();
|
||||
}
|
||||
|
|
|
@ -1,251 +0,0 @@
|
|||
/* 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)
|
||||
{
|
||||
}
|
|
@ -47,7 +47,8 @@ struct message
|
|||
msg_flags_t flags; /* message props */
|
||||
WPARAM wParam; /* expected value of wParam */
|
||||
LPARAM lParam; /* expected value of lParam */
|
||||
UINT id; /* id of the window */
|
||||
UINT id; /* extra message data: id of the window,
|
||||
notify code etc. */
|
||||
};
|
||||
|
||||
struct msg_sequence
|
||||
|
@ -57,17 +58,237 @@ struct msg_sequence
|
|||
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);
|
||||
static 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++;
|
||||
}
|
||||
|
||||
static 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;
|
||||
}
|
||||
|
||||
static void flush_sequences(struct msg_sequence **seq, int n)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
flush_sequence(seq, i);
|
||||
}
|
||||
|
||||
static 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 && expected->flags & optional)
|
||||
{
|
||||
expected++;
|
||||
continue;
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
#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);
|
||||
static void init_msg_sequences(struct msg_sequence **seq, int n)
|
||||
{
|
||||
int i;
|
||||
|
||||
void init_msg_sequences(struct msg_sequence **seq, int n);
|
||||
for (i = 0; i < n; i++)
|
||||
seq[i] = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(struct msg_sequence));
|
||||
}
|
||||
|
|
|
@ -163,6 +163,7 @@ static void cleanup(void)
|
|||
static void test_redraw(void)
|
||||
{
|
||||
RECT client_rect;
|
||||
LRESULT ret;
|
||||
|
||||
SendMessageA(hProgressWnd, PBM_SETRANGE, 0, MAKELPARAM(0, 100));
|
||||
SendMessageA(hProgressWnd, PBM_SETPOS, 10, 0);
|
||||
|
@ -184,7 +185,11 @@ static void test_redraw(void)
|
|||
/* 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");
|
||||
ret = SendMessageA(hProgressWnd, PBM_GETPOS, 0, 0);
|
||||
if (ret == 0)
|
||||
win_skip("PBM_GETPOS needs comctl32 > 4.70\n");
|
||||
else
|
||||
ok(ret == 100, "PBM_GETPOS returned a wrong position : %d\n", (UINT)ret);
|
||||
|
||||
/* PBM_SETRANGE and PBM_SETRANGE32:
|
||||
Usually the progress bar doesn't repaint itself immediately. If the
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
/* Unit test suite for property sheet control.
|
||||
*
|
||||
* Copyright 2006 Huw Davies
|
||||
* Copyright 2009 Jan de Mooij
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -20,9 +21,16 @@
|
|||
#include <windows.h>
|
||||
#include <commctrl.h>
|
||||
|
||||
#include "resources.h"
|
||||
|
||||
#include "wine/test.h"
|
||||
|
||||
static HWND parent;
|
||||
static HWND sheethwnd;
|
||||
|
||||
static LONG active_page = -1;
|
||||
|
||||
#define IDC_APPLY_BUTTON 12321
|
||||
|
||||
static int CALLBACK sheet_callback(HWND hwnd, UINT msg, LPARAM lparam)
|
||||
{
|
||||
|
@ -33,12 +41,13 @@ static int CALLBACK sheet_callback(HWND hwnd, UINT msg, LPARAM lparam)
|
|||
char caption[256];
|
||||
GetWindowTextA(hwnd, caption, sizeof(caption));
|
||||
ok(!strcmp(caption,"test caption"), "caption: %s\n", caption);
|
||||
sheethwnd = hwnd;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static INT_PTR CALLBACK page_dlg_proc(HWND hwnd, UINT msg, WPARAM wparam,
|
||||
LPARAM lparam)
|
||||
{
|
||||
|
@ -64,6 +73,10 @@ static INT_PTR CALLBACK page_dlg_proc(HWND hwnd, UINT msg, WPARAM wparam,
|
|||
return FALSE;
|
||||
}
|
||||
}
|
||||
case WM_NCDESTROY:
|
||||
ok(!SendMessageA(sheethwnd, PSM_INDEXTOHWND, 400, 0),"Should always be 0\n");
|
||||
return TRUE;
|
||||
|
||||
default:
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -79,7 +92,7 @@ static void test_title(void)
|
|||
memset(&psp, 0, sizeof(psp));
|
||||
psp.dwSize = sizeof(psp);
|
||||
psp.dwFlags = 0;
|
||||
psp.hInstance = GetModuleHandleW(NULL);
|
||||
psp.hInstance = GetModuleHandleA(NULL);
|
||||
U(psp).pszTemplate = "prop_page1";
|
||||
U2(psp).pszIcon = NULL;
|
||||
psp.pfnDlgProc = page_dlg_proc;
|
||||
|
@ -97,6 +110,12 @@ static void test_title(void)
|
|||
psh.pfnCallback = sheet_callback;
|
||||
|
||||
hdlg = (HWND)PropertySheetA(&psh);
|
||||
if (hdlg == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
win_skip("comctl32 4.70 needs dwSize adjustment\n");
|
||||
psh.dwSize = sizeof(psh) - sizeof(HBITMAP) - sizeof(HPALETTE) - sizeof(HBITMAP);
|
||||
hdlg = (HWND)PropertySheetA(&psh);
|
||||
}
|
||||
DestroyWindow(hdlg);
|
||||
}
|
||||
|
||||
|
@ -110,7 +129,7 @@ static void test_nopage(void)
|
|||
memset(&psp, 0, sizeof(psp));
|
||||
psp.dwSize = sizeof(psp);
|
||||
psp.dwFlags = 0;
|
||||
psp.hInstance = GetModuleHandleW(NULL);
|
||||
psp.hInstance = GetModuleHandleA(NULL);
|
||||
U(psp).pszTemplate = "prop_page1";
|
||||
U2(psp).pszIcon = NULL;
|
||||
psp.pfnDlgProc = page_dlg_proc;
|
||||
|
@ -128,6 +147,12 @@ static void test_nopage(void)
|
|||
psh.pfnCallback = sheet_callback;
|
||||
|
||||
hdlg = (HWND)PropertySheetA(&psh);
|
||||
if (hdlg == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
win_skip("comctl32 4.70 needs dwSize adjustment\n");
|
||||
psh.dwSize = sizeof(psh) - sizeof(HBITMAP) - sizeof(HPALETTE) - sizeof(HBITMAP);
|
||||
hdlg = (HWND)PropertySheetA(&psh);
|
||||
}
|
||||
ShowWindow(hdlg,SW_NORMAL);
|
||||
SendMessage(hdlg, PSM_REMOVEPAGE, 0, 0);
|
||||
RedrawWindow(hdlg,NULL,NULL,RDW_UPDATENOW|RDW_ERASENOW);
|
||||
|
@ -170,6 +195,7 @@ static void test_disableowner(void)
|
|||
HPROPSHEETPAGE hpsp[1];
|
||||
PROPSHEETPAGEA psp;
|
||||
PROPSHEETHEADERA psh;
|
||||
INT_PTR p;
|
||||
|
||||
register_parent_wnd_class();
|
||||
parent = CreateWindowA("parent class", "", WS_CAPTION | WS_SYSMENU | WS_VISIBLE, 100, 100, 100, 100, GetDesktopWindow(), NULL, GetModuleHandleA(NULL), 0);
|
||||
|
@ -177,7 +203,7 @@ static void test_disableowner(void)
|
|||
memset(&psp, 0, sizeof(psp));
|
||||
psp.dwSize = sizeof(psp);
|
||||
psp.dwFlags = 0;
|
||||
psp.hInstance = GetModuleHandleW(NULL);
|
||||
psp.hInstance = GetModuleHandleA(NULL);
|
||||
U(psp).pszTemplate = "prop_page1";
|
||||
U2(psp).pszIcon = NULL;
|
||||
psp.pfnDlgProc = NULL;
|
||||
|
@ -194,14 +220,227 @@ static void test_disableowner(void)
|
|||
U3(psh).phpage = hpsp;
|
||||
psh.pfnCallback = disableowner_callback;
|
||||
|
||||
PropertySheetA(&psh);
|
||||
p = PropertySheetA(&psh);
|
||||
todo_wine
|
||||
ok(p == 0, "Expected 0, got %ld\n", p);
|
||||
ok(IsWindowEnabled(parent) != 0, "parent window should be enabled\n");
|
||||
DestroyWindow(parent);
|
||||
}
|
||||
|
||||
static INT_PTR CALLBACK nav_page_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
|
||||
{
|
||||
switch(msg){
|
||||
case WM_NOTIFY:
|
||||
{
|
||||
LPNMHDR hdr = (LPNMHDR)lparam;
|
||||
switch(hdr->code){
|
||||
case PSN_SETACTIVE:
|
||||
active_page = PropSheet_HwndToIndex(hdr->hwndFrom, hwnd);
|
||||
return TRUE;
|
||||
case PSN_KILLACTIVE:
|
||||
/* prevent navigation away from the fourth page */
|
||||
if(active_page == 3){
|
||||
SetWindowLongPtr(hwnd, DWLP_MSGRESULT, TRUE);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void test_wiznavigation(void)
|
||||
{
|
||||
HPROPSHEETPAGE hpsp[4];
|
||||
PROPSHEETPAGEA psp[4];
|
||||
PROPSHEETHEADERA psh;
|
||||
HWND hdlg, control;
|
||||
LONG_PTR controlID;
|
||||
LRESULT defidres;
|
||||
BOOL hwndtoindex_supported = TRUE;
|
||||
const INT nextID = 12324;
|
||||
const INT backID = 12323;
|
||||
|
||||
/* create the property sheet pages */
|
||||
memset(psp, 0, sizeof(PROPSHEETPAGEA) * 4);
|
||||
|
||||
psp[0].dwSize = sizeof(PROPSHEETPAGEA);
|
||||
psp[0].hInstance = GetModuleHandleA(NULL);
|
||||
U(psp[0]).pszTemplate = MAKEINTRESOURCE(IDD_PROP_PAGE_INTRO);
|
||||
psp[0].pfnDlgProc = nav_page_proc;
|
||||
hpsp[0] = CreatePropertySheetPageA(&psp[0]);
|
||||
|
||||
psp[1].dwSize = sizeof(PROPSHEETPAGEA);
|
||||
psp[1].hInstance = GetModuleHandleA(NULL);
|
||||
U(psp[1]).pszTemplate = MAKEINTRESOURCE(IDD_PROP_PAGE_EDIT);
|
||||
psp[1].pfnDlgProc = nav_page_proc;
|
||||
hpsp[1] = CreatePropertySheetPageA(&psp[1]);
|
||||
|
||||
psp[2].dwSize = sizeof(PROPSHEETPAGEA);
|
||||
psp[2].hInstance = GetModuleHandleA(NULL);
|
||||
U(psp[2]).pszTemplate = MAKEINTRESOURCE(IDD_PROP_PAGE_RADIO);
|
||||
psp[2].pfnDlgProc = nav_page_proc;
|
||||
hpsp[2] = CreatePropertySheetPageA(&psp[2]);
|
||||
|
||||
psp[3].dwSize = sizeof(PROPSHEETPAGEA);
|
||||
psp[3].hInstance = GetModuleHandleA(NULL);
|
||||
U(psp[3]).pszTemplate = MAKEINTRESOURCE(IDD_PROP_PAGE_EXIT);
|
||||
psp[3].pfnDlgProc = nav_page_proc;
|
||||
hpsp[3] = CreatePropertySheetPageA(&psp[3]);
|
||||
|
||||
/* set up the property sheet dialog */
|
||||
memset(&psh, 0, sizeof(psh));
|
||||
psh.dwSize = sizeof(psh);
|
||||
psh.dwFlags = PSH_MODELESS | PSH_WIZARD;
|
||||
psh.pszCaption = "A Wizard";
|
||||
psh.nPages = 4;
|
||||
psh.hwndParent = GetDesktopWindow();
|
||||
U3(psh).phpage = hpsp;
|
||||
hdlg = (HWND)PropertySheetA(&psh);
|
||||
if (hdlg == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
win_skip("comctl32 4.70 needs dwSize adjustment\n");
|
||||
psh.dwSize = sizeof(psh) - sizeof(HBITMAP) - sizeof(HPALETTE) - sizeof(HBITMAP);
|
||||
hdlg = (HWND)PropertySheetA(&psh);
|
||||
}
|
||||
|
||||
ok(active_page == 0, "Active page should be 0. Is: %d\n", active_page);
|
||||
|
||||
control = GetFocus();
|
||||
controlID = GetWindowLongPtr(control, GWLP_ID);
|
||||
ok(controlID == nextID, "Focus should have been set to the Next button. Expected: %d, Found: %ld\n", nextID, controlID);
|
||||
|
||||
/* simulate pressing the Next button */
|
||||
SendMessage(hdlg, PSM_PRESSBUTTON, PSBTN_NEXT, 0);
|
||||
if (!active_page) hwndtoindex_supported = FALSE;
|
||||
if (hwndtoindex_supported)
|
||||
ok(active_page == 1, "Active page should be 1 after pressing Next. Is: %d\n", active_page);
|
||||
|
||||
control = GetFocus();
|
||||
controlID = GetWindowLongPtr(control, GWLP_ID);
|
||||
ok(controlID == IDC_PS_EDIT1, "Focus should be set to the first item on the second page. Expected: %d, Found: %ld\n", IDC_PS_EDIT1, controlID);
|
||||
|
||||
defidres = SendMessage(hdlg, DM_GETDEFID, 0, 0);
|
||||
ok(defidres == MAKELRESULT(nextID, DC_HASDEFID), "Expected default button ID to be %d, is %d\n", nextID, LOWORD(defidres));
|
||||
|
||||
/* set the focus to the second edit box on this page */
|
||||
SetFocus(GetNextDlgTabItem(hdlg, control, FALSE));
|
||||
|
||||
/* press next again */
|
||||
SendMessage(hdlg, PSM_PRESSBUTTON, PSBTN_NEXT, 0);
|
||||
if (hwndtoindex_supported)
|
||||
ok(active_page == 2, "Active page should be 2 after pressing Next. Is: %d\n", active_page);
|
||||
|
||||
control = GetFocus();
|
||||
controlID = GetWindowLongPtr(control, GWLP_ID);
|
||||
ok(controlID == IDC_PS_RADIO1, "Focus should have been set to item on third page. Expected: %d, Found %ld\n", IDC_PS_RADIO1, controlID);
|
||||
|
||||
/* back button */
|
||||
SendMessage(hdlg, PSM_PRESSBUTTON, PSBTN_BACK, 0);
|
||||
if (hwndtoindex_supported)
|
||||
ok(active_page == 1, "Active page should be 1 after pressing Back. Is: %d\n", active_page);
|
||||
|
||||
control = GetFocus();
|
||||
controlID = GetWindowLongPtr(control, GWLP_ID);
|
||||
ok(controlID == IDC_PS_EDIT1, "Focus should have been set to the first item on second page. Expected: %d, Found %ld\n", IDC_PS_EDIT1, controlID);
|
||||
|
||||
defidres = SendMessage(hdlg, DM_GETDEFID, 0, 0);
|
||||
ok(defidres == MAKELRESULT(backID, DC_HASDEFID), "Expected default button ID to be %d, is %d\n", backID, LOWORD(defidres));
|
||||
|
||||
/* press next twice */
|
||||
SendMessage(hdlg, PSM_PRESSBUTTON, PSBTN_NEXT, 0);
|
||||
if (hwndtoindex_supported)
|
||||
ok(active_page == 2, "Active page should be 2 after pressing Next. Is: %d\n", active_page);
|
||||
SendMessage(hdlg, PSM_PRESSBUTTON, PSBTN_NEXT, 0);
|
||||
if (hwndtoindex_supported)
|
||||
ok(active_page == 3, "Active page should be 3 after pressing Next. Is: %d\n", active_page);
|
||||
else
|
||||
active_page = 3;
|
||||
|
||||
control = GetFocus();
|
||||
controlID = GetWindowLongPtr(control, GWLP_ID);
|
||||
ok(controlID == nextID, "Focus should have been set to the Next button. Expected: %d, Found: %ld\n", nextID, controlID);
|
||||
|
||||
/* try to navigate away, but shouldn't be able to */
|
||||
SendMessage(hdlg, PSM_PRESSBUTTON, PSBTN_BACK, 0);
|
||||
ok(active_page == 3, "Active page should still be 3 after pressing Back. Is: %d\n", active_page);
|
||||
|
||||
defidres = SendMessage(hdlg, DM_GETDEFID, 0, 0);
|
||||
ok(defidres == MAKELRESULT(nextID, DC_HASDEFID), "Expected default button ID to be %d, is %d\n", nextID, LOWORD(defidres));
|
||||
|
||||
DestroyWindow(hdlg);
|
||||
}
|
||||
static void test_buttons(void)
|
||||
{
|
||||
HPROPSHEETPAGE hpsp[1];
|
||||
PROPSHEETPAGEA psp;
|
||||
PROPSHEETHEADERA psh;
|
||||
HWND hdlg;
|
||||
HWND button;
|
||||
RECT rc;
|
||||
int prevRight, top;
|
||||
|
||||
memset(&psp, 0, sizeof(psp));
|
||||
psp.dwSize = sizeof(psp);
|
||||
psp.dwFlags = 0;
|
||||
psp.hInstance = GetModuleHandleA(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);
|
||||
if (hdlg == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
win_skip("comctl32 4.70 needs dwSize adjustment\n");
|
||||
psh.dwSize = sizeof(psh) - sizeof(HBITMAP) - sizeof(HPALETTE) - sizeof(HBITMAP);
|
||||
hdlg = (HWND)PropertySheetA(&psh);
|
||||
}
|
||||
|
||||
/* OK button */
|
||||
button = GetDlgItem(hdlg, IDOK);
|
||||
GetWindowRect(button, &rc);
|
||||
prevRight = rc.right;
|
||||
top = rc.top;
|
||||
|
||||
/* Cancel button */
|
||||
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");
|
||||
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");
|
||||
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");
|
||||
|
||||
DestroyWindow(hdlg);
|
||||
}
|
||||
|
||||
START_TEST(propsheet)
|
||||
{
|
||||
test_title();
|
||||
test_nopage();
|
||||
test_disableowner();
|
||||
test_wiznavigation();
|
||||
test_buttons();
|
||||
}
|
||||
|
|
|
@ -32,7 +32,6 @@
|
|||
|
||||
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 && \
|
||||
|
@ -66,14 +65,17 @@ static BOOL is_font_installed(const char *name)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void rebuild_rebar(HWND *hRebar)
|
||||
static HWND create_rebar_control(void)
|
||||
{
|
||||
if (*hRebar)
|
||||
DestroyWindow(*hRebar);
|
||||
HWND hwnd;
|
||||
|
||||
*hRebar = CreateWindow(REBARCLASSNAME, NULL, WS_CHILD | WS_VISIBLE, 0, 0, 0, 0,
|
||||
hwnd = 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);
|
||||
ok(hwnd != NULL, "Failed to create Rebar\n");
|
||||
|
||||
SendMessageA(hwnd, WM_SETFONT, (WPARAM)GetStockObject(SYSTEM_FONT), 0);
|
||||
|
||||
return hwnd;
|
||||
}
|
||||
|
||||
static HWND build_toolbar(int nr, HWND hParent)
|
||||
|
@ -85,7 +87,7 @@ static HWND build_toolbar(int nr, HWND hParent)
|
|||
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_BUTTONSTRUCTSIZE, 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");
|
||||
|
||||
|
@ -104,7 +106,7 @@ static HWND build_toolbar(int nr, HWND hParent)
|
|||
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_LOADIMAGES, iBitmapId, (LPARAM)HINST_COMMCTRL) == 0, "TB_LOADIMAGES failed\n");
|
||||
ok(SendMessage(hToolbar, TB_ADDBUTTONS, 5+nr, (LPARAM)btns), "TB_ADDBUTTONS failed\n");
|
||||
return hToolbar;
|
||||
}
|
||||
|
@ -117,7 +119,7 @@ static LRESULT CALLBACK MyWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lPa
|
|||
{
|
||||
NMHDR *lpnm = (NMHDR *)lParam;
|
||||
if (lpnm->code == RBN_HEIGHTCHANGE)
|
||||
GetClientRect(hRebar, &height_change_notify_rect);
|
||||
GetClientRect(lpnm->hwndFrom, &height_change_notify_rect);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -150,7 +152,7 @@ static void dump_sizes(HWND hRebar)
|
|||
for (i=0; i<count; i++)
|
||||
{
|
||||
REBARBANDINFO rbi;
|
||||
rbi.cbSize = sizeof(REBARBANDINFO);
|
||||
rbi.cbSize = REBARBANDINFOA_V6_SIZE;
|
||||
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");
|
||||
|
@ -310,10 +312,10 @@ static int rbsize_numtests = 0;
|
|||
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"); \
|
||||
ok(SendMessageA(hRebar, RB_GETRECT, i, (LPARAM)&rc) == 1, "RB_GETRECT\n"); \
|
||||
if (!(res->bands[i].fStyle & RBBS_HIDDEN)) \
|
||||
check_rect("band", rc, res->bands[i].rc); \
|
||||
rbi.cbSize = sizeof(REBARBANDINFO); \
|
||||
rbi.cbSize = REBARBANDINFOA_V6_SIZE; \
|
||||
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"); \
|
||||
|
@ -329,11 +331,11 @@ static int rbsize_numtests = 0;
|
|||
static void add_band_w(HWND hRebar, LPCSTR lpszText, int cxMinChild, int cx, int cxIdeal)
|
||||
{
|
||||
CHAR buffer[MAX_PATH];
|
||||
REBARBANDINFO rbi;
|
||||
REBARBANDINFOA rbi;
|
||||
|
||||
if (lpszText != NULL)
|
||||
strcpy(buffer, lpszText);
|
||||
rbi.cbSize = sizeof(rbi);
|
||||
rbi.cbSize = REBARBANDINFOA_V6_SIZE;
|
||||
rbi.fMask = RBBIM_SIZE | RBBIM_CHILDSIZE | RBBIM_CHILD | RBBIM_IDEALSIZE | RBBIM_TEXT;
|
||||
rbi.cx = cx;
|
||||
rbi.cxMinChild = cxMinChild;
|
||||
|
@ -344,16 +346,16 @@ static void add_band_w(HWND hRebar, LPCSTR lpszText, int cxMinChild, int cx, int
|
|||
SendMessage(hRebar, RB_INSERTBAND, -1, (LPARAM)&rbi);
|
||||
}
|
||||
|
||||
static void layout_test(void)
|
||||
static void test_layout(void)
|
||||
{
|
||||
HWND hRebar = NULL;
|
||||
HWND hRebar;
|
||||
REBARBANDINFO rbi;
|
||||
HIMAGELIST himl;
|
||||
REBARINFO ri;
|
||||
|
||||
rebuild_rebar(&hRebar);
|
||||
hRebar = create_rebar_control();
|
||||
check_sizes();
|
||||
rbi.cbSize = sizeof(rbi);
|
||||
rbi.cbSize = REBARBANDINFOA_V6_SIZE;
|
||||
rbi.fMask = RBBIM_SIZE | RBBIM_CHILDSIZE | RBBIM_CHILD;
|
||||
rbi.cx = 200;
|
||||
rbi.cxMinChild = 100;
|
||||
|
@ -409,7 +411,9 @@ static void layout_test(void)
|
|||
SendMessageA(hRebar, RB_DELETEBAND, 1, 0);
|
||||
check_sizes();
|
||||
|
||||
rebuild_rebar(&hRebar);
|
||||
DestroyWindow(hRebar);
|
||||
|
||||
hRebar = create_rebar_control();
|
||||
add_band_w(hRebar, "ABC", 70, 40, 100);
|
||||
add_band_w(hRebar, NULL, 40, 70, 100);
|
||||
add_band_w(hRebar, NULL, 170, 240, 100);
|
||||
|
@ -448,8 +452,10 @@ static void layout_test(void)
|
|||
SendMessage(hRebar, RB_SETBANDINFO, 1, (LPARAM)&rbi);
|
||||
check_sizes();
|
||||
|
||||
DestroyWindow(hRebar);
|
||||
|
||||
/* VARHEIGHT resizing test on a horizontal rebar */
|
||||
rebuild_rebar(&hRebar);
|
||||
hRebar = create_rebar_control();
|
||||
SetWindowLong(hRebar, GWL_STYLE, GetWindowLong(hRebar, GWL_STYLE) | RBS_AUTOSIZE);
|
||||
check_sizes();
|
||||
rbi.fMask = RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_SIZE | RBBIM_STYLE;
|
||||
|
@ -474,8 +480,10 @@ static void layout_test(void)
|
|||
SendMessageA(hRebar, RB_INSERTBAND, -1, (LPARAM)&rbi);
|
||||
check_sizes();
|
||||
|
||||
DestroyWindow(hRebar);
|
||||
|
||||
/* VARHEIGHT resizing on a vertical rebar */
|
||||
rebuild_rebar(&hRebar);
|
||||
hRebar = create_rebar_control();
|
||||
SetWindowLong(hRebar, GWL_STYLE, GetWindowLong(hRebar, GWL_STYLE) | CCS_VERT | RBS_AUTOSIZE);
|
||||
check_sizes();
|
||||
rbi.fMask = RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_SIZE | RBBIM_STYLE;
|
||||
|
@ -503,6 +511,7 @@ static void layout_test(void)
|
|||
check_sizes();
|
||||
|
||||
DestroyWindow(hRebar);
|
||||
ImageList_Destroy(himl);
|
||||
}
|
||||
|
||||
#if 0 /* use this to generate more tests */
|
||||
|
@ -684,7 +693,7 @@ static int resize_numtests = 0;
|
|||
|
||||
#endif
|
||||
|
||||
static void resize_test(void)
|
||||
static void test_resize(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,
|
||||
|
@ -696,6 +705,8 @@ static void resize_test(void)
|
|||
|
||||
for (i = 0; i < styles_count; i++)
|
||||
{
|
||||
HWND hRebar;
|
||||
|
||||
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);
|
||||
|
@ -735,17 +746,17 @@ static void resize_test(void)
|
|||
}
|
||||
}
|
||||
|
||||
static void expect_band_content(UINT uBand, INT fStyle, COLORREF clrFore,
|
||||
static void expect_band_content(HWND hRebar, 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)
|
||||
INT cxHeader, INT cxHeader_broken)
|
||||
{
|
||||
CHAR buf[MAX_PATH] = "abc";
|
||||
REBARBANDINFO rb;
|
||||
REBARBANDINFOA rb;
|
||||
|
||||
memset(&rb, 0xdd, sizeof(rb));
|
||||
rb.cbSize = sizeof(rb);
|
||||
rb.cbSize = REBARBANDINFOA_V6_SIZE;
|
||||
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;
|
||||
|
@ -753,8 +764,8 @@ static void expect_band_content(UINT uBand, INT fStyle, COLORREF clrFore,
|
|||
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(rb.clrFore, clrFore, COLORREF, "%x");
|
||||
expect_eq(rb.clrBack, clrBack, COLORREF, "%x");
|
||||
expect_eq(strcmp(rb.lpText, lpText), 0, int, "%d");
|
||||
expect_eq(rb.iImage, iImage, int, "%x");
|
||||
expect_eq(rb.hwndChild, hwndChild, HWND, "%p");
|
||||
|
@ -769,20 +780,27 @@ static void expect_band_content(UINT uBand, INT fStyle, COLORREF clrFore,
|
|||
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");
|
||||
ok( rb.cxHeader == cxHeader || broken(rb.cxHeader == cxHeader_broken),
|
||||
"expected %d for %d\n", cxHeader, rb.cxHeader );
|
||||
}
|
||||
|
||||
static void bandinfo_test(void)
|
||||
static void test_bandinfo(void)
|
||||
{
|
||||
REBARBANDINFOA rb;
|
||||
CHAR szABC[] = "ABC";
|
||||
CHAR szABCD[] = "ABCD";
|
||||
HWND hRebar;
|
||||
|
||||
rebuild_rebar(&hRebar);
|
||||
rb.cbSize = sizeof(REBARBANDINFO);
|
||||
hRebar = create_rebar_control();
|
||||
rb.cbSize = REBARBANDINFOA_V6_SIZE;
|
||||
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);
|
||||
if (!SendMessageA(hRebar, RB_INSERTBANDA, 0, (LPARAM)&rb))
|
||||
{
|
||||
win_skip( "V6 info not supported\n" );
|
||||
DestroyWindow(hRebar);
|
||||
return;
|
||||
}
|
||||
expect_band_content(hRebar, 0, 0, 0, GetSysColor(COLOR_3DFACE), "", -1, NULL, 0, 0, 0, NULL, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 0, -1);
|
||||
|
||||
rb.fMask = RBBIM_CHILDSIZE;
|
||||
rb.cxMinChild = 15;
|
||||
|
@ -790,62 +808,93 @@ static void bandinfo_test(void)
|
|||
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);
|
||||
ok(SendMessageA(hRebar, RB_SETBANDINFOA, 0, (LPARAM)&rb), "RB_SETBANDINFO failed\n");
|
||||
expect_band_content(hRebar, 0, 0, 0, GetSysColor(COLOR_3DFACE), "", -1, NULL, 15, 20, 0, NULL, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 0, -1);
|
||||
|
||||
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);
|
||||
ok(SendMessageA(hRebar, RB_SETBANDINFOA, 0, (LPARAM)&rb), "RB_SETBANDINFO failed\n");
|
||||
expect_band_content(hRebar, 0, 0, 0, GetSysColor(COLOR_3DFACE), "ABC", -1, NULL, 15, 20, 0, NULL, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 35, -1);
|
||||
|
||||
rb.cbSize = sizeof(REBARBANDINFO);
|
||||
rb.cbSize = REBARBANDINFOA_V6_SIZE;
|
||||
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);
|
||||
expect_band_content(hRebar, 1, 0, 0, GetSysColor(COLOR_3DFACE), "", -1, NULL, 0, 0, 0, NULL, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 9, -1);
|
||||
expect_band_content(hRebar, 0, 0, 0, GetSysColor(COLOR_3DFACE), "ABC", -1, NULL, 15, 20, 0, NULL, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 40, -1);
|
||||
|
||||
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);
|
||||
ok(SendMessageA(hRebar, RB_SETBANDINFOA, 0, (LPARAM)&rb), "RB_SETBANDINFO failed\n");
|
||||
expect_band_content(hRebar, 0, 0x40000000, 0, GetSysColor(COLOR_3DFACE), "ABC", -1, NULL, 15, 20, 0, NULL, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 50, -1);
|
||||
|
||||
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);
|
||||
ok(SendMessageA(hRebar, RB_SETBANDINFOA, 0, (LPARAM)&rb), "RB_SETBANDINFO failed\n");
|
||||
expect_band_content(hRebar, 0, 0x40000000, 0, GetSysColor(COLOR_3DFACE), "ABC", -1, NULL, 15, 20, 0, NULL, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 5, -1);
|
||||
|
||||
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);
|
||||
ok(SendMessageA(hRebar, RB_SETBANDINFOA, 0, (LPARAM)&rb), "RB_SETBANDINFO failed\n");
|
||||
expect_band_content(hRebar, 0, 0x40000000, 0, GetSysColor(COLOR_3DFACE), "ABCD", -1, NULL, 15, 20, 0, NULL, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 5, -1);
|
||||
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);
|
||||
ok(SendMessageA(hRebar, RB_SETBANDINFOA, 0, (LPARAM)&rb), "RB_SETBANDINFO failed\n");
|
||||
expect_band_content(hRebar, 0, RBBS_VARIABLEHEIGHT, 0, GetSysColor(COLOR_3DFACE), "ABC", -1, NULL, 15, 20, 0, NULL, 0, 20, 0x7fffffff, 0, 0, 0, 40, 5);
|
||||
|
||||
DestroyWindow(hRebar);
|
||||
}
|
||||
|
||||
START_TEST(rebar)
|
||||
static void test_colors(void)
|
||||
{
|
||||
HMODULE hComctl32;
|
||||
BOOL (WINAPI *pInitCommonControlsEx)(const INITCOMMONCONTROLSEX*);
|
||||
INITCOMMONCONTROLSEX iccex;
|
||||
WNDCLASSA wc;
|
||||
MSG msg;
|
||||
RECT rc;
|
||||
COLORSCHEME scheme;
|
||||
COLORREF clr;
|
||||
BOOL ret;
|
||||
HWND hRebar;
|
||||
REBARBANDINFOA bi;
|
||||
|
||||
/* LoadLibrary is needed. This file has no references to functions in comctl32 */
|
||||
hComctl32 = LoadLibraryA("comctl32.dll");
|
||||
pInitCommonControlsEx = (void*)GetProcAddress(hComctl32, "InitCommonControlsEx");
|
||||
if (!pInitCommonControlsEx)
|
||||
hRebar = create_rebar_control();
|
||||
|
||||
/* test default colors */
|
||||
clr = SendMessage(hRebar, RB_GETTEXTCOLOR, 0, 0);
|
||||
compare(clr, CLR_NONE, "%x");
|
||||
clr = SendMessage(hRebar, RB_GETBKCOLOR, 0, 0);
|
||||
compare(clr, CLR_NONE, "%x");
|
||||
|
||||
scheme.dwSize = sizeof(scheme);
|
||||
scheme.clrBtnHighlight = 0;
|
||||
scheme.clrBtnShadow = 0;
|
||||
ret = SendMessage(hRebar, RB_GETCOLORSCHEME, 0, (LPARAM)&scheme);
|
||||
if (ret)
|
||||
{
|
||||
skip("InitCommonControlsEx() is missing. Skipping the tests\n");
|
||||
return;
|
||||
compare(scheme.clrBtnHighlight, CLR_DEFAULT, "%x");
|
||||
compare(scheme.clrBtnShadow, CLR_DEFAULT, "%x");
|
||||
}
|
||||
iccex.dwSize = sizeof(iccex);
|
||||
iccex.dwICC = ICC_COOL_CLASSES;
|
||||
pInitCommonControlsEx(&iccex);
|
||||
else
|
||||
skip("RB_GETCOLORSCHEME not supported\n");
|
||||
|
||||
/* check default band colors */
|
||||
add_band_w(hRebar, "", 0, 10, 10);
|
||||
bi.cbSize = REBARBANDINFOA_V6_SIZE;
|
||||
bi.fMask = RBBIM_COLORS;
|
||||
bi.clrFore = bi.clrBack = 0xc0ffe;
|
||||
ret = SendMessage(hRebar, RB_GETBANDINFO, 0, (LPARAM)&bi);
|
||||
ok(ret, "RB_GETBANDINFO failed\n");
|
||||
compare(bi.clrFore, RGB(0, 0, 0), "%x");
|
||||
compare(bi.clrBack, GetSysColor(COLOR_3DFACE), "%x");
|
||||
|
||||
SendMessage(hRebar, RB_SETTEXTCOLOR, 0, RGB(255, 0, 0));
|
||||
bi.clrFore = bi.clrBack = 0xc0ffe;
|
||||
ret = SendMessage(hRebar, RB_GETBANDINFO, 0, (LPARAM)&bi);
|
||||
ok(ret, "RB_GETBANDINFO failed\n");
|
||||
compare(bi.clrFore, RGB(0, 0, 0), "%x");
|
||||
|
||||
DestroyWindow(hRebar);
|
||||
}
|
||||
|
||||
|
||||
static BOOL register_parent_wnd_class(void)
|
||||
{
|
||||
WNDCLASSA wc;
|
||||
|
||||
wc.style = CS_HREDRAW | CS_VREDRAW;
|
||||
wc.cbClsExtra = 0;
|
||||
|
@ -857,23 +906,59 @@ START_TEST(rebar)
|
|||
wc.lpszMenuName = NULL;
|
||||
wc.lpszClassName = "MyTestWnd";
|
||||
wc.lpfnWndProc = MyWndProc;
|
||||
RegisterClassA(&wc);
|
||||
hMainWnd = CreateWindowExA(0, "MyTestWnd", "Blah", WS_OVERLAPPEDWINDOW,
|
||||
|
||||
return RegisterClassA(&wc);
|
||||
}
|
||||
|
||||
static HWND create_parent_window(void)
|
||||
{
|
||||
HWND hwnd;
|
||||
|
||||
if (!register_parent_wnd_class()) return NULL;
|
||||
|
||||
hwnd = 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();
|
||||
ShowWindow(hwnd, SW_SHOW);
|
||||
return hwnd;
|
||||
}
|
||||
|
||||
if(is_font_installed("System") && is_font_installed("Tahoma"))
|
||||
START_TEST(rebar)
|
||||
{
|
||||
HMODULE hComctl32;
|
||||
BOOL (WINAPI *pInitCommonControlsEx)(const INITCOMMONCONTROLSEX*);
|
||||
INITCOMMONCONTROLSEX iccex;
|
||||
MSG msg;
|
||||
|
||||
/* LoadLibrary is needed. This file has no references to functions in comctl32 */
|
||||
hComctl32 = LoadLibraryA("comctl32.dll");
|
||||
pInitCommonControlsEx = (void*)GetProcAddress(hComctl32, "InitCommonControlsEx");
|
||||
if (!pInitCommonControlsEx)
|
||||
{
|
||||
layout_test();
|
||||
resize_test();
|
||||
} else
|
||||
skip("Missing System or Tahoma font\n");
|
||||
win_skip("InitCommonControlsEx() is missing. Skipping the tests\n");
|
||||
return;
|
||||
}
|
||||
iccex.dwSize = sizeof(iccex);
|
||||
iccex.dwICC = ICC_COOL_CLASSES;
|
||||
pInitCommonControlsEx(&iccex);
|
||||
|
||||
hMainWnd = create_parent_window();
|
||||
|
||||
test_bandinfo();
|
||||
test_colors();
|
||||
|
||||
if(!is_font_installed("System") || !is_font_installed("Tahoma"))
|
||||
{
|
||||
skip("Missing System or Tahoma font\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
test_layout();
|
||||
test_resize();
|
||||
|
||||
out:
|
||||
PostQuitMessage(0);
|
||||
while(GetMessageA(&msg,0,0,0)) {
|
||||
TranslateMessage(&msg);
|
||||
|
|
|
@ -31,4 +31,14 @@
|
|||
#define IDS_TBADD5 20
|
||||
#define IDS_TBADD7 22
|
||||
|
||||
#define IDD_PROP_PAGE_INTRO 30
|
||||
#define IDD_PROP_PAGE_EDIT 31
|
||||
#define IDD_PROP_PAGE_RADIO 32
|
||||
#define IDD_PROP_PAGE_EXIT 33
|
||||
|
||||
#define IDC_PS_EDIT1 1000
|
||||
#define IDC_PS_EDIT2 1001
|
||||
#define IDC_PS_RADIO1 1010
|
||||
#define IDC_PS_RADIO2 1011
|
||||
|
||||
#endif /* __WINE_COMCTL32_TEST_RESOURCES_H */
|
||||
|
|
|
@ -30,6 +30,40 @@ FONT 8, "MS Shell Dlg"
|
|||
LTEXT "Test", -1, 10, 6, 100, 8
|
||||
}
|
||||
|
||||
IDD_PROP_PAGE_INTRO DIALOG LOADONCALL MOVEABLE DISCARDABLE 5, 43, 227, 215
|
||||
STYLE WS_POPUP | WS_CAPTION | WS_CLIPSIBLINGS | WS_VISIBLE
|
||||
CAPTION "Edit Control Page"
|
||||
FONT 8, "MS Shell Dlg"
|
||||
{
|
||||
LTEXT "This is a test property sheet!", -1, 10, 6, 100, 8
|
||||
}
|
||||
|
||||
IDD_PROP_PAGE_EDIT DIALOG LOADONCALL MOVEABLE DISCARDABLE 5, 43, 227, 215
|
||||
STYLE WS_POPUP | WS_CAPTION | WS_CLIPSIBLINGS | WS_VISIBLE
|
||||
CAPTION "Edit Control Page"
|
||||
FONT 8, "MS Shell Dlg"
|
||||
{
|
||||
EDITTEXT IDC_PS_EDIT1, 5, 5, 150, 140, WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_MULTILINE
|
||||
EDITTEXT IDC_PS_EDIT2, 5, 160, 150, 28, WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_MULTILINE
|
||||
}
|
||||
|
||||
IDD_PROP_PAGE_RADIO DIALOG LOADONCALL MOVEABLE DISCARDABLE 5, 43, 227, 215
|
||||
STYLE WS_POPUP | WS_CAPTION | WS_CLIPSIBLINGS | WS_VISIBLE
|
||||
CAPTION "Edit Control Page"
|
||||
FONT 8, "MS Shell Dlg"
|
||||
{
|
||||
CONTROL "Radio1", IDC_PS_RADIO1, "Button", BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP, 20, 20, 39, 10
|
||||
CONTROL "Radio2", IDC_PS_RADIO2, "Button", BS_AUTORADIOBUTTON, 20, 40, 39, 10
|
||||
}
|
||||
|
||||
IDD_PROP_PAGE_EXIT DIALOG LOADONCALL MOVEABLE DISCARDABLE 5, 43, 227, 215
|
||||
STYLE WS_POPUP | WS_CAPTION | WS_CLIPSIBLINGS | WS_VISIBLE
|
||||
CAPTION "Edit Control Page"
|
||||
FONT 8, "MS Shell Dlg"
|
||||
{
|
||||
LTEXT "This has been a test property sheet!", -1, 10, 6, 170, 8
|
||||
}
|
||||
|
||||
STRINGTABLE
|
||||
{
|
||||
IDS_TBADD1 "abc"
|
||||
|
|
|
@ -466,6 +466,112 @@ static void test_status_ownerdraw(void)
|
|||
SetWindowLongPtr( g_hMainWnd, GWLP_WNDPROC, (LONG_PTR)g_wndproc_saved );
|
||||
}
|
||||
|
||||
static void test_gettext(void)
|
||||
{
|
||||
HWND hwndStatus = CreateWindow(SUBCLASS_NAME, NULL, WS_CHILD|WS_VISIBLE,
|
||||
0, 0, 300, 20, g_hMainWnd, NULL, NULL, NULL);
|
||||
char buf[5];
|
||||
int r;
|
||||
|
||||
r = SendMessage(hwndStatus, SB_SETTEXT, 0, (LPARAM)"Text");
|
||||
expect(TRUE, r);
|
||||
r = SendMessage(hwndStatus, WM_GETTEXTLENGTH, 0, 0);
|
||||
expect(4, r);
|
||||
/* A size of 0 returns the length of the text */
|
||||
r = SendMessage(hwndStatus, WM_GETTEXT, 0, 0);
|
||||
expect(4, r);
|
||||
/* A size of 1 only stores the NULL terminator */
|
||||
buf[0] = 0xa;
|
||||
r = SendMessage(hwndStatus, WM_GETTEXT, 1, (LPARAM)buf);
|
||||
ok( r == 0 || broken(r == 4), "Expected 0 got %d\n", r );
|
||||
if (!r) ok(!buf[0], "expected empty buffer\n");
|
||||
/* A size of 2 returns a length 1 */
|
||||
r = SendMessage(hwndStatus, WM_GETTEXT, 2, (LPARAM)buf);
|
||||
ok( r == 1 || broken(r == 4), "Expected 1 got %d\n", r );
|
||||
r = SendMessage(hwndStatus, WM_GETTEXT, sizeof(buf), (LPARAM)buf);
|
||||
expect(4, r);
|
||||
ok(!strcmp(buf, "Text"), "expected Text, got %s\n", buf);
|
||||
DestroyWindow(hwndStatus);
|
||||
}
|
||||
|
||||
/* Notify events to parent */
|
||||
static BOOL g_got_dblclk;
|
||||
static BOOL g_got_click;
|
||||
static BOOL g_got_rdblclk;
|
||||
static BOOL g_got_rclick;
|
||||
|
||||
/* Messages to parent */
|
||||
static BOOL g_got_contextmenu;
|
||||
|
||||
static LRESULT WINAPI test_notify_parent_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch(msg)
|
||||
{
|
||||
case WM_NOTIFY:
|
||||
{
|
||||
NMHDR *hdr = ((LPNMHDR)lParam);
|
||||
switch(hdr->code)
|
||||
{
|
||||
case NM_DBLCLK: g_got_dblclk = TRUE; break;
|
||||
case NM_CLICK: g_got_click = TRUE; break;
|
||||
case NM_RDBLCLK: g_got_rdblclk = TRUE; break;
|
||||
case NM_RCLICK: g_got_rclick = TRUE; break;
|
||||
}
|
||||
|
||||
/* Return zero to indicate default processing */
|
||||
return 0;
|
||||
}
|
||||
|
||||
case WM_CONTEXTMENU: g_got_contextmenu = TRUE; return 0;
|
||||
|
||||
default:
|
||||
return( DefWindowProcA(hwnd, msg, wParam, lParam));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Test that WM_NOTIFY messages from the status control works correctly */
|
||||
static void test_notify(void)
|
||||
{
|
||||
HWND hwndParent;
|
||||
HWND hwndStatus;
|
||||
ATOM atom;
|
||||
WNDCLASSA wclass = {0};
|
||||
wclass.lpszClassName = "TestNotifyParentClass";
|
||||
wclass.lpfnWndProc = test_notify_parent_proc;
|
||||
atom = RegisterClassA(&wclass);
|
||||
ok(atom, "RegisterClass failed\n");
|
||||
|
||||
/* create parent */
|
||||
hwndParent = CreateWindow(wclass.lpszClassName, "parent", WS_OVERLAPPEDWINDOW,
|
||||
CW_USEDEFAULT, 0, 300, 20, NULL, NULL, NULL, NULL);
|
||||
ok(hwndParent != NULL, "Parent creation failed!\n");
|
||||
|
||||
/* create status bar */
|
||||
hwndStatus = CreateWindow(STATUSCLASSNAME, NULL, WS_VISIBLE | WS_CHILD,
|
||||
0, 0, 300, 20, hwndParent, NULL, NULL, NULL);
|
||||
ok(hwndStatus != NULL, "Status creation failed!\n");
|
||||
|
||||
/* Send various mouse event, and check that we get them */
|
||||
g_got_dblclk = FALSE;
|
||||
SendMessage(hwndStatus, WM_LBUTTONDBLCLK, 0, 0);
|
||||
ok(g_got_dblclk, "WM_LBUTTONDBLCLK was not processed correctly!\n");
|
||||
g_got_rdblclk = FALSE;
|
||||
SendMessage(hwndStatus, WM_RBUTTONDBLCLK, 0, 0);
|
||||
ok(g_got_rdblclk, "WM_RBUTTONDBLCLK was not processed correctly!\n");
|
||||
g_got_click = FALSE;
|
||||
SendMessage(hwndStatus, WM_LBUTTONUP, 0, 0);
|
||||
ok(g_got_click, "WM_LBUTTONUP was not processed correctly!\n");
|
||||
|
||||
/* For R-UP, check that we also get the context menu from the default processing */
|
||||
g_got_contextmenu = FALSE;
|
||||
g_got_rclick = FALSE;
|
||||
SendMessage(hwndStatus, WM_RBUTTONUP, 0, 0);
|
||||
ok(g_got_rclick, "WM_RBUTTONUP was not processed correctly!\n");
|
||||
ok(g_got_contextmenu, "WM_RBUTTONUP did not activate the context menu!\n");
|
||||
}
|
||||
|
||||
START_TEST(status)
|
||||
{
|
||||
hinst = GetModuleHandleA(NULL);
|
||||
|
@ -483,4 +589,6 @@ START_TEST(status)
|
|||
test_create();
|
||||
test_height();
|
||||
test_status_ownerdraw();
|
||||
test_gettext();
|
||||
test_notify();
|
||||
}
|
||||
|
|
|
@ -279,21 +279,49 @@ static BOOL RegisterWindowClasses(void)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
START_TEST(subclass)
|
||||
static int init_function_pointers(void)
|
||||
{
|
||||
HMODULE hdll;
|
||||
|
||||
hdll = GetModuleHandleA("comctl32.dll");
|
||||
assert(hdll);
|
||||
HMODULE hmod;
|
||||
void *ptr;
|
||||
|
||||
hmod = GetModuleHandleA("comctl32.dll");
|
||||
assert(hmod);
|
||||
|
||||
/* 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);
|
||||
|
||||
#define MAKEFUNC_ORD(f, ord) (p##f = (void*)GetProcAddress(hmod, (LPSTR)(ord)))
|
||||
MAKEFUNC_ORD(SetWindowSubclass, 410);
|
||||
MAKEFUNC_ORD(RemoveWindowSubclass, 412);
|
||||
MAKEFUNC_ORD(DefSubclassProc, 413);
|
||||
#undef MAKEFUNC_ORD
|
||||
|
||||
if(!pSetWindowSubclass || !pRemoveWindowSubclass || !pDefSubclassProc)
|
||||
return;
|
||||
{
|
||||
win_skip("SetWindowSubclass and friends are not available\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* test named exports */
|
||||
ptr = GetProcAddress(hmod, "SetWindowSubclass");
|
||||
ok(broken(ptr == 0) || ptr != 0, "expected named export for SetWindowSubclass\n");
|
||||
if(ptr)
|
||||
{
|
||||
#define TESTNAMED(f) \
|
||||
ptr = (void*)GetProcAddress(hmod, #f); \
|
||||
ok(ptr != 0, "expected named export for " #f "\n");
|
||||
TESTNAMED(RemoveWindowSubclass);
|
||||
TESTNAMED(DefSubclassProc);
|
||||
/* GetWindowSubclass exported for V6 only */
|
||||
#undef TESTNAMED
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
START_TEST(subclass)
|
||||
{
|
||||
if(!init_function_pointers()) return;
|
||||
|
||||
if(!RegisterWindowClasses()) assert(0);
|
||||
|
||||
|
|
|
@ -89,13 +89,14 @@ static const struct message create_parent_wnd_seq[] = {
|
|||
|
||||
static const struct message add_tab_to_parent[] = {
|
||||
{ TCM_INSERTITEMA, sent },
|
||||
{ TCM_INSERTITEMA, sent },
|
||||
{ TCM_INSERTITEMA, sent|optional },
|
||||
{ WM_NOTIFYFORMAT, sent|defwinproc },
|
||||
{ WM_QUERYUISTATE, sent|wparam|lparam|defwinproc|optional, 0, 0 },
|
||||
{ WM_PARENTNOTIFY, sent|defwinproc },
|
||||
{ TCM_INSERTITEMA, sent },
|
||||
{ TCM_INSERTITEMA, sent },
|
||||
{ TCM_INSERTITEMA, sent },
|
||||
{ TCM_INSERTITEMA, sent|optional },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
|
@ -236,12 +237,15 @@ 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 },
|
||||
{ WM_NOTIFYFORMAT, sent|defwinproc|optional },
|
||||
{ WM_QUERYUISTATE, sent|defwinproc|optional },
|
||||
{ WM_PARENTNOTIFY, sent|defwinproc|optional },
|
||||
{ TCM_GETITEMCOUNT, sent|wparam|lparam, 0, 0 },
|
||||
{ TCM_GETCURFOCUS, sent|wparam|lparam, 0, 0 },
|
||||
{ TCM_INSERTITEM, sent|wparam, 2 },
|
||||
{ WM_NOTIFYFORMAT, sent|defwinproc, },
|
||||
{ WM_NOTIFYFORMAT, sent|defwinproc|optional },
|
||||
{ WM_QUERYUISTATE, sent|defwinproc|optional, },
|
||||
{ WM_PARENTNOTIFY, sent|defwinproc, },
|
||||
{ WM_PARENTNOTIFY, sent|defwinproc|optional },
|
||||
{ TCM_GETITEMCOUNT, sent|wparam|lparam, 0, 0 },
|
||||
{ TCM_GETCURFOCUS, sent|wparam|lparam, 0, 0 },
|
||||
{ TCM_SETCURFOCUS, sent|wparam|lparam, -1, 0 },
|
||||
|
@ -370,14 +374,9 @@ static HWND createParentWindow(void)
|
|||
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);
|
||||
WNDPROC oldproc = (WNDPROC)GetWindowLongPtrA(hwnd, GWLP_USERDATA);
|
||||
static LONG defwndproc_counter = 0;
|
||||
LRESULT ret;
|
||||
struct message msg;
|
||||
|
@ -402,7 +401,7 @@ static LRESULT WINAPI tabSubclassProcess(HWND hwnd, UINT message, WPARAM wParam,
|
|||
}
|
||||
|
||||
defwndproc_counter++;
|
||||
ret = CallWindowProcA(info->oldproc, hwnd, message, wParam, lParam);
|
||||
ret = CallWindowProcA(oldproc, hwnd, message, wParam, lParam);
|
||||
defwndproc_counter--;
|
||||
|
||||
return ret;
|
||||
|
@ -412,14 +411,10 @@ static HWND createFilledTabControl(HWND parent_wnd, DWORD style, DWORD mask, INT
|
|||
{
|
||||
HWND tabHandle;
|
||||
TCITEM tcNewTab;
|
||||
struct subclass_info *info;
|
||||
WNDPROC oldproc;
|
||||
RECT rect;
|
||||
INT i;
|
||||
|
||||
info = HeapAlloc(GetProcessHeap(), 0, sizeof(struct subclass_info));
|
||||
if (!info)
|
||||
return NULL;
|
||||
|
||||
GetClientRect(parent_wnd, &rect);
|
||||
|
||||
tabHandle = CreateWindow (
|
||||
|
@ -431,8 +426,8 @@ static HWND createFilledTabControl(HWND parent_wnd, DWORD style, DWORD mask, INT
|
|||
|
||||
assert(tabHandle);
|
||||
|
||||
info->oldproc = (WNDPROC)SetWindowLongPtrA(tabHandle, GWLP_WNDPROC, (LONG_PTR)tabSubclassProcess);
|
||||
SetWindowLongPtrA(tabHandle, GWLP_USERDATA, (LONG_PTR)info);
|
||||
oldproc = (WNDPROC)SetWindowLongPtrA(tabHandle, GWLP_WNDPROC, (LONG_PTR)tabSubclassProcess);
|
||||
SetWindowLongPtrA(tabHandle, GWLP_USERDATA, (LONG_PTR)oldproc);
|
||||
|
||||
tcNewTab.mask = mask;
|
||||
|
||||
|
@ -505,7 +500,7 @@ static void test_tab(INT nMinTabWidth)
|
|||
SIZE size;
|
||||
HDC hdc;
|
||||
HFONT hOldFont;
|
||||
INT i, dpi;
|
||||
INT i, dpi, exp;
|
||||
|
||||
hwTab = create_tabcontrol(TCS_FIXEDWIDTH, TCIF_TEXT|TCIF_IMAGE);
|
||||
SendMessage(hwTab, TCM_SETMINTABWIDTH, 0, nMinTabWidth);
|
||||
|
@ -585,8 +580,11 @@ static void test_tab(INT nMinTabWidth)
|
|||
SendMessage(hwTab, TCM_SETMINTABWIDTH, 0, nMinTabWidth);
|
||||
|
||||
trace (" non fixed width, with text...\n");
|
||||
CheckSize(hwTab, max(size.cx +TAB_PADDING_X*2, (nMinTabWidth < 0) ? DEFAULT_MIN_TAB_WIDTH : nMinTabWidth), -1,
|
||||
"no icon, default width");
|
||||
exp = max(size.cx +TAB_PADDING_X*2, (nMinTabWidth < 0) ? DEFAULT_MIN_TAB_WIDTH : nMinTabWidth);
|
||||
SendMessage( hwTab, TCM_GETITEMRECT, 0, (LPARAM)&rTab );
|
||||
ok( rTab.right - rTab.left == exp || broken(rTab.right - rTab.left == DEFAULT_MIN_TAB_WIDTH),
|
||||
"no icon, default width: Expected width [%d] got [%d]\n", exp, rTab.right - rTab.left );
|
||||
|
||||
for (i=0; i<8; i++)
|
||||
{
|
||||
INT nTabWidth = (nMinTabWidth < 0) ? TabWidthPadded(i, 2) : nMinTabWidth;
|
||||
|
@ -610,7 +608,11 @@ static void test_tab(INT nMinTabWidth)
|
|||
SendMessage(hwTab, TCM_SETMINTABWIDTH, 0, nMinTabWidth);
|
||||
|
||||
trace (" non fixed width, no text...\n");
|
||||
CheckSize(hwTab, (nMinTabWidth < 0) ? DEFAULT_MIN_TAB_WIDTH : nMinTabWidth, -1, "no icon, default width");
|
||||
exp = (nMinTabWidth < 0) ? DEFAULT_MIN_TAB_WIDTH : nMinTabWidth;
|
||||
SendMessage( hwTab, TCM_GETITEMRECT, 0, (LPARAM)&rTab );
|
||||
ok( rTab.right - rTab.left == exp || broken(rTab.right - rTab.left == DEFAULT_MIN_TAB_WIDTH),
|
||||
"no icon, default width: Expected width [%d] got [%d]\n", exp, rTab.right - rTab.left );
|
||||
|
||||
for (i=0; i<8; i++)
|
||||
{
|
||||
INT nTabWidth = (nMinTabWidth < 0) ? TabWidthPadded(i, 2) : nMinTabWidth;
|
||||
|
@ -636,7 +638,290 @@ static void test_tab(INT nMinTabWidth)
|
|||
DeleteObject(hFont);
|
||||
}
|
||||
|
||||
static void test_getters_setters(HWND parent_wnd, INT nTabs)
|
||||
static void test_curfocus(HWND parent_wnd, INT nTabs)
|
||||
{
|
||||
INT focusIndex;
|
||||
HWND hTab;
|
||||
|
||||
hTab = createFilledTabControl(parent_wnd, TCS_FIXEDWIDTH, TCIF_TEXT|TCIF_IMAGE, nTabs);
|
||||
ok(hTab != NULL, "Failed to create tab control\n");
|
||||
|
||||
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);
|
||||
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);
|
||||
|
||||
DestroyWindow(hTab);
|
||||
}
|
||||
|
||||
static void test_cursel(HWND parent_wnd, INT nTabs)
|
||||
{
|
||||
INT selectionIndex;
|
||||
INT focusIndex;
|
||||
TCITEM tcItem;
|
||||
HWND hTab;
|
||||
|
||||
hTab = createFilledTabControl(parent_wnd, TCS_FIXEDWIDTH, TCIF_TEXT|TCIF_IMAGE, nTabs);
|
||||
ok(hTab != NULL, "Failed to create tab control\n");
|
||||
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
|
||||
/* Testing CurSel with largest appropriate value */
|
||||
selectionIndex = SendMessage(hTab, TCM_SETCURSEL, nTabs-1, 0);
|
||||
expect(0, 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);
|
||||
|
||||
/* selected item should have TCIS_BUTTONPRESSED state
|
||||
It doesn't depend on button state */
|
||||
memset(&tcItem, 0, sizeof(TCITEM));
|
||||
tcItem.mask = TCIF_STATE;
|
||||
tcItem.dwStateMask = TCIS_BUTTONPRESSED;
|
||||
selectionIndex = SendMessage(hTab, TCM_GETCURSEL, 0, 0);
|
||||
SendMessage(hTab, TCM_GETITEM, selectionIndex, (LPARAM) &tcItem);
|
||||
ok (tcItem.dwState & TCIS_BUTTONPRESSED || broken(tcItem.dwState == 0), /* older comctl32 */
|
||||
"Selected item should have TCIS_BUTTONPRESSED\n");
|
||||
|
||||
DestroyWindow(hTab);
|
||||
}
|
||||
|
||||
static void test_extendedstyle(HWND parent_wnd, INT nTabs)
|
||||
{
|
||||
DWORD prevExtendedStyle;
|
||||
DWORD extendedStyle;
|
||||
HWND hTab;
|
||||
|
||||
hTab = createFilledTabControl(parent_wnd, TCS_FIXEDWIDTH, TCIF_TEXT|TCIF_IMAGE, nTabs);
|
||||
ok(hTab != NULL, "Failed to create tab control\n");
|
||||
|
||||
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);
|
||||
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);
|
||||
|
||||
DestroyWindow(hTab);
|
||||
}
|
||||
|
||||
static void test_unicodeformat(HWND parent_wnd, INT nTabs)
|
||||
{
|
||||
INT unicodeFormat;
|
||||
HWND hTab;
|
||||
|
||||
hTab = createFilledTabControl(parent_wnd, TCS_FIXEDWIDTH, TCIF_TEXT|TCIF_IMAGE, nTabs);
|
||||
ok(hTab != NULL, "Failed to create tab control\n");
|
||||
|
||||
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);
|
||||
|
||||
DestroyWindow(hTab);
|
||||
}
|
||||
|
||||
static void test_getset_item(HWND parent_wnd, INT nTabs)
|
||||
{
|
||||
TCITEM tcItem;
|
||||
DWORD ret;
|
||||
char szText[32] = "New Label";
|
||||
HWND hTab;
|
||||
|
||||
hTab = createFilledTabControl(parent_wnd, TCS_FIXEDWIDTH, TCIF_TEXT|TCIF_IMAGE, nTabs);
|
||||
ok(hTab != NULL, "Failed to create tab control\n");
|
||||
|
||||
/* passing invalid index should result in initialization to zero
|
||||
for members mentioned in mask requested */
|
||||
|
||||
/* valid range here is [0,4] */
|
||||
memset(&tcItem, 0xcc, sizeof(tcItem));
|
||||
tcItem.mask = TCIF_PARAM;
|
||||
ret = SendMessage(hTab, TCM_GETITEM, 5, (LPARAM)&tcItem);
|
||||
expect(FALSE, ret);
|
||||
ok(tcItem.lParam == 0, "Expected zero lParam, got %lu\n", tcItem.lParam);
|
||||
|
||||
memset(&tcItem, 0xcc, sizeof(tcItem));
|
||||
tcItem.mask = TCIF_IMAGE;
|
||||
ret = SendMessage(hTab, TCM_GETITEM, 5, (LPARAM)&tcItem);
|
||||
expect(FALSE, ret);
|
||||
expect(0, tcItem.iImage);
|
||||
|
||||
memset(&tcItem, 0xcc, sizeof(tcItem));
|
||||
tcItem.mask = TCIF_TEXT;
|
||||
tcItem.pszText = szText;
|
||||
szText[0] = 'a';
|
||||
ret = SendMessage(hTab, TCM_GETITEM, 5, (LPARAM)&tcItem);
|
||||
expect(FALSE, ret);
|
||||
expect('a', szText[0]);
|
||||
|
||||
memset(&tcItem, 0xcc, sizeof(tcItem));
|
||||
tcItem.mask = TCIF_STATE;
|
||||
tcItem.dwStateMask = 0;
|
||||
tcItem.dwState = TCIS_BUTTONPRESSED;
|
||||
ret = SendMessage(hTab, TCM_GETITEM, 5, (LPARAM)&tcItem);
|
||||
expect(FALSE, ret);
|
||||
ok(tcItem.dwState == 0, "Expected zero dwState, got %u\n", tcItem.dwState);
|
||||
|
||||
memset(&tcItem, 0xcc, sizeof(tcItem));
|
||||
tcItem.mask = TCIF_STATE;
|
||||
tcItem.dwStateMask = TCIS_BUTTONPRESSED;
|
||||
tcItem.dwState = TCIS_BUTTONPRESSED;
|
||||
ret = SendMessage(hTab, TCM_GETITEM, 5, (LPARAM)&tcItem);
|
||||
expect(FALSE, ret);
|
||||
ok(tcItem.dwState == 0, "Expected zero dwState\n");
|
||||
|
||||
/* check with negative index to be sure */
|
||||
memset(&tcItem, 0xcc, sizeof(tcItem));
|
||||
tcItem.mask = TCIF_PARAM;
|
||||
ret = SendMessage(hTab, TCM_GETITEM, -1, (LPARAM)&tcItem);
|
||||
expect(FALSE, ret);
|
||||
ok(tcItem.lParam == 0, "Expected zero lParam, got %lu\n", tcItem.lParam);
|
||||
|
||||
memset(&tcItem, 0xcc, sizeof(tcItem));
|
||||
tcItem.mask = TCIF_PARAM;
|
||||
ret = SendMessage(hTab, TCM_GETITEM, -2, (LPARAM)&tcItem);
|
||||
expect(FALSE, ret);
|
||||
ok(tcItem.lParam == 0, "Expected zero lParam, got %lu\n", tcItem.lParam);
|
||||
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
|
||||
tcItem.mask = TCIF_TEXT;
|
||||
tcItem.pszText = &szText[0];
|
||||
tcItem.cchTextMax = sizeof(szText);
|
||||
|
||||
strcpy(szText, "New Label");
|
||||
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);
|
||||
|
||||
/* TCIS_BUTTONPRESSED doesn't depend on tab style */
|
||||
memset(&tcItem, 0, sizeof(tcItem));
|
||||
tcItem.mask = TCIF_STATE;
|
||||
tcItem.dwStateMask = TCIS_BUTTONPRESSED;
|
||||
tcItem.dwState = TCIS_BUTTONPRESSED;
|
||||
ok ( SendMessage(hTab, TCM_SETITEM, 0, (LPARAM) &tcItem), "Setting new item failed.\n");
|
||||
tcItem.dwState = 0;
|
||||
ok ( SendMessage(hTab, TCM_GETITEM, 0, (LPARAM) &tcItem), "Getting item failed.\n");
|
||||
if (tcItem.dwState)
|
||||
{
|
||||
ok (tcItem.dwState == TCIS_BUTTONPRESSED, "TCIS_BUTTONPRESSED should be set.\n");
|
||||
/* next highlight item, test that dwStateMask actually masks */
|
||||
tcItem.mask = TCIF_STATE;
|
||||
tcItem.dwStateMask = TCIS_HIGHLIGHTED;
|
||||
tcItem.dwState = TCIS_HIGHLIGHTED;
|
||||
ok ( SendMessage(hTab, TCM_SETITEM, 0, (LPARAM) &tcItem), "Setting new item failed.\n");
|
||||
tcItem.dwState = 0;
|
||||
ok ( SendMessage(hTab, TCM_GETITEM, 0, (LPARAM) &tcItem), "Getting item failed.\n");
|
||||
ok (tcItem.dwState == TCIS_HIGHLIGHTED, "TCIS_HIGHLIGHTED should be set.\n");
|
||||
tcItem.mask = TCIF_STATE;
|
||||
tcItem.dwStateMask = TCIS_BUTTONPRESSED;
|
||||
tcItem.dwState = 0;
|
||||
ok ( SendMessage(hTab, TCM_GETITEM, 0, (LPARAM) &tcItem), "Getting item failed.\n");
|
||||
ok (tcItem.dwState == TCIS_BUTTONPRESSED, "TCIS_BUTTONPRESSED should be set.\n");
|
||||
}
|
||||
else win_skip( "Item state mask not supported\n" );
|
||||
|
||||
DestroyWindow(hTab);
|
||||
}
|
||||
|
||||
static void test_getset_tooltips(HWND parent_wnd, INT nTabs)
|
||||
{
|
||||
HWND hTab, toolTip;
|
||||
char toolTipText[32] = "ToolTip Text Test";
|
||||
|
||||
hTab = createFilledTabControl(parent_wnd, TCS_FIXEDWIDTH, TCIF_TEXT|TCIF_IMAGE, nTabs);
|
||||
ok(hTab != NULL, "Failed to create tab control\n");
|
||||
|
||||
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, 0, 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_misc(HWND parent_wnd, INT nTabs)
|
||||
{
|
||||
HWND hTab;
|
||||
RECT rTab;
|
||||
|
@ -694,196 +979,6 @@ static void test_getters_setters(HWND parent_wnd, INT nTabs)
|
|||
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;
|
||||
TCITEM tcItem;
|
||||
|
||||
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);
|
||||
|
||||
/* selected item should have TCIS_BUTTONPRESSED state
|
||||
It doesn't depend on button state */
|
||||
memset(&tcItem, 0, sizeof(TCITEM));
|
||||
tcItem.mask = TCIF_STATE;
|
||||
tcItem.dwStateMask = TCIS_BUTTONPRESSED;
|
||||
selectionIndex = SendMessage(hTab, TCM_GETCURSEL, 0, 0);
|
||||
SendMessage(hTab, TCM_GETITEM, selectionIndex, (LPARAM) &tcItem);
|
||||
ok (tcItem.dwState & TCIS_BUTTONPRESSED, "Selected item should have TCIS_BUTTONPRESSED\n");
|
||||
}
|
||||
|
||||
/* 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);
|
||||
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);
|
||||
|
||||
/* TCIS_BUTTONPRESSED doesn't depend on tab style */
|
||||
memset(&tcItem, 0, sizeof(tcItem));
|
||||
tcItem.mask = TCIF_STATE;
|
||||
tcItem.dwStateMask = TCIS_BUTTONPRESSED;
|
||||
tcItem.dwState = TCIS_BUTTONPRESSED;
|
||||
ok ( SendMessage(hTab, TCM_SETITEM, 0, (LPARAM) &tcItem), "Setting new item failed.\n");
|
||||
tcItem.dwState = 0;
|
||||
ok ( SendMessage(hTab, TCM_GETITEM, 0, (LPARAM) &tcItem), "Getting item failed.\n");
|
||||
ok (tcItem.dwState == TCIS_BUTTONPRESSED, "TCIS_BUTTONPRESSED should be set.\n");
|
||||
/* next highlight item, test that dwStateMask actually masks */
|
||||
tcItem.mask = TCIF_STATE;
|
||||
tcItem.dwStateMask = TCIS_HIGHLIGHTED;
|
||||
tcItem.dwState = TCIS_HIGHLIGHTED;
|
||||
ok ( SendMessage(hTab, TCM_SETITEM, 0, (LPARAM) &tcItem), "Setting new item failed.\n");
|
||||
tcItem.dwState = 0;
|
||||
ok ( SendMessage(hTab, TCM_GETITEM, 0, (LPARAM) &tcItem), "Getting item failed.\n");
|
||||
ok (tcItem.dwState == TCIS_HIGHLIGHTED, "TCIS_HIGHLIGHTED should be set.\n");
|
||||
tcItem.mask = TCIF_STATE;
|
||||
tcItem.dwStateMask = TCIS_BUTTONPRESSED;
|
||||
tcItem.dwState = 0;
|
||||
ok ( SendMessage(hTab, TCM_GETITEM, 0, (LPARAM) &tcItem), "Getting item failed.\n");
|
||||
ok (tcItem.dwState == TCIS_BUTTONPRESSED, "TCIS_BUTTONPRESSED should be set.\n");
|
||||
}
|
||||
|
||||
/* 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, 0, 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);
|
||||
}
|
||||
|
||||
|
@ -903,6 +998,7 @@ static void test_adjustrect(HWND parent_wnd)
|
|||
r = SendMessage(hTab, TCM_ADJUSTRECT, TRUE, 0);
|
||||
expect(-1, r);
|
||||
}
|
||||
|
||||
static void test_insert_focus(HWND parent_wnd)
|
||||
{
|
||||
HWND hTab;
|
||||
|
@ -960,8 +1056,8 @@ static void test_insert_focus(HWND parent_wnd)
|
|||
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);
|
||||
ok_sequence(sequences, TAB_SEQ_INDEX, insert_focus_seq, "insert_focus test sequence", FALSE);
|
||||
ok_sequence(sequences, PARENT_SEQ_INDEX, empty_sequence, "insert_focus parent test sequence", TRUE);
|
||||
|
||||
DestroyWindow(hTab);
|
||||
}
|
||||
|
@ -1010,7 +1106,7 @@ static void test_delete_focus(HWND parent_wnd)
|
|||
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);
|
||||
ok_sequence(sequences, PARENT_SEQ_INDEX, empty_sequence, "delete_focus parent test sequence", TRUE);
|
||||
|
||||
DestroyWindow(hTab);
|
||||
}
|
||||
|
@ -1078,6 +1174,28 @@ static void test_removeimage(HWND parent_wnd)
|
|||
DestroyIcon(hicon);
|
||||
}
|
||||
|
||||
static void test_delete_selection(HWND parent_wnd)
|
||||
{
|
||||
HWND hTab;
|
||||
DWORD ret;
|
||||
|
||||
hTab = createFilledTabControl(parent_wnd, TCS_FIXEDWIDTH, TCIF_TEXT|TCIF_IMAGE, 4);
|
||||
ok(hTab != NULL, "Failed to create tab control\n");
|
||||
|
||||
ret = SendMessage(hTab, TCM_SETCURSEL, 3, 0);
|
||||
expect(0, ret);
|
||||
ret = SendMessage(hTab, TCM_GETCURSEL, 0, 0);
|
||||
expect(3, ret);
|
||||
/* delete selected item - selection goes to -1 */
|
||||
ret = SendMessage(hTab, TCM_DELETEITEM, 3, 0);
|
||||
expect(TRUE, ret);
|
||||
|
||||
ret = SendMessage(hTab, TCM_GETCURSEL, 0, 0);
|
||||
expect(-1, ret);
|
||||
|
||||
DestroyWindow(hTab);
|
||||
}
|
||||
|
||||
START_TEST(tab)
|
||||
{
|
||||
HWND parent_wnd;
|
||||
|
@ -1108,13 +1226,19 @@ START_TEST(tab)
|
|||
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_curfocus(parent_wnd, 5);
|
||||
test_cursel(parent_wnd, 5);
|
||||
test_extendedstyle(parent_wnd, 5);
|
||||
test_unicodeformat(parent_wnd, 5);
|
||||
test_getset_item(parent_wnd, 5);
|
||||
test_getset_tooltips(parent_wnd, 5);
|
||||
test_misc(parent_wnd, 5);
|
||||
|
||||
test_adjustrect(parent_wnd);
|
||||
|
||||
test_insert_focus(parent_wnd);
|
||||
test_delete_focus(parent_wnd);
|
||||
test_delete_selection(parent_wnd);
|
||||
test_removeimage(parent_wnd);
|
||||
|
||||
DestroyWindow(parent_wnd);
|
||||
|
|
|
@ -15,7 +15,6 @@ 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);
|
||||
|
@ -40,7 +39,6 @@ const struct test winetest_testlist[] =
|
|||
{ "misc", func_misc },
|
||||
{ "monthcal", func_monthcal },
|
||||
{ "mru", func_mru },
|
||||
{ "msg", func_msg },
|
||||
{ "progress", func_progress },
|
||||
{ "propsheet", func_propsheet },
|
||||
{ "rebar", func_rebar },
|
||||
|
|
|
@ -33,12 +33,27 @@
|
|||
|
||||
#include "wine/test.h"
|
||||
|
||||
#include "msg.h"
|
||||
|
||||
#define PARENT_SEQ_INDEX 0
|
||||
#define NUM_MSG_SEQUENCES 1
|
||||
|
||||
static struct msg_sequence *sequences[NUM_MSG_SEQUENCES];
|
||||
|
||||
static HWND hMainWnd;
|
||||
static BOOL g_fBlockHotItemChange;
|
||||
static BOOL g_fReceivedHotItemChange;
|
||||
static BOOL g_fExpectedHotItemOld;
|
||||
static BOOL g_fExpectedHotItemNew;
|
||||
static DWORD g_dwExpectedDispInfoMask;
|
||||
static BOOL g_ResetDispTextPtr;
|
||||
|
||||
static const struct message ttgetdispinfo_parent_seq[] = {
|
||||
{ WM_NOTIFY, sent|id, 0, 0, TBN_GETINFOTIPA },
|
||||
/* next line is todo, currently TTN_GETDISPINFOW is raised here */
|
||||
{ WM_NOTIFY, sent|id, 0, 0, TTN_GETDISPINFOA },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
#define expect(EXPECTED,GOT) ok((GOT)==(EXPECTED), "Expected %d, got %d\n", (EXPECTED), (GOT))
|
||||
|
||||
|
@ -56,7 +71,7 @@ static void MakeButton(TBBUTTON *p, int idCommand, int fsStyle, int nString) {
|
|||
p->iString = nString;
|
||||
}
|
||||
|
||||
static LRESULT MyWnd_Notify(LPARAM lParam)
|
||||
static LRESULT parent_wnd_notify(LPARAM lParam)
|
||||
{
|
||||
NMHDR *hdr = (NMHDR *)lParam;
|
||||
NMTBHOTITEM *nmhi;
|
||||
|
@ -79,25 +94,65 @@ static LRESULT MyWnd_Notify(LPARAM lParam)
|
|||
ok(FALSE, "TBN_GETDISPINFOA received\n");
|
||||
break;
|
||||
|
||||
case TBN_GETINFOTIPA:
|
||||
{
|
||||
NMTBGETINFOTIPA *tbgit = (NMTBGETINFOTIPA*)lParam;
|
||||
|
||||
if (g_ResetDispTextPtr)
|
||||
{
|
||||
tbgit->pszText = NULL;
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TBN_GETDISPINFOW:
|
||||
nmdisp = (NMTBDISPINFOA *)lParam;
|
||||
|
||||
compare(nmdisp->dwMask, g_dwExpectedDispInfoMask, "%x");
|
||||
compare(nmdisp->iImage, -1, "%d");
|
||||
ok(nmdisp->pszText == NULL, "pszText is not NULL\n");
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static LRESULT CALLBACK MyWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
static LRESULT CALLBACK parent_wnd_proc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch (msg)
|
||||
static LONG defwndproc_counter = 0;
|
||||
struct message msg;
|
||||
LRESULT ret;
|
||||
|
||||
msg.message = message;
|
||||
msg.flags = sent|wparam|lparam;
|
||||
if (defwndproc_counter) msg.flags |= defwinproc;
|
||||
msg.wParam = wParam;
|
||||
msg.lParam = lParam;
|
||||
if (message == WM_NOTIFY && lParam) msg.id = ((NMHDR*)lParam)->code;
|
||||
|
||||
/* log system messages, except for painting */
|
||||
if (message < WM_USER &&
|
||||
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);
|
||||
add_message(sequences, PARENT_SEQ_INDEX, &msg);
|
||||
}
|
||||
|
||||
switch (message)
|
||||
{
|
||||
case WM_NOTIFY:
|
||||
return MyWnd_Notify(lParam);
|
||||
return parent_wnd_notify(lParam);
|
||||
}
|
||||
return DefWindowProcA(hWnd, msg, wParam, lParam);
|
||||
|
||||
defwndproc_counter++;
|
||||
ret = DefWindowProcA(hWnd, message, wParam, lParam);
|
||||
defwndproc_counter--;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void basic_test(void)
|
||||
|
@ -163,7 +218,7 @@ static void basic_test(void)
|
|||
|
||||
static void rebuild_toolbar(HWND *hToolbar)
|
||||
{
|
||||
if (*hToolbar != NULL)
|
||||
if (*hToolbar)
|
||||
DestroyWindow(*hToolbar);
|
||||
*hToolbar = CreateWindowEx(0, TOOLBARCLASSNAME, NULL, WS_CHILD | WS_VISIBLE, 0, 0, 0, 0,
|
||||
hMainWnd, (HMENU)5, GetModuleHandle(NULL), NULL);
|
||||
|
@ -374,6 +429,8 @@ static void test_add_bitmap(void)
|
|||
addbmp.hInst = HINST_COMMCTRL;
|
||||
addbmp.nID = IDB_STD_SMALL_COLOR;
|
||||
rebuild_toolbar(&hToolbar);
|
||||
ImageList_Destroy(himl);
|
||||
|
||||
ok(SendMessageA(hToolbar, TB_ADDBITMAP, 1, (LPARAM)&addbmp) == 0, "TB_ADDBITMAP - unexpected return\n");
|
||||
CHECK_IMAGELIST(15, 16, 16);
|
||||
compare((int)SendMessageA(hToolbar, TB_GETBUTTONSIZE, 0, 0), MAKELONG(23, 22), "%x");
|
||||
|
@ -415,7 +472,7 @@ static void test_add_bitmap(void)
|
|||
ok(strcmp(_buf, (tab)[_i]) == 0, "Invalid string #%d - '%s' vs '%s'\n", _i, (tab)[_i], _buf); \
|
||||
} \
|
||||
ok(SendMessageA(hToolbar, TB_GETSTRING, MAKEWPARAM(260, (count)), (LPARAM)_buf) == -1, \
|
||||
"Too many string in table\n"); \
|
||||
"Too many strings in table\n"); \
|
||||
}
|
||||
|
||||
static void test_add_string(void)
|
||||
|
@ -432,10 +489,17 @@ static void test_add_string(void)
|
|||
HWND hToolbar = NULL;
|
||||
TBBUTTON button;
|
||||
int ret;
|
||||
CHAR buf[260];
|
||||
|
||||
rebuild_toolbar(&hToolbar);
|
||||
ret = SendMessageA(hToolbar, TB_ADDSTRINGA, 0, (LPARAM)test1);
|
||||
ok(ret == 0, "TB_ADDSTRINGA - unexpected return %d\n", ret);
|
||||
ret = SendMessageA(hToolbar, TB_GETSTRING, MAKEWPARAM(260, 1), (LPARAM)buf);
|
||||
if (ret == 0)
|
||||
{
|
||||
win_skip("TB_GETSTRING needs 5.80\n");
|
||||
return;
|
||||
}
|
||||
CHECK_STRING_TABLE(2, ret1);
|
||||
ret = SendMessageA(hToolbar, TB_ADDSTRINGA, 0, (LPARAM)test2);
|
||||
ok(ret == 2, "TB_ADDSTRINGA - unexpected return %d\n", ret);
|
||||
|
@ -734,6 +798,22 @@ static tbsize_result_t tbsize_results[] =
|
|||
|
||||
static int tbsize_numtests = 0;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int test_num;
|
||||
int rect_index;
|
||||
RECT rcButton;
|
||||
} tbsize_alt_result_t;
|
||||
|
||||
static tbsize_alt_result_t tbsize_alt_results[] =
|
||||
{
|
||||
{ 5, 2, { 0, 24, 8, 29 } },
|
||||
{ 20, 1, { 100, 2, 107, 102 } },
|
||||
{ 20, 2, { 107, 2, 207, 102 } }
|
||||
};
|
||||
|
||||
static int tbsize_alt_numtests = 0;
|
||||
|
||||
#define check_sizes_todo(todomask) { \
|
||||
RECT rc; \
|
||||
int buttonCount, i, mask=(todomask); \
|
||||
|
@ -745,7 +825,11 @@ static int tbsize_numtests = 0;
|
|||
compare(buttonCount, res->nButtons, "%d"); \
|
||||
for (i=0; i<min(buttonCount, res->nButtons); i++) { \
|
||||
ok(SendMessageA(hToolbar, TB_GETITEMRECT, i, (LPARAM)&rc) == 1, "TB_GETITEMRECT\n"); \
|
||||
if (!(mask&1)) { \
|
||||
if (broken(tbsize_alt_numtests < sizeof(tbsize_alt_results)/sizeof(tbsize_alt_results[0]) && \
|
||||
memcmp(&rc, &tbsize_alt_results[tbsize_alt_numtests].rcButton, sizeof(RECT)) == 0)) { \
|
||||
win_skip("Alternate rect found\n"); \
|
||||
tbsize_alt_numtests++; \
|
||||
} else if (!(mask&1)) { \
|
||||
check_rect("button", rc, res->rcButtons[i]); \
|
||||
} else {\
|
||||
todo_wine { check_rect("button", rc, res->rcButtons[i]); } \
|
||||
|
@ -954,6 +1038,7 @@ static void test_sizes(void)
|
|||
|
||||
rebuild_toolbar(&hToolbar);
|
||||
ImageList_Destroy(himl);
|
||||
ImageList_Destroy(himl2);
|
||||
|
||||
SendMessageA(hToolbar, TB_ADDBUTTONS, 1, (LPARAM)&buttons3[3]);
|
||||
ok(SendMessageA(hToolbar, TB_GETBUTTONSIZE, 0, 0) == MAKELONG(27, 39), "Unexpected button size\n");
|
||||
|
@ -995,10 +1080,17 @@ static void test_sizes(void)
|
|||
tbinfo.cx = 672;
|
||||
tbinfo.cbSize = sizeof(TBBUTTONINFO);
|
||||
tbinfo.dwMask = TBIF_SIZE | TBIF_BYINDEX;
|
||||
ok(SendMessageA(hToolbar, TB_SETBUTTONINFO, 0, (LPARAM)&tbinfo) != 0, "TB_SETBUTTONINFO failed\n");
|
||||
ok(SendMessageA(hToolbar, TB_SETBUTTONINFO, 1, (LPARAM)&tbinfo) != 0, "TB_SETBUTTONINFO failed\n");
|
||||
SendMessageA(hToolbar, TB_AUTOSIZE, 0, 0);
|
||||
check_sizes();
|
||||
if (SendMessageA(hToolbar, TB_SETBUTTONINFO, 0, (LPARAM)&tbinfo))
|
||||
{
|
||||
ok(SendMessageA(hToolbar, TB_SETBUTTONINFO, 1, (LPARAM)&tbinfo) != 0, "TB_SETBUTTONINFO failed\n");
|
||||
SendMessageA(hToolbar, TB_AUTOSIZE, 0, 0);
|
||||
check_sizes();
|
||||
}
|
||||
else /* TBIF_BYINDEX probably not supported, confirm that this was the reason for the failure */
|
||||
{
|
||||
tbinfo.dwMask = TBIF_SIZE;
|
||||
ok(SendMessageA(hToolbar, TB_SETBUTTONINFO, 33, (LPARAM)&tbinfo) != 0, "TB_SETBUTTONINFO failed\n");
|
||||
}
|
||||
|
||||
DestroyWindow(hToolbar);
|
||||
}
|
||||
|
@ -1049,21 +1141,24 @@ static void restore_recalc_state(HWND hToolbar)
|
|||
|
||||
static void test_recalc(void)
|
||||
{
|
||||
HWND hToolbar;
|
||||
HWND hToolbar = NULL;
|
||||
TBBUTTONINFO bi;
|
||||
CHAR test[] = "Test";
|
||||
const int EX_STYLES_COUNT = 5;
|
||||
int i;
|
||||
BOOL recalc;
|
||||
|
||||
/* Like TB_ADDBUTTONS tested in test_sized, inserting a button without text
|
||||
* results in a relayout, while adding one with text forces a recalc */
|
||||
prepare_recalc_test(&hToolbar);
|
||||
SendMessage(hToolbar, TB_INSERTBUTTON, 1, (LPARAM)&buttons3[0]);
|
||||
ok(!did_recalc(hToolbar), "Unexpected recalc - adding button without text\n");
|
||||
recalc = did_recalc(hToolbar);
|
||||
ok(!recalc, "Unexpected recalc - adding button without text\n");
|
||||
|
||||
prepare_recalc_test(&hToolbar);
|
||||
SendMessage(hToolbar, TB_INSERTBUTTON, 1, (LPARAM)&buttons3[3]);
|
||||
ok(did_recalc(hToolbar), "Expected a recalc - adding button with text\n");
|
||||
recalc = did_recalc(hToolbar);
|
||||
ok(recalc, "Expected a recalc - adding button with text\n");
|
||||
|
||||
/* TB_SETBUTTONINFO, even when adding a text, results only in a relayout */
|
||||
prepare_recalc_test(&hToolbar);
|
||||
|
@ -1071,7 +1166,8 @@ static void test_recalc(void)
|
|||
bi.dwMask = TBIF_TEXT;
|
||||
bi.pszText = test;
|
||||
SendMessage(hToolbar, TB_SETBUTTONINFO, 1, (LPARAM)&bi);
|
||||
ok(!did_recalc(hToolbar), "Unexpected recalc - setting a button text\n");
|
||||
recalc = did_recalc(hToolbar);
|
||||
ok(!recalc, "Unexpected recalc - setting a button text\n");
|
||||
|
||||
/* most extended styled doesn't force a recalc (testing all the bits gives
|
||||
* the same results, but prints some ERRs while testing) */
|
||||
|
@ -1082,22 +1178,31 @@ static void test_recalc(void)
|
|||
prepare_recalc_test(&hToolbar);
|
||||
expect(0, (int)SendMessage(hToolbar, TB_GETEXTENDEDSTYLE, 0, 0));
|
||||
SendMessage(hToolbar, TB_SETEXTENDEDSTYLE, 0, (1 << i));
|
||||
ok(!did_recalc(hToolbar), "Unexpected recalc - setting bit %d\n", i);
|
||||
recalc = did_recalc(hToolbar);
|
||||
ok(!recalc, "Unexpected recalc - setting bit %d\n", i);
|
||||
SendMessage(hToolbar, TB_SETEXTENDEDSTYLE, 0, 0);
|
||||
ok(!did_recalc(hToolbar), "Unexpected recalc - clearing bit %d\n", i);
|
||||
recalc = did_recalc(hToolbar);
|
||||
ok(!recalc, "Unexpected recalc - clearing bit %d\n", i);
|
||||
expect(0, (int)SendMessage(hToolbar, TB_GETEXTENDEDSTYLE, 0, 0));
|
||||
}
|
||||
|
||||
/* TBSTYLE_EX_MIXEDBUTTONS does a recalc on change */
|
||||
prepare_recalc_test(&hToolbar);
|
||||
SendMessage(hToolbar, TB_SETEXTENDEDSTYLE, 0, TBSTYLE_EX_MIXEDBUTTONS);
|
||||
ok(did_recalc(hToolbar), "Expected a recalc - setting TBSTYLE_EX_MIXEDBUTTONS\n");
|
||||
restore_recalc_state(hToolbar);
|
||||
SendMessage(hToolbar, TB_SETEXTENDEDSTYLE, 0, TBSTYLE_EX_MIXEDBUTTONS);
|
||||
ok(!did_recalc(hToolbar), "Unexpected recalc - setting TBSTYLE_EX_MIXEDBUTTONS again\n");
|
||||
restore_recalc_state(hToolbar);
|
||||
SendMessage(hToolbar, TB_SETEXTENDEDSTYLE, 0, 0);
|
||||
ok(did_recalc(hToolbar), "Expected a recalc - clearing TBSTYLE_EX_MIXEDBUTTONS\n");
|
||||
recalc = did_recalc(hToolbar);
|
||||
if (recalc)
|
||||
{
|
||||
ok(recalc, "Expected a recalc - setting TBSTYLE_EX_MIXEDBUTTONS\n");
|
||||
restore_recalc_state(hToolbar);
|
||||
SendMessage(hToolbar, TB_SETEXTENDEDSTYLE, 0, TBSTYLE_EX_MIXEDBUTTONS);
|
||||
recalc = did_recalc(hToolbar);
|
||||
ok(!recalc, "Unexpected recalc - setting TBSTYLE_EX_MIXEDBUTTONS again\n");
|
||||
restore_recalc_state(hToolbar);
|
||||
SendMessage(hToolbar, TB_SETEXTENDEDSTYLE, 0, 0);
|
||||
recalc = did_recalc(hToolbar);
|
||||
ok(recalc, "Expected a recalc - clearing TBSTYLE_EX_MIXEDBUTTONS\n");
|
||||
}
|
||||
else win_skip( "No recalc on TBSTYLE_EX_MIXEDBUTTONS\n" );
|
||||
|
||||
/* undocumented exstyle 0x2 seems to changes the top margin, what
|
||||
* interferes with these tests */
|
||||
|
@ -1117,8 +1222,8 @@ static void test_getbuttoninfo(void)
|
|||
int ret;
|
||||
|
||||
tbi.cbSize = i;
|
||||
tbi.dwMask = TBIF_BYINDEX | TBIF_COMMAND;
|
||||
ret = (int)SendMessage(hToolbar, TB_GETBUTTONINFO, 0, (LPARAM)&tbi);
|
||||
tbi.dwMask = TBIF_COMMAND;
|
||||
ret = (int)SendMessage(hToolbar, TB_GETBUTTONINFO, 1, (LPARAM)&tbi);
|
||||
if (i == sizeof(TBBUTTONINFO)) {
|
||||
compare(ret, 0, "%d");
|
||||
} else {
|
||||
|
@ -1189,7 +1294,7 @@ static void test_dispinfo(void)
|
|||
rebuild_toolbar(&hToolbar);
|
||||
SendMessageA(hToolbar, TB_LOADIMAGES, IDB_HIST_SMALL_COLOR, (LPARAM)HINST_COMMCTRL);
|
||||
SendMessageA(hToolbar, TB_ADDBUTTONS, 2, (LPARAM)buttons_disp);
|
||||
g_dwExpectedDispInfoMask = 1;
|
||||
g_dwExpectedDispInfoMask = TBNF_IMAGE;
|
||||
/* Some TBN_GETDISPINFO tests will be done in MyWnd_Notify function.
|
||||
* We will receive TBN_GETDISPINFOW even if the control is ANSI */
|
||||
compare((BOOL)SendMessageA(hToolbar, CCM_GETUNICODEFORMAT, 0, 0), 0, "%d");
|
||||
|
@ -1281,6 +1386,12 @@ static void test_getstring(void)
|
|||
ok(hToolbar != NULL, "Toolbar creation problem\n");
|
||||
|
||||
r = SendMessage(hToolbar, TB_GETSTRING, MAKEWPARAM(0, 0), 0);
|
||||
if (r == 0)
|
||||
{
|
||||
win_skip("TB_GETSTRING and TB_GETSTRINGW need 5.80\n");
|
||||
DestroyWindow(hToolbar);
|
||||
return;
|
||||
}
|
||||
expect(-1, r);
|
||||
r = SendMessage(hToolbar, TB_GETSTRINGW, MAKEWPARAM(0, 0), 0);
|
||||
expect(-1, r);
|
||||
|
@ -1300,12 +1411,46 @@ static void test_getstring(void)
|
|||
DestroyWindow(hToolbar);
|
||||
}
|
||||
|
||||
static void test_tooltip(void)
|
||||
{
|
||||
HWND hToolbar = NULL;
|
||||
const TBBUTTON buttons_disp[] = {
|
||||
{-1, 20, TBSTATE_ENABLED, 0, {0, }, 0, -1},
|
||||
{0, 21, TBSTATE_ENABLED, 0, {0, }, 0, -1},
|
||||
};
|
||||
NMTTDISPINFOW nmtti;
|
||||
|
||||
rebuild_toolbar(&hToolbar);
|
||||
|
||||
SendMessageA(hToolbar, TB_ADDBUTTONS, 2, (LPARAM)buttons_disp);
|
||||
|
||||
/* W used to get through toolbar code that assumes tooltip is always Unicode */
|
||||
memset(&nmtti, 0, sizeof(nmtti));
|
||||
nmtti.hdr.code = TTN_GETDISPINFOW;
|
||||
nmtti.hdr.idFrom = 20;
|
||||
|
||||
SendMessageA(hToolbar, CCM_SETUNICODEFORMAT, FALSE, 0);
|
||||
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
SendMessageA(hToolbar, WM_NOTIFY, 0, (LPARAM)&nmtti);
|
||||
ok_sequence(sequences, PARENT_SEQ_INDEX, ttgetdispinfo_parent_seq,
|
||||
"dispinfo from tooltip", TRUE);
|
||||
|
||||
g_ResetDispTextPtr = TRUE;
|
||||
SendMessageA(hToolbar, WM_NOTIFY, 0, (LPARAM)&nmtti);
|
||||
g_ResetDispTextPtr = FALSE;
|
||||
|
||||
DestroyWindow(hToolbar);
|
||||
}
|
||||
|
||||
START_TEST(toolbar)
|
||||
{
|
||||
WNDCLASSA wc;
|
||||
MSG msg;
|
||||
RECT rc;
|
||||
|
||||
|
||||
init_msg_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
|
||||
InitCommonControls();
|
||||
|
||||
wc.style = CS_HREDRAW | CS_VREDRAW;
|
||||
|
@ -1316,11 +1461,11 @@ START_TEST(toolbar)
|
|||
wc.hCursor = LoadCursorA(NULL, IDC_IBEAM);
|
||||
wc.hbrBackground = GetSysColorBrush(COLOR_WINDOW);
|
||||
wc.lpszMenuName = NULL;
|
||||
wc.lpszClassName = "MyTestWnd";
|
||||
wc.lpfnWndProc = MyWndProc;
|
||||
wc.lpszClassName = "Toolbar test parent";
|
||||
wc.lpfnWndProc = parent_wnd_proc;
|
||||
RegisterClassA(&wc);
|
||||
|
||||
hMainWnd = CreateWindowExA(0, "MyTestWnd", "Blah", WS_OVERLAPPEDWINDOW,
|
||||
hMainWnd = CreateWindowExA(0, "Toolbar test parent", "Blah", WS_OVERLAPPEDWINDOW,
|
||||
CW_USEDEFAULT, CW_USEDEFAULT, 680, 260, NULL, NULL, GetModuleHandleA(NULL), 0);
|
||||
GetClientRect(hMainWnd, &rc);
|
||||
ShowWindow(hMainWnd, SW_SHOW);
|
||||
|
@ -1336,6 +1481,7 @@ START_TEST(toolbar)
|
|||
test_dispinfo();
|
||||
test_setrows();
|
||||
test_getstring();
|
||||
test_tooltip();
|
||||
|
||||
PostQuitMessage(0);
|
||||
while(GetMessageA(&msg,0,0,0)) {
|
||||
|
|
|
@ -23,6 +23,8 @@
|
|||
|
||||
#include "wine/test.h"
|
||||
|
||||
#define expect(expected, got) ok(got == expected, "Expected %d, got %d\n", expected, got)
|
||||
|
||||
static void test_create_tooltip(void)
|
||||
{
|
||||
HWND parent, hwnd;
|
||||
|
@ -42,7 +44,8 @@ static void test_create_tooltip(void)
|
|||
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 %08x/%08x\n", style, exp_style);
|
||||
ok(style == exp_style || broken(style == (exp_style | WS_BORDER)), /* nt4 */
|
||||
"wrong style %08x/%08x\n", style, exp_style);
|
||||
|
||||
DestroyWindow(hwnd);
|
||||
|
||||
|
@ -142,7 +145,6 @@ static void test_customdraw(void) {
|
|||
/* Invalid notification responses */
|
||||
{CDRF_NOTIFYITEMDRAW, TEST_CDDS_PREPAINT},
|
||||
{CDRF_NOTIFYPOSTERASE, TEST_CDDS_PREPAINT},
|
||||
{CDRF_NOTIFYSUBITEMDRAW, TEST_CDDS_PREPAINT},
|
||||
{CDRF_NEWFONT, TEST_CDDS_PREPAINT}
|
||||
};
|
||||
|
||||
|
@ -168,6 +170,7 @@ static void test_customdraw(void) {
|
|||
iterationNumber++) {
|
||||
|
||||
HWND parent, hwndTip;
|
||||
RECT rect;
|
||||
TOOLINFO toolInfo = { 0 };
|
||||
|
||||
/* Create a main window */
|
||||
|
@ -201,7 +204,7 @@ static void test_customdraw(void) {
|
|||
SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
|
||||
|
||||
/* Create a tool */
|
||||
toolInfo.cbSize = sizeof(TOOLINFO);
|
||||
toolInfo.cbSize = TTTOOLINFO_V1_SIZE;
|
||||
toolInfo.hwnd = parent;
|
||||
toolInfo.hinst = GetModuleHandleA(NULL);
|
||||
toolInfo.uFlags = TTF_SUBCLASS;
|
||||
|
@ -216,13 +219,18 @@ static void test_customdraw(void) {
|
|||
SendMessage(hwndTip, TTM_SETDELAYTIME, TTDT_INITIAL, MAKELPARAM(1,0));
|
||||
|
||||
/* Put cursor inside window, tooltip will appear immediately */
|
||||
SetCursorPos(100, 100);
|
||||
GetWindowRect( parent, &rect );
|
||||
SetCursorPos( (rect.left + rect.right) / 2, (rect.top + rect.bottom) / 2 );
|
||||
flush_events(200);
|
||||
|
||||
/* Check CustomDraw results */
|
||||
ok(CD_Stages == expectedResults[iterationNumber].ExpectedCalls,
|
||||
"CustomDraw run %d stages %x, expected %x\n", iterationNumber, CD_Stages,
|
||||
expectedResults[iterationNumber].ExpectedCalls);
|
||||
if (CD_Stages)
|
||||
{
|
||||
/* Check CustomDraw results */
|
||||
ok(CD_Stages == expectedResults[iterationNumber].ExpectedCalls ||
|
||||
broken(CD_Stages == (expectedResults[iterationNumber].ExpectedCalls & ~TEST_CDDS_POSTPAINT)), /* nt4 */
|
||||
"CustomDraw run %d stages %x, expected %x\n", iterationNumber, CD_Stages,
|
||||
expectedResults[iterationNumber].ExpectedCalls);
|
||||
}
|
||||
|
||||
/* Clean up */
|
||||
DestroyWindow(hwndTip);
|
||||
|
@ -232,14 +240,63 @@ static void test_customdraw(void) {
|
|||
|
||||
}
|
||||
|
||||
static const CHAR testcallbackA[] = "callback";
|
||||
|
||||
static LRESULT WINAPI parent_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
if (message == WM_NOTIFY && lParam)
|
||||
{
|
||||
NMTTDISPINFOA *ttnmdi = (NMTTDISPINFOA*)lParam;
|
||||
|
||||
if (ttnmdi->hdr.code == TTN_GETDISPINFOA)
|
||||
lstrcpy(ttnmdi->lpszText, testcallbackA);
|
||||
}
|
||||
|
||||
return DefWindowProcA(hwnd, message, wParam, lParam);
|
||||
}
|
||||
|
||||
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, IDC_ARROW);
|
||||
cls.hbrBackground = GetStockObject(WHITE_BRUSH);
|
||||
cls.lpszMenuName = NULL;
|
||||
cls.lpszClassName = "Tooltips test parent class";
|
||||
return RegisterClassA(&cls);
|
||||
}
|
||||
|
||||
static HWND create_parent_window(void)
|
||||
{
|
||||
if (!register_parent_wnd_class())
|
||||
return NULL;
|
||||
|
||||
return CreateWindowEx(0, "Tooltips test parent class",
|
||||
"Tooltips test parent window",
|
||||
WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX |
|
||||
WS_MAXIMIZEBOX | WS_VISIBLE,
|
||||
0, 0, 100, 100,
|
||||
GetDesktopWindow(), NULL, GetModuleHandleA(NULL), NULL);
|
||||
}
|
||||
|
||||
static void test_gettext(void)
|
||||
{
|
||||
HWND hwnd;
|
||||
HWND hwnd, notify;
|
||||
TTTOOLINFOA toolinfoA;
|
||||
TTTOOLINFOW toolinfoW;
|
||||
LRESULT r;
|
||||
char bufA[10] = "";
|
||||
CHAR bufA[10] = "";
|
||||
WCHAR bufW[10] = { 0 };
|
||||
static const CHAR testtipA[] = "testtip";
|
||||
|
||||
notify = create_parent_window();
|
||||
ok(notify != NULL, "Expected notification window to be created\n");
|
||||
|
||||
/* For bug 14790 - lpszText is NULL */
|
||||
hwnd = CreateWindowExA(0, TOOLTIPS_CLASSA, NULL, 0,
|
||||
|
@ -247,6 +304,8 @@ static void test_gettext(void)
|
|||
NULL, NULL, NULL, 0);
|
||||
assert(hwnd);
|
||||
|
||||
/* use sizeof(TTTOOLINFOA) instead of TTTOOLINFOA_V1_SIZE so that adding it fails on Win9x */
|
||||
/* otherwise it crashes on the NULL lpszText */
|
||||
toolinfoA.cbSize = sizeof(TTTOOLINFOA);
|
||||
toolinfoA.hwnd = NULL;
|
||||
toolinfoA.hinst = GetModuleHandleA(NULL);
|
||||
|
@ -256,7 +315,6 @@ static void test_gettext(void)
|
|||
toolinfoA.lParam = 0xdeadbeef;
|
||||
GetClientRect(hwnd, &toolinfoA.rect);
|
||||
r = SendMessageA(hwnd, TTM_ADDTOOL, 0, (LPARAM)&toolinfoA);
|
||||
ok(r, "Adding the tool to the tooltip failed\n");
|
||||
if (r)
|
||||
{
|
||||
toolinfoA.hwnd = NULL;
|
||||
|
@ -265,8 +323,65 @@ static void test_gettext(void)
|
|||
SendMessageA(hwnd, TTM_GETTEXTA, 0, (LPARAM)&toolinfoA);
|
||||
ok(strcmp(toolinfoA.lpszText, "") == 0, "lpszText should be an empty string\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
win_skip( "Old comctl32, not testing NULL text\n" );
|
||||
DestroyWindow( hwnd );
|
||||
return;
|
||||
}
|
||||
|
||||
/* add another tool with text */
|
||||
toolinfoA.cbSize = sizeof(TTTOOLINFOA);
|
||||
toolinfoA.hwnd = NULL;
|
||||
toolinfoA.hinst = GetModuleHandleA(NULL);
|
||||
toolinfoA.uFlags = 0;
|
||||
toolinfoA.uId = 0x1235ABCD;
|
||||
strcpy(bufA, testtipA);
|
||||
toolinfoA.lpszText = bufA;
|
||||
toolinfoA.lParam = 0xdeadbeef;
|
||||
GetClientRect(hwnd, &toolinfoA.rect);
|
||||
r = SendMessageA(hwnd, TTM_ADDTOOL, 0, (LPARAM)&toolinfoA);
|
||||
ok(r, "Adding the tool to the tooltip failed\n");
|
||||
if (r)
|
||||
{
|
||||
DWORD length;
|
||||
|
||||
length = SendMessage(hwnd, WM_GETTEXTLENGTH, 0, 0);
|
||||
ok(length == 0, "Expected 0, got %d\n", length);
|
||||
|
||||
toolinfoA.hwnd = NULL;
|
||||
toolinfoA.uId = 0x1235ABCD;
|
||||
toolinfoA.lpszText = bufA;
|
||||
SendMessageA(hwnd, TTM_GETTEXTA, 0, (LPARAM)&toolinfoA);
|
||||
ok(strcmp(toolinfoA.lpszText, testtipA) == 0, "lpszText should be an empty string\n");
|
||||
|
||||
length = SendMessage(hwnd, WM_GETTEXTLENGTH, 0, 0);
|
||||
ok(length == 0, "Expected 0, got %d\n", length);
|
||||
}
|
||||
|
||||
/* add another with callback text */
|
||||
toolinfoA.cbSize = sizeof(TTTOOLINFOA);
|
||||
toolinfoA.hwnd = notify;
|
||||
toolinfoA.hinst = GetModuleHandleA(NULL);
|
||||
toolinfoA.uFlags = 0;
|
||||
toolinfoA.uId = 0x1236ABCD;
|
||||
toolinfoA.lpszText = LPSTR_TEXTCALLBACKA;
|
||||
toolinfoA.lParam = 0xdeadbeef;
|
||||
GetClientRect(hwnd, &toolinfoA.rect);
|
||||
r = SendMessageA(hwnd, TTM_ADDTOOL, 0, (LPARAM)&toolinfoA);
|
||||
ok(r, "Adding the tool to the tooltip failed\n");
|
||||
if (r)
|
||||
{
|
||||
toolinfoA.hwnd = notify;
|
||||
toolinfoA.uId = 0x1236ABCD;
|
||||
toolinfoA.lpszText = bufA;
|
||||
SendMessageA(hwnd, TTM_GETTEXTA, 0, (LPARAM)&toolinfoA);
|
||||
ok(strcmp(toolinfoA.lpszText, testcallbackA) == 0,
|
||||
"lpszText should be an (%s) string\n", testcallbackA);
|
||||
}
|
||||
|
||||
DestroyWindow(hwnd);
|
||||
DestroyWindow(notify);
|
||||
|
||||
SetLastError(0xdeadbeef);
|
||||
hwnd = CreateWindowExW(0, TOOLTIPS_CLASSW, NULL, 0,
|
||||
|
@ -303,6 +418,208 @@ static void test_gettext(void)
|
|||
DestroyWindow(hwnd);
|
||||
}
|
||||
|
||||
static void test_ttm_gettoolinfo(void)
|
||||
{
|
||||
TTTOOLINFOA ti;
|
||||
TTTOOLINFOW tiW;
|
||||
HWND hwnd;
|
||||
DWORD r;
|
||||
|
||||
hwnd = CreateWindowExA(0, TOOLTIPS_CLASSA, NULL, 0,
|
||||
10, 10, 300, 100,
|
||||
NULL, NULL, NULL, 0);
|
||||
|
||||
ti.cbSize = TTTOOLINFOA_V2_SIZE;
|
||||
ti.hwnd = NULL;
|
||||
ti.hinst = GetModuleHandleA(NULL);
|
||||
ti.uFlags = 0;
|
||||
ti.uId = 0x1234ABCD;
|
||||
ti.lpszText = NULL;
|
||||
ti.lParam = 0xdeadbeef;
|
||||
GetClientRect(hwnd, &ti.rect);
|
||||
r = SendMessageA(hwnd, TTM_ADDTOOLA, 0, (LPARAM)&ti);
|
||||
ok(r, "Adding the tool to the tooltip failed\n");
|
||||
|
||||
ti.cbSize = TTTOOLINFOA_V2_SIZE;
|
||||
ti.lParam = 0xaaaaaaaa;
|
||||
r = SendMessageA(hwnd, TTM_GETTOOLINFOA, 0, (LPARAM)&ti);
|
||||
ok(r, "Getting tooltip info failed\n");
|
||||
ok(0xdeadbeef == ti.lParam ||
|
||||
broken(0xdeadbeef != ti.lParam), /* comctl32 < 5.81 */
|
||||
"Expected 0xdeadbeef, got %lx\n", ti.lParam);
|
||||
|
||||
tiW.cbSize = TTTOOLINFOW_V2_SIZE;
|
||||
tiW.hwnd = NULL;
|
||||
tiW.uId = 0x1234ABCD;
|
||||
tiW.lParam = 0xaaaaaaaa;
|
||||
r = SendMessageA(hwnd, TTM_GETTOOLINFOW, 0, (LPARAM)&tiW);
|
||||
ok(r, "Getting tooltip info failed\n");
|
||||
ok(0xdeadbeef == tiW.lParam ||
|
||||
broken(0xdeadbeef != tiW.lParam), /* comctl32 < 5.81 */
|
||||
"Expected 0xdeadbeef, got %lx\n", tiW.lParam);
|
||||
|
||||
ti.cbSize = TTTOOLINFOA_V2_SIZE;
|
||||
ti.uId = 0x1234ABCD;
|
||||
ti.lParam = 0xaaaaaaaa;
|
||||
SendMessageA(hwnd, TTM_SETTOOLINFOA, 0, (LPARAM)&ti);
|
||||
|
||||
ti.cbSize = TTTOOLINFOA_V2_SIZE;
|
||||
ti.lParam = 0xdeadbeef;
|
||||
r = SendMessageA(hwnd, TTM_GETTOOLINFOA, 0, (LPARAM)&ti);
|
||||
ok(r, "Getting tooltip info failed\n");
|
||||
ok(0xaaaaaaaa == ti.lParam ||
|
||||
broken(0xaaaaaaaa != ti.lParam), /* comctl32 < 5.81 */
|
||||
"Expected 0xaaaaaaaa, got %lx\n", ti.lParam);
|
||||
|
||||
DestroyWindow(hwnd);
|
||||
|
||||
/* 1. test size parameter validation rules (ansi messages) */
|
||||
hwnd = CreateWindowExA(0, TOOLTIPS_CLASSA, NULL, 0,
|
||||
10, 10, 300, 100,
|
||||
NULL, NULL, NULL, 0);
|
||||
|
||||
ti.cbSize = TTTOOLINFOA_V1_SIZE - 1;
|
||||
ti.hwnd = NULL;
|
||||
ti.hinst = GetModuleHandleA(NULL);
|
||||
ti.uFlags = 0;
|
||||
ti.uId = 0x1234ABCD;
|
||||
ti.lpszText = NULL;
|
||||
ti.lParam = 0xdeadbeef;
|
||||
GetClientRect(hwnd, &ti.rect);
|
||||
r = SendMessage(hwnd, TTM_ADDTOOLA, 0, (LPARAM)&ti);
|
||||
ok(r, "Adding the tool to the tooltip failed\n");
|
||||
r = SendMessage(hwnd, TTM_GETTOOLCOUNT, 0, 0);
|
||||
expect(1, r);
|
||||
|
||||
ti.cbSize = TTTOOLINFOA_V1_SIZE - 1;
|
||||
ti.hwnd = NULL;
|
||||
ti.uId = 0x1234ABCD;
|
||||
SendMessage(hwnd, TTM_DELTOOLA, 0, (LPARAM)&ti);
|
||||
r = SendMessage(hwnd, TTM_GETTOOLCOUNT, 0, 0);
|
||||
expect(0, r);
|
||||
|
||||
ti.cbSize = TTTOOLINFOA_V2_SIZE - 1;
|
||||
ti.hwnd = NULL;
|
||||
ti.hinst = GetModuleHandleA(NULL);
|
||||
ti.uFlags = 0;
|
||||
ti.uId = 0x1234ABCD;
|
||||
ti.lpszText = NULL;
|
||||
ti.lParam = 0xdeadbeef;
|
||||
GetClientRect(hwnd, &ti.rect);
|
||||
r = SendMessage(hwnd, TTM_ADDTOOLA, 0, (LPARAM)&ti);
|
||||
ok(r, "Adding the tool to the tooltip failed\n");
|
||||
r = SendMessage(hwnd, TTM_GETTOOLCOUNT, 0, 0);
|
||||
expect(1, r);
|
||||
|
||||
ti.cbSize = TTTOOLINFOA_V2_SIZE - 1;
|
||||
ti.hwnd = NULL;
|
||||
ti.uId = 0x1234ABCD;
|
||||
SendMessage(hwnd, TTM_DELTOOLA, 0, (LPARAM)&ti);
|
||||
r = SendMessage(hwnd, TTM_GETTOOLCOUNT, 0, 0);
|
||||
expect(0, r);
|
||||
|
||||
ti.cbSize = TTTOOLINFOA_V2_SIZE + 1;
|
||||
ti.hwnd = NULL;
|
||||
ti.hinst = GetModuleHandleA(NULL);
|
||||
ti.uFlags = 0;
|
||||
ti.uId = 0x1234ABCD;
|
||||
ti.lpszText = NULL;
|
||||
ti.lParam = 0xdeadbeef;
|
||||
GetClientRect(hwnd, &ti.rect);
|
||||
r = SendMessage(hwnd, TTM_ADDTOOLA, 0, (LPARAM)&ti);
|
||||
ok(r, "Adding the tool to the tooltip failed\n");
|
||||
r = SendMessage(hwnd, TTM_GETTOOLCOUNT, 0, 0);
|
||||
expect(1, r);
|
||||
|
||||
ti.cbSize = TTTOOLINFOA_V2_SIZE + 1;
|
||||
ti.hwnd = NULL;
|
||||
ti.uId = 0x1234ABCD;
|
||||
SendMessage(hwnd, TTM_DELTOOLA, 0, (LPARAM)&ti);
|
||||
r = SendMessage(hwnd, TTM_GETTOOLCOUNT, 0, 0);
|
||||
expect(0, r);
|
||||
|
||||
DestroyWindow(hwnd);
|
||||
|
||||
/* 2. test size parameter validation rules (w-messages) */
|
||||
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;
|
||||
}
|
||||
|
||||
tiW.cbSize = TTTOOLINFOW_V1_SIZE - 1;
|
||||
tiW.hwnd = NULL;
|
||||
tiW.hinst = GetModuleHandleA(NULL);
|
||||
tiW.uFlags = 0;
|
||||
tiW.uId = 0x1234ABCD;
|
||||
tiW.lpszText = NULL;
|
||||
tiW.lParam = 0xdeadbeef;
|
||||
GetClientRect(hwnd, &tiW.rect);
|
||||
r = SendMessageW(hwnd, TTM_ADDTOOLW, 0, (LPARAM)&tiW);
|
||||
ok(r, "Adding the tool to the tooltip failed\n");
|
||||
r = SendMessageW(hwnd, TTM_GETTOOLCOUNT, 0, 0);
|
||||
expect(1, r);
|
||||
|
||||
tiW.cbSize = TTTOOLINFOW_V1_SIZE - 1;
|
||||
tiW.hwnd = NULL;
|
||||
tiW.uId = 0x1234ABCD;
|
||||
SendMessageW(hwnd, TTM_DELTOOLW, 0, (LPARAM)&tiW);
|
||||
r = SendMessageW(hwnd, TTM_GETTOOLCOUNT, 0, 0);
|
||||
expect(0, r);
|
||||
|
||||
tiW.cbSize = TTTOOLINFOW_V2_SIZE - 1;
|
||||
tiW.hwnd = NULL;
|
||||
tiW.hinst = GetModuleHandleA(NULL);
|
||||
tiW.uFlags = 0;
|
||||
tiW.uId = 0x1234ABCD;
|
||||
tiW.lpszText = NULL;
|
||||
tiW.lParam = 0xdeadbeef;
|
||||
GetClientRect(hwnd, &tiW.rect);
|
||||
r = SendMessageW(hwnd, TTM_ADDTOOLW, 0, (LPARAM)&tiW);
|
||||
ok(r, "Adding the tool to the tooltip failed\n");
|
||||
r = SendMessageW(hwnd, TTM_GETTOOLCOUNT, 0, 0);
|
||||
expect(1, r);
|
||||
|
||||
tiW.cbSize = TTTOOLINFOW_V2_SIZE - 1;
|
||||
tiW.hwnd = NULL;
|
||||
tiW.uId = 0x1234ABCD;
|
||||
SendMessageW(hwnd, TTM_DELTOOLW, 0, (LPARAM)&tiW);
|
||||
r = SendMessageW(hwnd, TTM_GETTOOLCOUNT, 0, 0);
|
||||
expect(0, r);
|
||||
|
||||
tiW.cbSize = TTTOOLINFOW_V2_SIZE + 1;
|
||||
tiW.hwnd = NULL;
|
||||
tiW.hinst = GetModuleHandleA(NULL);
|
||||
tiW.uFlags = 0;
|
||||
tiW.uId = 0x1234ABCD;
|
||||
tiW.lpszText = NULL;
|
||||
tiW.lParam = 0xdeadbeef;
|
||||
GetClientRect(hwnd, &tiW.rect);
|
||||
r = SendMessageW(hwnd, TTM_ADDTOOLA, 0, (LPARAM)&tiW);
|
||||
ok(r, "Adding the tool to the tooltip failed\n");
|
||||
r = SendMessageW(hwnd, TTM_GETTOOLCOUNT, 0, 0);
|
||||
expect(1, r);
|
||||
/* looks like TTM_DELTOOLW doesn't work with invalid size */
|
||||
tiW.cbSize = TTTOOLINFOW_V2_SIZE + 1;
|
||||
tiW.hwnd = NULL;
|
||||
tiW.uId = 0x1234ABCD;
|
||||
SendMessageW(hwnd, TTM_DELTOOLW, 0, (LPARAM)&tiW);
|
||||
r = SendMessageW(hwnd, TTM_GETTOOLCOUNT, 0, 0);
|
||||
expect(1, r);
|
||||
|
||||
tiW.cbSize = TTTOOLINFOW_V2_SIZE;
|
||||
tiW.hwnd = NULL;
|
||||
tiW.uId = 0x1234ABCD;
|
||||
SendMessageW(hwnd, TTM_DELTOOLW, 0, (LPARAM)&tiW);
|
||||
r = SendMessageW(hwnd, TTM_GETTOOLCOUNT, 0, 0);
|
||||
expect(0, r);
|
||||
|
||||
DestroyWindow(hwnd);
|
||||
}
|
||||
|
||||
START_TEST(tooltips)
|
||||
{
|
||||
InitCommonControls();
|
||||
|
@ -310,4 +627,5 @@ START_TEST(tooltips)
|
|||
test_create_tooltip();
|
||||
test_customdraw();
|
||||
test_gettext();
|
||||
test_ttm_gettoolinfo();
|
||||
}
|
||||
|
|
|
@ -30,32 +30,10 @@
|
|||
#define PARENT_SEQ_INDEX 0
|
||||
#define TRACKBAR_SEQ_INDEX 1
|
||||
|
||||
HWND hWndParent;
|
||||
|
||||
static struct msg_sequence *sequences[NUM_MSG_SEQUENCE];
|
||||
|
||||
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_QUERYNEWPALETTE, sent|optional },
|
||||
{ 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 create_trackbar_wnd_seq[] = {
|
||||
{0}
|
||||
};
|
||||
|
@ -81,12 +59,12 @@ static const struct message parent_create_trackbar_wnd_seq[] = {
|
|||
|
||||
static const struct message parent_new_window_test_seq[] = {
|
||||
{ WM_QUERYNEWPALETTE, sent|optional },
|
||||
{ WM_WINDOWPOSCHANGING, sent},
|
||||
{ WM_NCACTIVATE, sent},
|
||||
{ PBT_APMRESUMECRITICAL, sent},
|
||||
{ WM_WINDOWPOSCHANGING, sent|optional},
|
||||
{ WM_NCACTIVATE, sent|optional},
|
||||
{ PBT_APMRESUMECRITICAL, sent|optional},
|
||||
{ WM_IME_SETCONTEXT, sent|defwinproc|optional},
|
||||
{ WM_IME_NOTIFY, sent|defwinproc|optional},
|
||||
{ WM_SETFOCUS, sent|defwinproc},
|
||||
{ WM_SETFOCUS, sent|defwinproc|optional},
|
||||
{ WM_NOTIFYFORMAT, sent},
|
||||
{ WM_QUERYUISTATE, sent|optional},
|
||||
{0}
|
||||
|
@ -386,11 +364,6 @@ static const struct message ignore_selection_test_seq[] = {
|
|||
{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;
|
||||
|
@ -452,7 +425,7 @@ static HWND create_parent_window(void){
|
|||
}
|
||||
|
||||
static LRESULT WINAPI trackbar_subclass_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){
|
||||
struct subclass_info *info = (struct subclass_info *) GetWindowLongPtrA(hwnd, GWLP_USERDATA);
|
||||
WNDPROC oldproc = (WNDPROC)GetWindowLongPtrA(hwnd, GWLP_USERDATA);
|
||||
static LONG defwndproc_counter = 0;
|
||||
LRESULT ret;
|
||||
struct message msg;
|
||||
|
@ -467,36 +440,27 @@ static LRESULT WINAPI trackbar_subclass_proc(HWND hwnd, UINT message, WPARAM wPa
|
|||
add_message(sequences, TRACKBAR_SEQ_INDEX, &msg);
|
||||
|
||||
defwndproc_counter++;
|
||||
ret = CallWindowProcA(info->oldproc, hwnd, message, wParam, lParam);
|
||||
ret = CallWindowProcA(oldproc, hwnd, message, wParam, lParam);
|
||||
defwndproc_counter--;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static HWND create_trackbar(DWORD style, HWND parent){
|
||||
struct subclass_info *info;
|
||||
HWND hWndTrack;
|
||||
WNDPROC oldproc;
|
||||
RECT rect;
|
||||
|
||||
info = HeapAlloc(GetProcessHeap(), 0, sizeof(struct subclass_info));
|
||||
if (!info)
|
||||
return NULL;
|
||||
|
||||
GetClientRect(parent, &rect);
|
||||
hWndTrack = CreateWindowEx(
|
||||
0, TRACKBAR_CLASS,"Trackbar Control", style,
|
||||
rect.right,rect.bottom, 100, 50,
|
||||
parent, NULL,GetModuleHandleA(NULL) ,NULL);
|
||||
|
||||
if (!hWndTrack)
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, info);
|
||||
return NULL;
|
||||
}
|
||||
if (!hWndTrack) return NULL;
|
||||
|
||||
info->oldproc = (WNDPROC)SetWindowLongPtrA(hWndTrack, GWLP_WNDPROC, (LONG_PTR)trackbar_subclass_proc);
|
||||
|
||||
SetWindowLongPtrA(hWndTrack, GWLP_USERDATA, (LONG_PTR)info);
|
||||
oldproc = (WNDPROC)SetWindowLongPtrA(hWndTrack, GWLP_WNDPROC, (LONG_PTR)trackbar_subclass_proc);
|
||||
SetWindowLongPtrA(hWndTrack, GWLP_USERDATA, (LONG_PTR)oldproc);
|
||||
|
||||
return hWndTrack;
|
||||
}
|
||||
|
@ -785,40 +749,63 @@ static void test_thumb_length(HWND hWndTrackbar){
|
|||
static void test_tic_settings(HWND hWndTrackbar){
|
||||
int r;
|
||||
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCE);
|
||||
/* testing TBM_SETTIC */
|
||||
/* Set tics at 5 and 10 */
|
||||
/* 0 and 20 are out of range and should not be set */
|
||||
r = SendMessage(hWndTrackbar, TBM_GETRANGEMAX, 0, 0);
|
||||
expect(10, r);
|
||||
r = SendMessage(hWndTrackbar, TBM_GETRANGEMIN, 0, 0);
|
||||
expect(5, r);
|
||||
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCE);
|
||||
r = SendMessage(hWndTrackbar, TBM_SETTIC, 0, 0);
|
||||
ok(r == FALSE, "Expected FALSE, got %d\n", r);
|
||||
r = SendMessage(hWndTrackbar, TBM_SETTIC, 0, 5);
|
||||
todo_wine{
|
||||
ok(r == TRUE, "Expected TRUE, got %d\n", r);
|
||||
r = SendMessage(hWndTrackbar, TBM_SETTIC, 0, 10);
|
||||
ok(r == TRUE, "Expected TRUE, got %d\n", r);
|
||||
}
|
||||
ok(r == TRUE, "Expected TRUE, got %d\n", r);
|
||||
r = SendMessage(hWndTrackbar, TBM_SETTIC, 0, 10);
|
||||
ok(r == TRUE, "Expected TRUE, got %d\n", r);
|
||||
|
||||
r = SendMessage(hWndTrackbar, TBM_SETTIC, 0, 20);
|
||||
ok(r == FALSE, "Expected False, got %d\n", r);
|
||||
|
||||
/* test TBM_SETTICFREQ */
|
||||
SendMessage(hWndTrackbar, TBM_SETRANGE, TRUE, MAKELONG(0, 10));
|
||||
SendMessage(hWndTrackbar, TBM_SETTICFREQ, 2, 0);
|
||||
r = SendMessage(hWndTrackbar, TBM_GETNUMTICS, 0,0);
|
||||
r = SendMessage(hWndTrackbar, TBM_GETNUMTICS, 0, 0);
|
||||
expect(6, r);
|
||||
SendMessage(hWndTrackbar, TBM_SETTICFREQ, 5, 0);
|
||||
r = SendMessage(hWndTrackbar, TBM_GETNUMTICS, 0,0);
|
||||
r = SendMessage(hWndTrackbar, TBM_GETNUMTICS, 0, 0);
|
||||
expect(3, r);
|
||||
SendMessage(hWndTrackbar, TBM_SETTICFREQ, 15, 0);
|
||||
r = SendMessage(hWndTrackbar, TBM_GETNUMTICS, 0,0);
|
||||
r = SendMessage(hWndTrackbar, TBM_GETNUMTICS, 0, 0);
|
||||
expect(2, r);
|
||||
|
||||
/* test TBM_GETNUMTICS */
|
||||
/* since TIC FREQ is 15, there should be only 2 tics now */
|
||||
r = SendMessage(hWndTrackbar, TBM_GETNUMTICS, 0,0);
|
||||
r = SendMessage(hWndTrackbar, TBM_GETNUMTICS, 0, 0);
|
||||
expect(2, r);
|
||||
|
||||
ok_sequence(sequences, TRACKBAR_SEQ_INDEX, tic_settings_test_seq, "tic settings test sequence", TRUE);
|
||||
ok_sequence(sequences, PARENT_SEQ_INDEX, parent_tic_settings_test_seq, "parent tic settings test sequence", TRUE);
|
||||
|
||||
/* range [0,0], freq = 1 */
|
||||
SendMessage(hWndTrackbar, TBM_SETRANGEMAX, TRUE, 0);
|
||||
SendMessage(hWndTrackbar, TBM_SETRANGEMIN, TRUE, 0);
|
||||
SendMessage(hWndTrackbar, TBM_SETTICFREQ, 1, 0);
|
||||
r = SendMessage(hWndTrackbar, TBM_GETNUMTICS, 0, 0);
|
||||
expect(2, r);
|
||||
/* range [0,1], freq = 1 */
|
||||
SendMessage(hWndTrackbar, TBM_SETRANGEMAX, TRUE, 1);
|
||||
SendMessage(hWndTrackbar, TBM_SETRANGEMIN, TRUE, 0);
|
||||
SendMessage(hWndTrackbar, TBM_SETTICFREQ, 1, 0);
|
||||
r = SendMessage(hWndTrackbar, TBM_GETNUMTICS, 0, 0);
|
||||
expect(2, r);
|
||||
/* range [0,2], freq = 1 */
|
||||
SendMessage(hWndTrackbar, TBM_SETRANGEMAX, TRUE, 2);
|
||||
SendMessage(hWndTrackbar, TBM_SETRANGEMIN, TRUE, 0);
|
||||
SendMessage(hWndTrackbar, TBM_SETTICFREQ, 1, 0);
|
||||
r = SendMessage(hWndTrackbar, TBM_GETNUMTICS, 0, 0);
|
||||
expect(3, r);
|
||||
}
|
||||
|
||||
static void test_tic_placement(HWND hWndTrackbar){
|
||||
|
@ -846,9 +833,7 @@ static void test_tic_placement(HWND hWndTrackbar){
|
|||
r = SendMessage(hWndTrackbar, TBM_GETTIC, 2,0);
|
||||
expect(4, r);
|
||||
r = SendMessage(hWndTrackbar, TBM_GETTIC, 4,0);
|
||||
todo_wine{
|
||||
expect(-1, r);
|
||||
}
|
||||
expect(-1, r);
|
||||
|
||||
/* test TBM_GETTICPIC */
|
||||
r = SendMessage(hWndTrackbar, TBM_GETTICPOS, 0, 0);
|
||||
|
@ -869,15 +854,13 @@ static void test_tool_tips(HWND hWndTrackbar){
|
|||
flush_sequences(sequences, NUM_MSG_SEQUENCE);
|
||||
/* testing TBM_SETTIPSIDE */
|
||||
r = SendMessage(hWndTrackbar, TBM_SETTIPSIDE, TBTS_TOP, 0);
|
||||
todo_wine{
|
||||
expect(0, r);
|
||||
}
|
||||
expect(TBTS_TOP, r);
|
||||
r = SendMessage(hWndTrackbar, TBM_SETTIPSIDE, TBTS_LEFT, 0);
|
||||
expect(0, r);
|
||||
expect(TBTS_TOP, r);
|
||||
r = SendMessage(hWndTrackbar, TBM_SETTIPSIDE, TBTS_BOTTOM, 0);
|
||||
expect(1, r);
|
||||
expect(TBTS_LEFT, r);
|
||||
r = SendMessage(hWndTrackbar, TBM_SETTIPSIDE, TBTS_RIGHT, 0);
|
||||
expect(2, r);
|
||||
expect(TBTS_BOTTOM, r);
|
||||
|
||||
/* testing TBM_SETTOOLTIPS */
|
||||
hWndTooltip = CreateWindowEx(WS_EX_TOPMOST, TOOLTIPS_CLASS, NULL, 0,
|
||||
|
@ -967,17 +950,31 @@ static void test_ignore_selection(HWND hWndTrackbar){
|
|||
ok_sequence(sequences, PARENT_SEQ_INDEX, parent_empty_test_seq, "parent ignore selection setting test sequence", FALSE);
|
||||
}
|
||||
|
||||
static void test_initial_state(void)
|
||||
{
|
||||
HWND hWnd;
|
||||
DWORD ret;
|
||||
|
||||
hWnd = create_trackbar(0, hWndParent);
|
||||
|
||||
ret = SendMessage(hWnd, TBM_GETNUMTICS, 0, 0);
|
||||
expect(2, ret);
|
||||
ret = SendMessage(hWnd, TBM_GETTIC, 0, 0);
|
||||
expect(-1, ret);
|
||||
ret = SendMessage(hWnd, TBM_GETTICPOS, 0, 0);
|
||||
expect(-1, ret);
|
||||
|
||||
DestroyWindow(hWnd);
|
||||
}
|
||||
|
||||
START_TEST(trackbar)
|
||||
{
|
||||
DWORD style = WS_VISIBLE | TBS_TOOLTIPS | TBS_ENABLESELRANGE | TBS_FIXEDLENGTH | TBS_AUTOTICKS;
|
||||
HWND hWndTrackbar;
|
||||
HWND hWndParent;
|
||||
|
||||
init_msg_sequences(sequences, NUM_MSG_SEQUENCE);
|
||||
InitCommonControls();
|
||||
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCE);
|
||||
|
||||
/* create parent window */
|
||||
hWndParent = create_parent_window();
|
||||
ok(hWndParent != NULL, "Failed to create parent Window!\n");
|
||||
|
@ -987,7 +984,6 @@ START_TEST(trackbar)
|
|||
return;
|
||||
}
|
||||
|
||||
ok_sequence(sequences, PARENT_SEQ_INDEX, create_parent_wnd_seq, "create Parent Window", TRUE);
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCE);
|
||||
|
||||
/* create trackbar with set styles */
|
||||
|
@ -1036,5 +1032,7 @@ START_TEST(trackbar)
|
|||
|
||||
DestroyWindow(hWndTrackbar);
|
||||
|
||||
test_initial_state();
|
||||
|
||||
DestroyWindow(hWndParent);
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -59,38 +59,15 @@
|
|||
#define EDIT_SEQ_INDEX 1
|
||||
#define UPDOWN_SEQ_INDEX 2
|
||||
|
||||
static HWND parent_wnd, edit, updown;
|
||||
#define UPDOWN_ID 0
|
||||
#define BUDDY_ID 1
|
||||
|
||||
static HWND parent_wnd, g_edit;
|
||||
|
||||
static BOOL (WINAPI *pSetWindowSubclass)(HWND, SUBCLASSPROC, UINT_PTR, DWORD_PTR);
|
||||
|
||||
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_QUERYNEWPALETTE, sent|optional },
|
||||
{ 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 },
|
||||
|
@ -182,12 +159,8 @@ static const struct message test_updown_unicode_seq[] = {
|
|||
{ 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},
|
||||
static const struct message test_updown_pos_nochange_seq[] = {
|
||||
{ WM_GETTEXT, sent|id, 0, 0, BUDDY_ID },
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
|
@ -254,14 +227,9 @@ static HWND create_parent_window(void)
|
|||
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);
|
||||
WNDPROC oldproc = (WNDPROC)GetWindowLongPtrA(hwnd, GWLP_USERDATA);
|
||||
static LONG defwndproc_counter = 0;
|
||||
LRESULT ret;
|
||||
struct message msg;
|
||||
|
@ -273,43 +241,37 @@ static LRESULT WINAPI edit_subclass_proc(HWND hwnd, UINT message, WPARAM wParam,
|
|||
if (defwndproc_counter) msg.flags |= defwinproc;
|
||||
msg.wParam = wParam;
|
||||
msg.lParam = lParam;
|
||||
msg.id = BUDDY_ID;
|
||||
add_message(sequences, EDIT_SEQ_INDEX, &msg);
|
||||
|
||||
defwndproc_counter++;
|
||||
ret = CallWindowProcA(info->oldproc, hwnd, message, wParam, lParam);
|
||||
ret = CallWindowProcA(oldproc, hwnd, message, wParam, lParam);
|
||||
defwndproc_counter--;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static HWND create_edit_control(void)
|
||||
{
|
||||
struct subclass_info *info;
|
||||
WNDPROC oldproc;
|
||||
HWND hwnd;
|
||||
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,
|
||||
hwnd = CreateWindowExA(0, WC_EDITA, 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;
|
||||
}
|
||||
if (!hwnd) return NULL;
|
||||
|
||||
info->oldproc = (WNDPROC)SetWindowLongPtrA(edit, GWLP_WNDPROC,
|
||||
(LONG_PTR)edit_subclass_proc);
|
||||
SetWindowLongPtrA(edit, GWLP_USERDATA, (LONG_PTR)info);
|
||||
oldproc = (WNDPROC)SetWindowLongPtrA(hwnd, GWLP_WNDPROC,
|
||||
(LONG_PTR)edit_subclass_proc);
|
||||
SetWindowLongPtrA(hwnd, GWLP_USERDATA, (LONG_PTR)oldproc);
|
||||
|
||||
return edit;
|
||||
return hwnd;
|
||||
}
|
||||
|
||||
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);
|
||||
WNDPROC oldproc = (WNDPROC)GetWindowLongPtrA(hwnd, GWLP_USERDATA);
|
||||
static LONG defwndproc_counter = 0;
|
||||
LRESULT ret;
|
||||
struct message msg;
|
||||
|
@ -321,46 +283,42 @@ static LRESULT WINAPI updown_subclass_proc(HWND hwnd, UINT message, WPARAM wPara
|
|||
if (defwndproc_counter) msg.flags |= defwinproc;
|
||||
msg.wParam = wParam;
|
||||
msg.lParam = lParam;
|
||||
msg.id = UPDOWN_ID;
|
||||
add_message(sequences, UPDOWN_SEQ_INDEX, &msg);
|
||||
|
||||
defwndproc_counter++;
|
||||
ret = CallWindowProcA(info->oldproc, hwnd, message, wParam, lParam);
|
||||
ret = CallWindowProcA(oldproc, hwnd, message, wParam, lParam);
|
||||
defwndproc_counter--;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static HWND create_updown_control(void)
|
||||
static HWND create_updown_control(DWORD style, HWND buddy)
|
||||
{
|
||||
struct subclass_info *info;
|
||||
WNDPROC oldproc;
|
||||
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,
|
||||
updown = CreateUpDownControl(WS_CHILD | WS_BORDER | WS_VISIBLE | style,
|
||||
0, 0, rect.right, rect.bottom, parent_wnd, 1, GetModuleHandleA(NULL), buddy,
|
||||
100, 0, 50);
|
||||
if (!updown)
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, info);
|
||||
return NULL;
|
||||
}
|
||||
if (!updown) return NULL;
|
||||
|
||||
info->oldproc = (WNDPROC)SetWindowLongPtrA(updown, GWLP_WNDPROC,
|
||||
(LONG_PTR)updown_subclass_proc);
|
||||
SetWindowLongPtrA(updown, GWLP_USERDATA, (LONG_PTR)info);
|
||||
oldproc = (WNDPROC)SetWindowLongPtrA(updown, GWLP_WNDPROC,
|
||||
(LONG_PTR)updown_subclass_proc);
|
||||
SetWindowLongPtrA(updown, GWLP_USERDATA, (LONG_PTR)oldproc);
|
||||
|
||||
return updown;
|
||||
}
|
||||
|
||||
static void test_updown_pos(void)
|
||||
{
|
||||
HWND updown;
|
||||
int r;
|
||||
|
||||
updown = create_updown_control(UDS_ALIGNRIGHT, g_edit);
|
||||
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
|
||||
/* Set Range from 0 to 100 */
|
||||
|
@ -410,24 +368,63 @@ static void test_updown_pos(void)
|
|||
expect(1,HIWORD(r));
|
||||
|
||||
ok_sequence(sequences, UPDOWN_SEQ_INDEX, test_updown_pos_seq , "test updown pos", FALSE);
|
||||
|
||||
DestroyWindow(updown);
|
||||
|
||||
/* there's no attempt to update buddy Edit if text didn't change */
|
||||
SetWindowTextA(g_edit, "50");
|
||||
updown = create_updown_control(UDS_ALIGNRIGHT | UDS_SETBUDDYINT, g_edit);
|
||||
|
||||
/* test sequence only on 5.8x versions */
|
||||
r = SendMessage(updown, UDM_GETPOS32, 0, 0);
|
||||
if (r)
|
||||
{
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
|
||||
r = SendMessage(updown, UDM_SETPOS, 0, 50);
|
||||
expect(50,r);
|
||||
|
||||
ok_sequence(sequences, EDIT_SEQ_INDEX, test_updown_pos_nochange_seq,
|
||||
"test updown pos, no change", FALSE);
|
||||
}
|
||||
|
||||
DestroyWindow(updown);
|
||||
}
|
||||
|
||||
static void test_updown_pos32(void)
|
||||
{
|
||||
HWND updown;
|
||||
int r;
|
||||
int low, high;
|
||||
|
||||
updown = create_updown_control(UDS_ALIGNRIGHT, g_edit);
|
||||
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
|
||||
/* Set the position to 0 to 1000 */
|
||||
SendMessage(updown, UDM_SETRANGE32, 0 , 1000 );
|
||||
|
||||
low = high = -1;
|
||||
r = SendMessage(updown, UDM_GETRANGE32, (WPARAM) &low , (LPARAM) &high );
|
||||
if (low == -1)
|
||||
{
|
||||
win_skip("UDM_SETRANGE32/UDM_GETRANGE32 not available\n");
|
||||
DestroyWindow(updown);
|
||||
return;
|
||||
}
|
||||
|
||||
expect(0,low);
|
||||
expect(1000,high);
|
||||
|
||||
/* Set position to 500, don't check return since it is unset*/
|
||||
SendMessage(updown, UDM_SETPOS32, 0 , 500 );
|
||||
/* Set position to 500 */
|
||||
r = SendMessage(updown, UDM_SETPOS32, 0 , 500 );
|
||||
if (!r)
|
||||
{
|
||||
win_skip("UDM_SETPOS32 and UDM_GETPOS32 need 5.80\n");
|
||||
DestroyWindow(updown);
|
||||
return;
|
||||
}
|
||||
expect(50,r);
|
||||
|
||||
/* Since UDM_SETBUDDYINT was not set at creation bRet will always be true as a return from UDM_GETPOS32 */
|
||||
|
||||
|
@ -464,30 +461,83 @@ static void test_updown_pos32(void)
|
|||
expect(1,high);
|
||||
|
||||
ok_sequence(sequences, UPDOWN_SEQ_INDEX, test_updown_pos32_seq, "test updown pos32", FALSE);
|
||||
|
||||
DestroyWindow(updown);
|
||||
|
||||
/* there's no attempt to update buddy Edit if text didn't change */
|
||||
SetWindowTextA(g_edit, "50");
|
||||
updown = create_updown_control(UDS_ALIGNRIGHT | UDS_SETBUDDYINT, g_edit);
|
||||
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
|
||||
r = SendMessage(updown, UDM_SETPOS32, 0, 50);
|
||||
expect(50,r);
|
||||
ok_sequence(sequences, EDIT_SEQ_INDEX, test_updown_pos_nochange_seq,
|
||||
"test updown pos, no change", FALSE);
|
||||
|
||||
DestroyWindow(updown);
|
||||
}
|
||||
|
||||
static void test_updown_buddy(void)
|
||||
{
|
||||
HWND buddyReturn;
|
||||
HWND updown, buddyReturn, buddy;
|
||||
WNDPROC proc;
|
||||
DWORD style;
|
||||
|
||||
updown = create_updown_control(UDS_ALIGNRIGHT, g_edit);
|
||||
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
|
||||
buddyReturn = (HWND)SendMessage(updown, UDM_GETBUDDY, 0 , 0 );
|
||||
ok(buddyReturn == edit, "Expected edit handle\n");
|
||||
ok(buddyReturn == g_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_SETBUDDY, (WPARAM) g_edit, 0);
|
||||
ok(buddyReturn == g_edit, "Expected edit handle\n");
|
||||
|
||||
buddyReturn = (HWND)SendMessage(updown, UDM_GETBUDDY, 0 , 0 );
|
||||
ok(buddyReturn == edit, "Expected edit handle\n");
|
||||
ok(buddyReturn == g_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);
|
||||
|
||||
DestroyWindow(updown);
|
||||
|
||||
buddy = create_edit_control();
|
||||
proc = (WNDPROC)GetWindowLongPtrA(buddy, GWLP_WNDPROC);
|
||||
|
||||
updown= create_updown_control(UDS_ALIGNRIGHT, buddy);
|
||||
ok(proc == (WNDPROC)GetWindowLongPtrA(buddy, GWLP_WNDPROC), "No subclassing expected\n");
|
||||
|
||||
style = GetWindowLongA(updown, GWL_STYLE);
|
||||
SetWindowLongA(updown, GWL_STYLE, style | UDS_ARROWKEYS);
|
||||
style = GetWindowLongA(updown, GWL_STYLE);
|
||||
ok(style & UDS_ARROWKEYS, "Expected UDS_ARROWKEYS\n");
|
||||
/* no subclass if UDS_ARROWKEYS set after creation */
|
||||
ok(proc == (WNDPROC)GetWindowLongPtrA(buddy, GWLP_WNDPROC), "No subclassing expected\n");
|
||||
|
||||
DestroyWindow(updown);
|
||||
|
||||
updown= create_updown_control(UDS_ALIGNRIGHT | UDS_ARROWKEYS, buddy);
|
||||
ok(proc != (WNDPROC)GetWindowLongPtrA(buddy, GWLP_WNDPROC), "Subclassing expected\n");
|
||||
|
||||
if (pSetWindowSubclass)
|
||||
{
|
||||
/* updown uses subclass helpers for buddy on >5.8x systems */
|
||||
ok(GetPropA(buddy, "CC32SubclassInfo") != NULL, "Expected CC32SubclassInfo property\n");
|
||||
}
|
||||
|
||||
DestroyWindow(updown);
|
||||
|
||||
DestroyWindow(buddy);
|
||||
}
|
||||
|
||||
static void test_updown_base(void)
|
||||
{
|
||||
HWND updown;
|
||||
int r;
|
||||
CHAR text[10];
|
||||
|
||||
updown = create_updown_control(UDS_ALIGNRIGHT, g_edit);
|
||||
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
|
||||
|
@ -520,12 +570,36 @@ static void test_updown_base(void)
|
|||
expect(10,r);
|
||||
|
||||
ok_sequence(sequences, UPDOWN_SEQ_INDEX, test_updown_base_seq, "test updown base", FALSE);
|
||||
|
||||
DestroyWindow(updown);
|
||||
|
||||
/* switch base with buddy attached */
|
||||
updown = create_updown_control(UDS_SETBUDDYINT | UDS_ALIGNRIGHT, g_edit);
|
||||
|
||||
r = SendMessage(updown, UDM_SETPOS, 0, 10);
|
||||
expect(50, r);
|
||||
|
||||
GetWindowTextA(g_edit, text, sizeof(text)/sizeof(CHAR));
|
||||
ok(lstrcmpA(text, "10") == 0, "Expected '10', got '%s'\n", text);
|
||||
|
||||
r = SendMessage(updown, UDM_SETBASE, 16, 0);
|
||||
expect(10, r);
|
||||
|
||||
GetWindowTextA(g_edit, text, sizeof(text)/sizeof(CHAR));
|
||||
/* FIXME: currently hex output isn't properly formatted, but for this
|
||||
test only change from initial text matters */
|
||||
ok(lstrcmpA(text, "10") != 0, "Expected '0x000A', got '%s'\n", text);
|
||||
|
||||
DestroyWindow(updown);
|
||||
}
|
||||
|
||||
static void test_updown_unicode(void)
|
||||
{
|
||||
HWND updown;
|
||||
int r;
|
||||
|
||||
updown = create_updown_control(UDS_ALIGNRIGHT, g_edit);
|
||||
|
||||
flush_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
|
||||
/* Set it to ANSI, don't check return as we don't know previous state */
|
||||
|
@ -537,6 +611,12 @@ static void test_updown_unicode(void)
|
|||
r = SendMessage(updown, UDM_SETUNICODEFORMAT, 1 , 0);
|
||||
expect(0,r);
|
||||
r = SendMessage(updown, UDM_GETUNICODEFORMAT, 0 , 0);
|
||||
if (!r)
|
||||
{
|
||||
win_skip("UDM_SETUNICODEFORMAT not available\n");
|
||||
DestroyWindow(updown);
|
||||
return;
|
||||
}
|
||||
expect(1,r);
|
||||
|
||||
/* And now set it back to ANSI */
|
||||
|
@ -546,49 +626,161 @@ static void test_updown_unicode(void)
|
|||
expect(0,r);
|
||||
|
||||
ok_sequence(sequences, UPDOWN_SEQ_INDEX, test_updown_unicode_seq, "test updown unicode", FALSE);
|
||||
|
||||
DestroyWindow(updown);
|
||||
}
|
||||
|
||||
|
||||
static void test_create_updown_control(void)
|
||||
static void test_updown_create(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);
|
||||
HWND updown;
|
||||
RECT r;
|
||||
|
||||
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();
|
||||
updown = create_updown_control(UDS_ALIGNRIGHT, g_edit);
|
||||
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);
|
||||
GetWindowTextA(g_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);
|
||||
DestroyWindow(updown);
|
||||
|
||||
/* create with zero width */
|
||||
updown = CreateWindowA (UPDOWN_CLASSA, 0, WS_CHILD | WS_BORDER | WS_VISIBLE, 0, 0, 0, 0,
|
||||
parent_wnd, (HMENU)(DWORD_PTR)1, GetModuleHandleA(NULL), 0);
|
||||
ok(updown != NULL, "Failed to create updown control\n");
|
||||
r.right = 0;
|
||||
GetClientRect(updown, &r);
|
||||
ok(r.right > 0, "Expected default width, got %d\n", r.right);
|
||||
DestroyWindow(updown);
|
||||
/* create with really small width */
|
||||
updown = CreateWindowA (UPDOWN_CLASSA, 0, WS_CHILD | WS_BORDER | WS_VISIBLE, 0, 0, 2, 0,
|
||||
parent_wnd, (HMENU)(DWORD_PTR)1, GetModuleHandleA(NULL), 0);
|
||||
ok(updown != NULL, "Failed to create updown control\n");
|
||||
r.right = 0;
|
||||
GetClientRect(updown, &r);
|
||||
ok(r.right != 2 && r.right > 0, "Expected default width, got %d\n", r.right);
|
||||
DestroyWindow(updown);
|
||||
/* create with width greater than default */
|
||||
updown = CreateWindowA (UPDOWN_CLASSA, 0, WS_CHILD | WS_BORDER | WS_VISIBLE, 0, 0, 100, 0,
|
||||
parent_wnd, (HMENU)(DWORD_PTR)1, GetModuleHandleA(NULL), 0);
|
||||
ok(updown != NULL, "Failed to create updown control\n");
|
||||
r.right = 0;
|
||||
GetClientRect(updown, &r);
|
||||
ok(r.right < 100 && r.right > 0, "Expected default width, got %d\n", r.right);
|
||||
DestroyWindow(updown);
|
||||
/* create with zero height, UDS_HORZ */
|
||||
updown = CreateWindowA (UPDOWN_CLASSA, 0, UDS_HORZ | WS_CHILD | WS_BORDER | WS_VISIBLE, 0, 0, 0, 0,
|
||||
parent_wnd, (HMENU)(DWORD_PTR)1, GetModuleHandleA(NULL), 0);
|
||||
ok(updown != NULL, "Failed to create updown control\n");
|
||||
r.bottom = 0;
|
||||
GetClientRect(updown, &r);
|
||||
ok(r.bottom == 0, "Expected zero height, got %d\n", r.bottom);
|
||||
DestroyWindow(updown);
|
||||
/* create with really small height, UDS_HORZ */
|
||||
updown = CreateWindowA (UPDOWN_CLASSA, 0, UDS_HORZ | WS_CHILD | WS_BORDER | WS_VISIBLE, 0, 0, 0, 2,
|
||||
parent_wnd, (HMENU)(DWORD_PTR)1, GetModuleHandleA(NULL), 0);
|
||||
ok(updown != NULL, "Failed to create updown control\n");
|
||||
r.bottom = 0;
|
||||
GetClientRect(updown, &r);
|
||||
ok(r.bottom == 0, "Expected zero height, got %d\n", r.bottom);
|
||||
DestroyWindow(updown);
|
||||
/* create with height greater than default, UDS_HORZ */
|
||||
updown = CreateWindowA (UPDOWN_CLASSA, 0, UDS_HORZ | WS_CHILD | WS_BORDER | WS_VISIBLE, 0, 0, 0, 100,
|
||||
parent_wnd, (HMENU)(DWORD_PTR)1, GetModuleHandleA(NULL), 0);
|
||||
ok(updown != NULL, "Failed to create updown control\n");
|
||||
r.bottom = 0;
|
||||
GetClientRect(updown, &r);
|
||||
ok(r.bottom < 100 && r.bottom > 0, "Expected default height, got %d\n", r.bottom);
|
||||
DestroyWindow(updown);
|
||||
}
|
||||
|
||||
static void test_UDS_SETBUDDYINT(void)
|
||||
{
|
||||
HWND updown;
|
||||
DWORD style, ret;
|
||||
CHAR text[10];
|
||||
|
||||
/* cleanup buddy */
|
||||
text[0] = '\0';
|
||||
SetWindowTextA(g_edit, text);
|
||||
|
||||
/* creating without UDS_SETBUDDYINT */
|
||||
updown = create_updown_control(UDS_ALIGNRIGHT, g_edit);
|
||||
/* try to set UDS_SETBUDDYINT after creation */
|
||||
style = GetWindowLongA(updown, GWL_STYLE);
|
||||
SetWindowLongA(updown, GWL_STYLE, style | UDS_SETBUDDYINT);
|
||||
style = GetWindowLongA(updown, GWL_STYLE);
|
||||
ok(style & UDS_SETBUDDYINT, "Expected UDS_SETBUDDY to be set\n");
|
||||
SendMessage(updown, UDM_SETPOS, 0, 20);
|
||||
GetWindowTextA(g_edit, text, sizeof(text)/sizeof(CHAR));
|
||||
ok(lstrlenA(text) == 0, "Expected empty string\n");
|
||||
DestroyWindow(updown);
|
||||
|
||||
/* creating with UDS_SETBUDDYINT */
|
||||
updown = create_updown_control(UDS_SETBUDDYINT | UDS_ALIGNRIGHT, g_edit);
|
||||
GetWindowTextA(g_edit, text, sizeof(text)/sizeof(CHAR));
|
||||
/* 50 is initial value here */
|
||||
ok(lstrcmpA(text, "50") == 0, "Expected '50', got '%s'\n", text);
|
||||
/* now remove style flag */
|
||||
style = GetWindowLongA(updown, GWL_STYLE);
|
||||
SetWindowLongA(updown, GWL_STYLE, style & ~UDS_SETBUDDYINT);
|
||||
SendMessage(updown, UDM_SETPOS, 0, 20);
|
||||
GetWindowTextA(g_edit, text, sizeof(text)/sizeof(CHAR));
|
||||
ok(lstrcmpA(text, "20") == 0, "Expected '20', got '%s'\n", text);
|
||||
/* set edit text directly, check position */
|
||||
strcpy(text, "10");
|
||||
SetWindowTextA(g_edit, text);
|
||||
ret = SendMessageA(updown, UDM_GETPOS, 0, 0);
|
||||
expect(10, ret);
|
||||
strcpy(text, "11");
|
||||
SetWindowTextA(g_edit, text);
|
||||
ret = SendMessageA(updown, UDM_GETPOS, 0, 0);
|
||||
expect(11, LOWORD(ret));
|
||||
expect(0, HIWORD(ret));
|
||||
/* set to invalid value */
|
||||
strcpy(text, "21st");
|
||||
SetWindowTextA(g_edit, text);
|
||||
ret = SendMessageA(updown, UDM_GETPOS, 0, 0);
|
||||
expect(11, LOWORD(ret));
|
||||
expect(TRUE, HIWORD(ret));
|
||||
/* set style back */
|
||||
style = GetWindowLongA(updown, GWL_STYLE);
|
||||
SetWindowLongA(updown, GWL_STYLE, style | UDS_SETBUDDYINT);
|
||||
SendMessage(updown, UDM_SETPOS, 0, 30);
|
||||
GetWindowTextA(g_edit, text, sizeof(text)/sizeof(CHAR));
|
||||
ok(lstrcmpA(text, "30") == 0, "Expected '30', got '%s'\n", text);
|
||||
DestroyWindow(updown);
|
||||
}
|
||||
|
||||
START_TEST(updown)
|
||||
{
|
||||
HMODULE mod = GetModuleHandleA("comctl32.dll");
|
||||
|
||||
pSetWindowSubclass = (void*)GetProcAddress(mod, (LPSTR)410);
|
||||
|
||||
InitCommonControls();
|
||||
init_msg_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
|
||||
parent_wnd = create_parent_window();
|
||||
ok(parent_wnd != NULL, "Failed to create parent window!\n");
|
||||
g_edit = create_edit_control();
|
||||
ok(g_edit != NULL, "Failed to create edit control\n");
|
||||
|
||||
test_updown_create();
|
||||
test_updown_pos();
|
||||
test_updown_pos32();
|
||||
test_updown_buddy();
|
||||
test_updown_base();
|
||||
test_updown_unicode();
|
||||
}
|
||||
test_UDS_SETBUDDYINT();
|
||||
|
||||
START_TEST(updown)
|
||||
{
|
||||
InitCommonControls();
|
||||
init_msg_sequences(sequences, NUM_MSG_SEQUENCES);
|
||||
|
||||
test_create_updown_control();
|
||||
DestroyWindow(g_edit);
|
||||
DestroyWindow(parent_wnd);
|
||||
}
|
||||
|
|
142
rostests/winetests/comctl32/v6util.h
Normal file
142
rostests/winetests/comctl32/v6util.h
Normal file
|
@ -0,0 +1,142 @@
|
|||
/*
|
||||
* Utility routines for comctl32 v6 tests
|
||||
*
|
||||
* Copyright 2006 Mike McCormack for CodeWeavers
|
||||
* Copyright 2007 George Gov
|
||||
* Copyright 2009 Owen Rudge for CodeWeavers
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
#define expect(expected, got) ok(got == expected, "Expected %d, got %d\n", expected, got)
|
||||
|
||||
#ifdef __i386__
|
||||
#define ARCH "x86"
|
||||
#elif defined __x86_64__
|
||||
#define ARCH "amd64"
|
||||
#else
|
||||
#define ARCH "none"
|
||||
#endif
|
||||
|
||||
static const CHAR manifest_name[] = "cc6.manifest";
|
||||
|
||||
static const CHAR manifest[] =
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n"
|
||||
"<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\">\n"
|
||||
" <assemblyIdentity\n"
|
||||
" type=\"win32\"\n"
|
||||
" name=\"Wine.ComCtl32.Tests\"\n"
|
||||
" version=\"1.0.0.0\"\n"
|
||||
" processorArchitecture=\"" ARCH "\"\n"
|
||||
" />\n"
|
||||
"<description>Wine comctl32 test suite</description>\n"
|
||||
"<dependency>\n"
|
||||
" <dependentAssembly>\n"
|
||||
" <assemblyIdentity\n"
|
||||
" type=\"win32\"\n"
|
||||
" name=\"microsoft.windows.common-controls\"\n"
|
||||
" version=\"6.0.0.0\"\n"
|
||||
" processorArchitecture=\"" ARCH "\"\n"
|
||||
" publicKeyToken=\"6595b64144ccf1df\"\n"
|
||||
" language=\"*\"\n"
|
||||
" />\n"
|
||||
"</dependentAssembly>\n"
|
||||
"</dependency>\n"
|
||||
"</assembly>\n";
|
||||
|
||||
static void unload_v6_module(ULONG_PTR cookie, HANDLE hCtx)
|
||||
{
|
||||
HANDLE hKernel32;
|
||||
BOOL (WINAPI *pDeactivateActCtx)(DWORD, ULONG_PTR);
|
||||
VOID (WINAPI *pReleaseActCtx)(HANDLE);
|
||||
|
||||
hKernel32 = GetModuleHandleA("kernel32.dll");
|
||||
pDeactivateActCtx = (void*)GetProcAddress(hKernel32, "DeactivateActCtx");
|
||||
pReleaseActCtx = (void*)GetProcAddress(hKernel32, "ReleaseActCtx");
|
||||
if (!pDeactivateActCtx || !pReleaseActCtx)
|
||||
{
|
||||
win_skip("Activation contexts unsupported\n");
|
||||
return;
|
||||
}
|
||||
|
||||
pDeactivateActCtx(0, cookie);
|
||||
pReleaseActCtx(hCtx);
|
||||
|
||||
DeleteFileA(manifest_name);
|
||||
}
|
||||
|
||||
static BOOL load_v6_module(ULONG_PTR *pcookie, HANDLE *hCtx)
|
||||
{
|
||||
HANDLE hKernel32;
|
||||
HANDLE (WINAPI *pCreateActCtxA)(ACTCTXA*);
|
||||
BOOL (WINAPI *pActivateActCtx)(HANDLE, ULONG_PTR*);
|
||||
|
||||
ACTCTXA ctx;
|
||||
BOOL ret;
|
||||
HANDLE file;
|
||||
DWORD written;
|
||||
|
||||
hKernel32 = GetModuleHandleA("kernel32.dll");
|
||||
pCreateActCtxA = (void*)GetProcAddress(hKernel32, "CreateActCtxA");
|
||||
pActivateActCtx = (void*)GetProcAddress(hKernel32, "ActivateActCtx");
|
||||
if (!(pCreateActCtxA && pActivateActCtx))
|
||||
{
|
||||
win_skip("Activation contexts unsupported. No version 6 tests possible.\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* create manifest */
|
||||
file = CreateFileA( manifest_name, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL );
|
||||
if (file != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
ret = (WriteFile( file, manifest, sizeof(manifest)-1, &written, NULL ) &&
|
||||
written == sizeof(manifest)-1);
|
||||
CloseHandle( file );
|
||||
if (!ret)
|
||||
{
|
||||
DeleteFileA( manifest_name );
|
||||
skip("Failed to fill manifest file. Skipping comctl32 V6 tests.\n");
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
trace("created %s\n", manifest_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
skip("Failed to create manifest file. Skipping comctl32 V6 tests.\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
memset(&ctx, 0, sizeof(ctx));
|
||||
ctx.cbSize = sizeof(ctx);
|
||||
ctx.lpSource = manifest_name;
|
||||
|
||||
*hCtx = pCreateActCtxA(&ctx);
|
||||
ok(*hCtx != 0, "Expected context handle\n");
|
||||
|
||||
ret = pActivateActCtx(*hCtx, pcookie);
|
||||
expect(TRUE, ret);
|
||||
|
||||
if (!ret)
|
||||
{
|
||||
win_skip("A problem during context activation occurred.\n");
|
||||
DeleteFileA(manifest_name);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#undef expect
|
||||
#undef ARCH
|
Loading…
Add table
Add a link
Reference in a new issue