From 4e28716aca8125ffbbf63feda73e1584588c6fed Mon Sep 17 00:00:00 2001 From: James Tabor Date: Thu, 26 Jan 2012 15:19:24 +0000 Subject: [PATCH] [ComCtl32_wineTest] - Sync to Wine 1.3.37. svn path=/trunk/; revision=55206 --- rostests/winetests/comctl32/comboex.c | 87 ++- rostests/winetests/comctl32/datetime.c | 49 +- rostests/winetests/comctl32/dpa.c | 40 +- rostests/winetests/comctl32/header.c | 8 +- rostests/winetests/comctl32/imagelist.c | 791 ++++++++++++++++-------- rostests/winetests/comctl32/ipaddress.c | 1 - rostests/winetests/comctl32/listview.c | 577 ++++++++++++----- rostests/winetests/comctl32/misc.c | 7 - rostests/winetests/comctl32/monthcal.c | 611 +++++++++++++----- rostests/winetests/comctl32/mru.c | 390 +++++++++--- rostests/winetests/comctl32/msg.h | 4 +- rostests/winetests/comctl32/propsheet.c | 363 +++++++++-- rostests/winetests/comctl32/rebar.c | 445 ++++++++----- rostests/winetests/comctl32/resources.h | 1 + rostests/winetests/comctl32/status.c | 49 +- rostests/winetests/comctl32/tab.c | 407 +++++++++--- rostests/winetests/comctl32/toolbar.c | 575 ++++++++++++----- rostests/winetests/comctl32/tooltips.c | 24 +- rostests/winetests/comctl32/trackbar.c | 6 +- rostests/winetests/comctl32/treeview.c | 766 ++++++++++++++++++++--- rostests/winetests/comctl32/updown.c | 2 +- 21 files changed, 3909 insertions(+), 1294 deletions(-) diff --git a/rostests/winetests/comctl32/comboex.c b/rostests/winetests/comctl32/comboex.c index f9a42dfe604..172e56429d4 100644 --- a/rostests/winetests/comctl32/comboex.c +++ b/rostests/winetests/comctl32/comboex.c @@ -42,6 +42,8 @@ static BOOL (WINAPI *pSetWindowSubclass)(HWND, SUBCLASSPROC, UINT_PTR, DWORD_PTR #define MAX_CHARS 100 static char *textBuffer = NULL; +static BOOL received_end_edit = FALSE; + static HWND createComboEx(DWORD style) { return CreateWindowExA(0, WC_COMBOBOXEXA, NULL, style, 0, 0, 300, 300, hComboExParentWnd, NULL, hMainHinst, NULL); @@ -234,7 +236,8 @@ static void test_WM_LBUTTONDOWN(void) COMBOBOXINFO cbInfo; UINT x, y, item_height; LRESULT result; - int i, idx; + UINT i; + int idx; RECT rect; WCHAR buffer[3]; static const UINT choices[] = {8,9,10,11,12,14,16,18,20,22,24,26,28,36,48,72}; @@ -340,6 +343,7 @@ static void test_WM_LBUTTONDOWN(void) ok(idx == 4 || broken(idx == -1), /* win98 */ "Current Selection: expected %d, got %d\n", 4, idx); + ok(received_end_edit, "Expected to receive a CBEN_ENDEDIT message\n"); DestroyWindow(hComboEx); } @@ -379,6 +383,77 @@ static void test_CB_GETLBTEXT(void) DestroyWindow(hCombo); } +static void test_WM_WINDOWPOSCHANGING(void) +{ + HWND hCombo; + WINDOWPOS wp; + RECT rect; + int combo_height; + int ret; + + hCombo = createComboEx(WS_BORDER | WS_VISIBLE | WS_CHILD | CBS_DROPDOWN); + ok(hCombo != NULL, "createComboEx failed\n"); + ret = GetWindowRect(hCombo, &rect); + ok(ret, "GetWindowRect failed\n"); + combo_height = rect.bottom - rect.top; + ok(combo_height > 0, "wrong combo height\n"); + + /* Test height > combo_height */ + wp.x = rect.left; + wp.y = rect.top; + wp.cx = (rect.right - rect.left); + wp.cy = combo_height * 2; + wp.flags = 0; + wp.hwnd = hCombo; + wp.hwndInsertAfter = NULL; + + ret = SendMessageA(hCombo, WM_WINDOWPOSCHANGING, 0, (LPARAM)&wp); + ok(ret == 0, "expected 0, got %x\n", ret); + ok(wp.cy == combo_height, + "Expected height %d, got %d\n", combo_height, wp.cy); + + /* Test height < combo_height */ + wp.x = rect.left; + wp.y = rect.top; + wp.cx = (rect.right - rect.left); + wp.cy = combo_height / 2; + wp.flags = 0; + wp.hwnd = hCombo; + wp.hwndInsertAfter = NULL; + + ret = SendMessageA(hCombo, WM_WINDOWPOSCHANGING, 0, (LPARAM)&wp); + ok(ret == 0, "expected 0, got %x\n", ret); + ok(wp.cy == combo_height, + "Expected height %d, got %d\n", combo_height, wp.cy); + + ret = DestroyWindow(hCombo); + ok(ret, "DestroyWindow failed\n"); +} + +static LRESULT ComboExTestOnNotify(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + NMHDR *hdr = (NMHDR*)lParam; + switch(hdr->code){ + case CBEN_ENDEDITA: + { + NMCBEENDEDITA *edit_info = (NMCBEENDEDITA*)hdr; + if(edit_info->iWhy==CBENF_DROPDOWN){ + received_end_edit = TRUE; + } + break; + } + case CBEN_ENDEDITW: + { + NMCBEENDEDITW *edit_info = (NMCBEENDEDITW*)hdr; + if(edit_info->iWhy==CBENF_DROPDOWN){ + received_end_edit = TRUE; + } + break; + } + } + return 0; +} + static LRESULT CALLBACK ComboExTestWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch(msg) { @@ -386,7 +461,8 @@ static LRESULT CALLBACK ComboExTestWndProc(HWND hWnd, UINT msg, WPARAM wParam, L case WM_DESTROY: PostQuitMessage(0); break; - + case WM_NOTIFY: + return ComboExTestOnNotify(hWnd,msg,wParam,lParam); default: return DefWindowProcA(hWnd, msg, wParam, lParam); } @@ -503,16 +579,16 @@ static void test_get_set_item(void) 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); + ok(item.lParam == 0, "Expected zero, got %lx\n", item.lParam); - item.lParam = 0xdeadbeef; + item.lParam = 0x1abe11ed; 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); + ok(item.lParam == 0x1abe11ed, "Expected 0x1abe11ed, got %lx\n", item.lParam); DestroyWindow(hComboEx); } @@ -527,6 +603,7 @@ START_TEST(comboex) test_comboboxex(); test_WM_LBUTTONDOWN(); test_CB_GETLBTEXT(); + test_WM_WINDOWPOSCHANGING(); test_comboboxex_subclass(); test_get_set_item(); diff --git a/rostests/winetests/comctl32/datetime.c b/rostests/winetests/comctl32/datetime.c index a97ab342dae..171da5ce594 100644 --- a/rostests/winetests/comctl32/datetime.c +++ b/rostests/winetests/comctl32/datetime.c @@ -204,22 +204,21 @@ static void test_dtm_set_format(void) static void test_mccolor_types(HWND hWndDateTime, int mccolor_type, const char* mccolor_name) { - LRESULT r; - COLORREF theColor, prevColor; + COLORREF theColor, prevColor, crColor; theColor=RGB(0,0,0); - r = SendMessage(hWndDateTime, DTM_SETMCCOLOR, mccolor_type, theColor); - ok(r != -1, "%s: Set RGB(0,0,0): Expected COLORREF of previous value, got %ld\n", mccolor_name, r); + crColor = SendMessage(hWndDateTime, DTM_SETMCCOLOR, mccolor_type, theColor); + ok(crColor != ~0u, "%s: Set RGB(0,0,0): Expected COLORREF of previous value, got %d\n", mccolor_name, crColor); prevColor=theColor; theColor=RGB(255,255,255); - r = SendMessage(hWndDateTime, DTM_SETMCCOLOR, mccolor_type, theColor); - ok(r==prevColor, "%s: Set RGB(255,255,255): Expected COLORREF of previous value, got %ld\n", mccolor_name, r); + crColor = SendMessage(hWndDateTime, DTM_SETMCCOLOR, mccolor_type, theColor); + ok(crColor==prevColor, "%s: Set RGB(255,255,255): Expected COLORREF of previous value, got %d\n", mccolor_name, crColor); prevColor=theColor; theColor=RGB(100,180,220); - r = SendMessage(hWndDateTime, DTM_SETMCCOLOR, mccolor_type, theColor); - ok(r==prevColor, "%s: Set RGB(100,180,220): Expected COLORREF of previous value, got %ld\n", mccolor_name, r); - r = SendMessage(hWndDateTime, DTM_GETMCCOLOR, mccolor_type, 0); - ok(r==theColor, "%s: GETMCCOLOR: Expected %d, got %ld\n", mccolor_name, theColor, r); + crColor = SendMessage(hWndDateTime, DTM_SETMCCOLOR, mccolor_type, theColor); + ok(crColor==prevColor, "%s: Set RGB(100,180,220): Expected COLORREF of previous value, got %d\n", mccolor_name, crColor); + crColor = SendMessage(hWndDateTime, DTM_GETMCCOLOR, mccolor_type, 0); + ok(crColor==theColor, "%s: GETMCCOLOR: Expected %d, got %d\n", mccolor_name, theColor, crColor); } static void test_dtm_set_and_get_mccolor(void) @@ -600,6 +599,15 @@ static void test_dtm_set_and_get_system_time(void) r = SendMessage(hWnd, DTM_GETSYSTEMTIME, 0, (LPARAM)&getSt); expect(GDT_VALID, r); expect_systime(&ref, &getSt); + /* day invalid for current month */ + st = ref; + st.wDay = 30; + st.wMonth = 2; + 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; @@ -659,7 +667,7 @@ static void test_dtm_set_and_get_system_time(void) static void test_wm_set_get_text(void) { static const CHAR a_str[] = "a"; - char buff[16], time[16]; + CHAR buff[16], time[16], caltype[3]; HWND hWnd; LRESULT ret; @@ -673,10 +681,23 @@ static void test_wm_set_get_text(void) 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); + ok(strcmp(buff, a_str) != 0, "Expected text to change, got %s\n", buff); + ok(ret != 0, "Expected non-zero return value\n"); - GetDateFormat(LOCALE_USER_DEFAULT, 0, NULL, NULL, time, sizeof(time)); - ok(!strcmp(buff, time), "Expected %s, got %s\n", time, buff); + SetLastError(0xdeadbeef); + ret = GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_ICALENDARTYPE, caltype, 3); + if (ret == 0) + skip("Must know local calendar type (%x)\n", GetLastError()); + else if (atoi(caltype) != CAL_GREGORIAN) + skip("DateTimePicker Control only supports Gregorian calendar (type: %s)\n", caltype); + else { + SetLastError(0xdeadbeef); + ret = GetDateFormat(LOCALE_USER_DEFAULT, 0, NULL, NULL, time, sizeof(time)); + if (ret == 0) + skip("GetDateFormat failed, returned %ld, error %d\n", ret, GetLastError()); + else + ok(!strcmp(buff, time), "Expected %s, got %s\n", time, buff); + } DestroyWindow(hWnd); } diff --git a/rostests/winetests/comctl32/dpa.c b/rostests/winetests/comctl32/dpa.c index 419c1b14d0e..e3591397fd5 100644 --- a/rostests/winetests/comctl32/dpa.c +++ b/rostests/winetests/comctl32/dpa.c @@ -96,13 +96,13 @@ static BOOL InitFunctionPtrs(HMODULE hcomctl32) /* Callbacks */ static INT CALLBACK CB_CmpLT(PVOID p1, PVOID p2, LPARAM lp) { - ok(lp == 0xdeadbeef, "lp=%ld\n", lp); + ok(lp == 0x1abe11ed, "lp=%ld\n", lp); return p1 < p2 ? -1 : p1 > p2 ? 1 : 0; } static INT CALLBACK CB_CmpGT(PVOID p1, PVOID p2, LPARAM lp) { - ok(lp == 0xdeadbeef, "lp=%ld\n", lp); + ok(lp == 0x1abe11ed, "lp=%ld\n", lp); return p1 > p2 ? -1 : p1 < p2 ? 1 : 0; } @@ -115,14 +115,14 @@ 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); + ok(lp == 0x1abe11ed, "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); + ok(lp == 0x1abe11ed, "lp=%ld\n", lp); return ((PCHAR)p2)+1; } @@ -247,12 +247,12 @@ static void test_dpa(void) INT j, k; k = pDPA_GetPtrIndex(dpa, (PVOID)(INT_PTR)i); /* Linear searches should work on unsorted DPAs */ - j = pDPA_Search(dpa, (PVOID)(INT_PTR)i, 0, CB_CmpLT, 0xdeadbeef, 0); + j = pDPA_Search(dpa, (PVOID)(INT_PTR)i, 0, CB_CmpLT, 0x1abe11ed, 0); ok(j == k, "j=%d k=%d\n", j, k); } /* Sort DPA */ - ok(pDPA_Sort(dpa, CB_CmpGT, 0xdeadbeef), "\n"); + ok(pDPA_Sort(dpa, CB_CmpGT, 0x1abe11ed), "\n"); rc=CheckDPA(dpa, 0x654321, &dw); ok(rc, "dw=0x%x\n", dw); @@ -262,7 +262,7 @@ static void test_dpa(void) /* The old data should have been preserved */ rc=CheckDPA(dpa2, 0x654321, &dw2); ok(rc, "dw=0x%x\n", dw2); - ok(pDPA_Sort(dpa, CB_CmpLT, 0xdeadbeef), "\n"); + ok(pDPA_Sort(dpa, CB_CmpLT, 0x1abe11ed), "\n"); /* Test if the DPA itself was really copied */ rc=CheckDPA(dpa, 0x123456, &dw); @@ -284,14 +284,14 @@ static void test_dpa(void) /* The array is in order so ptr == index+1 */ j = pDPA_GetPtrIndex(dpa, (PVOID)(INT_PTR)i); ok(j+1 == i, "j=%d i=%d\n", j, i); - j = pDPA_Search(dpa, (PVOID)(INT_PTR)i, 0, CB_CmpLT, 0xdeadbeef, DPAS_SORTED); + j = pDPA_Search(dpa, (PVOID)(INT_PTR)i, 0, CB_CmpLT, 0x1abe11ed, DPAS_SORTED); ok(j+1 == i, "j=%d i=%d\n", j, i); /* Linear searches respect iStart ... */ - j = pDPA_Search(dpa, (PVOID)(INT_PTR)i, i+1, CB_CmpLT, 0xdeadbeef, 0); + j = pDPA_Search(dpa, (PVOID)(INT_PTR)i, i+1, CB_CmpLT, 0x1abe11ed, 0); 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); + j = pDPA_Search(dpa, (PVOID)(INT_PTR)i, i+1, CB_CmpLT, 0x1abe11ed, DPAS_SORTED); ok(j+1 == i, "j=%d i=%d\n", j, i); } @@ -313,15 +313,15 @@ static void test_dpa(void) /* Check where to re-insert the deleted item */ i = pDPA_Search(dpa, (PVOID)3, 0, - CB_CmpLT, 0xdeadbeef, DPAS_SORTED|DPAS_INSERTAFTER); + CB_CmpLT, 0x1abe11ed, DPAS_SORTED|DPAS_INSERTAFTER); ok(i == 2, "i=%d\n", i); /* DPAS_INSERTBEFORE works just like DPAS_INSERTAFTER */ i = pDPA_Search(dpa, (PVOID)3, 0, - CB_CmpLT, 0xdeadbeef, DPAS_SORTED|DPAS_INSERTBEFORE); + CB_CmpLT, 0x1abe11ed, DPAS_SORTED|DPAS_INSERTBEFORE); ok(i == 2, "i=%d\n", i); /* without DPAS_INSERTBEFORE/AFTER */ i = pDPA_Search(dpa, (PVOID)3, 0, - CB_CmpLT, 0xdeadbeef, DPAS_SORTED); + CB_CmpLT, 0x1abe11ed, DPAS_SORTED); ok(i == -1, "i=%d\n", i); /* Re-insert the item */ @@ -334,7 +334,7 @@ static void test_dpa(void) * should be bogus */ for(i = 0; i < 6; i++) { - INT j = pDPA_Search(dpa, (PVOID)(INT_PTR)i, 0, CB_CmpGT, 0xdeadbeef, + INT j = pDPA_Search(dpa, (PVOID)(INT_PTR)i, 0, CB_CmpGT, 0x1abe11ed, DPAS_SORTED|DPAS_INSERTBEFORE); ok(j != i, "i=%d\n", i); } @@ -396,7 +396,7 @@ static void test_DPA_Merge(void) /* Delete all odd entries from dpa2 */ memset(nMessages, 0, sizeof(nMessages)); pDPA_Merge(dpa2, dpa, DPAM_INTERSECT, - CB_CmpLT, CB_MergeDeleteOddSrc, 0xdeadbeef); + CB_CmpLT, CB_MergeDeleteOddSrc, 0x1abe11ed); rc = CheckDPA(dpa2, 0x246, &dw); ok(rc, "dw=0x%x\n", dw); @@ -413,7 +413,7 @@ static void test_DPA_Merge(void) /* DPAM_INTERSECT - returning source while merging */ memset(nMessages, 0, sizeof(nMessages)); pDPA_Merge(dpa2, dpa, DPAM_INTERSECT, - CB_CmpLT, CB_MergeInsertSrc, 0xdeadbeef); + CB_CmpLT, CB_MergeInsertSrc, 0x1abe11ed); rc = CheckDPA(dpa2, 0x135, &dw); ok(rc, "dw=0x%x\n", dw); @@ -433,7 +433,7 @@ static void test_DPA_Merge(void) memset(nMessages, 0, sizeof(nMessages)); pDPA_Merge(dpa2, dpa, DPAM_UNION, - CB_CmpLT, CB_MergeInsertSrc, 0xdeadbeef); + CB_CmpLT, CB_MergeInsertSrc, 0x1abe11ed); rc = CheckDPA(dpa2, 0x123456, &dw); ok(rc || broken(!rc && dw == 0x23456), /* 4.7x */ @@ -448,7 +448,7 @@ static void test_DPA_Merge(void) /* Merge dpa3 into dpa2 and dpa */ memset(nMessages, 0, sizeof(nMessages)); pDPA_Merge(dpa, dpa3, DPAM_UNION|DPAM_SORTED, - CB_CmpLT, CB_MergeInsertSrc, 0xdeadbeef); + CB_CmpLT, CB_MergeInsertSrc, 0x1abe11ed); expect(3, nMessages[DPAMM_MERGE]); expect(0, nMessages[DPAMM_DELETE]); expect(3, nMessages[DPAMM_INSERT]); @@ -461,7 +461,7 @@ static void test_DPA_Merge(void) memset(nMessages, 0, sizeof(nMessages)); pDPA_Merge(dpa2, dpa3, DPAM_UNION|DPAM_SORTED, - CB_CmpLT, CB_MergeInsertSrc, 0xdeadbeef); + CB_CmpLT, CB_MergeInsertSrc, 0x1abe11ed); expect(3, nMessages[DPAMM_MERGE]); expect(0, nMessages[DPAMM_DELETE]); ok(nMessages[DPAMM_INSERT] == 3 || @@ -667,7 +667,7 @@ static void test_DPA_SaveStream(void) IStream* pStm = NULL; DWORD dwMode, dw; HRESULT hRes; - ULONG ret; + INT ret; INT i; BOOL rc; LARGE_INTEGER liZero; diff --git a/rostests/winetests/comctl32/header.c b/rostests/winetests/comctl32/header.c index d9b4a7329ff..08d5065bbcb 100644 --- a/rostests/winetests/comctl32/header.c +++ b/rostests/winetests/comctl32/header.c @@ -955,6 +955,7 @@ static void test_hdm_imageMessages(HWND hParent) { HIMAGELIST hImageList = ImageList_Create (4, 4, 0, 1, 0); HIMAGELIST hIml; + BOOL wasValid; HWND hChild; flush_sequences(sequences, NUM_MSG_SEQUENCES); @@ -977,6 +978,9 @@ static void test_hdm_imageMessages(HWND hParent) ok_sequence(sequences, HEADER_SEQ_INDEX, imageMessages_seq, "imageMessages sequence testing", FALSE); DestroyWindow(hChild); + + wasValid = ImageList_Destroy(hImageList); + ok(wasValid, "Header must not free image list at destruction!\n"); } static void test_hdm_filterMessages(HWND hParent) @@ -1024,10 +1028,6 @@ static void test_hdm_filterMessages(HWND hParent) else ok_sequence(sequences, HEADER_SEQ_INDEX, filterMessages_seq_noninteractive, "filterMessages sequence testing", FALSE); - /* Some Win9x versions don't send a WM_KILLFOCUS. - * Set the focus explicitly to the parent to avoid a crash. - */ - SetFocus(hParent); DestroyWindow(hChild); } diff --git a/rostests/winetests/comctl32/imagelist.c b/rostests/winetests/comctl32/imagelist.c index 5398201d708..b920b9aaf5b 100644 --- a/rostests/winetests/comctl32/imagelist.c +++ b/rostests/winetests/comctl32/imagelist.c @@ -254,7 +254,7 @@ static void check_bits(HWND hwnd, HIMAGELIST himl, int idx, int size, #endif /* VISIBLE */ } -static void testHotspot (void) +static void test_hotspot(void) { struct hotspot { int dx; @@ -328,7 +328,7 @@ static void testHotspot (void) DestroyWindow(hwnd); } -static BOOL DoTest1(void) +static void test_add_remove(void) { HIMAGELIST himl ; @@ -369,67 +369,42 @@ static BOOL DoTest1(void) /* remove one extra */ ok(!ImageList_Remove(himl,0),"removed nonexistent icon\n"); - /* check SetImageCount/GetImageCount */ - if (pImageList_SetImageCount) - { - ok(pImageList_SetImageCount(himl, 3), "couldn't increase image count\n"); - ok(ImageList_GetImageCount(himl) == 3, "invalid image count after increase\n"); - ok(pImageList_SetImageCount(himl, 1), "couldn't decrease image count\n"); - ok(ImageList_GetImageCount(himl) == 1, "invalid image count after decrease to 1\n"); - ok(pImageList_SetImageCount(himl, 0), "couldn't decrease image count\n"); - ok(ImageList_GetImageCount(himl) == 0, "invalid image count after decrease to 0\n"); - } - else - { - skip("skipped ImageList_SetImageCount tests\n"); - } - /* destroy it */ ok(ImageList_Destroy(himl),"destroy imagelist failed\n"); + ok(-1==ImageList_AddIcon((HIMAGELIST)0xdeadbeef, hicon1),"don't crash on bad handle\n"); + ok(DestroyIcon(hicon1),"icon 1 wasn't deleted\n"); ok(DestroyIcon(hicon2),"icon 2 wasn't deleted\n"); ok(DestroyIcon(hicon3),"icon 3 wasn't deleted\n"); - - return TRUE; } -static BOOL DoTest2(void) +static void test_imagecount(void) { - HIMAGELIST himl ; + HIMAGELIST himl; - HICON hicon1 ; - HICON hicon2 ; - HICON hicon3 ; + ok(0==ImageList_GetImageCount((HIMAGELIST)0xdeadbeef),"don't crash on bad handle\n"); + + if (!pImageList_SetImageCount) + { + win_skip("ImageList_SetImageCount not available\n"); + return; + } - /* create an imagelist to play with */ 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 */ - 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"); + ok(pImageList_SetImageCount(himl, 3), "couldn't increase image count\n"); + ok(ImageList_GetImageCount(himl) == 3, "invalid image count after increase\n"); + ok(pImageList_SetImageCount(himl, 1), "couldn't decrease image count\n"); + ok(ImageList_GetImageCount(himl) == 1, "invalid image count after decrease to 1\n"); + ok(pImageList_SetImageCount(himl, 0), "couldn't decrease image count\n"); + ok(ImageList_GetImageCount(himl) == 0, "invalid image count after decrease to 0\n"); - /* add three */ - ok(0==ImageList_AddIcon(himl, hicon1),"failed to add icon1\n"); - ok(1==ImageList_AddIcon(himl, hicon2),"failed to add icon2\n"); - ok(2==ImageList_AddIcon(himl, hicon3),"failed to add icon3\n"); - - /* destroy it */ - ok(ImageList_Destroy(himl),"destroy 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"); - - return TRUE; + ok(ImageList_Destroy(himl), "destroy imagelist failed\n"); } -static BOOL DoTest3(void) +static void test_DrawIndirect(void) { HIMAGELIST himl; @@ -444,7 +419,7 @@ static BOOL DoTest3(void) if (!pImageList_DrawIndirect) { win_skip("ImageList_DrawIndirect not available, skipping test\n"); - return TRUE; + return; } hwndfortest = create_a_window(); @@ -476,17 +451,14 @@ static BOOL DoTest3(void) memset(&imldp, 0, sizeof (imldp)); ok(!pImageList_DrawIndirect(&imldp), "zero data succeeded!\n"); - imldp.cbSize = sizeof (imldp); + imldp.cbSize = IMAGELISTDRAWPARAMS_V3_SIZE; ok(!pImageList_DrawIndirect(&imldp), "zero hdc succeeded!\n"); imldp.hdcDst = hdc; ok(!pImageList_DrawIndirect(&imldp),"zero himl succeeded!\n"); + imldp.himl = (HIMAGELIST)0xdeadbeef; + ok(!pImageList_DrawIndirect(&imldp),"bad himl succeeded!\n"); imldp.himl = himl; - if (!pImageList_DrawIndirect(&imldp)) - { - /* Earlier versions of native comctl32 use a smaller structure */ - imldp.cbSize -= 3 * sizeof(DWORD); - ok(pImageList_DrawIndirect(&imldp),"DrawIndirect should succeed\n"); - } + REDRAW(hwndfortest); WAIT; @@ -518,11 +490,9 @@ static BOOL DoTest3(void) ReleaseDC(hwndfortest, hdc); DestroyWindow(hwndfortest); - - return TRUE; } -static void testMerge(void) +static void test_merge(void) { HIMAGELIST himl1, himl2, hmerge; HICON hicon1; @@ -604,39 +574,37 @@ static void testMerge(void) struct my_IStream { - IStream is; + IStream IStream_iface; char *iml_data; /* written imagelist data */ ULONG iml_data_size; }; -static HRESULT STDMETHODCALLTYPE Test_Stream_QueryInterface( - IStream* This, - REFIID riid, - void** ppvObject) +static struct my_IStream *impl_from_IStream(IStream *iface) +{ + return CONTAINING_RECORD(iface, struct my_IStream, IStream_iface); +} + +static HRESULT STDMETHODCALLTYPE Test_Stream_QueryInterface(IStream *iface, REFIID riid, + void **ppvObject) { assert(0); return E_NOTIMPL; } -static ULONG STDMETHODCALLTYPE Test_Stream_AddRef( - IStream* This) +static ULONG STDMETHODCALLTYPE Test_Stream_AddRef(IStream *iface) { assert(0); return 2; } -static ULONG STDMETHODCALLTYPE Test_Stream_Release( - IStream* This) +static ULONG STDMETHODCALLTYPE Test_Stream_Release(IStream *iface) { assert(0); return 1; } -static HRESULT STDMETHODCALLTYPE Test_Stream_Read( - IStream* This, - void* pv, - ULONG cb, - ULONG* pcbRead) +static HRESULT STDMETHODCALLTYPE Test_Stream_Read(IStream *iface, void *pv, ULONG cb, + ULONG *pcbRead) { assert(0); return E_NOTIMPL; @@ -654,13 +622,10 @@ static BOOL allocate_storage(struct my_IStream *my_is, ULONG add) return my_is->iml_data ? TRUE : FALSE; } -static HRESULT STDMETHODCALLTYPE Test_Stream_Write( - IStream* This, - const void* pv, - ULONG cb, - ULONG* pcbWritten) +static HRESULT STDMETHODCALLTYPE Test_Stream_Write(IStream *iface, const void *pv, ULONG cb, + ULONG *pcbWritten) { - struct my_IStream *my_is = (struct my_IStream *)This; + struct my_IStream *my_is = impl_from_IStream(iface); ULONG current_iml_data_size = my_is->iml_data_size; if (!allocate_storage(my_is, cb)) return E_FAIL; @@ -671,82 +636,61 @@ static HRESULT STDMETHODCALLTYPE Test_Stream_Write( return S_OK; } -static HRESULT STDMETHODCALLTYPE Test_Stream_Seek( - IStream* This, - LARGE_INTEGER dlibMove, - DWORD dwOrigin, - ULARGE_INTEGER* plibNewPosition) +static HRESULT STDMETHODCALLTYPE Test_Stream_Seek(IStream *iface, LARGE_INTEGER dlibMove, + DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition) { assert(0); return E_NOTIMPL; } -static HRESULT STDMETHODCALLTYPE Test_Stream_SetSize( - IStream* This, - ULARGE_INTEGER libNewSize) +static HRESULT STDMETHODCALLTYPE Test_Stream_SetSize(IStream *iface, ULARGE_INTEGER libNewSize) { assert(0); return E_NOTIMPL; } -static HRESULT STDMETHODCALLTYPE Test_Stream_CopyTo( - IStream* This, - IStream* pstm, - ULARGE_INTEGER cb, - ULARGE_INTEGER* pcbRead, - ULARGE_INTEGER* pcbWritten) +static HRESULT STDMETHODCALLTYPE Test_Stream_CopyTo(IStream *iface, IStream *pstm, + ULARGE_INTEGER cb, ULARGE_INTEGER *pcbRead, + ULARGE_INTEGER *pcbWritten) { assert(0); return E_NOTIMPL; } -static HRESULT STDMETHODCALLTYPE Test_Stream_Commit( - IStream* This, - DWORD grfCommitFlags) +static HRESULT STDMETHODCALLTYPE Test_Stream_Commit(IStream *iface, DWORD grfCommitFlags) { assert(0); return E_NOTIMPL; } -static HRESULT STDMETHODCALLTYPE Test_Stream_Revert( - IStream* This) +static HRESULT STDMETHODCALLTYPE Test_Stream_Revert(IStream *iface) { assert(0); return E_NOTIMPL; } -static HRESULT STDMETHODCALLTYPE Test_Stream_LockRegion( - IStream* This, - ULARGE_INTEGER libOffset, - ULARGE_INTEGER cb, - DWORD dwLockType) +static HRESULT STDMETHODCALLTYPE Test_Stream_LockRegion(IStream *iface, ULARGE_INTEGER libOffset, + ULARGE_INTEGER cb, DWORD dwLockType) { assert(0); return E_NOTIMPL; } -static HRESULT STDMETHODCALLTYPE Test_Stream_UnlockRegion( - IStream* This, - ULARGE_INTEGER libOffset, - ULARGE_INTEGER cb, - DWORD dwLockType) +static HRESULT STDMETHODCALLTYPE Test_Stream_UnlockRegion(IStream *iface, ULARGE_INTEGER libOffset, + ULARGE_INTEGER cb, DWORD dwLockType) { assert(0); return E_NOTIMPL; } -static HRESULT STDMETHODCALLTYPE Test_Stream_Stat( - IStream* This, - STATSTG* pstatstg, - DWORD grfStatFlag) +static HRESULT STDMETHODCALLTYPE Test_Stream_Stat(IStream *iface, STATSTG *pstatstg, + DWORD grfStatFlag) { assert(0); return E_NOTIMPL; } -static HRESULT STDMETHODCALLTYPE Test_Stream_Clone( - IStream* This, - IStream** ppstm) +static HRESULT STDMETHODCALLTYPE Test_Stream_Clone(IStream *iface, IStream **ppstm) { assert(0); return E_NOTIMPL; @@ -774,30 +718,12 @@ static struct my_IStream Test_Stream = { { &Test_Stream_Vtbl }, 0, 0 }; static INT DIB_GetWidthBytes( int width, int bpp ) { - int words; - - switch (bpp) - { - case 1: words = (width + 31) / 32; break; - case 4: words = (width + 7) / 8; break; - case 8: words = (width + 3) / 4; break; - case 15: - case 16: words = (width + 1) / 2; break; - case 24: words = (width * 3 + 3)/4; break; - case 32: words = width; break; - - default: - words=0; - trace("Unknown depth %d, please report.\n", bpp ); - assert(0); - break; - } - return 4 * words; + return ((width * bpp + 31) / 8) & ~3; } -static void check_bitmap_data(const char *bm_data, ULONG bm_data_size, - INT width, INT height, INT bpp, - const char *comment) +static ULONG check_bitmap_data(const char *bm_data, ULONG bm_data_size, + INT width, INT height, INT bpp, + const char *comment) { const BITMAPFILEHEADER *bmfh = (const BITMAPFILEHEADER *)bm_data; const BITMAPINFOHEADER *bmih = (const BITMAPINFOHEADER *)(bm_data + sizeof(*bmfh)); @@ -830,9 +756,10 @@ static void check_bitmap_data(const char *bm_data, ULONG bm_data_size, fclose(f); } #endif + return hdr_size + image_size; } -static void check_ilhead_data(const char *ilh_data, INT cx, INT cy, INT cur, INT max, INT grow) +static void check_ilhead_data(const char *ilh_data, INT cx, INT cy, INT cur, INT max, INT grow, INT flags) { const ILHEAD *ilh = (const ILHEAD *)ilh_data; @@ -844,19 +771,12 @@ static void check_ilhead_data(const char *ilh_data, INT cx, INT cy, INT cur, INT ok(ilh->cx == cx, "wrong cx %d (expected %d)\n", ilh->cx, cx); ok(ilh->cy == cy, "wrong cy %d (expected %d)\n", ilh->cy, cy); ok(ilh->bkcolor == CLR_NONE, "wrong bkcolor %x\n", ilh->bkcolor); - ok(ilh->flags == ILC_COLOR24, "wrong flags %04x\n", ilh->flags); - ok(ilh->ovls[0] == -1 || - ilh->ovls[0] == 0, /* win95 */ - "wrong ovls[0] %04x\n", ilh->ovls[0]); - ok(ilh->ovls[1] == -1 || - ilh->ovls[1] == 0, /* win95 */ - "wrong ovls[1] %04x\n", ilh->ovls[1]); - ok(ilh->ovls[2] == -1 || - ilh->ovls[2] == 0, /* win95 */ - "wrong ovls[2] %04x\n", ilh->ovls[2]); - ok(ilh->ovls[3] == -1 || - ilh->ovls[3] == 0, /* win95 */ - "wrong ovls[3] %04x\n", ilh->ovls[3]); + ok(ilh->flags == flags || broken(!(ilh->flags & 0xfe) && (flags & 0xfe) == ILC_COLOR4), /* <= w2k */ + "wrong flags %04x\n", ilh->flags); + ok(ilh->ovls[0] == -1, "wrong ovls[0] %04x\n", ilh->ovls[0]); + ok(ilh->ovls[1] == -1, "wrong ovls[1] %04x\n", ilh->ovls[1]); + ok(ilh->ovls[2] == -1, "wrong ovls[2] %04x\n", ilh->ovls[2]); + ok(ilh->ovls[3] == -1, "wrong ovls[3] %04x\n", ilh->ovls[3]); } static HBITMAP create_bitmap(INT cx, INT cy, COLORREF color, const char *comment) @@ -899,9 +819,9 @@ static HBITMAP create_bitmap(INT cx, INT cy, COLORREF color, const char *comment Test_Stream.iml_data_size = 0; static void check_iml_data(HIMAGELIST himl, INT cx, INT cy, INT cur, INT max, INT grow, - INT width, INT height, INT bpp, const char *comment) + INT width, INT height, INT flags, const char *comment) { - INT ret, cxx, cyy; + INT ret, cxx, cyy, size; trace("%s\n", comment); @@ -914,23 +834,32 @@ static void check_iml_data(HIMAGELIST himl, INT cx, INT cy, INT cur, INT max, IN ok(cyy == cy, "wrong cy %d (expected %d)\n", cyy, cy); iml_clear_stream_data(); - ret = ImageList_Write(himl, &Test_Stream.is); + ret = ImageList_Write(himl, &Test_Stream.IStream_iface); ok(ret, "ImageList_Write failed\n"); ok(Test_Stream.iml_data != 0, "ImageList_Write didn't write any data\n"); ok(Test_Stream.iml_data_size > sizeof(ILHEAD), "ImageList_Write wrote not enough data\n"); - check_ilhead_data(Test_Stream.iml_data, cx, cy, cur, max, grow); - check_bitmap_data(Test_Stream.iml_data + sizeof(ILHEAD), - Test_Stream.iml_data_size - sizeof(ILHEAD), - width, height, bpp, comment); + check_ilhead_data(Test_Stream.iml_data, cx, cy, cur, max, grow, flags); + size = check_bitmap_data(Test_Stream.iml_data + sizeof(ILHEAD), + Test_Stream.iml_data_size - sizeof(ILHEAD), + width, height, flags & 0xfe, comment); + if (size < Test_Stream.iml_data_size - sizeof(ILHEAD)) /* mask is present */ + { + ok( flags & ILC_MASK, "extra data %u/%u but mask not expected\n", + Test_Stream.iml_data_size, size ); + check_bitmap_data(Test_Stream.iml_data + sizeof(ILHEAD) + size, + Test_Stream.iml_data_size - sizeof(ILHEAD) - size, + width, height, 1, comment); + } } static void image_list_init(HIMAGELIST himl) { HBITMAP hbm; char comment[16]; - INT n = 1, i; + INT n = 1; + DWORD i; static const struct test_data { BYTE grey; @@ -964,7 +893,7 @@ static void image_list_init(HIMAGELIST himl) { 255, BMP_CX, BMP_CX, 24, 27, 4, BMP_CX * 4, BMP_CX * 7, 24, "total 24" } }; - check_iml_data(himl, BMP_CX, BMP_CX, 0, 2, 4, BMP_CX * 4, BMP_CX * 1, 24, "total 0"); + check_iml_data(himl, BMP_CX, BMP_CX, 0, 2, 4, BMP_CX * 4, BMP_CX * 1, ILC_COLOR24, "total 0"); #define add_bitmap(grey) \ sprintf(comment, "%d", n++); \ @@ -985,43 +914,44 @@ static void test_imagelist_storage(void) { HIMAGELIST himl; HBITMAP hbm; + HICON icon; INT ret; himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR24, 1, 1); ok(himl != 0, "ImageList_Create failed\n"); - check_iml_data(himl, BMP_CX, BMP_CX, 0, 2, 4, BMP_CX * 4, BMP_CX * 1, 24, "empty"); + check_iml_data(himl, BMP_CX, BMP_CX, 0, 2, 4, BMP_CX * 4, BMP_CX * 1, ILC_COLOR24, "empty"); image_list_init(himl); - check_iml_data(himl, BMP_CX, BMP_CX, 24, 27, 4, BMP_CX * 4, BMP_CX * 7, 24, "orig"); + check_iml_data(himl, BMP_CX, BMP_CX, 24, 27, 4, BMP_CX * 4, BMP_CX * 7, ILC_COLOR24, "orig"); ret = ImageList_Remove(himl, 4); ok(ret, "ImageList_Remove failed\n"); - check_iml_data(himl, BMP_CX, BMP_CX, 23, 27, 4, BMP_CX * 4, BMP_CX * 7, 24, "1"); + check_iml_data(himl, BMP_CX, BMP_CX, 23, 27, 4, BMP_CX * 4, BMP_CX * 7, ILC_COLOR24, "1"); ret = ImageList_Remove(himl, 5); ok(ret, "ImageList_Remove failed\n"); - check_iml_data(himl, BMP_CX, BMP_CX, 22, 27, 4, BMP_CX * 4, BMP_CX * 7, 24, "2"); + check_iml_data(himl, BMP_CX, BMP_CX, 22, 27, 4, BMP_CX * 4, BMP_CX * 7, ILC_COLOR24, "2"); ret = ImageList_Remove(himl, 6); ok(ret, "ImageList_Remove failed\n"); - check_iml_data(himl, BMP_CX, BMP_CX, 21, 27, 4, BMP_CX * 4, BMP_CX * 7, 24, "3"); + check_iml_data(himl, BMP_CX, BMP_CX, 21, 27, 4, BMP_CX * 4, BMP_CX * 7, ILC_COLOR24, "3"); ret = ImageList_Remove(himl, 7); ok(ret, "ImageList_Remove failed\n"); - check_iml_data(himl, BMP_CX, BMP_CX, 20, 27, 4, BMP_CX * 4, BMP_CX * 7, 24, "4"); + check_iml_data(himl, BMP_CX, BMP_CX, 20, 27, 4, BMP_CX * 4, BMP_CX * 7, ILC_COLOR24, "4"); ret = ImageList_Remove(himl, -2); ok(!ret, "ImageList_Remove(-2) should fail\n"); - check_iml_data(himl, BMP_CX, BMP_CX, 20, 27, 4, BMP_CX * 4, BMP_CX * 7, 24, "5"); + check_iml_data(himl, BMP_CX, BMP_CX, 20, 27, 4, BMP_CX * 4, BMP_CX * 7, ILC_COLOR24, "5"); ret = ImageList_Remove(himl, 20); ok(!ret, "ImageList_Remove(20) should fail\n"); - check_iml_data(himl, BMP_CX, BMP_CX, 20, 27, 4, BMP_CX * 4, BMP_CX * 7, 24, "6"); + check_iml_data(himl, BMP_CX, BMP_CX, 20, 27, 4, BMP_CX * 4, BMP_CX * 7, ILC_COLOR24, "6"); ret = ImageList_Remove(himl, -1); ok(ret, "ImageList_Remove(-1) failed\n"); - check_iml_data(himl, BMP_CX, BMP_CX, 0, 4, 4, BMP_CX * 4, BMP_CX * 1, 24, "7"); + check_iml_data(himl, BMP_CX, BMP_CX, 0, 4, 4, BMP_CX * 4, BMP_CX * 1, ILC_COLOR24, "7"); ret = ImageList_Destroy(himl); ok(ret, "ImageList_Destroy failed\n"); @@ -1032,11 +962,11 @@ static void test_imagelist_storage(void) himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR24, 0, 32); ok(himl != 0, "ImageList_Create failed\n"); - check_iml_data(himl, BMP_CX, BMP_CX, 0, 1, 32, BMP_CX * 4, BMP_CX * 1, 24, "init 0 grow 32"); + check_iml_data(himl, BMP_CX, BMP_CX, 0, 1, 32, BMP_CX * 4, BMP_CX * 1, ILC_COLOR24, "init 0 grow 32"); hbm = create_bitmap(BMP_CX * 9, BMP_CX, 0, "9"); ret = ImageList_Add(himl, hbm, NULL); ok(ret == 0, "ImageList_Add returned %d, expected 0\n", ret); - check_iml_data(himl, BMP_CX, BMP_CX, 1, 34, 32, BMP_CX * 4, BMP_CX * 9, 24, "add 1 x 9"); + check_iml_data(himl, BMP_CX, BMP_CX, 1, 34, 32, BMP_CX * 4, BMP_CX * 9, ILC_COLOR24, "add 1 x 9"); DeleteObject(hbm); ret = ImageList_Destroy(himl); ok(ret, "ImageList_Destroy failed\n"); @@ -1044,14 +974,14 @@ static void test_imagelist_storage(void) himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR24, 4, 4); ok(himl != 0, "ImageList_Create failed\n"); - check_iml_data(himl, BMP_CX, BMP_CX, 0, 5, 4, BMP_CX * 4, BMP_CX * 2, 24, "init 4 grow 4"); + check_iml_data(himl, BMP_CX, BMP_CX, 0, 5, 4, BMP_CX * 4, BMP_CX * 2, ILC_COLOR24, "init 4 grow 4"); hbm = create_bitmap(BMP_CX, BMP_CX * 9, 0, "9"); ret = ImageList_Add(himl, hbm, NULL); ok(ret == 0, "ImageList_Add returned %d, expected 0\n", ret); - check_iml_data(himl, BMP_CX, BMP_CX, 9, 15, 4, BMP_CX * 4, BMP_CX * 4, 24, "add 9 x 1"); + check_iml_data(himl, BMP_CX, BMP_CX, 9, 15, 4, BMP_CX * 4, BMP_CX * 4, ILC_COLOR24, "add 9 x 1"); ret = ImageList_Add(himl, hbm, NULL); ok(ret == 9, "ImageList_Add returned %d, expected 9\n", ret); - check_iml_data(himl, BMP_CX, BMP_CX, 18, 25, 4, BMP_CX * 4, BMP_CX * 7, 24, "add 9 x 1"); + check_iml_data(himl, BMP_CX, BMP_CX, 18, 25, 4, BMP_CX * 4, BMP_CX * 7, ILC_COLOR24, "add 9 x 1"); DeleteObject(hbm); ret = ImageList_Destroy(himl); ok(ret, "ImageList_Destroy failed\n"); @@ -1059,49 +989,156 @@ static void test_imagelist_storage(void) himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR24, 207, 209); ok(himl != 0, "ImageList_Create failed\n"); - check_iml_data(himl, BMP_CX, BMP_CX, 0, 208, 212, BMP_CX * 4, BMP_CX * 52, 24, "init 207 grow 209"); + check_iml_data(himl, BMP_CX, BMP_CX, 0, 208, 212, BMP_CX * 4, BMP_CX * 52, ILC_COLOR24, "init 207 grow 209"); ret = ImageList_Destroy(himl); ok(ret, "ImageList_Destroy failed\n"); iml_clear_stream_data(); himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR24, 209, 207); ok(himl != 0, "ImageList_Create failed\n"); - check_iml_data(himl, BMP_CX, BMP_CX, 0, 210, 208, BMP_CX * 4, BMP_CX * 53, 24, "init 209 grow 207"); + check_iml_data(himl, BMP_CX, BMP_CX, 0, 210, 208, BMP_CX * 4, BMP_CX * 53, ILC_COLOR24, "init 209 grow 207"); ret = ImageList_Destroy(himl); ok(ret, "ImageList_Destroy failed\n"); iml_clear_stream_data(); himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR24, 14, 4); ok(himl != 0, "ImageList_Create failed\n"); - check_iml_data(himl, BMP_CX, BMP_CX, 0, 15, 4, BMP_CX * 4, BMP_CX * 4, 24, "init 14 grow 4"); + check_iml_data(himl, BMP_CX, BMP_CX, 0, 15, 4, BMP_CX * 4, BMP_CX * 4, ILC_COLOR24, "init 14 grow 4"); ret = ImageList_Destroy(himl); ok(ret, "ImageList_Destroy failed\n"); iml_clear_stream_data(); himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR24, 5, 9); ok(himl != 0, "ImageList_Create failed\n"); - check_iml_data(himl, BMP_CX, BMP_CX, 0, 6, 12, BMP_CX * 4, BMP_CX * 2, 24, "init 5 grow 9"); + check_iml_data(himl, BMP_CX, BMP_CX, 0, 6, 12, BMP_CX * 4, BMP_CX * 2, ILC_COLOR24, "init 5 grow 9"); ret = ImageList_Destroy(himl); ok(ret, "ImageList_Destroy failed\n"); iml_clear_stream_data(); himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR24, 9, 5); ok(himl != 0, "ImageList_Create failed\n"); - check_iml_data(himl, BMP_CX, BMP_CX, 0, 10, 8, BMP_CX * 4, BMP_CX * 3, 24, "init 9 grow 5"); + check_iml_data(himl, BMP_CX, BMP_CX, 0, 10, 8, BMP_CX * 4, BMP_CX * 3, ILC_COLOR24, "init 9 grow 5"); ret = ImageList_Destroy(himl); ok(ret, "ImageList_Destroy failed\n"); iml_clear_stream_data(); himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR24, 2, 4); ok(himl != 0, "ImageList_Create failed\n"); - check_iml_data(himl, BMP_CX, BMP_CX, 0, 3, 4, BMP_CX * 4, BMP_CX * 1, 24, "init 2 grow 4"); + check_iml_data(himl, BMP_CX, BMP_CX, 0, 3, 4, BMP_CX * 4, BMP_CX * 1, ILC_COLOR24, "init 2 grow 4"); ret = ImageList_Destroy(himl); ok(ret, "ImageList_Destroy failed\n"); iml_clear_stream_data(); himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR24, 4, 2); ok(himl != 0, "ImageList_Create failed\n"); - check_iml_data(himl, BMP_CX, BMP_CX, 0, 5, 4, BMP_CX * 4, BMP_CX * 2, 24, "init 4 grow 2"); + check_iml_data(himl, BMP_CX, BMP_CX, 0, 5, 4, BMP_CX * 4, BMP_CX * 2, ILC_COLOR24, "init 4 grow 2"); + ret = ImageList_Destroy(himl); + ok(ret, "ImageList_Destroy failed\n"); + iml_clear_stream_data(); + + himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR8, 4, 2); + ok(himl != 0, "ImageList_Create failed\n"); + check_iml_data(himl, BMP_CX, BMP_CX, 0, 5, 4, BMP_CX * 4, BMP_CX * 2, ILC_COLOR8, "bpp 8"); + ret = ImageList_Destroy(himl); + ok(ret, "ImageList_Destroy failed\n"); + iml_clear_stream_data(); + + himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR4, 4, 2); + ok(himl != 0, "ImageList_Create failed\n"); + check_iml_data(himl, BMP_CX, BMP_CX, 0, 5, 4, BMP_CX * 4, BMP_CX * 2, ILC_COLOR4, "bpp 4"); + ret = ImageList_Destroy(himl); + ok(ret, "ImageList_Destroy failed\n"); + iml_clear_stream_data(); + + himl = ImageList_Create(BMP_CX, BMP_CX, 0, 4, 2); + ok(himl != 0, "ImageList_Create failed\n"); + check_iml_data(himl, BMP_CX, BMP_CX, 0, 5, 4, BMP_CX * 4, BMP_CX * 2, ILC_COLOR4, "bpp default"); + icon = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits); + ok( ImageList_AddIcon(himl, icon) == 0,"failed to add icon\n"); + ok( ImageList_AddIcon(himl, icon) == 1,"failed to add icon\n"); + DestroyIcon( icon ); + check_iml_data(himl, BMP_CX, BMP_CX, 2, 5, 4, BMP_CX * 4, BMP_CX * 2, ILC_COLOR4, "bpp default"); + ret = ImageList_Destroy(himl); + ok(ret, "ImageList_Destroy failed\n"); + iml_clear_stream_data(); + + himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR24|ILC_MASK, 4, 2); + ok(himl != 0, "ImageList_Create failed\n"); + check_iml_data(himl, BMP_CX, BMP_CX, 0, 5, 4, BMP_CX * 4, BMP_CX * 2, ILC_COLOR24|ILC_MASK, + "bpp 24 + mask"); + icon = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits); + ok( ImageList_AddIcon(himl, icon) == 0,"failed to add icon\n"); + ok( ImageList_AddIcon(himl, icon) == 1,"failed to add icon\n"); + DestroyIcon( icon ); + check_iml_data(himl, BMP_CX, BMP_CX, 2, 5, 4, BMP_CX * 4, BMP_CX * 2, ILC_COLOR24|ILC_MASK, + "bpp 24 + mask"); + ret = ImageList_Destroy(himl); + ok(ret, "ImageList_Destroy failed\n"); + iml_clear_stream_data(); + + himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR4|ILC_MASK, 4, 2); + ok(himl != 0, "ImageList_Create failed\n"); + check_iml_data(himl, BMP_CX, BMP_CX, 0, 5, 4, BMP_CX * 4, BMP_CX * 2, ILC_COLOR4|ILC_MASK, + "bpp 4 + mask"); + icon = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits); + ok( ImageList_AddIcon(himl, icon) == 0,"failed to add icon\n"); + ok( ImageList_AddIcon(himl, icon) == 1,"failed to add icon\n"); + DestroyIcon( icon ); + check_iml_data(himl, BMP_CX, BMP_CX, 2, 5, 4, BMP_CX * 4, BMP_CX * 2, ILC_COLOR4|ILC_MASK, + "bpp 4 + mask"); + ret = ImageList_Destroy(himl); + ok(ret, "ImageList_Destroy failed\n"); + iml_clear_stream_data(); + + himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR4|ILC_MASK, 2, 99); + ok(himl != 0, "ImageList_Create failed\n"); + check_iml_data(himl, BMP_CX, BMP_CX, 0, 3, 100, BMP_CX * 4, BMP_CX, ILC_COLOR4|ILC_MASK, + "init 2 grow 99"); + icon = CreateIcon(hinst, 32, 32, 1, 1, icon_bits, icon_bits); + ok( ImageList_AddIcon(himl, icon) == 0,"failed to add icon\n"); + ok( ImageList_AddIcon(himl, icon) == 1,"failed to add icon\n"); + check_iml_data(himl, BMP_CX, BMP_CX, 2, 3, 100, BMP_CX * 4, BMP_CX, ILC_COLOR4|ILC_MASK, + "init 2 grow 99 2 icons"); + ok( ImageList_AddIcon(himl, icon) == 2,"failed to add icon\n"); + DestroyIcon( icon ); + check_iml_data(himl, BMP_CX, BMP_CX, 3, 104, 100, BMP_CX * 4, BMP_CX * 104/4, ILC_COLOR4|ILC_MASK, + "init 2 grow 99 3 icons"); + ok( ImageList_Remove(himl, -1) == TRUE,"failed to remove icon\n"); + check_iml_data(himl, BMP_CX, BMP_CX, 0, 100, 100, BMP_CX * 4, BMP_CX * 100/4, ILC_COLOR4|ILC_MASK, + "init 2 grow 99 empty"); + ok( ImageList_SetImageCount(himl, 22) == TRUE,"failed to set image count\n"); + check_iml_data(himl, BMP_CX, BMP_CX, 22, 23, 100, BMP_CX * 4, BMP_CX * 24/4, ILC_COLOR4|ILC_MASK, + "init 2 grow 99 set count 22"); + ok( ImageList_SetImageCount(himl, 0) == TRUE,"failed to set image count\n"); + check_iml_data(himl, BMP_CX, BMP_CX, 0, 1, 100, BMP_CX * 4, BMP_CX, ILC_COLOR4|ILC_MASK, + "init 2 grow 99 set count 0"); + ok( ImageList_SetImageCount(himl, 42) == TRUE,"failed to set image count\n"); + check_iml_data(himl, BMP_CX, BMP_CX, 42, 43, 100, BMP_CX * 4, BMP_CX * 44/4, ILC_COLOR4|ILC_MASK, + "init 2 grow 99 set count 42"); + ret = ImageList_Destroy(himl); + ok(ret, "ImageList_Destroy failed\n"); + iml_clear_stream_data(); + + himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR4|ILC_MASK, 2, 65536+12); + ok(himl != 0, "ImageList_Create failed\n"); + check_iml_data(himl, BMP_CX, BMP_CX, 0, 3, 12, BMP_CX * 4, BMP_CX, ILC_COLOR4|ILC_MASK, + "init 2 grow 65536+12"); + ret = ImageList_Destroy(himl); + ok(ret, "ImageList_Destroy failed\n"); + iml_clear_stream_data(); + + himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR4|ILC_MASK, 2, 65535); + ok(himl != 0, "ImageList_Create failed\n"); + check_iml_data(himl, BMP_CX, BMP_CX, 0, 3, 0, BMP_CX * 4, BMP_CX, ILC_COLOR4|ILC_MASK, + "init 2 grow 65535"); + ret = ImageList_Destroy(himl); + ok(ret, "ImageList_Destroy failed\n"); + iml_clear_stream_data(); + + himl = ImageList_Create(BMP_CX, BMP_CX, ILC_COLOR4|ILC_MASK, 2, -20); + ok(himl != 0, "ImageList_Create failed\n"); + check_iml_data(himl, BMP_CX, BMP_CX, 0, 3, 4, BMP_CX * 4, BMP_CX, ILC_COLOR4|ILC_MASK, + "init 2 grow -20"); ret = ImageList_Destroy(himl); ok(ret, "ImageList_Destroy failed\n"); iml_clear_stream_data(); @@ -1245,6 +1282,7 @@ static void test_ImageList_DrawIndirect(void) int iImage = -1, iAlphaImage = -1, iTransparentImage = -1; UINT32 *bits = 0; UINT32 maskBits = 0x00000000, inverseMaskBits = 0xFFFFFFFF; + int bpp, broken_value; BITMAPINFO bitmapInfo = {{sizeof(BITMAPINFOHEADER), 2, 1, 1, 32, BI_RGB, 0, 0, 0, 0, 0}}; @@ -1253,6 +1291,7 @@ static void test_ImageList_DrawIndirect(void) ok(hdcDst != 0, "CreateCompatibleDC(0) failed to return a valid DC\n"); if (!hdcDst) return; + bpp = GetDeviceCaps(hdcDst, BITSPIXEL); hbmMask = CreateBitmap(2, 1, 1, 1, &maskBits); ok(hbmMask != 0, "CreateBitmap failed\n"); @@ -1301,19 +1340,22 @@ static void test_ImageList_DrawIndirect(void) 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__); + if (bpp == 16 || bpp == 24) broken_value = 0x00D4D9DD; + else broken_value = 0x00B4BDC4; + todo_wine check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_BLEND50, ILS_NORMAL, 0, 0x00E8F1FA, broken_value, __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__); - } + if (bpp == 16 || bpp == 24) broken_value = 0x00D4D9DD; + else broken_value = 0x009DA8B1; + todo_wine check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_BLEND25, ILS_NORMAL, 0, 0x00E8F1FA, broken_value, __LINE__); + if (bpp == 16 || bpp == 24) broken_value = 0x00D4D9DD; + else broken_value = 0x008C99A3; + todo_wine check_ImageList_DrawIndirect_broken(hdcDst, himl, bits, iAlphaImage, ILD_BLEND50, ILS_NORMAL, 0, 0x00E8F1FA, broken_value, __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__); @@ -1368,7 +1410,7 @@ cleanup: static void test_iimagelist(void) { - IImageList *imgl; + IImageList *imgl, *imgl2; HIMAGELIST himl; HRESULT hr; ULONG ret; @@ -1400,6 +1442,15 @@ static void test_iimagelist(void) ret = ImageList_Destroy((HIMAGELIST)imgl); ok(ret == FALSE, "Expected FALSE, got %d\n", ret); + /* ref counting, HIMAGELIST_QueryInterface adds a reference */ + imgl = (IImageList*)createImageList(32, 32); + hr = pHIMAGELIST_QueryInterface((HIMAGELIST)imgl, &IID_IImageList, (void**)&imgl2); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(imgl2 == imgl, "got different pointer\n"); + ret = IImageList_Release(imgl); + ok(ret == 1, "got %u\n", ret); + IImageList_Release(imgl); + if (!pImageList_CoCreateInstance) { win_skip("Vista imagelist functions not available\n"); @@ -1426,7 +1477,7 @@ static void test_iimagelist(void) ImageList_Destroy(himl); } -static void testHotspot_v6(void) +static void test_hotspot_v6(void) { struct hotspot { int dx; @@ -1501,7 +1552,7 @@ static void testHotspot_v6(void) IImageList_Release(imgl1); } -static void DoTest1_v6(void) +static void test_IImageList_Add_Remove(void) { IImageList *imgl; HIMAGELIST himl; @@ -1511,7 +1562,7 @@ static void DoTest1_v6(void) HICON hicon2; HICON hicon3; - int ret = 0; + int ret; /* create an imagelist to play with */ himl = ImageList_Create(84, 84, ILC_COLOR16, 0, 3); @@ -1529,45 +1580,71 @@ static void DoTest1_v6(void) /* remove when nothing exists */ hr = IImageList_Remove(imgl, 0); - ok(!(SUCCEEDED(hr)), "removed nonexistent icon\n"); + ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); /* removing everything from an empty imagelist should succeed */ hr = IImageList_Remove(imgl, -1); - ok(SUCCEEDED(hr), "removed nonexistent icon\n"); + ok(hr == S_OK, "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"); + ret = -1; + ok( IImageList_ReplaceIcon(imgl, -1, hicon1, &ret) == S_OK && (ret == 0),"failed to add icon1\n"); + ret = -1; + ok( IImageList_ReplaceIcon(imgl, -1, hicon2, &ret) == S_OK && (ret == 1),"failed to add icon2\n"); + ret = -1; + ok( IImageList_ReplaceIcon(imgl, -1, hicon3, &ret) == S_OK && (ret == 2),"failed to add icon3\n"); /* remove an index out of range */ - ok(FAILED(IImageList_Remove(imgl, 4711)),"removed nonexistent icon\n"); + ok( IImageList_Remove(imgl, 4711) == E_INVALIDARG, "got 0x%08x\n", hr); /* 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"); + ok( IImageList_Remove(imgl,0) == S_OK, "can't remove 0\n"); + ok( IImageList_Remove(imgl,0) == S_OK, "can't remove 0\n"); + ok( IImageList_Remove(imgl,0) == S_OK, "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( IImageList_Remove(imgl, 0) == E_INVALIDARG, "got 0x%08x\n", hr); + IImageList_Release(imgl); 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) +static void test_IImageList_Get_SetImageCount(void) +{ + IImageList *imgl; + HIMAGELIST himl; + HRESULT hr; + INT ret; + + /* 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; + + /* check SetImageCount/GetImageCount */ + hr = IImageList_SetImageCount(imgl, 3); + ok(hr == S_OK, "got 0x%08x\n", hr); + ret = 0; + hr = IImageList_GetImageCount(imgl, &ret); + ok(hr == S_OK && ret == 3, "invalid image count after increase\n"); + hr = IImageList_SetImageCount(imgl, 1); + ok(hr == S_OK, "got 0x%08x\n", hr); + ret = 0; + hr = IImageList_GetImageCount(imgl, &ret); + ok(hr == S_OK && ret == 1, "invalid image count after decrease to 1\n"); + hr = IImageList_SetImageCount(imgl, 0); + ok(hr == S_OK, "got 0x%08x\n", hr); + ret = -1; + hr = IImageList_GetImageCount(imgl, &ret); + ok(hr == S_OK && ret == 0, "invalid image count after decrease to 0\n"); + + IImageList_Release(imgl); +} + +static void test_IImageList_Draw(void) { IImageList *imgl; HIMAGELIST himl; @@ -1578,6 +1655,7 @@ static void DoTest3_v6(void) IMAGELISTDRAWPARAMS imldp; HWND hwndfortest; + HRESULT hr; HDC hdc; int ret; @@ -1600,26 +1678,28 @@ static void DoTest3_v6(void) 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"); + ret = -1; + ok( IImageList_Add(imgl, hbm1, 0, &ret) == S_OK && (ret == 0), "failed to add bitmap 1\n"); + ret = -1; + ok( IImageList_Add(imgl, hbm2, 0, &ret) == S_OK && (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"); + ok( IImageList_SetImageCount(imgl, 3) == S_OK, "Setimage count failed\n"); + ok( IImageList_Replace(imgl, 2, hbm3, 0) == S_OK, "failed to replace bitmap 3\n"); + +if (0) +{ + /* crashes on native */ + IImageList_Draw(imgl, NULL); +} memset(&imldp, 0, sizeof (imldp)); - ok(FAILED(IImageList_Draw(imgl, &imldp)), "zero data succeeded!\n"); + hr = IImageList_Draw(imgl, &imldp); + ok( hr == E_INVALIDARG, "got 0x%08x\n", hr); - imldp.cbSize = sizeof (imldp); + imldp.cbSize = IMAGELISTDRAWPARAMS_V3_SIZE; 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; @@ -1628,21 +1708,21 @@ static void DoTest3_v6(void) imldp.rgbFg = CLR_DEFAULT; imldp.y = 100; imldp.x = 100; - ok(SUCCEEDED(IImageList_Draw(imgl, &imldp)), "should succeed\n"); + ok( IImageList_Draw(imgl, &imldp) == S_OK, "should succeed\n"); imldp.i ++; - ok(SUCCEEDED(IImageList_Draw(imgl, &imldp)), "should succeed\n"); + ok( IImageList_Draw(imgl, &imldp) == S_OK, "should succeed\n"); imldp.i ++; - ok(SUCCEEDED(IImageList_Draw(imgl, &imldp)), "should succeed\n"); + ok( IImageList_Draw(imgl, &imldp) == S_OK, "should succeed\n"); imldp.i ++; - ok(FAILED(IImageList_Draw(imgl, &imldp)), "should fail\n"); + ok( IImageList_Draw(imgl, &imldp) == E_INVALIDARG, "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"); + ok( IImageList_Remove(imgl, 0) == S_OK, "removing 1st bitmap\n"); + ok( IImageList_Remove(imgl, 0) == S_OK, "removing 2nd bitmap\n"); + ok( IImageList_Remove(imgl, 0) == S_OK, "removing 3rd bitmap\n"); /* destroy it */ - ok(SUCCEEDED(IImageList_Release(imgl)), "release imagelist failed\n"); + IImageList_Release(imgl); /* bitmaps should not be deleted by the imagelist */ ok(DeleteObject(hbm1),"bitmap 1 can't be deleted\n"); @@ -1653,7 +1733,7 @@ static void DoTest3_v6(void) DestroyWindow(hwndfortest); } -static void testMerge_v6(void) +static void test_IImageList_Merge(void) { HIMAGELIST himl1, himl2; IImageList *imgl1, *imgl2, *merge; @@ -1678,16 +1758,24 @@ static void testMerge_v6(void) imgl1 = (IImageList *) himl1; imgl2 = (IImageList *) himl2; - ok(SUCCEEDED(IImageList_ReplaceIcon(imgl2, -1, hicon1, &ret)) && (ret == 0),"add icon1 to himl2 failed\n"); + ret = -1; + ok( IImageList_ReplaceIcon(imgl2, -1, hicon1, &ret) == S_OK && (ret == 0),"add icon1 to himl2 failed\n"); + +if (0) +{ + /* null cases that crash on native */ + IImageList_Merge(imgl1, -1, NULL, 0, 0, 0, &IID_IImageList, (void**)&merge); + IImageList_Merge(imgl1, -1, (IUnknown*) imgl2, 0, 0, 0, &IID_IImageList, NULL); +} /* 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); + ok(hr == S_OK, "merge himl1,-1 failed\n"); + if (hr == S_OK) 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); + ok(hr == S_OK, "merge himl1,0 failed\n"); + if (hr == S_OK) IImageList_Release(merge); /* Same happens if himl2 is empty */ IImageList_Release(imgl2); @@ -1697,30 +1785,32 @@ static void testMerge_v6(void) 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); + ok(hr == S_OK, "merge himl2,-1 failed\n"); + if (hr == S_OK) 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); + ok(hr == S_OK, "merge himl2,0 failed\n"); + if (hr == S_OK) 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"); + ret = -1; + ok( IImageList_ReplaceIcon(imgl2, -1, hicon1, &ret) == S_OK && (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); + ok(hr == S_OK, "merge himl2 with itself failed\n"); + if (hr == S_OK) 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"); + ret = -1; + ok( IImageList_ReplaceIcon(imgl1, -1, hicon1, &ret) == S_OK && (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); + ok(hr == S_OK, "merge himl1 with himl2 failed\n"); + if (hr == S_OK) 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); + ok(hr == S_OK, "merge himl1 with himl2 8,16 failed\n"); + if (hr == S_OK) IImageList_Release(merge); IImageList_Release(imgl1); IImageList_Release(imgl2); @@ -1729,6 +1819,181 @@ static void testMerge_v6(void) DestroyWindow(hwnd); } +static void test_iconsize(void) +{ + HIMAGELIST himl; + INT cx, cy; + BOOL ret; + + himl = ImageList_Create(16, 16, ILC_COLOR16, 0, 3); + /* null pointers, not zero imagelist dimensions */ + ret = ImageList_GetIconSize(himl, NULL, NULL); + ok(!ret, "got %d\n", ret); + + /* doesn't touch return pointers */ + cx = 0x1abe11ed; + ret = ImageList_GetIconSize(himl, &cx, NULL); + ok(!ret, "got %d\n", ret); + ok(cx == 0x1abe11ed, "got %d\n", cx); + + cy = 0x1abe11ed; + ret = ImageList_GetIconSize(himl, NULL, &cy); + ok(!ret, "got %d\n", ret); + ok(cy == 0x1abe11ed, "got %d\n", cy); + + ImageList_Destroy(himl); + + ret = ImageList_GetIconSize((HIMAGELIST)0xdeadbeef, &cx, &cy); + ok(!ret, "got %d\n", ret); +} + +static void test_create_destroy(void) +{ + HIMAGELIST himl; + BOOL rc; + + /* list with zero or negative image dimensions */ + himl = ImageList_Create(0, 0, ILC_COLOR16, 0, 3); + ok(himl == NULL, "got %p\n", himl); + + himl = ImageList_Create(0, 16, ILC_COLOR16, 0, 3); + ok(himl == NULL, "got %p\n", himl); + + himl = ImageList_Create(16, 0, ILC_COLOR16, 0, 3); + ok(himl == NULL, "got %p\n", himl); + + himl = ImageList_Create(16, -1, ILC_COLOR16, 0, 3); + ok(himl == NULL, "got %p\n", himl); + + himl = ImageList_Create(-1, 16, ILC_COLOR16, 0, 3); + ok(himl == NULL, "got %p\n", himl); + + rc = ImageList_Destroy((HIMAGELIST)0xdeadbeef); + ok(rc == FALSE, "ImageList_Destroy(0xdeadbeef) should fail and not crash\n"); +} + +static void test_IImageList_Clone(void) +{ + IImageList *imgl, *imgl2; + HIMAGELIST himl; + HRESULT hr; + ULONG ref; + + himl = ImageList_Create(16, 16, ILC_COLOR16, 0, 3); + imgl = (IImageList*)himl; + +if (0) +{ + /* crashes on native */ + IImageList_Clone(imgl, &IID_IImageList, NULL); +} + + hr = IImageList_Clone(imgl, &IID_IImageList, (void**)&imgl2); + ok(hr == S_OK, "got 0x%08x\n", hr); + ref = IImageList_Release(imgl2); + ok(ref == 0, "got %u\n", ref); + + IImageList_Release(imgl); +} + +static void test_IImageList_GetBkColor(void) +{ + IImageList *imgl; + HIMAGELIST himl; + COLORREF color; + HRESULT hr; + + himl = ImageList_Create(16, 16, ILC_COLOR16, 0, 3); + imgl = (IImageList*)himl; + +if (0) +{ + /* crashes on native */ + IImageList_GetBkColor(imgl, NULL); +} + + hr = IImageList_GetBkColor(imgl, &color); + ok(hr == S_OK, "got 0x%08x\n", hr); + + IImageList_Release(imgl); +} + +static void test_IImageList_SetBkColor(void) +{ + IImageList *imgl; + HIMAGELIST himl; + COLORREF color; + HRESULT hr; + + himl = ImageList_Create(16, 16, ILC_COLOR16, 0, 3); + imgl = (IImageList*)himl; + +if (0) +{ + /* crashes on native */ + IImageList_SetBkColor(imgl, RGB(0, 0, 0), NULL); +} + + hr = IImageList_SetBkColor(imgl, CLR_NONE, &color); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = IImageList_SetBkColor(imgl, CLR_NONE, &color); + ok(hr == S_OK, "got 0x%08x\n", hr); + + color = 0xdeadbeef; + hr = IImageList_GetBkColor(imgl, &color); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(color == CLR_NONE, "got %x\n", color); + + IImageList_Release(imgl); +} + +static void test_IImageList_GetImageCount(void) +{ + IImageList *imgl; + HIMAGELIST himl; + int count; + HRESULT hr; + + himl = ImageList_Create(16, 16, ILC_COLOR16, 0, 3); + imgl = (IImageList*)himl; + +if (0) +{ + /* crashes on native */ + IImageList_GetImageCount(imgl, NULL); +} + + count = -1; + hr = IImageList_GetImageCount(imgl, &count); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(count == 0, "got %d\n", count); + + IImageList_Release(imgl); +} + +static void test_IImageList_GetIconSize(void) +{ + IImageList *imgl; + HIMAGELIST himl; + int cx, cy; + HRESULT hr; + + himl = ImageList_Create(16, 16, ILC_COLOR16, 0, 3); + imgl = (IImageList*)himl; + + hr = IImageList_GetIconSize(imgl, NULL, NULL); + ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + + hr = IImageList_GetIconSize(imgl, &cx, NULL); + ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + + hr = IImageList_GetIconSize(imgl, NULL, &cy); + ok(hr == E_INVALIDARG, "got 0x%08x\n", hr); + + IImageList_Release(imgl); +} + START_TEST(imagelist) { ULONG_PTR ctx_cookie; @@ -1744,12 +2009,14 @@ START_TEST(imagelist) InitCommonControls(); - testHotspot(); - DoTest1(); - DoTest2(); - DoTest3(); - testMerge(); + test_create_destroy(); + test_hotspot(); + test_add_remove(); + test_imagecount(); + test_DrawIndirect(); + test_merge(); test_imagelist_storage(); + test_iconsize(); FreeLibrary(hComCtl32); @@ -1774,10 +2041,16 @@ START_TEST(imagelist) test_shell_imagelist(); test_iimagelist(); - testHotspot_v6(); - DoTest1_v6(); - DoTest3_v6(); - testMerge_v6(); + test_hotspot_v6(); + test_IImageList_Add_Remove(); + test_IImageList_Get_SetImageCount(); + test_IImageList_Draw(); + test_IImageList_Merge(); + test_IImageList_Clone(); + test_IImageList_GetBkColor(); + test_IImageList_SetBkColor(); + test_IImageList_GetImageCount(); + test_IImageList_GetIconSize(); CoUninitialize(); diff --git a/rostests/winetests/comctl32/ipaddress.c b/rostests/winetests/comctl32/ipaddress.c index 85f92b1d582..96540cbe68e 100644 --- a/rostests/winetests/comctl32/ipaddress.c +++ b/rostests/winetests/comctl32/ipaddress.c @@ -20,7 +20,6 @@ #include #include -#include #include "wine/test.h" diff --git a/rostests/winetests/comctl32/listview.c b/rostests/winetests/comctl32/listview.c index 6ef82bb359a..b3df59e7c63 100644 --- a/rostests/winetests/comctl32/listview.c +++ b/rostests/winetests/comctl32/listview.c @@ -3,7 +3,7 @@ * * Copyright 2006 Mike McCormack for CodeWeavers * Copyright 2007 George Gov - * Copyright 2009 Nikolay Sivov + * Copyright 2009-2011 Nikolay Sivov * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -59,6 +59,10 @@ static INT notifyFormat; static BOOL g_is_below_5; /* item data passed to LVN_GETDISPINFOA */ static LVITEMA g_itema; +/* alter notification code A->W */ +static BOOL g_disp_A_to_W; +/* dispinfo data sent with LVN_LVN_ENDLABELEDIT */ +static NMLVDISPINFO g_editbox_disp_info; static HWND subclass_editbox(HWND hwndListview); @@ -301,6 +305,13 @@ static const struct message listview_destroy[] = { { 0 } }; +static const struct message listview_header_changed_seq[] = { + { LVM_SETCOLUMNA, sent }, + { WM_NOTIFY, sent|id|defwinproc, 0, 0, LISTVIEW_ID }, + { WM_NOTIFY, sent|id|defwinproc, 0, 0, LISTVIEW_ID }, + { 0 } +}; + static LRESULT WINAPI parent_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { static LONG defwndproc_counter = 0; @@ -338,17 +349,36 @@ static LRESULT WINAPI parent_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LP switch (((NMHDR*)lParam)->code) { case LVN_BEGINLABELEDIT: + { + HWND edit = NULL; + /* subclass edit box */ if (!blockEdit) - subclass_editbox(((NMHDR*)lParam)->hwndFrom); + edit = subclass_editbox(((NMHDR*)lParam)->hwndFrom); + + if (edit) + { + INT len = SendMessageA(edit, EM_GETLIMITTEXT, 0, 0); + ok(len == 259 || broken(len == 260) /* includes NULL in NT4 */, + "text limit %d, expected 259\n", len); + } return blockEdit; - + } case LVN_ENDLABELEDIT: { + HWND edit; + /* always accept new item text */ NMLVDISPINFO *di = (NMLVDISPINFO*)lParam; - trace("LVN_ENDLABELEDIT: text=%s\n", di->item.pszText); + g_editbox_disp_info = *di; + trace("LVN_ENDLABELEDIT: text=%s\n", di->item.pszText ? di->item.pszText : "(null)"); + + /* edit control still available from this notification */ + edit = (HWND)SendMessageA(((NMHDR*)lParam)->hwndFrom, LVM_GETEDITCONTROL, 0, 0); + ok(IsWindow(edit), "expected valid edit control handle\n"); + ok((GetWindowLongA(edit, GWL_STYLE) & ES_MULTILINE) == 0, "edit is multiline\n"); + return TRUE; } case LVN_BEGINSCROLL: @@ -372,6 +402,20 @@ static LRESULT WINAPI parent_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LP { NMLVDISPINFOA *dispinfo = (NMLVDISPINFOA*)lParam; g_itema = dispinfo->item; + + if (g_disp_A_to_W && (dispinfo->item.mask & LVIF_TEXT)) + { + static const WCHAR testW[] = {'T','E','S','T',0}; + dispinfo->hdr.code = LVN_GETDISPINFOW; + memcpy(dispinfo->item.pszText, testW, sizeof(testW)); + } + + /* test control buffer size for text, 10 used to mask cases when control + is using caller buffer to process LVM_GETITEM for example */ + if (dispinfo->item.mask & LVIF_TEXT && dispinfo->item.cchTextMax > 10) + ok(dispinfo->item.cchTextMax == 260 || + broken(dispinfo->item.cchTextMax == 264) /* NT4 reports aligned size */, + "buffer size %d\n", dispinfo->item.cchTextMax); } break; case NM_HOVER: @@ -619,13 +663,12 @@ static void test_lvm_hittest_(HWND hwnd, INT x, INT y, INT item, UINT flags, UIN BOOL todo_item, BOOL todo_flags, int line) { LVHITTESTINFO lpht; - DWORD ret; + INT ret; lpht.pt.x = x; lpht.pt.y = y; lpht.iSubItem = 10; - trace("hittesting pt=(%d,%d)\n", lpht.pt.x, lpht.pt.y); ret = SendMessage(hwnd, LVM_HITTEST, 0, (LPARAM)&lpht); if (todo_item) @@ -663,12 +706,11 @@ static void test_lvm_subitemhittest_(HWND hwnd, INT x, INT y, INT item, INT subi BOOL todo_item, BOOL todo_subitem, BOOL todo_flags, int line) { LVHITTESTINFO lpht; - DWORD ret; + INT ret; lpht.pt.x = x; lpht.pt.y = y; - trace("subhittesting pt=(%d,%d)\n", lpht.pt.x, lpht.pt.y); ret = SendMessage(hwnd, LVM_SUBITEMHITTEST, 0, (LPARAM)&lpht); if (todo_item) @@ -707,7 +749,7 @@ static void test_lvm_subitemhittest_(HWND hwnd, INT x, INT y, INT item, INT subi static void test_images(void) { HWND hwnd; - DWORD r; + INT r; LVITEM item; HIMAGELIST himl; HBITMAP hbmp; @@ -736,6 +778,8 @@ static void test_images(void) ok(r == 0, "should return zero\n"); r = SendMessage(hwnd, LVM_SETICONSPACING, 0, MAKELONG(100,50)); + ok(r != 0, "got 0\n"); + /* returns dimensions */ r = SendMessage(hwnd, LVM_GETITEMCOUNT, 0, 0); @@ -757,6 +801,7 @@ static void test_images(void) memset(&r1, 0, sizeof r1); r1.left = LVIR_ICON; r = SendMessage(hwnd, LVM_GETITEMRECT, 0, (LPARAM) &r1); + expect(1, r); r = SendMessage(hwnd, LVM_DELETEALLITEMS, 0, 0); ok(r == TRUE, "should not fail\n"); @@ -769,6 +814,7 @@ static void test_images(void) memset(&r2, 0, sizeof r2); r2.left = LVIR_ICON; r = SendMessage(hwnd, LVM_GETITEMRECT, 0, (LPARAM) &r2); + expect(1, r); ok(!memcmp(&r1, &r2, sizeof r1), "rectangle should be the same\n"); @@ -796,12 +842,13 @@ static void test_checkboxes(void) item.iSubItem = 0; item.pszText = text; r = SendMessage(hwnd, LVM_INSERTITEMA, 0, (LPARAM) &item); - ok(r == 0, "ret %d\n", r); + expect(0, r); item.iItem = 0; item.mask = LVIF_STATE; item.stateMask = 0xffff; r = SendMessage(hwnd, LVM_GETITEMA, 0, (LPARAM) &item); + expect(1, r); ok(item.state == 0xfccc, "state %x\n", item.state); /* Don't set LVIF_STATE */ @@ -812,22 +859,24 @@ static void test_checkboxes(void) item.iSubItem = 0; item.pszText = text; r = SendMessage(hwnd, LVM_INSERTITEMA, 0, (LPARAM) &item); - ok(r == 1, "ret %d\n", r); + expect(1, r); item.iItem = 1; item.mask = LVIF_STATE; item.stateMask = 0xffff; r = SendMessage(hwnd, LVM_GETITEMA, 0, (LPARAM) &item); + expect(1, r); ok(item.state == 0, "state %x\n", item.state); r = SendMessage(hwnd, LVM_SETEXTENDEDLISTVIEWSTYLE, LVS_EX_CHECKBOXES, LVS_EX_CHECKBOXES); - ok(r == 0, "should return zero\n"); + expect(0, r); /* Having turned on checkboxes, check that all existing items are set to 0x1000 (unchecked) */ item.iItem = 0; item.mask = LVIF_STATE; item.stateMask = 0xffff; r = SendMessage(hwnd, LVM_GETITEMA, 0, (LPARAM) &item); + expect(1, r); if (item.state != 0x1ccc) { win_skip("LVS_EX_CHECKBOXES style is unavailable. Skipping.\n"); @@ -841,12 +890,13 @@ static void test_checkboxes(void) item.state = 0; item.pszText = text2; r = SendMessage(hwnd, LVM_INSERTITEMA, 0, (LPARAM) &item); - ok(r == 2, "ret %d\n", r); + expect(2, r); item.iItem = 2; item.mask = LVIF_STATE; item.stateMask = 0xffff; r = SendMessage(hwnd, LVM_GETITEMA, 0, (LPARAM) &item); + expect(1, r); ok(item.state == 0x1000, "state %x\n", item.state); /* Add a further item this time specifying a state and still its state goes to 0x1000 */ @@ -856,12 +906,13 @@ static void test_checkboxes(void) item.state = 0x2aaa; item.pszText = text3; r = SendMessage(hwnd, LVM_INSERTITEMA, 0, (LPARAM) &item); - ok(r == 3, "ret %d\n", r); + expect(3, r); item.iItem = 3; item.mask = LVIF_STATE; item.stateMask = 0xffff; r = SendMessage(hwnd, LVM_GETITEMA, 0, (LPARAM) &item); + expect(1, r); ok(item.state == 0x1aaa, "state %x\n", item.state); /* Set an item's state to checked */ @@ -870,11 +921,13 @@ static void test_checkboxes(void) item.stateMask = 0xf000; item.state = 0x2000; r = SendMessage(hwnd, LVM_SETITEMA, 0, (LPARAM) &item); + expect(1, r); item.iItem = 3; item.mask = LVIF_STATE; item.stateMask = 0xffff; r = SendMessage(hwnd, LVM_GETITEMA, 0, (LPARAM) &item); + expect(1, r); ok(item.state == 0x2aaa, "state %x\n", item.state); /* Check that only the bits we asked for are returned, @@ -885,6 +938,7 @@ static void test_checkboxes(void) item.stateMask = 0xf000; item.state = 0xffff; r = SendMessage(hwnd, LVM_GETITEMA, 0, (LPARAM) &item); + expect(1, r); ok(item.state == 0x2000, "state %x\n", item.state); /* Set the style again and check that doesn't change an item's state */ @@ -895,6 +949,7 @@ static void test_checkboxes(void) item.mask = LVIF_STATE; item.stateMask = 0xffff; r = SendMessage(hwnd, LVM_GETITEMA, 0, (LPARAM) &item); + expect(1, r); ok(item.state == 0x2aaa, "state %x\n", item.state); /* Unsetting the checkbox extended style doesn't change an item's state */ @@ -905,16 +960,18 @@ static void test_checkboxes(void) item.mask = LVIF_STATE; item.stateMask = 0xffff; r = SendMessage(hwnd, LVM_GETITEMA, 0, (LPARAM) &item); + expect(1, r); ok(item.state == 0x2aaa, "state %x\n", item.state); /* Now setting the style again will change an item's state */ r = SendMessage(hwnd, LVM_SETEXTENDEDLISTVIEWSTYLE, LVS_EX_CHECKBOXES, LVS_EX_CHECKBOXES); - ok(r == 0, "ret %x\n", r); + expect(0, r); item.iItem = 3; item.mask = LVIF_STATE; item.stateMask = 0xffff; r = SendMessage(hwnd, LVM_GETITEMA, 0, (LPARAM) &item); + expect(1, r); ok(item.state == 0x1aaa, "state %x\n", item.state); /* Toggle checkbox tests (bug 9934) */ @@ -931,6 +988,7 @@ static void test_checkboxes(void) item.mask = LVIF_STATE; item.stateMask = 0xffff; r = SendMessage(hwnd, LVM_GETITEMA, 0, (LPARAM) &item); + expect(1, r); ok(item.state == 0x1aab, "state %x\n", item.state); r = SendMessage(hwnd, WM_KEYDOWN, VK_SPACE, 0); @@ -942,6 +1000,7 @@ static void test_checkboxes(void) item.mask = LVIF_STATE; item.stateMask = 0xffff; r = SendMessage(hwnd, LVM_GETITEMA, 0, (LPARAM) &item); + expect(1, r); ok(item.state == 0x2aab, "state %x\n", item.state); r = SendMessage(hwnd, WM_KEYDOWN, VK_SPACE, 0); @@ -953,6 +1012,7 @@ static void test_checkboxes(void) item.mask = LVIF_STATE; item.stateMask = 0xffff; r = SendMessage(hwnd, LVM_GETITEMA, 0, (LPARAM) &item); + expect(1, r); ok(item.state == 0x1aab, "state %x\n", item.state); DestroyWindow(hwnd); @@ -961,7 +1021,7 @@ static void test_checkboxes(void) static void insert_column(HWND hwnd, int idx) { LVCOLUMN column; - DWORD rc; + INT rc; memset(&column, 0xcc, sizeof(column)); column.mask = LVCF_SUBITEM; @@ -976,7 +1036,7 @@ static void insert_item(HWND hwnd, int idx) static CHAR text[] = "foo"; LVITEMA item; - DWORD rc; + INT rc; memset(&item, 0xcc, sizeof (item)); item.mask = LVIF_TEXT; @@ -991,10 +1051,11 @@ static void insert_item(HWND hwnd, int idx) static void test_items(void) { const LPARAM lparamTest = 0x42; + static CHAR text[] = "Text"; + char buffA[5]; HWND hwnd; LVITEMA item; DWORD r; - static CHAR text[] = "Text"; hwnd = CreateWindowEx(0, "SysListView32", "foo", LVS_REPORT, 10, 10, 100, 200, hwndparent, NULL, NULL, NULL); @@ -1017,7 +1078,7 @@ static void test_items(void) item.iItem = 0; item.iSubItem = 0; r = SendMessage(hwnd, LVM_INSERTITEMA, 0, (LPARAM) &item); - ok(r == 0, "ret %d\n", r); + expect(0, r); /* get */ memset (&item, 0xcc, sizeof (item)); item.mask = LVIF_STATE; @@ -1026,7 +1087,7 @@ static void test_items(void) item.iItem = 0; item.iSubItem = 0; r = SendMessage(hwnd, LVM_GETITEMA, 0, (LPARAM) &item); - ok(r != 0, "ret %d\n", r); + expect(1, r); ok(item.state & LVIS_SELECTED, "Expected LVIS_SELECTED\n"); SendMessage(hwnd, LVM_DELETEITEM, 0, 0); @@ -1039,7 +1100,7 @@ static void test_items(void) item.iItem = 0; item.iSubItem = 0; r = SendMessage(hwnd, LVM_INSERTITEMA, 0, (LPARAM) &item); - ok(r == 0, "ret %d\n", r); + expect(0, r); /* get */ memset (&item, 0xcc, sizeof (item)); item.mask = LVIF_STATE; @@ -1048,7 +1109,7 @@ static void test_items(void) item.iItem = 0; item.iSubItem = 0; r = SendMessage(hwnd, LVM_GETITEMA, 0, (LPARAM) &item); - ok(r != 0, "ret %d\n", r); + expect(1, r); ok(item.state & LVIS_FOCUSED, "Expected LVIS_FOCUSED\n"); SendMessage(hwnd, LVM_DELETEITEM, 0, 0); @@ -1061,7 +1122,7 @@ static void test_items(void) item.iItem = 0; item.iSubItem = 0; r = SendMessage(hwnd, LVM_INSERTITEMA, 0, (LPARAM) &item); - ok(r == 0, "ret %d\n", r); + expect(0, r); /* get */ memset (&item, 0xcc, sizeof (item)); item.mask = LVIF_STATE; @@ -1070,7 +1131,7 @@ static void test_items(void) item.iItem = 0; item.iSubItem = 0; r = SendMessage(hwnd, LVM_GETITEMA, 0, (LPARAM) &item); - ok(r != 0, "ret %d\n", r); + expect(1, r); ok(item.state & LVIS_CUT, "Expected LVIS_CUT\n"); SendMessage(hwnd, LVM_DELETEITEM, 0, 0); @@ -1081,7 +1142,7 @@ static void test_items(void) item.iSubItem = 0; item.lParam = lparamTest; r = SendMessage(hwnd, LVM_INSERTITEMA, 0, (LPARAM) &item); - ok(r == 0, "ret %d\n", r); + expect(0, r); /* Test getting of the param */ memset (&item, 0xcc, sizeof (item)); @@ -1089,7 +1150,7 @@ static void test_items(void) item.iItem = 0; item.iSubItem = 0; r = SendMessage(hwnd, LVM_GETITEMA, 0, (LPARAM) &item); - ok(r != 0, "ret %d\n", r); + expect(1, r); ok(item.lParam == lparamTest, "got lParam %lx, expected %lx\n", item.lParam, lparamTest); /* Set up a subitem */ @@ -1099,7 +1160,56 @@ static void test_items(void) item.iSubItem = 1; item.pszText = text; r = SendMessage(hwnd, LVM_SETITEMA, 0, (LPARAM) &item); - ok(r != 0, "ret %d\n", r); + expect(1, r); + + item.mask = LVIF_TEXT; + item.iItem = 0; + item.iSubItem = 1; + item.pszText = buffA; + item.cchTextMax = sizeof(buffA); + r = SendMessage(hwnd, LVM_GETITEMA, 0, (LPARAM) &item); + expect(1, r); + ok(!memcmp(item.pszText, text, sizeof(text)), "got text %s, expected %s\n", item.pszText, text); + + /* set up with extra flag */ + /* 1. reset subitem text */ + item.mask = LVIF_TEXT; + item.iItem = 0; + item.iSubItem = 1; + item.pszText = NULL; + r = SendMessage(hwnd, LVM_SETITEMA, 0, (LPARAM) &item); + expect(1, r); + + item.mask = LVIF_TEXT; + item.iItem = 0; + item.iSubItem = 1; + item.pszText = buffA; + buffA[0] = 'a'; + item.cchTextMax = sizeof(buffA); + r = SendMessage(hwnd, LVM_GETITEMA, 0, (LPARAM) &item); + expect(1, r); + ok(item.pszText[0] == 0, "got %p\n", item.pszText); + + /* 2. set new text with extra flag specified */ + item.mask = LVIF_TEXT | LVIF_DI_SETITEM; + item.iItem = 0; + item.iSubItem = 1; + item.pszText = text; + r = SendMessage(hwnd, LVM_SETITEMA, 0, (LPARAM) &item); + ok(r == 1 || broken(r == 0) /* NT4 */, "ret %d\n", r); + + if (r == 1) + { + item.mask = LVIF_TEXT; + item.iItem = 0; + item.iSubItem = 1; + item.pszText = buffA; + buffA[0] = 'a'; + item.cchTextMax = sizeof(buffA); + r = SendMessage(hwnd, LVM_GETITEMA, 0, (LPARAM) &item); + expect(1, r); + ok(!memcmp(item.pszText, text, sizeof(text)), "got %s, expected %s\n", item.pszText, text); + } /* Query param from subitem: returns main item param */ memset (&item, 0xcc, sizeof (item)); @@ -1107,7 +1217,7 @@ static void test_items(void) item.iItem = 0; item.iSubItem = 1; r = SendMessage(hwnd, LVM_GETITEMA, 0, (LPARAM) &item); - ok(r != 0, "ret %d\n", r); + expect(1, r); ok(item.lParam == lparamTest, "got lParam %lx, expected %lx\n", item.lParam, lparamTest); /* Set up param on first subitem: no effect */ @@ -1117,7 +1227,7 @@ static void test_items(void) item.iSubItem = 1; item.lParam = lparamTest+1; r = SendMessage(hwnd, LVM_SETITEMA, 0, (LPARAM) &item); - ok(r == 0, "ret %d\n", r); + expect(0, r); /* Query param from subitem again: should still return main item param */ memset (&item, 0xcc, sizeof (item)); @@ -1125,7 +1235,7 @@ static void test_items(void) item.iItem = 0; item.iSubItem = 1; r = SendMessage(hwnd, LVM_GETITEMA, 0, (LPARAM) &item); - ok(r != 0, "ret %d\n", r); + expect(1, r); ok(item.lParam == lparamTest, "got lParam %lx, expected %lx\n", item.lParam, lparamTest); /**** Some tests of state highlighting ****/ @@ -1136,11 +1246,11 @@ static void test_items(void) item.state = LVIS_SELECTED; item.stateMask = LVIS_SELECTED | LVIS_DROPHILITED; r = SendMessage(hwnd, LVM_SETITEM, 0, (LPARAM) &item); - ok(r != 0, "ret %d\n", r); + expect(1, r); item.iSubItem = 1; item.state = LVIS_DROPHILITED; r = SendMessage(hwnd, LVM_SETITEM, 0, (LPARAM) &item); - ok(r != 0, "ret %d\n", r); + expect(1, r); memset (&item, 0xcc, sizeof (item)); item.mask = LVIF_STATE; @@ -1148,11 +1258,11 @@ static void test_items(void) item.iSubItem = 0; item.stateMask = -1; r = SendMessage(hwnd, LVM_GETITEM, 0, (LPARAM) &item); - ok(r != 0, "ret %d\n", r); + expect(1, r); ok(item.state == LVIS_SELECTED, "got state %x, expected %x\n", item.state, LVIS_SELECTED); item.iSubItem = 1; r = SendMessage(hwnd, LVM_GETITEM, 0, (LPARAM) &item); - ok(r != 0, "ret %d\n", r); + expect(1, r); todo_wine ok(item.state == LVIS_DROPHILITED, "got state %x, expected %x\n", item.state, LVIS_DROPHILITED); /* some notnull but meaningless masks */ @@ -1161,13 +1271,13 @@ static void test_items(void) item.iItem = 0; item.iSubItem = 0; r = SendMessage(hwnd, LVM_GETITEMA, 0, (LPARAM) &item); - ok(r != 0, "ret %d\n", r); + expect(1, r); memset (&item, 0, sizeof(item)); item.mask = LVIF_DI_SETITEM; item.iItem = 0; item.iSubItem = 0; r = SendMessage(hwnd, LVM_GETITEMA, 0, (LPARAM) &item); - ok(r != 0, "ret %d\n", r); + expect(1, r); /* set text to callback value already having it */ r = SendMessage(hwnd, LVM_DELETEALLITEMS, 0, 0); @@ -1177,7 +1287,7 @@ static void test_items(void) item.pszText = LPSTR_TEXTCALLBACK; item.iItem = 0; r = SendMessage(hwnd, LVM_INSERTITEMA, 0, (LPARAM) &item); - ok(r == 0, "ret %d\n", r); + expect(0, r); memset (&item, 0, sizeof (item)); flush_sequences(sequences, NUM_MSG_SEQUENCES); @@ -1213,8 +1323,7 @@ static void test_columns(void) /* Check its width */ rc = SendMessageA(hwnd, LVM_GETCOLUMNWIDTH, 0, 0); - ok(rc == 10 || broken(rc == 0) /* win9x */, - "Inserting column with no mask failed to set width to 10 with %d\n", rc); + ok(rc == 10, "Inserting column with no mask failed to set width to 10 with %d\n", rc); DestroyWindow(hwnd); @@ -1226,16 +1335,16 @@ static void test_columns(void) column.mask = LVCF_WIDTH; column.cx = 100; rc = SendMessageA(hwnd, LVM_INSERTCOLUMNA, 0, (LPARAM)&column); - ok(rc == 0, "Inserting column failed with %d\n", rc); + expect(0, rc); column.cx = 200; rc = SendMessageA(hwnd, LVM_INSERTCOLUMNA, 1, (LPARAM)&column); - ok(rc == 1, "Inserting column failed with %d\n", rc); + expect(1, rc); flush_sequences(sequences, NUM_MSG_SEQUENCES); rc = SendMessageA(hwnd, LVM_GETCOLUMNORDERARRAY, 2, (LPARAM)&order); - ok(rc == 1, "Expected LVM_GETCOLUMNORDERARRAY to succeed\n"); + expect(1, rc); ok(order[0] == 0, "Expected order 0, got %d\n", order[0]); ok(order[1] == 1, "Expected order 1, got %d\n", order[1]); @@ -1253,7 +1362,7 @@ static void test_columns(void) item.mask = LVIF_TEXT; memset(&g_itema, 0, sizeof(g_itema)); rc = SendMessageA(hwnd, LVM_GETITEMA, 0, (LPARAM)&item); - ok(rc == 1, "got %d\n", rc); + expect(1, rc); ok(g_itema.iSubItem == 1, "got %d\n", g_itema.iSubItem); ok_sequence(sequences, PARENT_SEQ_INDEX, single_getdispinfo_parent_seq, @@ -1326,7 +1435,7 @@ static void test_create(void) col.mask = LVCF_WIDTH; col.cx = 100; r = SendMessage(hList, LVM_INSERTCOLUMN, 0, (LPARAM)&col); - ok(r == 0, "Expected 0 column's inserted\n"); + expect(0, r); hHeader = (HWND)SendMessage(hList, LVM_GETHEADER, 0, 0); ok(IsWindow(hHeader), "Header should be created\n"); ok(hHeader == GetDlgItem(hList, 0), "Expected header as dialog item\n"); @@ -1344,7 +1453,7 @@ static void test_create(void) col.mask = LVCF_WIDTH; col.cx = 100; r = SendMessage(hList, LVM_INSERTCOLUMN, 0, (LPARAM)&col); - ok(r == 0, "Expected 0 column's inserted\n"); + expect(0, r); hHeader = (HWND)SendMessage(hList, LVM_GETHEADER, 0, 0); ok(IsWindow(hHeader), "Header should be created\n"); ok(hHeader == GetDlgItem(hList, 0), "Expected header as dialog item\n"); @@ -1392,7 +1501,7 @@ static void test_create(void) col.mask = LVCF_WIDTH; col.cx = 100; r = SendMessage(hList, LVM_INSERTCOLUMN, 0, (LPARAM)&col); - ok(r == 0, "Expected 0 column's inserted\n"); + expect(0, r); hHeader = (HWND)SendMessage(hList, LVM_GETHEADER, 0, 0); ok(IsWindow(hHeader), "Header should be created\n"); ok(hHeader == GetDlgItem(hList, 0), "Expected header as dialog item\n"); @@ -1434,6 +1543,34 @@ static void test_create(void) ok(hHeader == GetDlgItem(hList, 0), "Expected header as dialog item\n"); DestroyWindow(hList); + /* setting LVS_EX_GRIDLINES creates header */ + hList = CreateWindow("SysListView32", "Test", LVS_REPORT, 0, 0, 100, 100, NULL, NULL, + GetModuleHandle(NULL), 0); + hHeader = (HWND)SendMessage(hList, LVM_GETHEADER, 0, 0); + ok(!IsWindow(hHeader), "Header shouldn't be created\n"); + ok(NULL == GetDlgItem(hList, 0), "NULL dialog item expected\n"); + SendMessage(hList, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_GRIDLINES); + hHeader = (HWND)SendMessage(hList, LVM_GETHEADER, 0, 0); + ok(IsWindow(hHeader) || + broken(!IsWindow(hHeader)), /* 4.7x common controls */ + "Header should be created\n"); + ok(hHeader == GetDlgItem(hList, 0), "Expected header as dialog item\n"); + DestroyWindow(hList); + + /* setting LVS_EX_FULLROWSELECT creates header */ + hList = CreateWindow("SysListView32", "Test", LVS_REPORT, 0, 0, 100, 100, NULL, NULL, + GetModuleHandle(NULL), 0); + hHeader = (HWND)SendMessage(hList, LVM_GETHEADER, 0, 0); + ok(!IsWindow(hHeader), "Header shouldn't be created\n"); + ok(NULL == GetDlgItem(hList, 0), "NULL dialog item expected\n"); + SendMessage(hList, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_FULLROWSELECT); + hHeader = (HWND)SendMessage(hList, LVM_GETHEADER, 0, 0); + ok(IsWindow(hHeader) || + broken(!IsWindow(hHeader)), /* 4.7x common controls */ + "Header should be created\n"); + ok(hHeader == GetDlgItem(hList, 0), "Expected header as dialog item\n"); + DestroyWindow(hList); + /* not report style accepts LVS_EX_HEADERDRAGDROP too */ hList = create_listview_control(LVS_ICON); SendMessage(hList, LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_HEADERDRAGDROP); @@ -1451,11 +1588,11 @@ static void test_create(void) rect.top = 1; rect.right = rect.bottom = -10; r = SendMessage(hList, LVM_GETSUBITEMRECT, -1, (LPARAM)&rect); - ok(r != 0, "Expected not-null LRESULT\n"); + expect(1, r); hHeader = (HWND)SendMessage(hList, LVM_GETHEADER, 0, 0); ok(!IsWindow(hHeader), "Header shouldn't be created\n"); - ok(NULL == GetDlgItem(hList, 0), "NULL dialog item expected\n"); + ok(GetDlgItem(hList, 0) == NULL, "NULL dialog item expected\n"); DestroyWindow(hList); @@ -1479,7 +1616,6 @@ static void test_redraw(void) flush_sequences(sequences, NUM_MSG_SEQUENCES); - trace("invalidate & update\n"); InvalidateRect(hwnd, NULL, TRUE); UpdateWindow(hwnd); ok_sequence(sequences, LISTVIEW_SEQ_INDEX, redraw_listview_seq, "redraw listview", FALSE); @@ -1495,7 +1631,7 @@ static void test_redraw(void) flush_sequences(sequences, NUM_MSG_SEQUENCES); r = SendMessageA(hwnd, WM_ERASEBKGND, (WPARAM)hdc, 0); - ok(r != 0, "Expected not zero result\n"); + ok(r == 1, "Expected not zero result\n"); ok_sequence(sequences, PARENT_FULL_SEQ_INDEX, forward_erasebkgnd_parent_seq, "forward WM_ERASEBKGND on CLR_NONE", FALSE); @@ -1504,7 +1640,7 @@ static void test_redraw(void) flush_sequences(sequences, NUM_MSG_SEQUENCES); r = SendMessageA(hwnd, WM_ERASEBKGND, (WPARAM)hdc, 0); - ok(r != 0, "Expected not zero result\n"); + expect(1, r); ok_sequence(sequences, PARENT_FULL_SEQ_INDEX, empty_seq, "don't forward WM_ERASEBKGND on non-CLR_NONE", FALSE); @@ -1516,7 +1652,7 @@ static void test_redraw(void) flush_sequences(sequences, NUM_MSG_SEQUENCES); r = SendMessageA(hwnd, WM_ERASEBKGND, (WPARAM)hdc, 0); - ok(r != 0, "Expected not zero result\n"); + expect(1, r); ok_sequence(sequences, PARENT_FULL_SEQ_INDEX, forward_erasebkgnd_parent_seq, "forward WM_ERASEBKGND on CLR_NONE", FALSE); @@ -1525,7 +1661,7 @@ static void test_redraw(void) flush_sequences(sequences, NUM_MSG_SEQUENCES); r = SendMessageA(hwnd, WM_ERASEBKGND, (WPARAM)hdc, 0); - todo_wine ok(r != 0, "Expected not zero result\n"); + todo_wine expect(1, r); ok_sequence(sequences, PARENT_FULL_SEQ_INDEX, empty_seq, "don't forward WM_ERASEBKGND on non-CLR_NONE", FALSE); @@ -1595,7 +1731,7 @@ static void test_icon_spacing(void) HWND hwnd; WORD w, h; - DWORD r; + INT r; hwnd = create_listview_control(LVS_ICON); ok(hwnd != NULL, "failed to create a listview window\n"); @@ -1613,8 +1749,6 @@ static void test_icon_spacing(void) flush_sequences(sequences, NUM_MSG_SEQUENCES); - trace("test icon spacing\n"); - r = SendMessage(hwnd, LVM_SETICONSPACING, 0, MAKELPARAM(20, 30)); ok(r == MAKELONG(w, h) || broken(r == MAKELONG(w, w)), /* win98 */ @@ -1641,8 +1775,7 @@ static void test_icon_spacing(void) static void test_color(void) { - /* SETBKCOLOR/GETBKCOLOR, SETTEXTCOLOR/GETTEXTCOLOR, SETTEXTBKCOLOR/GETTEXTBKCOLOR */ - + RECT rect; HWND hwnd; DWORD r; int i; @@ -1655,30 +1788,60 @@ static void test_color(void) flush_sequences(sequences, NUM_MSG_SEQUENCES); - trace("test color seq\n"); for (i = 0; i < 4; i++) { color = colors[i]; r = SendMessage(hwnd, LVM_SETBKCOLOR, 0, color); expect(TRUE, r); - r = SendMessage(hwnd, LVM_GETBKCOLOR, 0, color); + r = SendMessage(hwnd, LVM_GETBKCOLOR, 0, 0); expect(color, r); r = SendMessage(hwnd, LVM_SETTEXTCOLOR, 0, color); expect (TRUE, r); - r = SendMessage(hwnd, LVM_GETTEXTCOLOR, 0, color); + r = SendMessage(hwnd, LVM_GETTEXTCOLOR, 0, 0); expect(color, r); r = SendMessage(hwnd, LVM_SETTEXTBKCOLOR, 0, color); expect(TRUE, r); - r = SendMessage(hwnd, LVM_GETTEXTBKCOLOR, 0, color); + r = SendMessage(hwnd, LVM_GETTEXTBKCOLOR, 0, 0); expect(color, r); } ok_sequence(sequences, LISTVIEW_SEQ_INDEX, listview_color_seq, "test color seq", FALSE); - flush_sequences(sequences, NUM_MSG_SEQUENCES); + + /* invalidation test done separately to avoid a message chain mess */ + r = ValidateRect(hwnd, NULL); + expect(TRUE, r); + r = SendMessage(hwnd, LVM_SETBKCOLOR, 0, colors[0]); + expect(TRUE, r); + + rect.right = rect.bottom = 1; + r = GetUpdateRect(hwnd, &rect, TRUE); + todo_wine expect(FALSE, r); + ok(rect.right == 0 && rect.bottom == 0, "got update rectangle\n"); + + r = ValidateRect(hwnd, NULL); + expect(TRUE, r); + r = SendMessage(hwnd, LVM_SETTEXTCOLOR, 0, colors[0]); + expect(TRUE, r); + + rect.right = rect.bottom = 1; + r = GetUpdateRect(hwnd, &rect, TRUE); + todo_wine expect(FALSE, r); + ok(rect.right == 0 && rect.bottom == 0, "got update rectangle\n"); + + r = ValidateRect(hwnd, NULL); + expect(TRUE, r); + r = SendMessage(hwnd, LVM_SETTEXTBKCOLOR, 0, colors[0]); + expect(TRUE, r); + + rect.right = rect.bottom = 1; + r = GetUpdateRect(hwnd, &rect, TRUE); + todo_wine expect(FALSE, r); + ok(rect.right == 0 && rect.bottom == 0, "got update rectangle\n"); + DestroyWindow(hwnd); } @@ -1719,8 +1882,6 @@ static void test_item_count(void) flush_sequences(sequences, NUM_MSG_SEQUENCES); - trace("test item count\n"); - r = SendMessage(hwnd, LVM_GETITEMCOUNT, 0, 0); expect(0, r); @@ -1809,8 +1970,6 @@ static void test_item_position(void) flush_sequences(sequences, NUM_MSG_SEQUENCES); - trace("test item position\n"); - /* [item0] */ item0.mask = LVIF_TEXT; item0.iItem = 0; @@ -1872,7 +2031,7 @@ static void test_getorigin(void) hwnd = create_listview_control(LVS_ICON); ok(hwnd != NULL, "failed to create a listview window\n"); flush_sequences(sequences, NUM_MSG_SEQUENCES); - trace("test get origin results\n"); + r = SendMessage(hwnd, LVM_GETORIGIN, 0, (LPARAM)&position); expect(TRUE, r); flush_sequences(sequences, NUM_MSG_SEQUENCES); @@ -1881,7 +2040,7 @@ static void test_getorigin(void) hwnd = create_listview_control(LVS_SMALLICON); ok(hwnd != NULL, "failed to create a listview window\n"); flush_sequences(sequences, NUM_MSG_SEQUENCES); - trace("test get origin results\n"); + r = SendMessage(hwnd, LVM_GETORIGIN, 0, (LPARAM)&position); expect(TRUE, r); flush_sequences(sequences, NUM_MSG_SEQUENCES); @@ -1890,7 +2049,7 @@ static void test_getorigin(void) hwnd = create_listview_control(LVS_LIST); ok(hwnd != NULL, "failed to create a listview window\n"); flush_sequences(sequences, NUM_MSG_SEQUENCES); - trace("test get origin results\n"); + r = SendMessage(hwnd, LVM_GETORIGIN, 0, (LPARAM)&position); expect(FALSE, r); flush_sequences(sequences, NUM_MSG_SEQUENCES); @@ -1899,12 +2058,11 @@ static void test_getorigin(void) hwnd = create_listview_control(LVS_REPORT); ok(hwnd != NULL, "failed to create a listview window\n"); flush_sequences(sequences, NUM_MSG_SEQUENCES); - trace("test get origin results\n"); + r = SendMessage(hwnd, LVM_GETORIGIN, 0, (LPARAM)&position); expect(FALSE, r); flush_sequences(sequences, NUM_MSG_SEQUENCES); DestroyWindow(hwnd); - } static void test_multiselect(void) @@ -1919,7 +2077,7 @@ static void test_multiselect(void) } select_task; HWND hwnd; - DWORD r; + INT r; int i,j,item_count,selected_count; static const int items=5; BYTE kstate[256]; @@ -2118,8 +2276,8 @@ static void test_subitem_rect(void) rect.top = 1; rect.right = rect.bottom = 0; r = SendMessage(hwnd, LVM_GETSUBITEMRECT, -1, (LPARAM)&rect); + expect(1, r); - ok(r != 0, "Expected not-null LRESULT\n"); expect(100, rect.left); expect(250, rect.right); todo_wine @@ -2129,8 +2287,8 @@ todo_wine rect.top = 2; rect.right = rect.bottom = 0; r = SendMessage(hwnd, LVM_GETSUBITEMRECT, -1, (LPARAM)&rect); + expect(1, r); - ok(r != 0, "Expected not-null LRESULT\n"); expect(250, rect.left); expect(450, rect.right); todo_wine @@ -2143,7 +2301,7 @@ todo_wine rect.top = 1; rect.right = rect.bottom = 0; r = SendMessage(hwnd, LVM_GETSUBITEMRECT, 0, (LPARAM)&rect); - ok(r != 0, "Expected not-null LRESULT\n"); + expect(1, r); expect(100, rect.left); expect(250, rect.right); @@ -2151,7 +2309,7 @@ todo_wine rect.top = 1; rect.right = rect.bottom = 0; r = SendMessage(hwnd, LVM_GETSUBITEMRECT, 0, (LPARAM)&rect); - ok(r != 0, "Expected not-null LRESULT\n"); + expect(1, r); /* no icon attached - zero width rectangle, with no left padding */ expect(100, rect.left); expect(100, rect.right); @@ -2160,7 +2318,7 @@ todo_wine rect.top = 1; rect.right = rect.bottom = 0; r = SendMessage(hwnd, LVM_GETSUBITEMRECT, 0, (LPARAM)&rect); - ok(r != 0, "Expected not-null LRESULT\n"); + expect(1, r); /* same as full LVIR_BOUNDS */ expect(100, rect.left); expect(250, rect.right); @@ -2171,7 +2329,7 @@ todo_wine rect.top = 1; rect.right = rect.bottom = 0; r = SendMessage(hwnd, LVM_GETSUBITEMRECT, 0, (LPARAM)&rect); - ok(r != 0, "Expected not-null LRESULT\n"); + expect(1, r); expect(90, rect.left); expect(240, rect.right); @@ -2205,21 +2363,21 @@ todo_wine rect.top = 0; rect.right = rect.bottom = -1; r = SendMessage(hwnd, LVM_GETSUBITEMRECT, 2, (LPARAM)&rect); - ok(r == FALSE, "got %d\n", r); + expect(FALSE, r); /* for subitems rectangle is calculated even if there's no item added */ rect.left = LVIR_BOUNDS; rect.top = 1; rect.right = rect.bottom = -1; r = SendMessage(hwnd, LVM_GETSUBITEMRECT, 1, (LPARAM)&rect); - ok(r == TRUE, "got %d\n", r); + expect(TRUE, r); rect2.left = LVIR_BOUNDS; rect2.top = 1; rect2.right = rect2.bottom = -1; r = SendMessage(hwnd, LVM_GETSUBITEMRECT, 2, (LPARAM)&rect2); todo_wine { - ok(r == TRUE, "got %d\n", r); + expect(TRUE, r); expect(rect.right, rect2.right); expect(rect.left, rect2.left); expect(rect.bottom, rect2.top); @@ -2234,7 +2392,7 @@ todo_wine { rect.top = 0; rect.right = rect.bottom = -1; r = SendMessage(hwnd, LVM_GETSUBITEMRECT, 0, (LPARAM)&rect); - ok(r == TRUE, "got %d\n", r); + expect(TRUE, r); expect(0, rect.left); expect(600, rect.right); @@ -2242,7 +2400,7 @@ todo_wine { rect.top = 1; rect.right = rect.bottom = -1; r = SendMessage(hwnd, LVM_GETSUBITEMRECT, 0, (LPARAM)&rect); - ok(r == TRUE, "got %d\n", r); + expect(TRUE, r); expect(0, rect.left); expect(200, rect.right); @@ -2250,7 +2408,7 @@ todo_wine { rect2.top = 1; rect2.right = rect2.bottom = -1; r = SendMessage(hwnd, LVM_GETSUBITEMRECT, 1, (LPARAM)&rect2); - ok(r == TRUE, "got %d\n", r); + expect(TRUE, r); expect(0, rect2.left); expect(200, rect2.right); /* items are of the same height */ @@ -2262,7 +2420,7 @@ todo_wine { rect.top = 2; rect.right = rect.bottom = -1; r = SendMessage(hwnd, LVM_GETSUBITEMRECT, 0, (LPARAM)&rect); - ok(r == TRUE, "got %d\n", r); + expect(TRUE, r); expect(300, rect.left); expect(600, rect.right); @@ -2275,7 +2433,7 @@ todo_wine { rect.top = 1; rect.right = rect.bottom = -10; r = SendMessage(hwnd, LVM_GETSUBITEMRECT, -1, (LPARAM)&rect); - ok(r == 0, "Expected not-null LRESULT\n"); + expect(0, r); /* rect is unchanged */ expect(0, rect.left); expect(-10, rect.right); @@ -2295,7 +2453,7 @@ static void test_sorting(void) { HWND hwnd; LVITEMA item = {0}; - DWORD r; + INT r; LONG_PTR style; static CHAR names[][5] = {"A", "B", "C", "D", "0"}; CHAR buff[10]; @@ -2541,7 +2699,7 @@ static void test_ownerdata(void) hwnd = create_listview_control(LVS_OWNERDATA | LVS_REPORT); ok(hwnd != NULL, "failed to create a listview window\n"); res = SendMessageA(hwnd, LVM_SETITEMCOUNT, 1, 0); - ok(res != 0, "Expected LVM_SETITEMCOUNT to succeed\n"); + expect(1, res); res = SendMessageA(hwnd, LVM_GETSELECTEDCOUNT, 0, 0); expect(0, res); memset(&item, 0, sizeof(item)); @@ -2559,7 +2717,7 @@ static void test_ownerdata(void) hwnd = create_listview_control(LVS_OWNERDATA | LVS_REPORT); ok(hwnd != NULL, "failed to create a listview window\n"); res = SendMessageA(hwnd, LVM_SETITEMCOUNT, 1, 0); - ok(res != 0, "Expected LVM_SETITEMCOUNT to succeed\n"); + expect(1, res); res = SendMessageA(hwnd, LVM_GETITEMCOUNT, 0, 0); expect(1, res); memset(&item, 0, sizeof(item)); @@ -2575,7 +2733,7 @@ static void test_ownerdata(void) hwnd = create_listview_control(LVS_OWNERDATA | LVS_REPORT); ok(hwnd != NULL, "failed to create a listview window\n"); res = SendMessageA(hwnd, LVM_SETITEMCOUNT, 20, 0); - ok(res != 0, "Expected LVM_SETITEMCOUNT to succeed\n"); + expect(1, res); flush_sequences(sequences, NUM_MSG_SEQUENCES); @@ -2718,7 +2876,7 @@ static void test_ownerdata(void) hwnd = create_listview_control(LVS_OWNERDATA | LVS_REPORT); ok(hwnd != NULL, "failed to create a listview window\n"); res = SendMessageA(hwnd, LVM_SETITEMCOUNT, 1, 0); - ok(res != 0, "Expected LVM_SETITEMCOUNT to succeed\n"); + expect(1, res); flush_sequences(sequences, NUM_MSG_SEQUENCES); @@ -2992,7 +3150,8 @@ static void test_hittest(void) LVITEMA item; static CHAR text[] = "1234567890ABCDEFGHIJKLMNOPQRST"; POINT pos; - INT x, y; + INT x, y, i; + WORD vert; HIMAGELIST himl, himl2; HBITMAP hbmp; @@ -3018,8 +3177,13 @@ static void test_hittest(void) memset(&bounds, 0, sizeof(bounds)); bounds.left = LVIR_BOUNDS; r = SendMessage(hwnd, LVM_GETITEMRECT, 0, (LPARAM)&bounds); + expect(1, r); ok(bounds.bottom - bounds.top > 0, "Expected non zero item height\n"); ok(bounds.right - bounds.left > 0, "Expected non zero item width\n"); + r = SendMessage(hwnd, LVM_GETITEMSPACING, TRUE, 0); + vert = HIWORD(r); + ok(bounds.bottom - bounds.top == vert, + "Vertical spacing inconsistent (%d != %d)\n", bounds.bottom - bounds.top, vert); r = SendMessage(hwnd, LVM_GETITEMPOSITION, 0, (LPARAM)&pos); expect(TRUE, r); @@ -3052,8 +3216,18 @@ static void test_hittest(void) test_lvm_subitemhittest(hwnd, x, y, -1, -1, LVHT_NOWHERE, FALSE, FALSE, FALSE); /* subitem returned with -1 item too */ x = pos.x + 150; - y = -10; + y = bounds.top - vert; test_lvm_subitemhittest(hwnd, x, y, -1, 1, LVHT_NOWHERE, FALSE, FALSE, FALSE); + test_lvm_subitemhittest(hwnd, x, y - vert + 1, -1, 1, LVHT_NOWHERE, FALSE, FALSE, FALSE); + /* return values appear to underflow with negative indices */ + i = -2; + y = y - vert; + while (i > -10) { + test_lvm_subitemhittest(hwnd, x, y, i, 1, LVHT_ONITEMLABEL, TRUE, FALSE, TRUE); + test_lvm_subitemhittest(hwnd, x, y - vert + 1, i, 1, LVHT_ONITEMLABEL, TRUE, FALSE, TRUE); + y = y - vert; + i--; + } /* parent client area is 100x100 by default */ MoveWindow(hwnd, 0, 0, 300, 100, FALSE); x = pos.x + 150; /* outside column */ @@ -3100,7 +3274,7 @@ static void test_hittest(void) ok(r == 1, "should be one\n"); r = SendMessage(hwnd, LVM_SETIMAGELIST, LVSIL_STATE, (LPARAM)himl); - ok(r == 0, "should return zero\n"); + expect(0, r); item.mask = LVIF_IMAGE; item.iImage = 0; @@ -3136,7 +3310,7 @@ static void test_hittest(void) ok(himl2 == himl, "should return handle\n"); r = SendMessage(hwnd, LVM_SETIMAGELIST, LVSIL_SMALL, (LPARAM)himl); - ok(r == 0, "should return zero\n"); + expect(0, r); /* on item icon */ x = pos.x + 8; y = pos.y + (bounds.bottom - bounds.top) / 2; @@ -3261,7 +3435,7 @@ static void test_columnscreation(void) static void test_getitemrect(void) { HWND hwnd; - HIMAGELIST himl; + HIMAGELIST himl, himl_ret; HBITMAP hbm; RECT rect; DWORD r; @@ -3269,6 +3443,7 @@ static void test_getitemrect(void) LVCOLUMNA col; INT order[2]; POINT pt; + HDC hdc; /* rectangle isn't empty for empty text items */ hwnd = create_listview_control(LVS_LIST); @@ -3278,10 +3453,13 @@ static void test_getitemrect(void) r = SendMessage(hwnd, LVM_INSERTITEMA, 0, (LPARAM)&item); expect(0, r); rect.left = LVIR_LABEL; - SendMessage(hwnd, LVM_GETITEMRECT, 0, (LPARAM)&rect); + r = SendMessage(hwnd, LVM_GETITEMRECT, 0, (LPARAM)&rect); + expect(TRUE, r); expect(0, rect.left); expect(0, rect.top); - todo_wine expect(96, rect.right); + hdc = GetDC(hwnd); + todo_wine expect(((GetDeviceCaps(hdc, LOGPIXELSX) + 15) / 16) * 16, rect.right); + ReleaseDC(hwnd, hdc); DestroyWindow(hwnd); hwnd = create_listview_control(LVS_REPORT); @@ -3385,14 +3563,14 @@ static void test_getitemrect(void) hbm = CreateBitmap(16, 16, 1, 1, NULL); ok(hbm != NULL, "failed to create bitmap\n"); r = ImageList_Add(himl, hbm, 0); - ok(r == 0, "should be zero\n"); + expect(0, r); hbm = CreateBitmap(16, 16, 1, 1, NULL); ok(hbm != NULL, "failed to create bitmap\n"); r = ImageList_Add(himl, hbm, 0); - ok(r == 1, "should be one\n"); + expect(1, r); r = SendMessage(hwnd, LVM_SETIMAGELIST, LVSIL_STATE, (LPARAM)himl); - ok(r == 0, "should return zero\n"); + expect(0, r); item.mask = LVIF_STATE; item.state = INDEXTOSTATEIMAGEMASK(1); @@ -3419,11 +3597,11 @@ static void test_getitemrect(void) expect(18, rect.left); expect(50, rect.right); - r = SendMessage(hwnd, LVM_SETIMAGELIST, LVSIL_STATE, 0); - ok(r != 0, "should return current list handle\n"); + himl_ret = (HIMAGELIST)SendMessage(hwnd, LVM_SETIMAGELIST, LVSIL_STATE, 0); + ok(himl_ret == himl, "got %p, expected %p\n", himl_ret, himl); r = SendMessage(hwnd, LVM_SETIMAGELIST, LVSIL_SMALL, (LPARAM)himl); - ok(r == 0, "should return zero\n"); + expect(0, r); item.mask = LVIF_STATE | LVIF_IMAGE; item.iImage = 1; @@ -3511,10 +3689,11 @@ static void test_editbox(void) { static CHAR testitemA[] = "testitem"; static CHAR testitem1A[] = "testitem_quitelongname"; + static CHAR testitem2A[] = "testITEM_quitelongname"; static CHAR buffer[25]; HWND hwnd, hwndedit, hwndedit2, header; LVITEMA item; - DWORD r; + INT r; hwnd = create_listview_control(LVS_EDITLABELS | LVS_REPORT); ok(hwnd != NULL, "failed to create a listview window\n"); @@ -3607,8 +3786,11 @@ static void test_editbox(void) /* modify edit and notify control that it lost focus */ r = SendMessage(hwndedit, WM_SETTEXT, 0, (LPARAM)testitem1A); expect(TRUE, r); + g_editbox_disp_info.item.pszText = NULL; r = SendMessage(hwnd, WM_COMMAND, MAKEWPARAM(0, EN_KILLFOCUS), (LPARAM)hwndedit); expect(0, r); + ok(g_editbox_disp_info.item.pszText != NULL, "expected notification with not null text\n"); + memset(&item, 0, sizeof(item)); item.pszText = buffer; item.cchTextMax = sizeof(buffer); @@ -3618,6 +3800,29 @@ static void test_editbox(void) expect(lstrlen(item.pszText), r); ok(strcmp(buffer, testitem1A) == 0, "Expected item text to change\n"); ok(!IsWindow(hwndedit), "Expected Edit window to be freed\n"); + + /* change item name to differ in casing only */ + SetFocus(hwnd); + hwndedit = (HWND)SendMessage(hwnd, LVM_EDITLABEL, 0, 0); + ok(IsWindow(hwndedit), "Expected Edit window to be created\n"); + /* modify edit and notify control that it lost focus */ + r = SendMessage(hwndedit, WM_SETTEXT, 0, (LPARAM)testitem2A); + expect(TRUE, r); + g_editbox_disp_info.item.pszText = NULL; + r = SendMessage(hwnd, WM_COMMAND, MAKEWPARAM(0, EN_KILLFOCUS), (LPARAM)hwndedit); + expect(0, r); + ok(g_editbox_disp_info.item.pszText != NULL, "got %p\n", g_editbox_disp_info.item.pszText); + + memset(&item, 0, sizeof(item)); + item.pszText = buffer; + item.cchTextMax = sizeof(buffer); + item.iItem = 0; + item.iSubItem = 0; + r = SendMessage(hwnd, LVM_GETITEMTEXTA, 0, (LPARAM)&item); + expect(lstrlen(item.pszText), r); + ok(strcmp(buffer, testitem2A) == 0, "got %s, expected %s\n", buffer, testitem2A); + ok(!IsWindow(hwndedit), "Expected Edit window to be freed\n"); + /* end edit without saving */ SetFocus(hwnd); hwndedit = (HWND)SendMessage(hwnd, LVM_EDITLABEL, 0, 0); @@ -3642,7 +3847,7 @@ static void test_editbox(void) item.iSubItem = 0; r = SendMessage(hwnd, LVM_GETITEMTEXTA, 0, (LPARAM)&item); expect(lstrlen(item.pszText), r); - ok(strcmp(buffer, testitem1A) == 0, "Expected item text to change\n"); + ok(strcmp(buffer, testitem2A) == 0, "Expected item text to change\n"); /* LVM_EDITLABEL with -1 destroys current edit */ hwndedit = (HWND)SendMessage(hwnd, LVM_GETEDITCONTROL, 0, 0); @@ -3686,7 +3891,7 @@ static void test_editbox(void) ok_sequence(sequences, EDITBOX_SEQ_INDEX, editbox_create_pos, "edit box create - sizing", FALSE); - /* WM_COMMAND with EN_KILLFOCUS isn't forwared to parent */ + /* WM_COMMAND with EN_KILLFOCUS isn't forwarded to parent */ SetFocus(hwnd); hwndedit = (HWND)SendMessage(hwnd, LVM_EDITLABEL, 0, 0); ok(IsWindow(hwndedit), "Expected Edit window to be created\n"); @@ -3711,7 +3916,7 @@ static void test_notifyformat(void) CCM_SETUNICODEFORMAT == LVM_SETUNICODEFORMAT */ r = SendMessage(hwnd, LVM_GETUNICODEFORMAT, 0, 0); expect(0, r); - r = SendMessage(hwnd, WM_NOTIFYFORMAT, 0, NF_QUERY); + SendMessage(hwnd, WM_NOTIFYFORMAT, 0, NF_QUERY); /* set */ r = SendMessage(hwnd, LVM_SETUNICODEFORMAT, 1, 0); expect(0, r); @@ -3741,7 +3946,7 @@ static void test_notifyformat(void) r = SendMessage(hwnd, LVM_GETUNICODEFORMAT, 0, 0); expect(0, r); r = SendMessage(header, HDM_GETUNICODEFORMAT, 0, 0); - ok( r == 1 || broken(r == 0), /* win9x */ "Expected 1, got %d\n", r ); + ok( r == 1, "Expected 1, got %d\n", r ); r = SendMessage(hwnd, WM_NOTIFYFORMAT, 0, NF_QUERY); ok(r != 0, "Expected valid format\n"); @@ -3751,7 +3956,7 @@ static void test_notifyformat(void) r = SendMessage(hwnd, LVM_GETUNICODEFORMAT, 0, 0); expect(1, r); r = SendMessage(header, HDM_GETUNICODEFORMAT, 0, 0); - ok( r == 1 || broken(r == 0), /* win9x */ "Expected 1, got %d\n", r ); + ok( r == 1, "Expected 1, got %d\n", r ); notifyFormat = NFR_ANSI; r = SendMessage(hwnd, WM_NOTIFYFORMAT, 0, NF_REQUERY); @@ -3759,17 +3964,10 @@ static void test_notifyformat(void) r = SendMessage(hwnd, LVM_GETUNICODEFORMAT, 0, 0); expect(0, r); r = SendMessage(header, HDM_GETUNICODEFORMAT, 0, 0); - ok( r == 1 || broken(r == 0), /* win9x */ "Expected 1, got %d\n", r ); + ok( r == 1, "Expected 1, got %d\n", r ); DestroyWindow(hwnd); - /* try different unicode window combination and defaults */ - if (!GetModuleHandleW(NULL)) - { - win_skip("Additional notify format tests are incompatible with Win9x\n"); - return; - } - hwndparentW = create_parent_window(TRUE); ok(IsWindow(hwndparentW), "Unicode parent creation failed\n"); if (!IsWindow(hwndparentW)) return; @@ -3966,7 +4164,7 @@ static void test_canceleditlabel(void) hwndedit = (HWND)SendMessage(hwnd, LVM_EDITLABEL, 0, 0); ok(IsWindow(hwndedit), "Expected edit control to be created\n"); ret = SetWindowText(hwndedit, test1); - ok(ret != 0, "Expected edit text to change\n"); + expect(1, ret); ret = SendMessage(hwnd, LVM_CANCELEDITLABEL, 0, 0); expect(TRUE, ret); ok(!IsWindow(hwndedit), "Expected edit control to be destroyed\n"); @@ -3983,7 +4181,7 @@ static void test_canceleditlabel(void) static void test_mapidindex(void) { HWND hwnd; - DWORD ret; + INT ret; /* LVM_MAPINDEXTOID unsupported with LVS_OWNERDATA */ hwnd = create_listview_control(LVS_OWNERDATA | LVS_REPORT); @@ -4105,10 +4303,11 @@ todo_wine { static void test_getcolumnwidth(void) { HWND hwnd; - DWORD ret; + INT ret; DWORD_PTR style; LVCOLUMNA col; LVITEMA itema; + HDC hdc; /* default column width */ hwnd = create_listview_control(LVS_ICON); @@ -4132,7 +4331,9 @@ static void test_getcolumnwidth(void) memset(&itema, 0, sizeof(itema)); SendMessage(hwnd, LVM_INSERTITEMA, 0, (LPARAM)&itema); ret = SendMessage(hwnd, LVM_GETCOLUMNWIDTH, 0, 0); - todo_wine expect(96, ret); + hdc = GetDC(hwnd); + todo_wine expect(((GetDeviceCaps(hdc, LOGPIXELSX) + 15) / 16) * 16, ret); + ReleaseDC(hwnd, hdc); DestroyWindow(hwnd); } @@ -4254,37 +4455,39 @@ static void test_approximate_viewrect(void) } ret = SendMessage(hwnd, LVM_APPROXIMATEVIEWRECT, 11, MAKELPARAM(100,100)); - ok(MAKELONG(77,827)==ret,"Incorrect Approximate rect\n"); + expect(MAKELONG(77,827), ret); ret = SendMessage(hwnd, LVM_SETICONSPACING, 0, MAKELPARAM(50, 50)); + ok(ret != 0, "got 0\n"); + ret = SendMessage(hwnd, LVM_APPROXIMATEVIEWRECT, 11, MAKELPARAM(100,100)); - ok(MAKELONG(102,302)==ret,"Incorrect Approximate rect\n"); + expect(MAKELONG(102,302), ret); ret = SendMessage(hwnd, LVM_APPROXIMATEVIEWRECT, -1, MAKELPARAM(100,100)); - ok(MAKELONG(52,52)==ret,"Incorrect Approximate rect\n"); + expect(MAKELONG(52,52), ret); itema.pszText = test; ret = SendMessage(hwnd, LVM_SETITEMTEXT, 0, (LPARAM)&itema); expect(TRUE, ret); ret = SendMessage(hwnd, LVM_APPROXIMATEVIEWRECT, -1, MAKELPARAM(100,100)); - ok(MAKELONG(52,52)==ret,"Incorrect Approximate rect\n"); + expect(MAKELONG(52,52), ret); ret = SendMessage(hwnd, LVM_APPROXIMATEVIEWRECT, 0, MAKELPARAM(100,100)); - ok(MAKELONG(52,2)==ret,"Incorrect Approximate rect\n"); + expect(MAKELONG(52,2), ret); ret = SendMessage(hwnd, LVM_APPROXIMATEVIEWRECT, 1, MAKELPARAM(100,100)); - ok(MAKELONG(52,52)==ret,"Incorrect Approximate rect\n"); + expect(MAKELONG(52,52), ret); ret = SendMessage(hwnd, LVM_APPROXIMATEVIEWRECT, 2, MAKELPARAM(100,100)); - ok(MAKELONG(102,52)==ret,"Incorrect Approximate rect\n"); + expect(MAKELONG(102,52), ret); ret = SendMessage(hwnd, LVM_APPROXIMATEVIEWRECT, 3, MAKELPARAM(100,100)); - ok(MAKELONG(102,102)==ret,"Incorrect Approximate rect\n"); + expect(MAKELONG(102,102), ret); ret = SendMessage(hwnd, LVM_APPROXIMATEVIEWRECT, 4, MAKELPARAM(100,100)); - ok(MAKELONG(102,102)==ret,"Incorrect Approximate rect\n"); + expect(MAKELONG(102,102), ret); ret = SendMessage(hwnd, LVM_APPROXIMATEVIEWRECT, 5, MAKELPARAM(100,100)); - ok(MAKELONG(102,152)==ret,"Incorrect Approximate rect\n"); + expect(MAKELONG(102,152), ret); ret = SendMessage(hwnd, LVM_APPROXIMATEVIEWRECT, 6, MAKELPARAM(100,100)); - ok(MAKELONG(102,152)==ret,"Incorrect Approximate rect\n"); + expect(MAKELONG(102,152), ret); ret = SendMessage(hwnd, LVM_APPROXIMATEVIEWRECT, 7, MAKELPARAM(160,100)); - ok(MAKELONG(152,152)==ret,"Incorrect Approximate rect\n"); + expect(MAKELONG(152,152), ret); DestroyWindow(hwnd); } @@ -4294,7 +4497,7 @@ static void test_finditem(void) LVFINDINFOA fi; static char f[5]; HWND hwnd; - DWORD r; + INT r; hwnd = create_listview_control(LVS_REPORT); insert_item(hwnd, 0); @@ -4453,31 +4656,48 @@ static void test_destroynotify(void) static void test_header_notification(void) { + static char textA[] = "newtext"; HWND list, header; HDITEMA item; NMHEADER nmh; LVCOLUMNA col; - LRESULT ret; + DWORD ret; + BOOL r; list = create_listview_control(LVS_REPORT); - ok(list != 0, "failed to create listview window\n"); + ok(list != NULL, "failed to create listview window\n"); memset(&col, 0, sizeof(col)); col.mask = LVCF_WIDTH; col.cx = 100; ret = SendMessage(list, LVM_INSERTCOLUMNA, 0, (LPARAM)&col); - ok(!ret, "expected 0, got %ld\n", ret); + expect(0, ret); + + /* check list parent notification after header item changed, + this test should be placed before header subclassing to avoid + Listview -> Header messages to be logged */ + flush_sequences(sequences, NUM_MSG_SEQUENCES); + + col.mask = LVCF_TEXT; + col.pszText = textA; + r = SendMessage(list, LVM_SETCOLUMNA, 0, (LPARAM)&col); + expect(TRUE, r); + + ok_sequence(sequences, LISTVIEW_SEQ_INDEX, listview_header_changed_seq, + "header notify, listview", FALSE); + ok_sequence(sequences, PARENT_SEQ_INDEX, empty_seq, + "header notify, parent", FALSE); header = subclass_header(list); ret = SendMessage(header, HDM_GETITEMCOUNT, 0, 0); - ok(ret == 1, "expected header item count 1, got %ld\n", ret); + expect(1, ret); memset(&item, 0, sizeof(item)); item.mask = HDI_WIDTH; ret = SendMessage(header, HDM_GETITEMA, 0, (LPARAM)&item); - ok(ret, "HDM_GETITEM failed\n"); - ok(item.cxy == 100, "expected 100, got %d\n", item.cxy); + expect(1, ret); + expect(100, item.cxy); nmh.hdr.hwndFrom = header; nmh.hdr.idFrom = GetWindowLongPtr(header, GWLP_ID); @@ -4488,7 +4708,7 @@ static void test_header_notification(void) item.cxy = 50; nmh.pitem = &item; ret = SendMessage(list, WM_NOTIFY, 0, (LPARAM)&nmh); - ok(!ret, "WM_NOTIFY/HDN_ITEMCHANGED failed\n"); + expect(0, ret); DestroyWindow(list); } @@ -4500,7 +4720,7 @@ static void test_createdragimage(void) HWND list; list = create_listview_control(LVS_ICON); - ok(list != 0, "failed to create listview window\n"); + ok(list != NULL, "failed to create listview window\n"); insert_item(list, 0); @@ -4515,6 +4735,73 @@ static void test_createdragimage(void) DestroyWindow(list); } +static void test_dispinfo(void) +{ + static const char testA[] = "TEST"; + WCHAR buff[10]; + LVITEMA item; + HWND hwnd; + DWORD ret; + + hwnd = create_listview_control(LVS_ICON); + ok(hwnd != NULL, "failed to create listview window\n"); + + insert_item(hwnd, 0); + + memset(&item, 0, sizeof(item)); + item.pszText = LPSTR_TEXTCALLBACKA; + ret = SendMessageA(hwnd, LVM_SETITEMTEXTA, 0, (LPARAM)&item); + expect(1, ret); + + g_disp_A_to_W = TRUE; + item.pszText = (char*)buff; + item.cchTextMax = sizeof(buff)/sizeof(WCHAR); + ret = SendMessageA(hwnd, LVM_GETITEMTEXTA, 0, (LPARAM)&item); + ok(ret == sizeof(testA)-1, "got %d, expected 4\n", ret); + g_disp_A_to_W = FALSE; + + ok(memcmp(item.pszText, testA, sizeof(testA)) == 0, + "got %s, expected %s\n", item.pszText, testA); + + DestroyWindow(hwnd); +} + +static void test_LVM_SETITEMTEXT(void) +{ + static char testA[] = "TEST"; + LVITEMA item; + HWND hwnd; + DWORD ret; + + hwnd = create_listview_control(LVS_ICON); + ok(hwnd != NULL, "failed to create listview window\n"); + + insert_item(hwnd, 0); + + /* null item pointer */ + ret = SendMessage(hwnd, LVM_SETITEMTEXTA, 0, 0); + expect(FALSE, ret); + + ret = SendMessage(hwnd, LVM_SETITEMTEXTW, 0, 0); + expect(FALSE, ret); + + /* index out of bounds */ + item.pszText = testA; + item.cchTextMax = 0; /* ignored */ + item.iSubItem = 0; + + ret = SendMessageA(hwnd, LVM_SETITEMTEXTA, 1, (LPARAM)&item); + expect(FALSE, ret); + + ret = SendMessageA(hwnd, LVM_SETITEMTEXTA, -1, (LPARAM)&item); + expect(FALSE, ret); + + ret = SendMessageA(hwnd, LVM_SETITEMTEXTA, 0, (LPARAM)&item); + expect(TRUE, ret); + + DestroyWindow(hwnd); +} + START_TEST(listview) { HMODULE hComctl32; @@ -4578,6 +4865,8 @@ START_TEST(listview) test_hover(); test_destroynotify(); test_createdragimage(); + test_dispinfo(); + test_LVM_SETITEMTEXT(); if (!load_v6_module(&ctx_cookie, &hCtx)) { diff --git a/rostests/winetests/comctl32/misc.c b/rostests/winetests/comctl32/misc.c index 8f83260db17..5aff06f95ea 100644 --- a/rostests/winetests/comctl32/misc.c +++ b/rostests/winetests/comctl32/misc.c @@ -87,18 +87,15 @@ static void test_GetPtrAW(void) * Our implementation also crashes and we should probably leave * it like that. */ - count = -1; count = pStr_GetPtrA(NULL, NULL, destsize); trace("count : %d\n", count); } - count = 0; count = pStr_GetPtrA(source, NULL, 0); ok (count == sourcelen || broken(count == sourcelen - 1), /* win9x */ "Expected count to be %d, it was %d\n", sourcelen, count); - count = 0; strcpy(dest, desttest); count = pStr_GetPtrA(source, dest, 0); ok (count == sourcelen || @@ -108,26 +105,22 @@ static void test_GetPtrAW(void) broken(!lstrcmp(dest, "")), /* Win7 */ "Expected destination to not have changed\n"); - count = 0; count = pStr_GetPtrA(source, NULL, destsize); ok (count == sourcelen || broken(count == sourcelen - 1), /* win9x */ "Expected count to be %d, it was %d\n", sourcelen, count); - count = 0; count = pStr_GetPtrA(source, dest, destsize); ok (count == sourcelen || broken(count == sourcelen - 1), /* win9x */ "Expected count to be %d, it was %d\n", sourcelen, count); ok (!lstrcmp(source, dest), "Expected source and destination to be the same\n"); - count = -1; strcpy(dest, desttest); count = pStr_GetPtrA(NULL, dest, destsize); ok (count == 0, "Expected count to be 0, it was %d\n", count); ok (dest[0] == '\0', "Expected destination to be cut-off and 0 terminated\n"); - count = 0; destsize = 15; count = pStr_GetPtrA(source, dest, destsize); ok (count == 15 || diff --git a/rostests/winetests/comctl32/monthcal.c b/rostests/winetests/comctl32/monthcal.c index 30f682ff815..0585bb44ba7 100644 --- a/rostests/winetests/comctl32/monthcal.c +++ b/rostests/winetests/comctl32/monthcal.c @@ -28,12 +28,14 @@ #include "commctrl.h" #include "wine/test.h" +#include "v6util.h" #include #include #include "msg.h" #define expect(expected, got) ok(expected == got, "Expected %d, got %d\n", expected, got); #define expect_hex(expected, got) ok(expected == got, "Expected %x, got %x\n", expected, got); +#define expect_d(expected, got) ok(abs((expected) - (got)) <= 2, "Expected %d, got %d\n", expected, got); #define NUM_MSG_SEQUENCES 2 #define PARENT_SEQ_INDEX 0 @@ -83,45 +85,6 @@ static const struct message create_monthcal_multi_sel_style_seq[] = { { 0 } }; -static const struct message monthcal_color_seq[] = { - { MCM_GETCOLOR, sent|wparam|lparam, MCSC_BACKGROUND, 0}, - { MCM_SETCOLOR, sent|wparam|lparam, MCSC_BACKGROUND, RGB(0,0,0)}, - { MCM_GETCOLOR, sent|wparam|lparam, MCSC_BACKGROUND, 0}, - { MCM_SETCOLOR, sent|wparam|lparam, MCSC_BACKGROUND, RGB(255,255,255)}, - { MCM_GETCOLOR, sent|wparam|lparam, MCSC_BACKGROUND, 0}, - - { MCM_GETCOLOR, sent|wparam|lparam, MCSC_MONTHBK, 0}, - { MCM_SETCOLOR, sent|wparam|lparam, MCSC_MONTHBK, RGB(0,0,0)}, - { MCM_GETCOLOR, sent|wparam|lparam, MCSC_MONTHBK, 0}, - { MCM_SETCOLOR, sent|wparam|lparam, MCSC_MONTHBK, RGB(255,255,255)}, - { MCM_GETCOLOR, sent|wparam|lparam, MCSC_MONTHBK, 0}, - - { MCM_GETCOLOR, sent|wparam|lparam, MCSC_TEXT, 0}, - { MCM_SETCOLOR, sent|wparam|lparam, MCSC_TEXT, RGB(0,0,0)}, - { MCM_GETCOLOR, sent|wparam|lparam, MCSC_TEXT, 0}, - { MCM_SETCOLOR, sent|wparam|lparam, MCSC_TEXT, RGB(255,255,255)}, - { MCM_GETCOLOR, sent|wparam|lparam, MCSC_TEXT, 0}, - - { MCM_GETCOLOR, sent|wparam|lparam, MCSC_TITLEBK, 0}, - { MCM_SETCOLOR, sent|wparam|lparam, MCSC_TITLEBK, RGB(0,0,0)}, - { MCM_GETCOLOR, sent|wparam|lparam, MCSC_TITLEBK, 0}, - { MCM_SETCOLOR, sent|wparam|lparam, MCSC_TITLEBK, RGB(255,255,255)}, - { MCM_GETCOLOR, sent|wparam|lparam, MCSC_TITLEBK, 0}, - - { MCM_GETCOLOR, sent|wparam|lparam, MCSC_TITLETEXT, 0}, - { MCM_SETCOLOR, sent|wparam|lparam, MCSC_TITLETEXT, RGB(0,0,0)}, - { MCM_GETCOLOR, sent|wparam|lparam, MCSC_TITLETEXT, 0}, - { MCM_SETCOLOR, sent|wparam|lparam, MCSC_TITLETEXT, RGB(255,255,255)}, - { MCM_GETCOLOR, sent|wparam|lparam, MCSC_TITLETEXT, 0}, - - { MCM_GETCOLOR, sent|wparam|lparam, MCSC_TRAILINGTEXT, 0}, - { MCM_SETCOLOR, sent|wparam|lparam, MCSC_TRAILINGTEXT, RGB(0,0,0)}, - { MCM_GETCOLOR, sent|wparam|lparam, MCSC_TRAILINGTEXT, 0}, - { MCM_SETCOLOR, sent|wparam|lparam, MCSC_TRAILINGTEXT, RGB(255,255,255)}, - { MCM_GETCOLOR, sent|wparam|lparam, MCSC_TRAILINGTEXT, 0}, - { 0 } -}; - static const struct message monthcal_curr_date_seq[] = { { MCM_SETCURSEL, sent|wparam, 0}, { WM_PAINT, sent|wparam|lparam|defwinproc, 0, 0}, @@ -292,26 +255,6 @@ static const struct message destroy_monthcal_multi_sel_style_seq[] = { { 0 } }; -/* expected message sequence for parent window*/ -static const struct message destroy_parent_seq[] = { - { 0x0090, sent|optional }, /* Vista */ - { WM_WINDOWPOSCHANGING, sent|wparam, 0}, - { WM_WINDOWPOSCHANGED, sent|wparam, 0}, - { WM_IME_SETCONTEXT, sent|wparam|optional, 0}, - { WM_IME_NOTIFY, sent|wparam|lparam|defwinproc|optional, 1, 0}, - { WM_NCACTIVATE, sent|wparam|optional, 0}, - { WM_ACTIVATE, sent|wparam|optional, 0}, - { WM_NCACTIVATE, sent|wparam|lparam|optional, 0, 0}, - { WM_ACTIVATE, sent|wparam|lparam|optional, 0, 0}, - { WM_ACTIVATEAPP, sent|wparam|optional, 0}, - { WM_KILLFOCUS, sent|wparam|lparam|optional, 0, 0}, - { WM_IME_SETCONTEXT, sent|wparam|optional, 0}, - { WM_IME_NOTIFY, sent|wparam|lparam|defwinproc|optional, 1, 0}, - { WM_DESTROY, sent|wparam|lparam, 0, 0}, - { WM_NCDESTROY, sent|wparam|lparam, 0, 0}, - { 0 } -}; - static void test_monthcal(void) { HWND hwnd; @@ -523,6 +466,29 @@ static LRESULT WINAPI parent_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LP add_message(sequences, PARENT_SEQ_INDEX, &msg); } + if (message == WM_NOTIFY) + { + NMHDR *hdr = (NMHDR*)lParam; + switch (hdr->code) + { + case MCN_GETDAYSTATE: + { + NMDAYSTATE *nmstate = (NMDAYSTATE*)lParam; + static MONTHDAYSTATE months[14] = { 0 }; + + ok(nmstate->cDayState > 0, "got %d\n", nmstate->cDayState); + ok(nmstate->cDayState <= 14, "got %d\n", nmstate->cDayState); + ok(nmstate->prgDayState != NULL, "got %p\n", nmstate->prgDayState); + + nmstate->prgDayState = months; + + return TRUE; + } + default: + break; + } + } + defwndproc_counter++; ret = DefWindowProcA(hwnd, message, wParam, lParam); defwndproc_counter--; @@ -629,82 +595,83 @@ static HWND create_monthcal_control(DWORD style) /* Setter and Getters Tests */ -static void test_monthcal_color(void) +static void test_color(void) { - int res, temp; + COLORREF color, prev; HWND hwnd; hwnd = create_monthcal_control(0); - flush_sequences(sequences, NUM_MSG_SEQUENCES); + /* invalid color index */ + color = SendMessage(hwnd, MCM_GETCOLOR, MCSC_TRAILINGTEXT + 1, 0); + expect(~0u, color); + prev = SendMessage(hwnd, MCM_SETCOLOR, MCSC_TRAILINGTEXT + 1, RGB(255,255,255)); + expect(~0u, prev); - /* Setter and Getters for color*/ - temp = SendMessage(hwnd, MCM_GETCOLOR, MCSC_BACKGROUND, 0); - res = SendMessage(hwnd, MCM_SETCOLOR, MCSC_BACKGROUND, RGB(0,0,0)); - expect(temp, res); - temp = SendMessage(hwnd, MCM_GETCOLOR, MCSC_BACKGROUND, 0); - expect(RGB(0,0,0), temp); - res = SendMessage(hwnd, MCM_SETCOLOR, MCSC_BACKGROUND, RGB(255,255,255)); - expect(temp, res); - temp = SendMessage(hwnd, MCM_GETCOLOR, MCSC_BACKGROUND, 0); - expect(RGB(255,255,255), temp); + color = SendMessage(hwnd, MCM_GETCOLOR, MCSC_BACKGROUND, 0); + prev = SendMessage(hwnd, MCM_SETCOLOR, MCSC_BACKGROUND, RGB(0,0,0)); + expect(color, prev); + color = SendMessage(hwnd, MCM_GETCOLOR, MCSC_BACKGROUND, 0); + expect(RGB(0,0,0), color); + prev = SendMessage(hwnd, MCM_SETCOLOR, MCSC_BACKGROUND, RGB(255,255,255)); + expect(color, prev); + color = SendMessage(hwnd, MCM_GETCOLOR, MCSC_BACKGROUND, 0); + expect(RGB(255,255,255), color); - temp = SendMessage(hwnd, MCM_GETCOLOR, MCSC_MONTHBK, 0); - res = SendMessage(hwnd, MCM_SETCOLOR, MCSC_MONTHBK, RGB(0,0,0)); - expect(temp, res); - temp = SendMessage(hwnd, MCM_GETCOLOR, MCSC_MONTHBK, 0); - expect(RGB(0,0,0), temp); - res = SendMessage(hwnd, MCM_SETCOLOR, MCSC_MONTHBK, RGB(255,255,255)); - expect(temp, res); - temp = SendMessage(hwnd, MCM_GETCOLOR, MCSC_MONTHBK, 0); - expect(RGB(255,255,255), temp); + color = SendMessage(hwnd, MCM_GETCOLOR, MCSC_MONTHBK, 0); + prev = SendMessage(hwnd, MCM_SETCOLOR, MCSC_MONTHBK, RGB(0,0,0)); + expect(color, prev); + color = SendMessage(hwnd, MCM_GETCOLOR, MCSC_MONTHBK, 0); + expect(RGB(0,0,0), color); + prev = SendMessage(hwnd, MCM_SETCOLOR, MCSC_MONTHBK, RGB(255,255,255)); + expect(color, prev); + color = SendMessage(hwnd, MCM_GETCOLOR, MCSC_MONTHBK, 0); + expect(RGB(255,255,255), color); - temp = SendMessage(hwnd, MCM_GETCOLOR, MCSC_TEXT, 0); - res = SendMessage(hwnd, MCM_SETCOLOR, MCSC_TEXT, RGB(0,0,0)); - expect(temp, res); - temp = SendMessage(hwnd, MCM_GETCOLOR, MCSC_TEXT, 0); - expect(RGB(0,0,0), temp); - res = SendMessage(hwnd, MCM_SETCOLOR, MCSC_TEXT, RGB(255,255,255)); - expect(temp, res); - temp = SendMessage(hwnd, MCM_GETCOLOR, MCSC_TEXT, 0); - expect(RGB(255,255,255), temp); + color = SendMessage(hwnd, MCM_GETCOLOR, MCSC_TEXT, 0); + prev = SendMessage(hwnd, MCM_SETCOLOR, MCSC_TEXT, RGB(0,0,0)); + expect(color, prev); + color = SendMessage(hwnd, MCM_GETCOLOR, MCSC_TEXT, 0); + expect(RGB(0,0,0), color); + prev = SendMessage(hwnd, MCM_SETCOLOR, MCSC_TEXT, RGB(255,255,255)); + expect(color, prev); + color = SendMessage(hwnd, MCM_GETCOLOR, MCSC_TEXT, 0); + expect(RGB(255,255,255), color); - temp = SendMessage(hwnd, MCM_GETCOLOR, MCSC_TITLEBK, 0); - res = SendMessage(hwnd, MCM_SETCOLOR, MCSC_TITLEBK, RGB(0,0,0)); - expect(temp, res); - temp = SendMessage(hwnd, MCM_GETCOLOR, MCSC_TITLEBK, 0); - expect(RGB(0,0,0), temp); - res = SendMessage(hwnd, MCM_SETCOLOR, MCSC_TITLEBK, RGB(255,255,255)); - expect(temp, res); - temp = SendMessage(hwnd, MCM_GETCOLOR, MCSC_TITLEBK, 0); - expect(RGB(255,255,255), temp); + color = SendMessage(hwnd, MCM_GETCOLOR, MCSC_TITLEBK, 0); + prev = SendMessage(hwnd, MCM_SETCOLOR, MCSC_TITLEBK, RGB(0,0,0)); + expect(color, prev); + color = SendMessage(hwnd, MCM_GETCOLOR, MCSC_TITLEBK, 0); + expect(RGB(0,0,0), color); + prev = SendMessage(hwnd, MCM_SETCOLOR, MCSC_TITLEBK, RGB(255,255,255)); + expect(color, prev); + color = SendMessage(hwnd, MCM_GETCOLOR, MCSC_TITLEBK, 0); + expect(RGB(255,255,255), color); - temp = SendMessage(hwnd, MCM_GETCOLOR, MCSC_TITLETEXT, 0); - res = SendMessage(hwnd, MCM_SETCOLOR, MCSC_TITLETEXT, RGB(0,0,0)); - expect(temp, res); - temp = SendMessage(hwnd, MCM_GETCOLOR, MCSC_TITLETEXT, 0); - expect(RGB(0,0,0), temp); - res = SendMessage(hwnd, MCM_SETCOLOR, MCSC_TITLETEXT, RGB(255,255,255)); - expect(temp, res); - temp = SendMessage(hwnd, MCM_GETCOLOR, MCSC_TITLETEXT, 0); - expect(RGB(255,255,255), temp); + color = SendMessage(hwnd, MCM_GETCOLOR, MCSC_TITLETEXT, 0); + prev = SendMessage(hwnd, MCM_SETCOLOR, MCSC_TITLETEXT, RGB(0,0,0)); + expect(color, prev); + color = SendMessage(hwnd, MCM_GETCOLOR, MCSC_TITLETEXT, 0); + expect(RGB(0,0,0), color); + prev = SendMessage(hwnd, MCM_SETCOLOR, MCSC_TITLETEXT, RGB(255,255,255)); + expect(color, prev); + color = SendMessage(hwnd, MCM_GETCOLOR, MCSC_TITLETEXT, 0); + expect(RGB(255,255,255), color); - temp = SendMessage(hwnd, MCM_GETCOLOR, MCSC_TRAILINGTEXT, 0); - res = SendMessage(hwnd, MCM_SETCOLOR, MCSC_TRAILINGTEXT, RGB(0,0,0)); - expect(temp, res); - temp = SendMessage(hwnd, MCM_GETCOLOR, MCSC_TRAILINGTEXT, 0); - expect(RGB(0,0,0), temp); - res = SendMessage(hwnd, MCM_SETCOLOR, MCSC_TRAILINGTEXT, RGB(255,255,255)); - expect(temp, res); - temp = SendMessage(hwnd, MCM_GETCOLOR, MCSC_TRAILINGTEXT, 0); - expect(RGB(255,255,255), temp); - - ok_sequence(sequences, MONTHCAL_SEQ_INDEX, monthcal_color_seq, "monthcal color", FALSE); + color = SendMessage(hwnd, MCM_GETCOLOR, MCSC_TRAILINGTEXT, 0); + prev = SendMessage(hwnd, MCM_SETCOLOR, MCSC_TRAILINGTEXT, RGB(0,0,0)); + expect(color, prev); + color = SendMessage(hwnd, MCM_GETCOLOR, MCSC_TRAILINGTEXT, 0); + expect(RGB(0,0,0), color); + prev = SendMessage(hwnd, MCM_SETCOLOR, MCSC_TRAILINGTEXT, RGB(255,255,255)); + expect(color, prev); + color = SendMessage(hwnd, MCM_GETCOLOR, MCSC_TRAILINGTEXT, 0); + expect(RGB(255,255,255), color); DestroyWindow(hwnd); } -static void test_monthcal_currdate(void) +static void test_currdate(void) { SYSTEMTIME st_original, st_new, st_test; int res; @@ -831,15 +798,43 @@ static void test_monthcal_currdate(void) res = SendMessage(hwnd, MCM_SETCURSEL, 0, (LPARAM)&st_new); expect(1, res); + /* set with invalid day of week */ + memset(&st_test, 0, sizeof(st_test)); + st_test.wYear = 2009; + st_test.wDay = 7; + st_test.wMonth = 10; + st_test.wDayOfWeek = 100; + res = SendMessage(hwnd, MCM_SETCURSEL, 0, (LPARAM)&st_test); + expect(1, res); + + memset(&st_test, 0, sizeof(st_test)); + res = SendMessage(hwnd, MCM_GETCURSEL, 0, (LPARAM)&st_test); + expect(1, res); + expect(2009, st_test.wYear); + expect(7, st_test.wDay); + expect(10, st_test.wMonth); + expect(3, st_test.wDayOfWeek); + DestroyWindow(hwnd); } -static void test_monthcal_firstDay(void) +static void test_firstDay(void) { int res, fday, i, prev; - CHAR b[128]; + CHAR b[128], caltype[3]; LCID lcid = LOCALE_USER_DEFAULT; HWND hwnd; + LRESULT ret; + + SetLastError(0xdeadbeef); + ret = GetLocaleInfoA(lcid, LOCALE_ICALENDARTYPE, caltype, 3); + if (ret == 0) { + skip("Must know local calendar type (%x)\n", GetLastError()); + return; + } else if (atoi(caltype) != CAL_GREGORIAN) { + skip("MonthCalendar Control only supports Gregorian calendar (type: %s)\n", caltype); + return; + } hwnd = create_monthcal_control(0); @@ -881,7 +876,7 @@ static void test_monthcal_firstDay(void) DestroyWindow(hwnd); } -static void test_monthcal_unicode(void) +static void test_unicode(void) { int res, temp; HWND hwnd; @@ -924,7 +919,7 @@ static void test_monthcal_unicode(void) DestroyWindow(hwnd); } -static void test_monthcal_hittest(void) +static void test_hittest(void) { typedef struct hittest_test { @@ -965,11 +960,11 @@ static void test_monthcal_hittest(void) res = SendMessage(hwnd, MCM_HITTEST, 0, (LPARAM)&mchit); expect(0, mchit.pt.x); expect(0, mchit.pt.y); - expect(-1, res); + expect(~0u, res); expect(0, mchit.uHit); /* test with invalid pointer */ res = SendMessage(hwnd, MCM_HITTEST, 0, 0); - expect(-1, res); + expect(~0u, res); /* resize control to display single Calendar */ res = SendMessage(hwnd, MCM_GETMINREQRECT, 0, (LPARAM)&r); @@ -1175,7 +1170,7 @@ static void test_monthcal_hittest(void) DestroyWindow(hwnd); } -static void test_monthcal_todaylink(void) +static void test_todaylink(void) { MCHITTESTINFO mchit; SYSTEMTIME st_test, st_new; @@ -1188,6 +1183,7 @@ static void test_monthcal_todaylink(void) hwnd = create_monthcal_control(0); res = SendMessage(hwnd, MCM_GETMINREQRECT, 0, (LPARAM)&r); + expect(1, res); MoveWindow(hwnd, 0, 0, r.right, r.bottom, FALSE); flush_sequences(sequences, NUM_MSG_SEQUENCES); @@ -1206,7 +1202,8 @@ static void test_monthcal_todaylink(void) st_test.wMonth = 1; st_test.wYear = 2005; - SendMessage(hwnd, MCM_SETTODAY, 0, (LPARAM)&st_test); + res = SendMessage(hwnd, MCM_SETTODAY, 0, (LPARAM)&st_test); + expect(0, res); memset(&st_new, 0, sizeof(st_new)); res = SendMessage(hwnd, MCM_GETTODAY, 0, (LPARAM)&st_new); @@ -1230,7 +1227,7 @@ static void test_monthcal_todaylink(void) DestroyWindow(hwnd); } -static void test_monthcal_today(void) +static void test_today(void) { SYSTEMTIME st_test, st_new; int res; @@ -1250,7 +1247,8 @@ static void test_monthcal_today(void) st_new.wDay = 27; st_new.wMonth = 27; - SendMessage(hwnd, MCM_SETTODAY, 0, (LPARAM)&st_test); + res = SendMessage(hwnd, MCM_SETTODAY, 0, (LPARAM)&st_test); + expect(0, res); res = SendMessage(hwnd, MCM_GETTODAY, 0, (LPARAM)&st_new); expect(1, res); @@ -1267,7 +1265,8 @@ static void test_monthcal_today(void) st_test.wDay = 0; st_test.wMonth = 0; - SendMessage(hwnd, MCM_SETTODAY, 0, (LPARAM)&st_test); + res = SendMessage(hwnd, MCM_SETTODAY, 0, (LPARAM)&st_test); + expect(0, res); res = SendMessage(hwnd, MCM_GETTODAY, 0, (LPARAM)&st_new); expect(1, res); @@ -1285,7 +1284,7 @@ static void test_monthcal_today(void) DestroyWindow(hwnd); } -static void test_monthcal_scroll(void) +static void test_scroll(void) { int res; HWND hwnd; @@ -1323,7 +1322,7 @@ static void test_monthcal_scroll(void) DestroyWindow(hwnd); } -static void test_monthcal_monthrange(void) +static void test_monthrange(void) { int res; SYSTEMTIME st_visible[2], st_daystate[2], st; @@ -1360,34 +1359,32 @@ static void test_monthcal_monthrange(void) flush_sequences(sequences, NUM_MSG_SEQUENCES); res = SendMessage(hwnd, MCM_GETMONTHRANGE, GMR_VISIBLE, (LPARAM)st_visible); - todo_wine { - expect(2, res); - } + expect(2, res); expect(2000, st_visible[0].wYear); expect(11, st_visible[0].wMonth); expect(1, st_visible[0].wDay); expect(2000, st_visible[1].wYear); + expect(12, st_visible[1].wMonth); + expect(31, st_visible[1].wDay); - todo_wine { - expect(12, st_visible[1].wMonth); - expect(31, st_visible[1].wDay); - } res = SendMessage(hwnd, MCM_GETMONTHRANGE, GMR_DAYSTATE, (LPARAM)st_daystate); - todo_wine { - expect(4, res); - } + expect(4, res); expect(2000, st_daystate[0].wYear); expect(10, st_daystate[0].wMonth); expect(29, st_daystate[0].wDay); - - todo_wine { - expect(2001, st_daystate[1].wYear); - expect(1, st_daystate[1].wMonth); - expect(6, st_daystate[1].wDay); - } + expect(2001, st_daystate[1].wYear); + expect(1, st_daystate[1].wMonth); + expect(6, st_daystate[1].wDay); ok_sequence(sequences, MONTHCAL_SEQ_INDEX, monthcal_monthrange_seq, "monthcal monthrange", FALSE); + /* with null date array parameter */ + res = SendMessage(hwnd, MCM_GETMONTHRANGE, GMR_VISIBLE, 0); + expect(2, res); + + res = SendMessage(hwnd, MCM_GETMONTHRANGE, GMR_DAYSTATE, 0); + expect(4, res); + /* resize control to display single Calendar */ MoveWindow(hwnd, 0, 0, r.right, r.bottom, FALSE); @@ -1416,7 +1413,7 @@ static void test_monthcal_monthrange(void) DestroyWindow(hwnd); } -static void test_monthcal_maxselday(void) +static void test_maxselday(void) { int res; HWND hwnd; @@ -1482,7 +1479,7 @@ static void test_monthcal_maxselday(void) DestroyWindow(hwnd); } -static void test_monthcal_size(void) +static void test_size(void) { int res; RECT r1, r2; @@ -1518,7 +1515,7 @@ static void test_monthcal_size(void) DestroyWindow(hwnd); } -static void test_monthcal_create(void) +static void test_create(void) { HWND hwnd; @@ -1535,7 +1532,7 @@ static void test_monthcal_create(void) DestroyWindow(hwnd); } -static void test_monthcal_destroy(void) +static void test_destroy(void) { HWND hwnd; @@ -1552,7 +1549,7 @@ static void test_monthcal_destroy(void) ok_sequence(sequences, MONTHCAL_SEQ_INDEX, destroy_monthcal_multi_sel_style_seq, "Destroy monthcal (multi sel style)", FALSE); } -static void test_monthcal_selrange(void) +static void test_selrange(void) { HWND hwnd; SYSTEMTIME st, range[2], range2[2]; @@ -1680,11 +1677,256 @@ static void test_killfocus(void) DestroyWindow(hwnd); } +static void test_hittest_v6(void) +{ + MCHITTESTINFO mchit; + DWORD ret; + HWND hwnd; + RECT r; + + hwnd = create_monthcal_control(0); + SendMessage(hwnd, MCM_SETCALENDARBORDER, TRUE, 0); + + SendMessage(hwnd, MCM_GETMINREQRECT, 0, (LPARAM)&r); + /* reserving some area around calendar */ + MoveWindow(hwnd, 0, 0, r.right * 3 / 2, r.bottom * 3 / 2, FALSE); + mchit.cbSize = sizeof(MCHITTESTINFO); + mchit.pt.x = mchit.pt.y = 0; + mchit.iOffset = -1; + mchit.iRow = -1; + mchit.iCol = -1; + ret = SendMessage(hwnd, MCM_HITTEST, 0, (LPARAM)&mchit); + if (ret == ~0u) + { + win_skip("Only MCHITTESTINFO_V1 supported\n"); + DestroyWindow(hwnd); + return; + } + todo_wine expect_hex(MCHT_NOWHERE, ret); + expect(-1, mchit.iOffset); + expect(-1, mchit.iRow); + expect(-1, mchit.iCol); + + MoveWindow(hwnd, 0, 0, r.right, r.bottom, FALSE); + mchit.pt.x = r.right / 2; + mchit.pt.y = r.bottom / 2; + mchit.iOffset = -1; + ret = SendMessage(hwnd, MCM_HITTEST, 0, (LPARAM)&mchit); + expect_hex(MCHT_CALENDARDATE, ret); + expect(0, mchit.iOffset); + + /* over day area */ + mchit.pt.x = r.right / (7*2); + mchit.pt.y = r.bottom / 2; + mchit.iOffset = -1; + mchit.iCol = mchit.iRow = -1; + mchit.uHit = 0; + mchit.rc.left = mchit.rc.right = mchit.rc.top = mchit.rc.bottom = -1; + ret = SendMessage(hwnd, MCM_HITTEST, 0, (LPARAM)&mchit); + expect_hex(MCHT_CALENDARDATE, ret); + expect_hex(MCHT_CALENDARDATE, mchit.uHit); + expect(0, mchit.iOffset); + expect(2, mchit.iRow); + expect(0, mchit.iCol); + /* returned a one day rectangle */ + expect_d(r.right / 7, mchit.rc.right - mchit.rc.left); + expect_d(r.bottom / 10, mchit.rc.bottom - mchit.rc.top); + + /* title */ + mchit.pt.x = 1; + mchit.pt.y = 1; + mchit.iOffset = -1; + mchit.iCol = mchit.iRow = -1; + mchit.uHit = 0; + mchit.rc.left = mchit.rc.right = mchit.rc.top = mchit.rc.bottom = -1; + ret = SendMessage(hwnd, MCM_HITTEST, 0, (LPARAM)&mchit); + expect_hex(MCHT_TITLE, ret); + expect_hex(MCHT_TITLE, mchit.uHit); + expect(0, mchit.iOffset); + expect(-1, mchit.iRow); + expect(-1, mchit.iCol); + expect(0, mchit.rc.left); + expect(0, mchit.rc.top); + expect_d(r.right, mchit.rc.right); + ok(mchit.rc.bottom > 0, "got %d\n", mchit.rc.bottom); + + /* between two calendars */ + MoveWindow(hwnd, 0, 0, r.right * 5/2, r.bottom, FALSE); + mchit.pt.x = r.right / (5*4); + mchit.pt.y = r.bottom / 2; + mchit.iOffset = -2; + mchit.iCol = mchit.iRow = -2; + mchit.uHit = ~0; + mchit.rc.left = mchit.rc.right = mchit.rc.top = mchit.rc.bottom = -1; + ret = SendMessage(hwnd, MCM_HITTEST, 0, (LPARAM)&mchit); + todo_wine expect_hex(MCHT_NOWHERE, ret); + todo_wine expect_hex(MCHT_NOWHERE, mchit.uHit); + expect(-2, mchit.iOffset); + expect(-2, mchit.iRow); + expect(-2, mchit.iCol); + todo_wine expect(0, mchit.rc.left); + todo_wine expect(0, mchit.rc.top); + todo_wine expect_d(r.right * 5/2, mchit.rc.right); + todo_wine expect_d(r.bottom, mchit.rc.bottom); + + DestroyWindow(hwnd); +} + +static void test_get_set_border(void) +{ + HWND hwnd; + DWORD ret; + + hwnd = create_monthcal_control(0); + + /* a non-default value */ + ret = SendMessage(hwnd, MCM_SETCALENDARBORDER, TRUE, 10); + expect(0, ret); + + ret = SendMessage(hwnd, MCM_GETCALENDARBORDER, 0, 0); + + if (ret != 10) + { + skip("MCM_GET/SETCALENDARBORDER not supported\n"); + DestroyWindow(hwnd); + return; + } + + expect(10, ret); + + DestroyWindow(hwnd); +} + +static void test_MCM_SIZERECTTOMIN(void) +{ + HWND hwnd; + DWORD ret; + RECT r, r2; + + hwnd = create_monthcal_control(0); + + ret = SendMessageA(hwnd, MCM_GETMINREQRECT, 0, (LPARAM)&r2); + if (ret == 0) + { + win_skip("Message MCM_GETMINREQRECT unsupported. Skipping.\n"); + DestroyWindow(hwnd); + return; + } + + ret = SendMessageA(hwnd, MCM_SIZERECTTOMIN, 0, 0); + ok(ret == 0, "got %d\n", ret); + + r.left = r.right = r.top = r.bottom = 0; + ret = SendMessageA(hwnd, MCM_SIZERECTTOMIN, 0, (LPARAM)&r); + if (ret == 0) + { + skip("Message MCM_SIZERECTTOMIN unsupported. Skipping.\n"); + DestroyWindow(hwnd); + return; + } + ok(ret == 1, "got %d\n", ret); + ok(r.left == 0 && r.right > 0, "got %d, %d\n", r.left, r.right); + + r = r2; + ret = SendMessageA(hwnd, MCM_SIZERECTTOMIN, 0, (LPARAM)&r); + ok(ret == 1, "got %d\n", ret); + + r2.right = (r2.right - r2.left) * 3; + r2.bottom = (r2.bottom - r2.top) * 3; + r2.left = r2.top = 0; + ret = SendMessageA(hwnd, MCM_SIZERECTTOMIN, 0, (LPARAM)&r2); + ok(ret == 1, "got %d\n", ret); + + DestroyWindow(hwnd); +} + +static void test_MCM_GETCALENDARCOUNT(void) +{ + HWND hwnd; + DWORD ret; + + hwnd = create_monthcal_control(0); + + ret = SendMessageA(hwnd, MCM_GETCALENDARCOUNT, 0, 0); + if (ret == 0) + { + win_skip("Message MCM_GETCALENDARCOUNT unsupported. Skipping.\n"); + DestroyWindow(hwnd); + return; + } + + expect(2, ret); + + DestroyWindow(hwnd); +} + +static void test_daystate(void) +{ + MONTHDAYSTATE state[4]; + DWORD ret, style; + HWND hwnd; + RECT r; + + /* without MCS_DAYSTATE */ + hwnd = create_monthcal_control(0); + + ret = SendMessage(hwnd, MCM_GETMINREQRECT, 0, (LPARAM)&r); + expect(TRUE, ret); + + /* resize control to display two Calendars */ + MoveWindow(hwnd, 0, 0, r.right, (5/2)*r.bottom, FALSE); + + ret = SendMessageA(hwnd, MCM_GETMONTHRANGE, GMR_DAYSTATE, 0); + expect(4, ret); + + ret = SendMessageA(hwnd, MCM_SETDAYSTATE, 4, (LPARAM)&state); + expect(0, ret); + + ret = SendMessageA(hwnd, MCM_SETDAYSTATE, 2, (LPARAM)&state); + expect(0, ret); + + ret = SendMessageA(hwnd, MCM_SETDAYSTATE, 0, 0); + expect(0, ret); + + /* try to switch on */ + SetWindowLongA(hwnd, GWL_STYLE, GetWindowLongA(hwnd, GWL_STYLE) | MCS_DAYSTATE); + style = GetWindowLongA(hwnd, GWL_STYLE); + ok((style & MCS_DAYSTATE) == 0, "got 0x%08x\n", style); + + DestroyWindow(hwnd); + + /* with MCS_DAYSTATE */ + hwnd = create_monthcal_control(MCS_DAYSTATE); + + ret = SendMessageA(hwnd, MCM_GETMONTHRANGE, GMR_DAYSTATE, 0); + expect(4, ret); + + ret = SendMessageA(hwnd, MCM_SETDAYSTATE, 4, (LPARAM)&state); + expect(1, ret); + + ret = SendMessageA(hwnd, MCM_SETDAYSTATE, 2, (LPARAM)&state); + expect(0, ret); + + ret = SendMessageA(hwnd, MCM_SETDAYSTATE, 0, 0); + expect(0, ret); + + /* try to switch off */ + SetWindowLongA(hwnd, GWL_STYLE, GetWindowLongA(hwnd, GWL_STYLE) & ~MCS_DAYSTATE); + style = GetWindowLongA(hwnd, GWL_STYLE); + ok((style & MCS_DAYSTATE) == MCS_DAYSTATE, "got 0x%08x\n", style); + + DestroyWindow(hwnd); +} + START_TEST(monthcal) { - HMODULE hComctl32; BOOL (WINAPI *pInitCommonControlsEx)(const INITCOMMONCONTROLSEX*); INITCOMMONCONTROLSEX iccex; + HMODULE hComctl32; + HWND hwnd; + + ULONG_PTR ctx_cookie; + HANDLE hCtx; hComctl32 = GetModuleHandleA("comctl32.dll"); pInitCommonControlsEx = (void*)GetProcAddress(hComctl32, "InitCommonControlsEx"); @@ -1703,23 +1945,50 @@ START_TEST(monthcal) parent_wnd = create_parent_window(); - test_monthcal_create(); - test_monthcal_destroy(); - test_monthcal_color(); - test_monthcal_currdate(); - test_monthcal_firstDay(); - test_monthcal_unicode(); - test_monthcal_today(); - test_monthcal_scroll(); - test_monthcal_monthrange(); - test_monthcal_hittest(); - test_monthcal_todaylink(); - test_monthcal_size(); - test_monthcal_maxselday(); - test_monthcal_selrange(); + test_create(); + test_destroy(); + test_color(); + test_currdate(); + test_firstDay(); + test_unicode(); + test_today(); + test_scroll(); + test_monthrange(); + test_hittest(); + test_todaylink(); + test_size(); + test_maxselday(); + test_selrange(); test_killfocus(); + test_daystate(); + + if (!load_v6_module(&ctx_cookie, &hCtx)) + { + DestroyWindow(parent_wnd); + return; + } + + /* this is a XP SP3 failure workaround */ + hwnd = CreateWindowExA(0, MONTHCAL_CLASSA, "foo", + WS_CHILD | WS_BORDER | WS_VISIBLE, + 0, 0, 100, 100, + parent_wnd, NULL, GetModuleHandleA(NULL), NULL); + if (!IsWindow(hwnd)) + { + win_skip("FIXME: failed to create Monthcal window.\n"); + unload_v6_module(ctx_cookie, hCtx); + DestroyWindow(parent_wnd); + return; + } + else + DestroyWindow(hwnd); + + test_hittest_v6(); + test_get_set_border(); + test_MCM_SIZERECTTOMIN(); + test_MCM_GETCALENDARCOUNT(); + + unload_v6_module(ctx_cookie, hCtx); - flush_sequences(sequences, NUM_MSG_SEQUENCES); DestroyWindow(parent_wnd); - ok_sequence(sequences, PARENT_SEQ_INDEX, destroy_parent_seq, "Destroy parent window", FALSE); } diff --git a/rostests/winetests/comctl32/mru.c b/rostests/winetests/comctl32/mru.c index 24fcff56d68..86eddc02607 100644 --- a/rostests/winetests/comctl32/mru.c +++ b/rostests/winetests/comctl32/mru.c @@ -37,57 +37,57 @@ #define REG_TEST_SUBKEYA "MRUTest" #define REG_TEST_FULLKEY REG_TEST_KEYA "\\" REG_TEST_SUBKEYA -/* Undocumented MRU structures & functions */ -typedef struct tagCREATEMRULISTA +/* Undocumented MRU functions */ +typedef struct tagMRUINFOA { DWORD cbSize; - DWORD nMaxItems; - DWORD dwFlags; + UINT uMax; + UINT fFlags; HKEY hKey; LPCSTR lpszSubKey; PROC lpfnCompare; -} CREATEMRULISTA, *LPCREATEMRULISTA; +} MRUINFOA; -#define MRUF_STRING_LIST 0 -#define MRUF_BINARY_LIST 1 -#define MRUF_DELAYED_SAVE 2 +typedef struct tagMRUINFOW +{ + DWORD cbSize; + UINT uMax; + UINT fFlags; + HKEY hKey; + LPCWSTR lpszSubKey; + PROC lpfnCompare; +} MRUINFOW; + +#define MRU_STRING 0 /* this one's invented */ +#define MRU_BINARY 1 +#define MRU_CACHEWRITE 2 #define LIST_SIZE 3 /* Max entries for each mru */ -static CREATEMRULISTA mruA = -{ - sizeof(CREATEMRULISTA), - LIST_SIZE, - 0, - NULL, - REG_TEST_SUBKEYA, - NULL -}; - static HMODULE hComctl32; -static HANDLE (WINAPI *pCreateMRUListA)(LPCREATEMRULISTA); +static HANDLE (WINAPI *pCreateMRUListA)(MRUINFOA*); static void (WINAPI *pFreeMRUList)(HANDLE); static INT (WINAPI *pAddMRUStringA)(HANDLE,LPCSTR); -static INT (WINAPI *pEnumMRUList)(HANDLE,INT,LPVOID,DWORD); +static INT (WINAPI *pEnumMRUListA)(HANDLE,INT,LPVOID,DWORD); static INT (WINAPI *pEnumMRUListW)(HANDLE,INT,LPVOID,DWORD); -static HANDLE (WINAPI *pCreateMRUListLazyA)(LPCREATEMRULISTA, DWORD, DWORD, DWORD); +static HANDLE (WINAPI *pCreateMRUListLazyA)(MRUINFOA*, DWORD, DWORD, DWORD); +static HANDLE (WINAPI *pCreateMRUListLazyW)(MRUINFOW*, 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 HANDLE (WINAPI *pCreateMRUListW)(MRUINFOW*); 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); + pEnumMRUListA = (void*)GetProcAddress(hComctl32,(LPCSTR)154); pCreateMRUListLazyA = (void*)GetProcAddress(hComctl32,(LPCSTR)157); pAddMRUData = (void*)GetProcAddress(hComctl32,(LPCSTR)167); pFindMRUData = (void*)GetProcAddress(hComctl32,(LPCSTR)169); + pCreateMRUListW = (void*)GetProcAddress(hComctl32,(LPCSTR)400); pEnumMRUListW = (void*)GetProcAddress(hComctl32,(LPCSTR)403); + pCreateMRUListLazyW = (void*)GetProcAddress(hComctl32,(LPCSTR)404); } /* Based on RegDeleteTreeW from dlls/advapi32/registry.c */ @@ -226,24 +226,15 @@ static INT CALLBACK cmp_mru_strA(LPCVOID data1, LPCVOID data2) return lstrcmpiA(data1, data2); } -static HANDLE create_mruA(HKEY hKey, DWORD flags, PROC cmp) -{ - mruA.dwFlags = flags; - mruA.lpfnCompare = cmp; - mruA.hKey = hKey; - - SetLastError(0); - return pCreateMRUListA(&mruA); -} - static void test_MRUListA(void) { const char *checks[LIST_SIZE+1]; + MRUINFOA infoA; HANDLE hMRU; HKEY hKey; INT iRet; - if (!pCreateMRUListA || !pFreeMRUList || !pAddMRUStringA || !pEnumMRUList) + if (!pCreateMRUListA || !pFreeMRUList || !pAddMRUStringA || !pEnumMRUListA) { skip("MRU entry points not found\n"); return; @@ -255,42 +246,75 @@ static void test_MRUListA(void) hMRU = pCreateMRUListA(NULL); } - /* Create (size too small) */ - mruA.cbSize = sizeof(mruA) - 2; - hMRU = create_mruA(NULL, MRUF_STRING_LIST, (PROC)cmp_mru_strA); + /* size too small */ + infoA.cbSize = sizeof(infoA) - 2; + infoA.uMax = LIST_SIZE; + infoA.fFlags = MRU_STRING; + infoA.hKey = NULL; + infoA.lpszSubKey = REG_TEST_SUBKEYA; + infoA.lpfnCompare = (PROC)cmp_mru_strA; + + SetLastError(0); + hMRU = pCreateMRUListA(&infoA); ok (!hMRU && !GetLastError(), "CreateMRUListA(too small) expected NULL,0 got %p,%d\n", hMRU, GetLastError()); - mruA.cbSize = sizeof(mruA); - /* Create (size too big) */ - mruA.cbSize = sizeof(mruA) + 2; - hMRU = create_mruA(NULL, MRUF_STRING_LIST, (PROC)cmp_mru_strA); + /* size too big */ + infoA.cbSize = sizeof(infoA) + 2; + infoA.uMax = LIST_SIZE; + infoA.fFlags = MRU_STRING; + infoA.hKey = NULL; + infoA.lpszSubKey = REG_TEST_SUBKEYA; + infoA.lpfnCompare = (PROC)cmp_mru_strA; + + SetLastError(0); + hMRU = pCreateMRUListA(&infoA); ok (!hMRU && !GetLastError(), "CreateMRUListA(too big) expected NULL,0 got %p,%d\n", hMRU, GetLastError()); - mruA.cbSize = sizeof(mruA); - /* Create (NULL hKey) */ - hMRU = create_mruA(NULL, MRUF_STRING_LIST, (PROC)cmp_mru_strA); + /* NULL hKey */ + infoA.cbSize = sizeof(infoA); + infoA.uMax = LIST_SIZE; + infoA.fFlags = MRU_STRING; + infoA.hKey = NULL; + infoA.lpszSubKey = REG_TEST_SUBKEYA; + infoA.lpfnCompare = (PROC)cmp_mru_strA; + + SetLastError(0); + hMRU = pCreateMRUListA(&infoA); ok (!hMRU && !GetLastError(), "CreateMRUListA(NULL key) expected NULL,0 got %p,%d\n", hMRU, GetLastError()); - /* Create (NULL name) */ - mruA.lpszSubKey = NULL; - hMRU = create_mruA(NULL, MRUF_STRING_LIST, (PROC)cmp_mru_strA); + /* NULL subkey name */ + infoA.cbSize = sizeof(infoA); + infoA.uMax = LIST_SIZE; + infoA.fFlags = MRU_STRING; + infoA.hKey = NULL; + infoA.lpszSubKey = NULL; + infoA.lpfnCompare = (PROC)cmp_mru_strA; + + SetLastError(0); + hMRU = pCreateMRUListA(&infoA); ok (!hMRU && !GetLastError(), "CreateMRUListA(NULL name) expected NULL,0 got %p,%d\n", hMRU, GetLastError()); - mruA.lpszSubKey = REG_TEST_SUBKEYA; /* Create a string MRU */ ok(!RegCreateKeyA(HKEY_CURRENT_USER, REG_TEST_KEYA, &hKey), "Couldn't create test key \"%s\"\n", REG_TEST_KEYA); - if (!hKey) - return; - hMRU = create_mruA(hKey, MRUF_STRING_LIST, (PROC)cmp_mru_strA); + if (!hKey) return; + + infoA.cbSize = sizeof(infoA); + infoA.uMax = LIST_SIZE; + infoA.fFlags = MRU_STRING; + infoA.hKey = hKey; + infoA.lpszSubKey = REG_TEST_SUBKEYA; + infoA.lpfnCompare = (PROC)cmp_mru_strA; + + hMRU = pCreateMRUListA(&infoA); ok(hMRU && !GetLastError(), "CreateMRUListA(string) expected non-NULL,0 got %p,%d\n", hMRU, GetLastError()); @@ -363,28 +387,28 @@ static void test_MRUListA(void) check_reg_entries("abc", checks); /* NULL buffer = get list size */ - iRet = pEnumMRUList(hMRU, 0, NULL, 0); + iRet = pEnumMRUListA(hMRU, 0, NULL, 0); ok(iRet == 3 || iRet == -1 /* Vista */, "EnumMRUList expected %d or -1, got %d\n", LIST_SIZE, iRet); /* negative item pos = get list size */ - iRet = pEnumMRUList(hMRU, -1, NULL, 0); + iRet = pEnumMRUListA(hMRU, -1, NULL, 0); ok(iRet == 3 || iRet == -1 /* Vista */, "EnumMRUList expected %d or -1, got %d\n", LIST_SIZE, iRet); /* negative item pos = get list size */ - iRet = pEnumMRUList(hMRU, -5, NULL, 0); + iRet = pEnumMRUListA(hMRU, -5, NULL, 0); ok(iRet == 3 || iRet == -1 /* Vista */, "EnumMRUList expected %d or -1, got %d\n", LIST_SIZE, iRet); /* negative item pos = get list size */ - iRet = pEnumMRUList(hMRU, -1, buffer, 255); + iRet = pEnumMRUListA(hMRU, -1, buffer, 255); ok(iRet == 3, "EnumMRUList expected %d, got %d\n", LIST_SIZE, iRet); /* negative item pos = get list size */ - iRet = pEnumMRUList(hMRU, -5, buffer, 255); + iRet = pEnumMRUListA(hMRU, -5, buffer, 255); ok(iRet == 3, "EnumMRUList expected %d, got %d\n", LIST_SIZE, iRet); /* check entry 0 */ buffer[0] = 0; - iRet = pEnumMRUList(hMRU, 0, buffer, 255); + iRet = pEnumMRUListA(hMRU, 0, buffer, 255); 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); @@ -393,7 +417,7 @@ static void test_MRUListA(void) buffer[1] = 'A'; /* overwritten with 0 */ buffer[2] = 'A'; /* unchanged */ buffer[3] = 0; /* unchanged */ - iRet = pEnumMRUList(hMRU, 0, buffer, 2); + iRet = pEnumMRUListA(hMRU, 0, buffer, 2); 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 */ @@ -401,19 +425,19 @@ static void test_MRUListA(void) /* check entry 1 */ buffer[0] = 0; - iRet = pEnumMRUList(hMRU, 1, buffer, 255); + iRet = pEnumMRUListA(hMRU, 1, buffer, 255); 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); + iRet = pEnumMRUListA(hMRU, 2, buffer, 255); 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 */ strcpy(buffer, "dummy"); - iRet = pEnumMRUList(hMRU, 3, buffer, 255); + iRet = pEnumMRUListA(hMRU, 3, buffer, 255); ok(iRet == -1, "EnumMRUList expected %d, got %d\n", -1, iRet); ok(strcmp(buffer, "dummy") == 0, "EnumMRUList expected unchanged buffer %s, got %s\n", "dummy", buffer); @@ -423,12 +447,37 @@ static void test_MRUListA(void) /* FreeMRUList(NULL) crashes on Win98 OSR0 */ } +/* +typedef struct tagMRUINFOA +{ + DWORD cbSize; + UINT uMax; + UINT fFlags; + HKEY hKey; + LPCSTR lpszSubKey; + PROC lpfnCompare; +} MRUINFOA; +*/ +typedef struct { + MRUINFOA mruA; + BOOL ret; +} create_lazya_t; + +static const create_lazya_t create_lazyA[] = { + {{ sizeof(MRUINFOA) + 1, 0, 0, HKEY_CURRENT_USER, NULL, NULL }, FALSE }, + {{ sizeof(MRUINFOA) - 1, 0, 0, HKEY_CURRENT_USER, NULL, NULL }, FALSE }, + {{ sizeof(MRUINFOA) + 1, 0, 0, HKEY_CURRENT_USER, "WineTest", NULL }, TRUE }, + {{ sizeof(MRUINFOA) - 1, 0, 0, HKEY_CURRENT_USER, "WineTest", NULL }, TRUE }, + {{ sizeof(MRUINFOA), 0, 0, HKEY_CURRENT_USER, "WineTest", NULL }, TRUE }, + {{ sizeof(MRUINFOA), 0, 0, HKEY_CURRENT_USER, NULL, NULL }, FALSE }, + {{ sizeof(MRUINFOA), 0, 0, NULL, "WineTest", NULL }, FALSE }, + {{ 0, 0, 0, NULL, "WineTest", NULL }, FALSE }, + {{ 0, 0, 0, HKEY_CURRENT_USER, "WineTest", NULL }, TRUE } +}; static void test_CreateMRUListLazyA(void) { - HANDLE hMRU; - HKEY hKey; - CREATEMRULISTA listA = { 0 }; + int i; if (!pCreateMRUListLazyA || !pFreeMRUList) { @@ -436,33 +485,25 @@ static void test_CreateMRUListLazyA(void) 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); + for (i = 0; i < sizeof(create_lazyA)/sizeof(create_lazya_t); i++) + { + const create_lazya_t *ptr = &create_lazyA[i]; + HANDLE hMRU; + + hMRU = pCreateMRUListLazyA((MRUINFOA*)&ptr->mruA, 0, 0, 0); + if (ptr->ret) + { + ok(hMRU != NULL, "%d: got %p\n", i, hMRU); + pFreeMRUList(hMRU); + } + else + ok(hMRU == NULL, "%d: got %p\n", i, hMRU); + } } static void test_EnumMRUList(void) { - if (!pEnumMRUList || !pEnumMRUListW) + if (!pEnumMRUListA || !pEnumMRUListW) { win_skip("EnumMRUListA/EnumMRUListW entry point not found\n"); return; @@ -472,7 +513,7 @@ static void test_EnumMRUList(void) if (0) { /* crashes on NT4, passed on Win2k, XP, 2k3, Vista, 2k8 */ - pEnumMRUList(NULL, 0, NULL, 0); + pEnumMRUListA(NULL, 0, NULL, 0); pEnumMRUListW(NULL, 0, NULL, 0); } } @@ -507,6 +548,171 @@ static void test_AddMRUData(void) ok(iRet == -1, "AddMRUData expected -1, got %d\n", iRet); } +static void test_CreateMRUListW(void) +{ + static const WCHAR mrutestW[] = {'M','R','U','T','e','s','t',0}; + MRUINFOW infoW; + void *named; + HKEY hKey; + HANDLE hMru; + + if (!pCreateMRUListW) + { + win_skip("CreateMRUListW entry point not found\n"); + return; + } + + /* exported by name too on recent versions */ + named = GetProcAddress(hComctl32, "CreateMRUListW"); + if (named) + ok(named == pCreateMRUListW, "got %p, expected %p\n", named, pCreateMRUListW); + + ok(!RegCreateKeyA(HKEY_CURRENT_USER, REG_TEST_KEYA, &hKey), + "Couldn't create test key \"%s\"\n", REG_TEST_KEYA); + + infoW.cbSize = sizeof(infoW); + infoW.uMax = 1; + infoW.fFlags = 0; + infoW.lpszSubKey = mrutestW; + infoW.hKey = hKey; + infoW.lpfnCompare = NULL; + + hMru = pCreateMRUListW(&infoW); + ok(hMru != NULL, "got %p\n", hMru); + pFreeMRUList(hMru); + + /* smaller size */ + infoW.cbSize = sizeof(infoW) - 1; + infoW.uMax = 1; + infoW.fFlags = 0; + infoW.lpszSubKey = mrutestW; + infoW.hKey = hKey; + infoW.lpfnCompare = NULL; + + hMru = pCreateMRUListW(&infoW); + ok(hMru != NULL, "got %p\n", hMru); + pFreeMRUList(hMru); + + /* increased size */ + infoW.cbSize = sizeof(infoW) + 1; + infoW.uMax = 1; + infoW.fFlags = 0; + infoW.lpszSubKey = mrutestW; + infoW.hKey = hKey; + infoW.lpfnCompare = NULL; + + hMru = pCreateMRUListW(&infoW); + ok(hMru != NULL, "got %p\n", hMru); + pFreeMRUList(hMru); + + /* zero size */ + infoW.cbSize = 0; + infoW.uMax = 1; + infoW.fFlags = 0; + infoW.lpszSubKey = mrutestW; + infoW.hKey = hKey; + infoW.lpfnCompare = NULL; + + hMru = pCreateMRUListW(&infoW); + ok(hMru != NULL, "got %p\n", hMru); + pFreeMRUList(hMru); + + /* NULL hKey */ + infoW.cbSize = sizeof(infoW); + infoW.uMax = 1; + infoW.fFlags = 0; + infoW.lpszSubKey = mrutestW; + infoW.hKey = NULL; + infoW.lpfnCompare = NULL; + + hMru = pCreateMRUListW(&infoW); + ok(hMru == NULL, "got %p\n", hMru); + + RegCloseKey(hKey); +} + +static void test_CreateMRUListLazyW(void) +{ + static const WCHAR mrutestW[] = {'M','R','U','T','e','s','t',0}; + MRUINFOW infoW; + void *named; + HKEY hKey; + HANDLE hMru; + + if (!pCreateMRUListLazyW) + { + win_skip("CreateMRUListLazyW entry point not found\n"); + return; + } + + /* check that it's not exported by name */ + named = GetProcAddress(hComctl32, "CreateMRUListLazyW"); + ok(named == NULL, "got %p\n", named); + + ok(!RegCreateKeyA(HKEY_CURRENT_USER, REG_TEST_KEYA, &hKey), + "Couldn't create test key \"%s\"\n", REG_TEST_KEYA); + + infoW.cbSize = sizeof(infoW); + infoW.uMax = 1; + infoW.fFlags = 0; + infoW.lpszSubKey = mrutestW; + infoW.hKey = hKey; + infoW.lpfnCompare = NULL; + + hMru = pCreateMRUListLazyW(&infoW, 0, 0, 0); + ok(hMru != NULL, "got %p\n", hMru); + pFreeMRUList(hMru); + + /* smaller size */ + infoW.cbSize = sizeof(infoW) - 1; + infoW.uMax = 1; + infoW.fFlags = 0; + infoW.lpszSubKey = mrutestW; + infoW.hKey = hKey; + infoW.lpfnCompare = NULL; + + hMru = pCreateMRUListLazyW(&infoW, 0, 0, 0); + ok(hMru != NULL, "got %p\n", hMru); + pFreeMRUList(hMru); + + /* increased size */ + infoW.cbSize = sizeof(infoW) + 1; + infoW.uMax = 1; + infoW.fFlags = 0; + infoW.lpszSubKey = mrutestW; + infoW.hKey = hKey; + infoW.lpfnCompare = NULL; + + hMru = pCreateMRUListLazyW(&infoW, 0, 0, 0); + ok(hMru != NULL, "got %p\n", hMru); + pFreeMRUList(hMru); + + /* zero size */ + infoW.cbSize = 0; + infoW.uMax = 1; + infoW.fFlags = 0; + infoW.lpszSubKey = mrutestW; + infoW.hKey = hKey; + infoW.lpfnCompare = NULL; + + hMru = pCreateMRUListLazyW(&infoW, 0, 0, 0); + ok(hMru != NULL, "got %p\n", hMru); + pFreeMRUList(hMru); + + /* NULL hKey */ + infoW.cbSize = sizeof(infoW); + infoW.uMax = 1; + infoW.fFlags = 0; + infoW.lpszSubKey = mrutestW; + infoW.hKey = NULL; + infoW.lpfnCompare = NULL; + + hMru = pCreateMRUListLazyW(&infoW, 0, 0, 0); + ok(hMru == NULL, "got %p\n", hMru); + + RegCloseKey(hKey); +} + START_TEST(mru) { hComctl32 = GetModuleHandleA("comctl32.dll"); @@ -519,9 +725,11 @@ START_TEST(mru) test_MRUListA(); test_CreateMRUListLazyA(); + test_CreateMRUListLazyW(); test_EnumMRUList(); test_FindMRUData(); test_AddMRUData(); + test_CreateMRUListW(); delete_reg_entries(); } diff --git a/rostests/winetests/comctl32/msg.h b/rostests/winetests/comctl32/msg.h index 361ccdbf598..1d78ffea94e 100644 --- a/rostests/winetests/comctl32/msg.h +++ b/rostests/winetests/comctl32/msg.h @@ -89,7 +89,7 @@ static void add_message(struct msg_sequence **seq, int sequence_index, msg_seq->count++; } -static void flush_sequence(struct msg_sequence **seg, int sequence_index) +static inline void flush_sequence(struct msg_sequence **seg, int sequence_index) { struct msg_sequence *msg_seq = seg[sequence_index]; HeapFree(GetProcessHeap(), 0, msg_seq->sequence); @@ -97,7 +97,7 @@ static void flush_sequence(struct msg_sequence **seg, int sequence_index) msg_seq->count = msg_seq->size = 0; } -static void flush_sequences(struct msg_sequence **seq, int n) +static inline void flush_sequences(struct msg_sequence **seq, int n) { int i; diff --git a/rostests/winetests/comctl32/propsheet.c b/rostests/winetests/comctl32/propsheet.c index bfbaaa0e7bd..92fb1dd19de 100644 --- a/rostests/winetests/comctl32/propsheet.c +++ b/rostests/winetests/comctl32/propsheet.c @@ -20,18 +20,37 @@ #include #include +#include "msg.h" #include "resources.h" #include "wine/test.h" -static HWND parent; +static HWND parenthwnd; static HWND sheethwnd; static LONG active_page = -1; #define IDC_APPLY_BUTTON 12321 + +/* try to make sure pending X events have been processed before continuing */ +static void flush_events(void) +{ + MSG msg; + int diff = 200; + int min_timeout = 100; + DWORD time = GetTickCount() + diff; + + while (diff > 0) + { + if (MsgWaitForMultipleObjects( 0, NULL, FALSE, min_timeout, QS_ALLINPUT ) == WAIT_TIMEOUT) break; + while (PeekMessage( &msg, 0, 0, 0, PM_REMOVE )) DispatchMessage( &msg ); + diff = time - GetTickCount(); + } +} + + static int CALLBACK sheet_callback(HWND hwnd, UINT msg, LPARAM lparam) { switch(msg) @@ -88,6 +107,7 @@ static void test_title(void) PROPSHEETPAGEA psp; PROPSHEETHEADERA psh; HWND hdlg; + DWORD style; memset(&psp, 0, sizeof(psp)); psp.dwSize = sizeof(psp); @@ -101,7 +121,7 @@ static void test_title(void) hpsp[0] = CreatePropertySheetPageA(&psp); memset(&psh, 0, sizeof(psh)); - psh.dwSize = sizeof(psh); + psh.dwSize = PROPSHEETHEADERA_V1_SIZE; psh.dwFlags = PSH_MODELESS | PSH_USECALLBACK; psh.pszCaption = "test caption"; psh.nPages = 1; @@ -110,12 +130,13 @@ 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); - } + ok(hdlg != INVALID_HANDLE_VALUE, "got invalid handle value %p\n", hdlg); + + style = GetWindowLong(hdlg, GWL_STYLE); + ok(style == (WS_POPUP|WS_VISIBLE|WS_CLIPSIBLINGS|WS_CAPTION|WS_SYSMENU| + DS_CONTEXTHELP|DS_MODALFRAME|DS_SETFONT|DS_3DLOOK), + "got unexpected style: %x\n", style); + DestroyWindow(hdlg); } @@ -124,7 +145,8 @@ static void test_nopage(void) HPROPSHEETPAGE hpsp[1]; PROPSHEETPAGEA psp; PROPSHEETHEADERA psh; - HWND hdlg; + HWND hdlg, hpage; + MSG msg; memset(&psp, 0, sizeof(psp)); psp.dwSize = sizeof(psp); @@ -138,7 +160,7 @@ static void test_nopage(void) hpsp[0] = CreatePropertySheetPageA(&psp); memset(&psh, 0, sizeof(psh)); - psh.dwSize = sizeof(psh); + psh.dwSize = PROPSHEETHEADERA_V1_SIZE; psh.dwFlags = PSH_MODELESS | PSH_USECALLBACK; psh.pszCaption = "test caption"; psh.nPages = 1; @@ -147,15 +169,18 @@ 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); - } + ok(hdlg != INVALID_HANDLE_VALUE, "got invalid handle value %p\n", hdlg); + ShowWindow(hdlg,SW_NORMAL); SendMessage(hdlg, PSM_REMOVEPAGE, 0, 0); + hpage = PropSheet_GetCurrentPageHwnd(hdlg); + ok(hpage == NULL, "expected no current page, got %p, index=%d\n", hpage, PropSheet_HwndToIndex(hdlg, hpage)); + flush_events(); RedrawWindow(hdlg,NULL,NULL,RDW_UPDATENOW|RDW_ERASENOW); + + /* Check that the property sheet was fully redrawn */ + ok(!PeekMessage(&msg, 0, WM_PAINT, WM_PAINT, PM_NOREMOVE), + "expected no pending WM_PAINT messages\n"); DestroyWindow(hdlg); } @@ -165,7 +190,7 @@ static int CALLBACK disableowner_callback(HWND hwnd, UINT msg, LPARAM lparam) { case PSCB_INITIALIZED: { - ok(IsWindowEnabled(parent) == 0, "parent window should be disabled\n"); + ok(IsWindowEnabled(parenthwnd) == 0, "parent window should be disabled\n"); PostQuitMessage(0); return FALSE; } @@ -198,7 +223,7 @@ static void test_disableowner(void) 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); + parenthwnd = CreateWindowA("parent class", "", WS_CAPTION | WS_SYSMENU | WS_VISIBLE, 100, 100, 100, 100, GetDesktopWindow(), NULL, GetModuleHandleA(NULL), 0); memset(&psp, 0, sizeof(psp)); psp.dwSize = sizeof(psp); @@ -212,19 +237,19 @@ static void test_disableowner(void) hpsp[0] = CreatePropertySheetPageA(&psp); memset(&psh, 0, sizeof(psh)); - psh.dwSize = sizeof(psh); + psh.dwSize = PROPSHEETHEADERA_V1_SIZE; psh.dwFlags = PSH_USECALLBACK; psh.pszCaption = "test caption"; psh.nPages = 1; - psh.hwndParent = parent; + psh.hwndParent = parenthwnd; U3(psh).phpage = hpsp; psh.pfnCallback = disableowner_callback; 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); + ok(IsWindowEnabled(parenthwnd) != 0, "parent window should be enabled\n"); + DestroyWindow(parenthwnd); } static INT_PTR CALLBACK nav_page_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) @@ -257,6 +282,7 @@ static void test_wiznavigation(void) PROPSHEETHEADERA psh; HWND hdlg, control; LONG_PTR controlID; + DWORD style; LRESULT defidres; BOOL hwndtoindex_supported = TRUE; const INT nextID = 12324; @@ -291,22 +317,22 @@ static void test_wiznavigation(void) /* set up the property sheet dialog */ memset(&psh, 0, sizeof(psh)); - psh.dwSize = sizeof(psh); + psh.dwSize = PROPSHEETHEADERA_V1_SIZE; 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(hdlg != INVALID_HANDLE_VALUE, "got invalid handle %p\n", hdlg); ok(active_page == 0, "Active page should be 0. Is: %d\n", active_page); + style = GetWindowLong(hdlg, GWL_STYLE) & ~(DS_CONTEXTHELP|WS_SYSMENU); + ok(style == (WS_POPUP|WS_VISIBLE|WS_CLIPSIBLINGS|WS_CAPTION| + DS_MODALFRAME|DS_SETFONT|DS_3DLOOK), + "got unexpected style: %x\n", style); + 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); @@ -394,7 +420,7 @@ static void test_buttons(void) hpsp[0] = CreatePropertySheetPageA(&psp); memset(&psh, 0, sizeof(psh)); - psh.dwSize = sizeof(psh); + psh.dwSize = PROPSHEETHEADERA_V1_SIZE; psh.dwFlags = PSH_MODELESS | PSH_USECALLBACK; psh.pszCaption = "test caption"; psh.nPages = 1; @@ -403,12 +429,7 @@ static void test_buttons(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); - } + ok(hdlg != INVALID_HANDLE_VALUE, "got null handle\n"); /* OK button */ button = GetDlgItem(hdlg, IDOK); @@ -478,7 +499,7 @@ static void test_custom_default_button(void) psp[0].pszTitle = "Page1"; psp[0].lParam = 0; - psh.dwSize = sizeof (PROPSHEETHEADERA); + psh.dwSize = PROPSHEETHEADERA_V1_SIZE; psh.dwFlags = PSH_PROPSHEETPAGE | PSH_MODELESS; psh.hwndParent = GetDesktopWindow(); psh.hInstance = GetModuleHandleA(NULL); @@ -519,12 +540,276 @@ static void test_custom_default_button(void) } } - todo_wine ok(add_button_has_been_pressed, "The Add button has not been pressed!\n"); DestroyWindow(hdlg); } +#define RECEIVER_SHEET_CALLBACK 0 +#define RECEIVER_SHEET_WINPROC 1 +#define RECEIVER_PAGE 2 + +#define NUM_MSG_SEQUENCES 1 +#define PROPSHEET_SEQ_INDEX 0 + +static struct msg_sequence *sequences[NUM_MSG_SEQUENCES]; +static WNDPROC oldWndProc; + +static const struct message property_sheet_seq[] = { + { PSCB_PRECREATE, sent|id, 0, 0, RECEIVER_SHEET_CALLBACK }, + { PSCB_INITIALIZED, sent|id, 0, 0, RECEIVER_SHEET_CALLBACK }, + { WM_WINDOWPOSCHANGING, sent|id, 0, 0, RECEIVER_SHEET_WINPROC }, + /*{ WM_NCCALCSIZE, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },*/ + { WM_WINDOWPOSCHANGED, sent|id, 0, 0, RECEIVER_SHEET_WINPROC }, + { WM_MOVE, sent|id, 0, 0, RECEIVER_SHEET_WINPROC }, + { WM_SIZE, sent|id, 0, 0, RECEIVER_SHEET_WINPROC }, + /*{ WM_GETTEXT, sent|id, 0, 0, RECEIVER_SHEET_WINPROC }, + { WM_GETICON, sent|id, 0, 0, RECEIVER_SHEET_WINPROC }, + { WM_GETICON, sent|id, 0, 0, RECEIVER_SHEET_WINPROC }, + { WM_GETICON, sent|id, 0, 0, RECEIVER_SHEET_WINPROC }, + { WM_NCCALCSIZE, sent|id|optional, 0, 0, RECEIVER_SHEET_WINPROC }, + { DM_REPOSITION, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },*/ + { WM_WINDOWPOSCHANGING, sent|id, 0, 0, RECEIVER_SHEET_WINPROC }, + { WM_WINDOWPOSCHANGING, sent|id, 0, 0, RECEIVER_SHEET_WINPROC }, + { WM_ACTIVATEAPP, sent|id, 0, 0, RECEIVER_SHEET_WINPROC }, + /*{ WM_NCACTIVATE, sent|id, 0, 0, RECEIVER_SHEET_WINPROC }, + { WM_GETTEXT, sent|id, 0, 0, RECEIVER_SHEET_WINPROC }, + { WM_GETICON, sent|id, 0, 0, RECEIVER_SHEET_WINPROC }, + { WM_GETICON, sent|id, 0, 0, RECEIVER_SHEET_WINPROC }, + { WM_GETICON, sent|id, 0, 0, RECEIVER_SHEET_WINPROC }, + { WM_GETTEXT, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },*/ + { WM_ACTIVATE, sent|id, 0, 0, RECEIVER_SHEET_WINPROC }, + /*{ WM_IME_SETCONTEXT, sent|id, 0, 0, RECEIVER_SHEET_WINPROC }, + { WM_IME_NOTIFY, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },*/ + { WM_SETFOCUS, sent|id, 0, 0, RECEIVER_SHEET_WINPROC }, + { WM_KILLFOCUS, sent|id, 0, 0, RECEIVER_SHEET_WINPROC }, + /*{ WM_IME_SETCONTEXT, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },*/ + { WM_PARENTNOTIFY, sent|id, 0, 0, RECEIVER_SHEET_WINPROC }, + { WM_INITDIALOG, sent|id, 0, 0, RECEIVER_PAGE }, + { WM_WINDOWPOSCHANGING, sent|id, 0, 0, RECEIVER_PAGE }, + /*{ WM_NCCALCSIZE, sent|id, 0, 0, RECEIVER_PAGE },*/ + { WM_CHILDACTIVATE, sent|id, 0, 0, RECEIVER_PAGE }, + { WM_WINDOWPOSCHANGED, sent|id, 0, 0, RECEIVER_PAGE }, + { WM_MOVE, sent|id, 0, 0, RECEIVER_PAGE }, + { WM_SIZE, sent|id, 0, 0, RECEIVER_PAGE }, + { WM_NOTIFY, sent|id, 0, 0, RECEIVER_PAGE }, + { WM_STYLECHANGING, sent|id|optional, 0, 0, RECEIVER_SHEET_WINPROC }, + { WM_STYLECHANGED, sent|id|optional, 0, 0, RECEIVER_SHEET_WINPROC }, + /*{ WM_GETTEXT, sent|id, 0, 0, RECEIVER_SHEET_WINPROC }, + { WM_GETICON, sent|id, 0, 0, RECEIVER_SHEET_WINPROC }, + { WM_GETICON, sent|id, 0, 0, RECEIVER_SHEET_WINPROC }, + { WM_GETICON, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },*/ + { WM_SETTEXT, sent|id, 0, 0, RECEIVER_SHEET_WINPROC }, + { WM_SHOWWINDOW, sent|id, 0, 0, RECEIVER_PAGE }, + /*{ 0x00000401, sent|id, 0, 0, RECEIVER_SHEET_WINPROC }, + { 0x00000400, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },*/ + { WM_CHANGEUISTATE, sent|id|optional, 0, 0, RECEIVER_SHEET_WINPROC }, + { WM_UPDATEUISTATE, sent|id|optional, 0, 0, RECEIVER_SHEET_WINPROC }, + { WM_UPDATEUISTATE, sent|id|optional, 0, 0, RECEIVER_PAGE }, + { WM_SHOWWINDOW, sent|id, 0, 0, RECEIVER_SHEET_WINPROC }, + { WM_WINDOWPOSCHANGING, sent|id, 0, 0, RECEIVER_SHEET_WINPROC }, + /*{ WM_NCPAINT, sent|id, 0, 0, RECEIVER_SHEET_WINPROC }, + { WM_GETICON, sent|id, 0, 0, RECEIVER_SHEET_WINPROC }, + { WM_GETICON, sent|id, 0, 0, RECEIVER_SHEET_WINPROC }, + { WM_GETICON, sent|id, 0, 0, RECEIVER_SHEET_WINPROC }, + { WM_ERASEBKGND, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },*/ + { WM_CTLCOLORDLG, sent|id, 0, 0, RECEIVER_SHEET_WINPROC }, + { WM_WINDOWPOSCHANGED, sent|id, 0, 0, RECEIVER_SHEET_WINPROC }, + /*{ WM_GETICON, sent|id, 0, 0, RECEIVER_SHEET_WINPROC }, + { WM_GETICON, sent|id, 0, 0, RECEIVER_SHEET_WINPROC }, + { WM_GETICON, sent|id, 0, 0, RECEIVER_SHEET_WINPROC }, + { WM_PAINT, sent|id, 0, 0, RECEIVER_SHEET_WINPROC }, + { WM_PAINT, sent|id, 0, 0, RECEIVER_PAGE }, + { WM_NCPAINT, sent|id, 0, 0, RECEIVER_PAGE }, + { WM_ERASEBKGND, sent|id, 0, 0, RECEIVER_PAGE },*/ + { WM_CTLCOLORDLG, sent|id, 0, 0, RECEIVER_PAGE }, + { WM_CTLCOLORSTATIC, sent|id, 0, 0, RECEIVER_PAGE }, + { WM_CTLCOLORSTATIC, sent|id, 0, 0, RECEIVER_SHEET_WINPROC }, + { WM_CTLCOLORBTN, sent|id, 0, 0, RECEIVER_SHEET_WINPROC }, + { WM_CTLCOLORBTN, sent|id, 0, 0, RECEIVER_SHEET_WINPROC }, + { WM_CTLCOLORBTN, sent|id, 0, 0, RECEIVER_SHEET_WINPROC }, + /*{ WM_GETICON, sent|id, 0, 0, RECEIVER_SHEET_WINPROC }, + { WM_GETICON, sent|id, 0, 0, RECEIVER_SHEET_WINPROC }, + { WM_GETICON, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },*/ + { WM_COMMAND, sent|id|optional, 0, 0, RECEIVER_SHEET_WINPROC }, + { WM_NOTIFY, sent|id|optional, 0, 0, RECEIVER_PAGE }, + { WM_NOTIFY, sent|id|optional, 0, 0, RECEIVER_PAGE }, + { WM_WINDOWPOSCHANGING, sent|id|optional, 0, 0, RECEIVER_SHEET_WINPROC }, + { WM_WINDOWPOSCHANGED, sent|id|optional, 0, 0, RECEIVER_SHEET_WINPROC }, + /*{ WM_NCACTIVATE, sent|id, 0, 0, RECEIVER_SHEET_WINPROC }, + { WM_GETICON, sent|id, 0, 0, RECEIVER_SHEET_WINPROC }, + { WM_GETICON, sent|id, 0, 0, RECEIVER_SHEET_WINPROC }, + { WM_GETICON, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },*/ + /*{ WM_ACTIVATE, sent|id, 0, 0, RECEIVER_SHEET_WINPROC }, + { WM_ACTIVATE, sent|id, 0, 0, RECEIVER_PAGE }, + { WM_ACTIVATEAPP, sent|id, 0, 0, RECEIVER_SHEET_WINPROC }, + { WM_ACTIVATEAPP, sent|id, 0, 0, RECEIVER_PAGE }, + { WM_DESTROY, sent|id, 0, 0, RECEIVER_SHEET_WINPROC }, + { WM_DESTROY, sent|id, 0, 0, RECEIVER_PAGE },*/ + /*{ WM_NCDESTROY, sent|id, 0, 0, RECEIVER_PAGE }, + { WM_NCDESTROY, sent|id, 0, 0, RECEIVER_SHEET_WINPROC },*/ + { 0 } +}; + +static void save_message(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam, INT receiver) +{ + struct message msg; + + if (message < WM_USER && + message != WM_GETICON && + message != WM_GETTEXT && + message != WM_IME_SETCONTEXT && + message != WM_IME_NOTIFY && + message != WM_PAINT && + message != WM_ERASEBKGND && + message != WM_SETCURSOR && + (message < WM_NCCREATE || message > WM_NCMBUTTONDBLCLK) && + (message < WM_MOUSEFIRST || message > WM_MOUSEHWHEEL) && + message != 0x90) + { + /*trace("check_message: %04x, %04x\n", message, receiver);*/ + + msg.message = message; + msg.flags = sent|wparam|lparam|id; + msg.wParam = wParam; + msg.lParam = lParam; + msg.id = receiver; + add_message(sequences, PROPSHEET_SEQ_INDEX, &msg); + } +} + +static LRESULT CALLBACK sheet_callback_messages_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + save_message(hwnd, msg, wParam, lParam, RECEIVER_SHEET_WINPROC); + + return CallWindowProc (oldWndProc, hwnd, msg, wParam, lParam); +} + +static int CALLBACK sheet_callback_messages(HWND hwnd, UINT msg, LPARAM lParam) +{ + save_message(hwnd, msg, 0, lParam, RECEIVER_SHEET_CALLBACK); + + switch (msg) + { + case PSCB_INITIALIZED: + oldWndProc = (WNDPROC)GetWindowLongPtr (hwnd, GWLP_WNDPROC); + SetWindowLongPtr (hwnd, GWLP_WNDPROC, (LONG_PTR)&sheet_callback_messages_proc); + return TRUE; + } + + return TRUE; +} + +static INT_PTR CALLBACK page_dlg_proc_messages(HWND hwnd, UINT msg, WPARAM wParam, + LPARAM lParam) +{ + save_message(hwnd, msg, wParam, lParam, RECEIVER_PAGE); + + return FALSE; +} + +static void test_messages(void) +{ + HPROPSHEETPAGE hpsp[1]; + PROPSHEETPAGEA psp; + PROPSHEETHEADERA psh; + HWND hdlg; + + init_msg_sequences(sequences, NUM_MSG_SEQUENCES); + + memset(&psp, 0, sizeof(psp)); + psp.dwSize = sizeof(psp); + psp.dwFlags = 0; + psp.hInstance = GetModuleHandleA(NULL); + U(psp).pszTemplate = MAKEINTRESOURCE(IDD_PROP_PAGE_MESSAGE_TEST); + U2(psp).pszIcon = NULL; + psp.pfnDlgProc = page_dlg_proc_messages; + psp.lParam = 0; + + hpsp[0] = CreatePropertySheetPageA(&psp); + + memset(&psh, 0, sizeof(psh)); + psh.dwSize = PROPSHEETHEADERA_V1_SIZE; + psh.dwFlags = PSH_NOAPPLYNOW | PSH_WIZARD | PSH_USECALLBACK + | PSH_MODELESS | PSH_USEICONID; + psh.pszCaption = "test caption"; + psh.nPages = 1; + psh.hwndParent = GetDesktopWindow(); + U3(psh).phpage = hpsp; + psh.pfnCallback = sheet_callback_messages; + + hdlg = (HWND)PropertySheetA(&psh); + ok(hdlg != INVALID_HANDLE_VALUE, "got invalid handle %p\n", hdlg); + + ShowWindow(hdlg,SW_NORMAL); + + ok_sequence(sequences, PROPSHEET_SEQ_INDEX, property_sheet_seq, "property sheet with custom window proc", TRUE); + + DestroyWindow(hdlg); +} + +static void test_PSM_ADDPAGE(void) +{ + HPROPSHEETPAGE hpsp[3]; + PROPSHEETPAGEA psp; + PROPSHEETHEADERA psh; + HWND hdlg, tab; + BOOL ret; + DWORD r; + + memset(&psp, 0, sizeof(psp)); + psp.dwSize = sizeof(psp); + psp.dwFlags = 0; + psp.hInstance = GetModuleHandleA(NULL); + U(psp).pszTemplate = MAKEINTRESOURCE(IDD_PROP_PAGE_MESSAGE_TEST); + U2(psp).pszIcon = NULL; + psp.pfnDlgProc = page_dlg_proc_messages; + psp.lParam = 0; + + /* two page with the same data */ + hpsp[0] = CreatePropertySheetPageA(&psp); + hpsp[1] = CreatePropertySheetPageA(&psp); + hpsp[2] = CreatePropertySheetPageA(&psp); + + memset(&psh, 0, sizeof(psh)); + psh.dwSize = PROPSHEETHEADERA_V1_SIZE; + psh.dwFlags = PSH_MODELESS; + psh.pszCaption = "test caption"; + psh.nPages = 1; + psh.hwndParent = GetDesktopWindow(); + U3(psh).phpage = hpsp; + + hdlg = (HWND)PropertySheetA(&psh); + ok(hdlg != INVALID_HANDLE_VALUE, "got invalid handle %p\n", hdlg); + + /* add pages one by one */ + ret = SendMessageA(hdlg, PSM_ADDPAGE, 0, (LPARAM)hpsp[1]); + ok(ret == TRUE, "got %d\n", ret); + + /* try with null and invalid value */ + ret = SendMessageA(hdlg, PSM_ADDPAGE, 0, 0); + ok(ret == FALSE, "got %d\n", ret); + +if (0) +{ + /* crashes on native */ + ret = SendMessageA(hdlg, PSM_ADDPAGE, 0, (LPARAM)INVALID_HANDLE_VALUE); +} + /* check item count */ + tab = (HWND)SendMessageA(hdlg, PSM_GETTABCONTROL, 0, 0); + + r = SendMessageA(tab, TCM_GETITEMCOUNT, 0, 0); + ok(r == 2, "got %d\n", r); + + ret = SendMessageA(hdlg, PSM_ADDPAGE, 0, (LPARAM)hpsp[2]); + ok(ret == TRUE, "got %d\n", ret); + + r = SendMessageA(tab, TCM_GETITEMCOUNT, 0, 0); + ok(r == 3, "got %d\n", r); + + DestroyWindow(hdlg); +} + START_TEST(propsheet) { test_title(); @@ -533,4 +818,6 @@ START_TEST(propsheet) test_wiznavigation(); test_buttons(); test_custom_default_button(); + test_messages(); + test_PSM_ADDPAGE(); } diff --git a/rostests/winetests/comctl32/rebar.c b/rostests/winetests/comctl32/rebar.c index d5f27b926a4..88c931c633a 100644 --- a/rostests/winetests/comctl32/rebar.c +++ b/rostests/winetests/comctl32/rebar.c @@ -30,8 +30,9 @@ #include "wine/test.h" -RECT height_change_notify_rect; +static RECT height_change_notify_rect; static HWND hMainWnd; +static int system_font_height; #define check_rect(name, val, exp) ok(val.top == exp.top && val.bottom == exp.bottom && \ @@ -46,7 +47,8 @@ static HWND hMainWnd; #define compare(val, exp, format) ok((val) == (exp), #val " value " format " expected " format "\n", (val), (exp)); -#define expect_eq(expr, value, type, format) { type ret = expr; ok((value) == ret, #expr " expected " format " got " format "\n", (value), (ret)); } +#define expect_eq(line, expr, value, type, format) { type ret = expr;\ + ok((value) == ret, #expr " expected " format " got " format " from line %d\n", (value), (ret), line); } static INT CALLBACK is_font_installed_proc(const LOGFONT *elf, const TEXTMETRIC *ntm, DWORD type, LPARAM lParam) { @@ -65,6 +67,17 @@ static BOOL is_font_installed(const char *name) return ret; } +static void init_system_font_height(void) { + HDC hDC; + TEXTMETRIC tm; + + hDC = CreateCompatibleDC(NULL); + GetTextMetrics(hDC, &tm); + DeleteDC(NULL); + + system_font_height = tm.tmHeight; +} + static HWND create_rebar_control(void) { HWND hwnd; @@ -167,131 +180,258 @@ static void dump_sizes(HWND hRebar) #else +static int string_width(const CHAR *s) { + SIZE sz; + HDC hdc; + + hdc = CreateCompatibleDC(NULL); + GetTextExtentPoint32A(hdc, s, strlen(s), &sz); + DeleteDC(hdc); + + return sz.cx; +} + typedef struct { RECT rc; DWORD fStyle; - INT cx; + UINT cx; } rbband_result_t; typedef struct { RECT rcClient; int cyBarHeight; int nRows; - int cyRowHeights[50]; + int *cyRowHeights; int nBands; - rbband_result_t bands[50]; + rbband_result_t *bands; } rbsize_result_t; -rbsize_result_t rbsize_results[] = { - { {0, 0, 672, 0}, 0, 0, {0, }, 0, {{{0, 0, 0, 0}, 0, 0}, - }, }, - { {0, 0, 672, 4}, 4, 1, {4, }, 1, { - { { 0, 0, 672, 4}, 0x00, 200}, - }, }, - { {0, 0, 672, 4}, 4, 1, {4, }, 2, { - { { 0, 0, 200, 4}, 0x00, 200}, { {200, 0, 672, 4}, 0x04, 200}, - }, }, - { {0, 0, 672, 30}, 30, 1, {30, }, 3, { - { { 0, 0, 200, 30}, 0x00, 200}, { {200, 0, 400, 30}, 0x04, 200}, - { {400, 0, 672, 30}, 0x00, 200}, - }, }, - { {0, 0, 672, 34}, 34, 1, {34, }, 4, { - { { 0, 0, 200, 34}, 0x00, 200}, { {200, 0, 400, 34}, 0x04, 200}, - { {400, 0, 604, 34}, 0x00, 200}, { {604, 0, 672, 34}, 0x04, 68}, - }, }, - { {0, 0, 672, 34}, 34, 1, {34, }, 4, { - { { 0, 0, 200, 34}, 0x00, 200}, { {200, 0, 400, 34}, 0x04, 200}, - { {400, 0, 604, 34}, 0x00, 200}, { {604, 0, 672, 34}, 0x04, 68}, - }, }, - { {0, 0, 672, 34}, 34, 1, {34, }, 4, { - { { 0, 0, 200, 34}, 0x00, 200}, { {202, 0, 402, 34}, 0x04, 200}, - { {404, 0, 604, 34}, 0x00, 200}, { {606, 0, 672, 34}, 0x04, 66}, - }, }, - { {0, 0, 672, 70}, 70, 2, {34, 34, }, 5, { - { { 0, 0, 142, 34}, 0x00, 200}, { {144, 0, 557, 34}, 0x00, 200}, - { {559, 0, 672, 34}, 0x04, 200}, { { 0, 36, 200, 70}, 0x00, 200}, - { {202, 36, 672, 70}, 0x04, 66}, - }, }, - { {0, 0, 672, 34}, 34, 1, {34, }, 5, { - { { 0, 0, 167, 34}, 0x00, 200}, { {169, 0, 582, 34}, 0x00, 200}, - { {559, 0, 759, 34}, 0x08, 200}, { {584, 0, 627, 34}, 0x00, 200}, - { {629, 0, 672, 34}, 0x04, 66}, - }, }, - { {0, 0, 672, 34}, 34, 1, {34, }, 4, { - { { 0, 0, 167, 34}, 0x00, 200}, { {169, 0, 582, 34}, 0x00, 200}, - { {584, 0, 627, 34}, 0x00, 200}, { {629, 0, 672, 34}, 0x04, 66}, - }, }, - { {0, 0, 672, 34}, 34, 1, {34, }, 3, { - { { 0, 0, 413, 34}, 0x00, 200}, { {415, 0, 615, 34}, 0x00, 200}, - { {617, 0, 672, 34}, 0x04, 66}, - }, }, - { {0, 0, 672, 34}, 34, 1, {34, }, 2, { - { { 0, 0, 604, 34}, 0x00, 200}, { {606, 0, 672, 34}, 0x04, 66}, - }, }, - { {0, 0, 672, 40}, 40, 2, {20, 20, }, 5, { - { { 0, 0, 114, 20}, 0x00, 40}, { {114, 0, 184, 20}, 0x00, 70}, - { {184, 0, 424, 20}, 0x00, 240}, { {424, 0, 672, 20}, 0x00, 60}, - { { 0, 20, 672, 40}, 0x00, 200}, - }, }, - { {0, 0, 672, 40}, 40, 2, {20, 20, }, 5, { - { { 0, 0, 114, 20}, 0x00, 40}, { {114, 0, 227, 20}, 0x00, 113}, - { {227, 0, 424, 20}, 0x00, 197}, { {424, 0, 672, 20}, 0x00, 60}, - { { 0, 20, 672, 40}, 0x00, 200}, - }, }, - { {0, 0, 672, 40}, 40, 2, {20, 20, }, 5, { - { { 0, 0, 114, 20}, 0x00, 40}, { {114, 0, 328, 20}, 0x00, 214}, - { {328, 0, 511, 20}, 0x00, 183}, { {511, 0, 672, 20}, 0x00, 161}, - { { 0, 20, 672, 40}, 0x00, 200}, - }, }, - { {0, 0, 672, 40}, 40, 2, {20, 20, }, 5, { - { { 0, 0, 114, 20}, 0x00, 40}, { {114, 0, 167, 20}, 0x00, 53}, - { {167, 0, 511, 20}, 0x00, 344}, { {511, 0, 672, 20}, 0x00, 161}, - { { 0, 20, 672, 40}, 0x00, 200}, - }, }, - { {0, 0, 672, 40}, 40, 2, {20, 20, }, 5, { - { { 0, 0, 114, 20}, 0x00, 40}, { {114, 0, 328, 20}, 0x00, 214}, - { {328, 0, 511, 20}, 0x00, 183}, { {511, 0, 672, 20}, 0x00, 161}, - { { 0, 20, 672, 40}, 0x00, 200}, - }, }, - { {0, 0, 672, 40}, 40, 2, {20, 20, }, 5, { - { { 0, 0, 114, 20}, 0x00, 40}, { {114, 0, 328, 20}, 0x00, 214}, - { {328, 0, 511, 20}, 0x00, 183}, { {511, 0, 672, 20}, 0x00, 161}, - { { 0, 20, 672, 40}, 0x00, 200}, - }, }, - { {0, 0, 672, 56}, 56, 2, {28, 28, }, 5, { - { { 0, 0, 114, 28}, 0x00, 40}, { {114, 0, 328, 28}, 0x00, 214}, - { {328, 0, 511, 28}, 0x00, 183}, { {511, 0, 672, 28}, 0x00, 161}, - { { 0, 28, 672, 56}, 0x00, 200}, - }, }, - { {0, 0, 672, 40}, 40, 2, {20, 20, }, 5, { - { { 0, 0, 114, 20}, 0x00, 40}, { {114, 0, 328, 20}, 0x00, 214}, - { {328, 0, 511, 20}, 0x00, 183}, { {511, 0, 672, 20}, 0x00, 161}, - { { 0, 20, 672, 40}, 0x00, 200}, - }, }, - { {0, 0, 672, 56}, 56, 2, {28, 28, }, 5, { - { { 0, 0, 114, 28}, 0x00, 40}, { {114, 0, 328, 28}, 0x00, 214}, - { {328, 0, 511, 28}, 0x00, 183}, { {511, 0, 672, 28}, 0x00, 161}, - { { 0, 28, 672, 56}, 0x00, 200}, - }, }, - { {0, 0, 672, 0}, 0, 0, {0, }, 0, {{{0, 0, 0, 0}, 0, 0}, - }, }, - { {0, 0, 672, 65}, 65, 1, {65, }, 3, { - { { 0, 0, 90, 65}, 0x40, 90}, { { 90, 0, 180, 65}, 0x40, 90}, - { {180, 0, 672, 65}, 0x40, 90}, - }, }, - { {0, 0, 0, 226}, 0, 0, {0, }, 0, {{{0, 0, 0, 0}, 0, 0}, - }, }, - { {0, 0, 65, 226}, 65, 1, {65, }, 1, { - { { 0, 0, 226, 65}, 0x40, 90}, - }, }, - { {0, 0, 65, 226}, 65, 1, {65, }, 2, { - { { 0, 0, 90, 65}, 0x40, 90}, { { 90, 0, 226, 65}, 0x40, 90}, - }, }, - { {0, 0, 65, 226}, 65, 1, {65, }, 3, { - { { 0, 0, 90, 65}, 0x40, 90}, { { 90, 0, 163, 65}, 0x40, 90}, - { {163, 0, 226, 65}, 0x40, 90}, - }, }, -}; +static rbsize_result_t rbsize_init(int cleft, int ctop, int cright, int cbottom, int cyBarHeight, int nRows, int nBands) +{ + rbsize_result_t ret; + + SetRect(&ret.rcClient, cleft, ctop, cright, cbottom); + ret.cyBarHeight = cyBarHeight; + ret.nRows = 0; + ret.cyRowHeights = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, nRows*sizeof(int)); + ret.nBands = 0; + ret.bands = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, nBands*sizeof(rbband_result_t)); + + return ret; +} + +static void rbsize_add_row(rbsize_result_t *rbsr, int rowHeight) { + rbsr->cyRowHeights[rbsr->nRows] = rowHeight; + rbsr->nRows++; +} + +static void rbsize_add_band(rbsize_result_t *rbsr, int left, int top, int right, int bottom, DWORD fStyle, UINT cx) +{ + SetRect(&(rbsr->bands[rbsr->nBands].rc), left, top, right, bottom); + rbsr->bands[rbsr->nBands].fStyle = fStyle; + rbsr->bands[rbsr->nBands].cx = cx; + rbsr->nBands++; +} + +static rbsize_result_t *rbsize_results; + +#define rbsize_results_num 27 + +static void rbsize_results_init(void) +{ + rbsize_results = HeapAlloc(GetProcessHeap(), 0, rbsize_results_num*sizeof(rbsize_result_t)); + + rbsize_results[0] = rbsize_init(0, 0, 672, 0, 0, 0, 0); + + rbsize_results[1] = rbsize_init(0, 0, 672, 4, 4, 1, 1); + rbsize_add_row(&rbsize_results[1], 4); + rbsize_add_band(&rbsize_results[1], 0, 0, 672, 4, 0x00, 200); + + rbsize_results[2] = rbsize_init(0, 0, 672, 4, 4, 1, 2); + rbsize_add_row(&rbsize_results[2], 4); + rbsize_add_band(&rbsize_results[2], 0, 0, 200, 4, 0x00, 200); + rbsize_add_band(&rbsize_results[2], 200, 0, 672, 4, 0x04, 200); + + rbsize_results[3] = rbsize_init(0, 0, 672, 30, 30, 1, 3); + rbsize_add_row(&rbsize_results[3], 30); + rbsize_add_band(&rbsize_results[3], 0, 0, 200, 30, 0x00, 200); + rbsize_add_band(&rbsize_results[3], 200, 0, 400, 30, 0x04, 200); + rbsize_add_band(&rbsize_results[3], 400, 0, 672, 30, 0x00, 200); + + rbsize_results[4] = rbsize_init(0, 0, 672, 34, 34, 1, 4); + rbsize_add_row(&rbsize_results[4], 34); + rbsize_add_band(&rbsize_results[4], 0, 0, 200, 34, 0x00, 200); + rbsize_add_band(&rbsize_results[4], 200, 0, 400, 34, 0x04, 200); + rbsize_add_band(&rbsize_results[4], 400, 0, 604, 34, 0x00, 200); + rbsize_add_band(&rbsize_results[4], 604, 0, 672, 34, 0x04, 68); + + rbsize_results[5] = rbsize_init(0, 0, 672, 34, 34, 1, 4); + rbsize_add_row(&rbsize_results[5], 34); + rbsize_add_band(&rbsize_results[5], 0, 0, 200, 34, 0x00, 200); + rbsize_add_band(&rbsize_results[5], 200, 0, 400, 34, 0x04, 200); + rbsize_add_band(&rbsize_results[5], 400, 0, 604, 34, 0x00, 200); + rbsize_add_band(&rbsize_results[5], 604, 0, 672, 34, 0x04, 68); + + rbsize_results[6] = rbsize_init(0, 0, 672, 34, 34, 1, 4); + rbsize_add_row(&rbsize_results[6], 34); + rbsize_add_band(&rbsize_results[6], 0, 0, 200, 34, 0x00, 200); + rbsize_add_band(&rbsize_results[6], 202, 0, 402, 34, 0x04, 200); + rbsize_add_band(&rbsize_results[6], 404, 0, 604, 34, 0x00, 200); + rbsize_add_band(&rbsize_results[6], 606, 0, 672, 34, 0x04, 66); + + rbsize_results[7] = rbsize_init(0, 0, 672, 70, 70, 2, 5); + rbsize_add_row(&rbsize_results[7], 34); + rbsize_add_row(&rbsize_results[7], 34); + rbsize_add_band(&rbsize_results[7], 0, 0, 142, 34, 0x00, 200); + rbsize_add_band(&rbsize_results[7], 144, 0, 557, 34, 0x00, 200); + rbsize_add_band(&rbsize_results[7], 559, 0, 672, 34, 0x04, 200); + rbsize_add_band(&rbsize_results[7], 0, 36, 200, 70, 0x00, 200); + rbsize_add_band(&rbsize_results[7], 202, 36, 672, 70, 0x04, 66); + + rbsize_results[8] = rbsize_init(0, 0, 672, 34, 34, 1, 5); + rbsize_add_row(&rbsize_results[8], 34); + rbsize_add_band(&rbsize_results[8], 0, 0, 167, 34, 0x00, 200); + rbsize_add_band(&rbsize_results[8], 169, 0, 582, 34, 0x00, 200); + rbsize_add_band(&rbsize_results[8], 559, 0, 759, 34, 0x08, 200); + rbsize_add_band(&rbsize_results[8], 584, 0, 627, 34, 0x00, 200); + rbsize_add_band(&rbsize_results[8], 629, 0, 672, 34, 0x04, 66); + + rbsize_results[9] = rbsize_init(0, 0, 672, 34, 34, 1, 4); + rbsize_add_row(&rbsize_results[9], 34); + rbsize_add_band(&rbsize_results[9], 0, 0, 167, 34, 0x00, 200); + rbsize_add_band(&rbsize_results[9], 169, 0, 582, 34, 0x00, 200); + rbsize_add_band(&rbsize_results[9], 584, 0, 627, 34, 0x00, 200); + rbsize_add_band(&rbsize_results[9], 629, 0, 672, 34, 0x04, 66); + + rbsize_results[10] = rbsize_init(0, 0, 672, 34, 34, 1, 3); + rbsize_add_row(&rbsize_results[10], 34); + rbsize_add_band(&rbsize_results[10], 0, 0, 413, 34, 0x00, 200); + rbsize_add_band(&rbsize_results[10], 415, 0, 615, 34, 0x00, 200); + rbsize_add_band(&rbsize_results[10], 617, 0, 672, 34, 0x04, 66); + + rbsize_results[11] = rbsize_init(0, 0, 672, 34, 34, 1, 2); + rbsize_add_row(&rbsize_results[11], 34); + rbsize_add_band(&rbsize_results[11], 0, 0, 604, 34, 0x00, 200); + rbsize_add_band(&rbsize_results[11], 606, 0, 672, 34, 0x04, 66); + + rbsize_results[12] = rbsize_init(0, 0, 672, 8 + 2*system_font_height, 40, 2, 5); + rbsize_add_row(&rbsize_results[12], 4 + system_font_height); + rbsize_add_row(&rbsize_results[12], 4 + system_font_height); + rbsize_add_band(&rbsize_results[12], 0, 0, 87 + string_width("ABC"), 4 + system_font_height, 0x00, 40); + rbsize_add_band(&rbsize_results[12], 87 + string_width("ABC"), 0, 157 + string_width("ABC"), 4 + system_font_height, 0x00, 70); + rbsize_add_band(&rbsize_results[12], 157 + string_width("ABC"), 0, 397 + string_width("ABC"), 4 + system_font_height, 0x00, 240); + rbsize_add_band(&rbsize_results[12], 397 + string_width("ABC"), 0, 672, 4 + system_font_height, 0x00, 60); + rbsize_add_band(&rbsize_results[12], 0, 4 + system_font_height, 672, 8 + 2*system_font_height, 0x00, 200); + + rbsize_results[13] = rbsize_init(0, 0, 672, 8 + 2*system_font_height, 40, 2, 5); + rbsize_add_row(&rbsize_results[13], 4 + system_font_height); + rbsize_add_row(&rbsize_results[13], 4 + system_font_height); + rbsize_add_band(&rbsize_results[13], 0, 0, 87 + string_width("ABC"), 4 + system_font_height, 0x00, 40); + rbsize_add_band(&rbsize_results[13], 87 + string_width("ABC"), 0, 200 + string_width("ABC"), 4 + system_font_height, 0x00, 113); + rbsize_add_band(&rbsize_results[13], 200 + string_width("ABC"), 0, 397 + string_width("ABC"), 4 + system_font_height, 0x00, 197); + rbsize_add_band(&rbsize_results[13], 397 + string_width("ABC"), 0, 672, 4 + system_font_height, 0x00, 60); + rbsize_add_band(&rbsize_results[13], 0, 4 + system_font_height, 672, 8 + 2*system_font_height, 0x00, 200); + + rbsize_results[14] = rbsize_init(0, 0, 672, 8 + 2*system_font_height, 40, 2, 5); + rbsize_add_row(&rbsize_results[14], 4 + system_font_height); + rbsize_add_row(&rbsize_results[14], 4 + system_font_height); + rbsize_add_band(&rbsize_results[14], 0, 0, 87 + string_width("ABC"), 4 + system_font_height, 0x00, 40); + rbsize_add_band(&rbsize_results[14], 87 + string_width("ABC"), 0, 412 - string_width("MMMMMMM"), 4 + system_font_height, 0x00, 325 - string_width("ABC") - string_width("MMMMMMM")); + rbsize_add_band(&rbsize_results[14], 412 - string_width("MMMMMMM"), 0, 595 - string_width("MMMMMMM"), 4 + system_font_height, 0x00, 183); + rbsize_add_band(&rbsize_results[14], 595 - string_width("MMMMMMM"), 0, 672, 4 + system_font_height, 0x00, 77 + string_width("MMMMMMM")); + rbsize_add_band(&rbsize_results[14], 0, 4 + system_font_height, 672, 8 + 2*system_font_height, 0x00, 200); + + rbsize_results[15] = rbsize_init(0, 0, 672, 8 + 2*system_font_height, 40, 2, 5); + rbsize_add_row(&rbsize_results[15], 4 + system_font_height); + rbsize_add_row(&rbsize_results[15], 4 + system_font_height); + rbsize_add_band(&rbsize_results[15], 0, 0, 87 + string_width("ABC"), 4 + system_font_height, 0x00, 40); + rbsize_add_band(&rbsize_results[15], 87 + string_width("ABC"), 0, 140 + string_width("ABC"), 4 + system_font_height, 0x00, 53); + rbsize_add_band(&rbsize_results[15], 140 + string_width("ABC"), 0, 595 - string_width("MMMMMMM"), 4 + system_font_height, 0x00, 455 - string_width("MMMMMMM") - string_width("ABC")); + rbsize_add_band(&rbsize_results[15], 595 - string_width("MMMMMMM"), 0, 672, 4 + system_font_height, 0x00, 77 + string_width("MMMMMMM")); + rbsize_add_band(&rbsize_results[15], 0, 4 + system_font_height, 672, 8 + 2*system_font_height, 0x00, 200); + + rbsize_results[16] = rbsize_init(0, 0, 672, 8 + 2*system_font_height, 40, 2, 5); + rbsize_add_row(&rbsize_results[16], 4 + system_font_height); + rbsize_add_row(&rbsize_results[16], 4 + system_font_height); + rbsize_add_band(&rbsize_results[16], 0, 0, 87 + string_width("ABC"), 4 + system_font_height, 0x00, 40); + rbsize_add_band(&rbsize_results[16], 87 + string_width("ABC"), 0, 412 - string_width("MMMMMMM"), 4 + system_font_height, 0x00, 325 - string_width("ABC") - string_width("MMMMMMM")); + rbsize_add_band(&rbsize_results[16], 412 - string_width("MMMMMMM"), 0, 595 - string_width("MMMMMMM"), 4 + system_font_height, 0x00, 183); + rbsize_add_band(&rbsize_results[16], 595 - string_width("MMMMMMM"), 0, 672, 4 + system_font_height, 0x00, 77 + string_width("MMMMMMM")); + rbsize_add_band(&rbsize_results[16], 0, 4 + system_font_height, 672, 8 + 2*system_font_height, 0x00, 200); + + rbsize_results[17] = rbsize_init(0, 0, 672, 8 + 2*system_font_height, 40, 2, 5); + rbsize_add_row(&rbsize_results[17], 4 + system_font_height); + rbsize_add_row(&rbsize_results[17], 4 + system_font_height); + rbsize_add_band(&rbsize_results[17], 0, 0, 87 + string_width("ABC"), 4 + system_font_height, 0x00, 40); + rbsize_add_band(&rbsize_results[17], 87 + string_width("ABC"), 0, 412 - string_width("MMMMMMM"), 4 + system_font_height, 0x00, 325 - string_width("ABC") - string_width("MMMMMMM")); + rbsize_add_band(&rbsize_results[17], 412 - string_width("MMMMMMM"), 0, 595 - string_width("MMMMMMM"), 4 + system_font_height, 0x00, 183); + rbsize_add_band(&rbsize_results[17], 595 - string_width("MMMMMMM"), 0, 672, 4 + system_font_height, 0x00, 77 + string_width("MMMMMMM")); + rbsize_add_band(&rbsize_results[17], 0, 4 + system_font_height, 672, 8 + 2*system_font_height, 0x00, 200); + + rbsize_results[18] = rbsize_init(0, 0, 672, 56, 56, 2, 5); + rbsize_add_row(&rbsize_results[18], 28); + rbsize_add_row(&rbsize_results[18], 28); + rbsize_add_band(&rbsize_results[18], 0, 0, 87 + string_width("ABC"), 28, 0x00, 40); + rbsize_add_band(&rbsize_results[18], 87 + string_width("ABC"), 0, 412 - string_width("MMMMMMM"), 28, 0x00, 325 - string_width("ABC") - string_width("MMMMMMM")); + rbsize_add_band(&rbsize_results[18], 412 - string_width("MMMMMMM"), 0, 595 - string_width("MMMMMMM"), 28, 0x00, 183); + rbsize_add_band(&rbsize_results[18], 595 - string_width("MMMMMMM"), 0, 672, 28, 0x00, 77 + string_width("MMMMMMM")); + rbsize_add_band(&rbsize_results[18], 0, 28, 672, 56, 0x00, 200); + + rbsize_results[19] = rbsize_init(0, 0, 672, 8 + 2*system_font_height, 40, 2, 5); + rbsize_add_row(&rbsize_results[19], 4 + system_font_height); + rbsize_add_row(&rbsize_results[19], 4 + system_font_height); + rbsize_add_band(&rbsize_results[19], 0, 0, 87 + string_width("ABC"), 4 + system_font_height, 0x00, 40); + rbsize_add_band(&rbsize_results[19], 87 + string_width("ABC"), 0, 412 - string_width("MMMMMMM"), 4 + system_font_height, 0x00, 325 - string_width("ABC") - string_width("MMMMMMM")); + rbsize_add_band(&rbsize_results[19], 412 - string_width("MMMMMMM"), 0, 595 - string_width("MMMMMMM"), 4 + system_font_height, 0x00, 183); + rbsize_add_band(&rbsize_results[19], 595 - string_width("MMMMMMM"), 0, 672, 4 + system_font_height, 0x00, 77 + string_width("MMMMMMM")); + rbsize_add_band(&rbsize_results[19], 0, 4 + system_font_height, 672, 8 + 2*system_font_height, 0x00, 200); + + rbsize_results[20] = rbsize_init(0, 0, 672, 56, 56, 2, 5); + rbsize_add_row(&rbsize_results[20], 28); + rbsize_add_row(&rbsize_results[20], 28); + rbsize_add_band(&rbsize_results[20], 0, 0, 87 + string_width("ABC"), 28, 0x00, 40); + rbsize_add_band(&rbsize_results[20], 87 + string_width("ABC"), 0, 412 - string_width("MMMMMMM"), 28, 0x00, 325 - string_width("ABC") - string_width("MMMMMMM")); + rbsize_add_band(&rbsize_results[20], 412 - string_width("MMMMMMM"), 0, 595 - string_width("MMMMMMM"), 28, 0x00, 183); + rbsize_add_band(&rbsize_results[20], 595 - string_width("MMMMMMM"), 0, 672, 28, 0x00, 77 + string_width("MMMMMMM")); + rbsize_add_band(&rbsize_results[20], 0, 28, 672, 56, 0x00, 200); + + rbsize_results[21] = rbsize_init(0, 0, 672, 0, 0, 0, 0); + + rbsize_results[22] = rbsize_init(0, 0, 672, 65, 56, 1, 3); + rbsize_add_row(&rbsize_results[22], 65); + rbsize_add_band(&rbsize_results[22], 0, 0, 90, 65, 0x40, 90); + rbsize_add_band(&rbsize_results[22], 90, 0, 180, 65, 0x40, 90); + rbsize_add_band(&rbsize_results[22], 180, 0, 672, 65, 0x40, 90); + + rbsize_results[23] = rbsize_init(0, 0, 0, 226, 0, 0, 0); + + rbsize_results[24] = rbsize_init(0, 0, 65, 226, 65, 1, 1); + rbsize_add_row(&rbsize_results[24], 65); + rbsize_add_band(&rbsize_results[24], 0, 0, 226, 65, 0x40, 90); + + rbsize_results[25] = rbsize_init(0, 0, 65, 226, 65, 1, 2); + rbsize_add_row(&rbsize_results[25], 65); + rbsize_add_band(&rbsize_results[25], 0, 0, 90, 65, 0x40, 90); + rbsize_add_band(&rbsize_results[25], 90, 0, 226, 65, 0x40, 90); + + rbsize_results[26] = rbsize_init(0, 0, 65, 226, 65, 1, 3); + rbsize_add_row(&rbsize_results[26], 65); + rbsize_add_band(&rbsize_results[26], 0, 0, 90, 65, 0x40, 90); + rbsize_add_band(&rbsize_results[26], 90, 0, 163, 65, 0x40, 90); + rbsize_add_band(&rbsize_results[26], 163, 0, 226, 65, 0x40, 90); +} + +static void rbsize_results_free(void) +{ + int i; + + for (i = 0; i < rbsize_results_num; i++) { + HeapFree(GetProcessHeap(), 0, rbsize_results[i].cyRowHeights); + HeapFree(GetProcessHeap(), 0, rbsize_results[i].bands); + } + HeapFree(GetProcessHeap(), 0, rbsize_results); + rbsize_results = NULL; +} static int rbsize_numtests = 0; @@ -299,8 +439,7 @@ static int rbsize_numtests = 0; RECT rc; \ REBARBANDINFO rbi; \ int count, i/*, mask=(todomask)*/; \ - rbsize_result_t *res = &rbsize_results[rbsize_numtests]; \ - assert(rbsize_numtests < sizeof(rbsize_results)/sizeof(rbsize_results[0])); \ + const rbsize_result_t *res = &rbsize_results[rbsize_numtests]; \ GetClientRect(hRebar, &rc); \ check_rect("client", rc, res->rcClient); \ count = SendMessage(hRebar, RB_GETROWCOUNT, 0, 0); \ @@ -353,6 +492,8 @@ static void test_layout(void) HIMAGELIST himl; REBARINFO ri; + rbsize_results_init(); + hRebar = create_rebar_control(); check_sizes(); rbi.cbSize = REBARBANDINFOA_V6_SIZE; @@ -510,6 +651,7 @@ static void test_layout(void) SendMessageA(hRebar, RB_INSERTBAND, -1, (LPARAM)&rbi); check_sizes(); + rbsize_results_free(); DestroyWindow(hRebar); ImageList_Destroy(himl); } @@ -547,7 +689,7 @@ typedef struct { BOOL heightNotify; } rbresize_test_result_t; -rbresize_test_result_t resize_results[] = { +static const rbresize_test_result_t resize_results[] = { /* style 00000001 */ {{0, 2, 672, 2}, 0, FALSE}, {{0, 2, 672, 22}, 1, TRUE}, @@ -668,12 +810,13 @@ rbresize_test_result_t resize_results[] = { {{-2, 0, 674, 24}, 0, FALSE}, }; -static int resize_numtests = 0; +static DWORD resize_numtests = 0; #define comment(fmt, arg1) #define check_client() { \ RECT r; \ - rbresize_test_result_t *res = &resize_results[resize_numtests++]; \ + int value; \ + const rbresize_test_result_t *res = &resize_results[resize_numtests++]; \ assert(resize_numtests <= sizeof(resize_results)/sizeof(resize_results[0])); \ GetWindowRect(hRebar, &r); \ MapWindowPoints(HWND_DESKTOP, hMainWnd, (LPPOINT)&r, 2); \ @@ -682,7 +825,8 @@ static int resize_numtests = 0; } else { \ check_rect("client", r, res->rc); \ } \ - expect_eq((int)SendMessage(hRebar, RB_GETROWCOUNT, 0, 0), res->iNumRows, int, "%d"); \ + value = (int)SendMessage(hRebar, RB_GETROWCOUNT, 0, 0); \ + ok(res->iNumRows == value, "RB_GETROWCOUNT expected %d got %d\n", res->iNumRows, value); \ if (res->heightNotify) { \ RECT rcClient; \ GetClientRect(hRebar, &rcClient); \ @@ -746,11 +890,11 @@ static void test_resize(void) } } -static void expect_band_content(HWND hRebar, UINT uBand, INT fStyle, COLORREF clrFore, +static void expect_band_content_(int line, 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_broken) + UINT cxHeader, UINT cxHeader_broken) { CHAR buf[MAX_PATH] = "abc"; REBARBANDINFOA rb; @@ -762,28 +906,35 @@ static void expect_band_content(HWND hRebar, UINT uBand, INT fStyle, COLORREF cl | RBBIM_SIZE | RBBIM_STYLE | RBBIM_TEXT; rb.lpText = buf; rb.cch = MAX_PATH; - ok(SendMessageA(hRebar, RB_GETBANDINFOA, uBand, (LPARAM)&rb), "RB_GETBANDINFO failed\n"); - expect_eq(rb.fStyle, fStyle, int, "%x"); - 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"); - expect_eq(rb.cxMinChild, cxMinChild, int, "%d"); - expect_eq(rb.cyMinChild, cyMinChild, int, "%d"); - expect_eq(rb.cx, cx, int, "%d"); - expect_eq(rb.hbmBack, hbmBack, HBITMAP, "%p"); - expect_eq(rb.wID, wID, int, "%d"); + ok(SendMessageA(hRebar, RB_GETBANDINFOA, uBand, (LPARAM)&rb), "RB_GETBANDINFO failed from line %d\n", line); + expect_eq(line, rb.fStyle, fStyle, int, "%x"); + expect_eq(line, rb.clrFore, clrFore, COLORREF, "%x"); + expect_eq(line, rb.clrBack, clrBack, COLORREF, "%x"); + expect_eq(line, strcmp(rb.lpText, lpText), 0, int, "%d"); + expect_eq(line, rb.iImage, iImage, int, "%x"); + expect_eq(line, rb.hwndChild, hwndChild, HWND, "%p"); + expect_eq(line, rb.cxMinChild, cxMinChild, int, "%d"); + expect_eq(line, rb.cyMinChild, cyMinChild, int, "%d"); + expect_eq(line, rb.cx, cx, int, "%d"); + expect_eq(line, rb.hbmBack, hbmBack, HBITMAP, "%p"); + expect_eq(line, rb.wID, wID, int, "%d"); /* the values of cyChild, cyMaxChild and cyIntegral can't be read unless the band is RBBS_VARIABLEHEIGHT */ - expect_eq(rb.cyChild, cyChild, int, "%x"); - expect_eq(rb.cyMaxChild, cyMaxChild, int, "%x"); - expect_eq(rb.cyIntegral, cyIntegral, int, "%x"); - expect_eq(rb.cxIdeal, cxIdeal, int, "%d"); - expect_eq(rb.lParam, lParam, LPARAM, "%ld"); - ok( rb.cxHeader == cxHeader || broken(rb.cxHeader == cxHeader_broken), - "expected %d for %d\n", cxHeader, rb.cxHeader ); + expect_eq(line, rb.cyChild, cyChild, int, "%x"); + expect_eq(line, rb.cyMaxChild, cyMaxChild, int, "%x"); + expect_eq(line, rb.cyIntegral, cyIntegral, int, "%x"); + expect_eq(line, rb.cxIdeal, cxIdeal, int, "%d"); + expect_eq(line, rb.lParam, lParam, LPARAM, "%ld"); + ok(rb.cxHeader == cxHeader || rb.cxHeader == cxHeader + 1 || broken(rb.cxHeader == cxHeader_broken), + "expected %d for %d from line %d\n", cxHeader, rb.cxHeader, line); } +#define expect_band_content(hRebar, uBand, fStyle, clrFore, clrBack,\ + lpText, iImage, hwndChild, cxMinChild, cyMinChild, cx, hbmBack, wID,\ + cyChild, cyMaxChild, cyIntegral, cxIdeal, lParam, cxHeader, cxHeader_broken) \ + expect_band_content_(__LINE__, hRebar, uBand, fStyle, clrFore, clrBack,\ + lpText, iImage, hwndChild, cxMinChild, cyMinChild, cx, hbmBack, wID,\ + cyChild, cyMaxChild, cyIntegral, cxIdeal, lParam, cxHeader, cxHeader_broken) + static void test_bandinfo(void) { REBARBANDINFOA rb; @@ -814,13 +965,13 @@ static void test_bandinfo(void) rb.fMask = RBBIM_TEXT; rb.lpText = szABC; 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); + expect_band_content(hRebar, 0, 0, 0, GetSysColor(COLOR_3DFACE), "ABC", -1, NULL, 15, 20, 0, NULL, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 3 + 2*system_font_height, -1); rb.cbSize = REBARBANDINFOA_V6_SIZE; rb.fMask = 0; ok(SendMessageA(hRebar, RB_INSERTBANDA, 1, (LPARAM)&rb), "RB_INSERTBAND failed\n"); 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); + expect_band_content(hRebar, 0, 0, 0, GetSysColor(COLOR_3DFACE), "ABC", -1, NULL, 15, 20, 0, NULL, 0, 0xdddddddd, 0xdddddddd, 0xdddddddd, 0, 0, 8 + 2*system_font_height, -1); rb.fMask = RBBIM_HEADERSIZE; rb.cxHeader = 50; @@ -839,7 +990,7 @@ static void test_bandinfo(void) rb.fStyle = RBBS_VARIABLEHEIGHT; rb.lpText = szABC; 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); + expect_band_content(hRebar, 0, RBBS_VARIABLEHEIGHT, 0, GetSysColor(COLOR_3DFACE), "ABC", -1, NULL, 15, 20, 0, NULL, 0, 20, 0x7fffffff, 0, 0, 0, 8 + 2*system_font_height, 5); DestroyWindow(hRebar); } @@ -962,7 +1113,9 @@ START_TEST(rebar) INITCOMMONCONTROLSEX iccex; MSG msg; - /* LoadLibrary is needed. This file has no references to functions in comctl32 */ + init_system_font_height(); + + /* LoadLibrary is needed. This file has no reference to functions in comctl32 */ hComctl32 = LoadLibraryA("comctl32.dll"); pInitCommonControlsEx = (void*)GetProcAddress(hComctl32, "InitCommonControlsEx"); if (!pInitCommonControlsEx) diff --git a/rostests/winetests/comctl32/resources.h b/rostests/winetests/comctl32/resources.h index beabce5bcee..e5217f1e9a5 100644 --- a/rostests/winetests/comctl32/resources.h +++ b/rostests/winetests/comctl32/resources.h @@ -37,6 +37,7 @@ #define IDD_PROP_PAGE_EXIT 33 #define IDD_PROP_PAGE_WITH_CUSTOM_DEFAULT_BUTTON 34 +#define IDD_PROP_PAGE_MESSAGE_TEST 35 #define IDC_PS_EDIT1 1000 #define IDC_PS_EDIT2 1001 diff --git a/rostests/winetests/comctl32/status.c b/rostests/winetests/comctl32/status.c index 839b138bb40..6e5a3e7d8dc 100644 --- a/rostests/winetests/comctl32/status.c +++ b/rostests/winetests/comctl32/status.c @@ -40,8 +40,8 @@ static WNDPROC g_status_wndproc; static RECT g_rcCreated; static HWND g_hMainWnd; static int g_wmsize_count = 0; -static DWORD g_ysize; -static DWORD g_dpisize; +static INT g_ysize; +static INT g_dpisize; static int g_wmdrawitm_ctr; static WNDPROC g_wndproc_saved; @@ -120,7 +120,7 @@ static int CALLBACK check_height_font_enumproc(ENUMLOGFONTEX *enumlf, NEWTEXTMET static const int sizes[] = { 6, 7, 8, 9, 10, 11, 12, 13, 15, 16, 20, 22, 28, 36, 48, 72}; DWORD i; - DWORD y; + INT y; LPSTR facename = (CHAR *)enumlf->elfFullName; /* on win9x, enumlf->elfFullName is only valid for truetype fonts */ @@ -260,8 +260,9 @@ static void test_status_control(void) HICON hIcon; char ch; char chstr[10] = "Inval id"; + COLORREF crColor = RGB(0,0,0); - hWndStatus = create_status_control(WS_VISIBLE, 0); + hWndStatus = create_status_control(WS_VISIBLE | SBT_TOOLTIPS, 0); /* Divide into parts and set text */ r = SendMessage(hWndStatus, SB_SETPARTS, 3, (LPARAM)nParts); @@ -343,14 +344,14 @@ static void test_status_control(void) } /* Set background color */ - r = SendMessage(hWndStatus, SB_SETBKCOLOR , 0, RGB(255,0,0)); - ok(r == CLR_DEFAULT || - broken(r == 0), /* win95 */ - "Expected %d, got %d\n", CLR_DEFAULT, r); - r = SendMessage(hWndStatus, SB_SETBKCOLOR , 0, CLR_DEFAULT); - ok(r == RGB(255,0,0) || - broken(r == 0), /* win95 */ - "Expected %d, got %d\n", RGB(255,0,0), r); + crColor = SendMessage(hWndStatus, SB_SETBKCOLOR , 0, RGB(255,0,0)); + ok(crColor == CLR_DEFAULT || + broken(crColor == RGB(0,0,0)), /* win95 */ + "Expected 0x%.8x, got 0x%.8x\n", CLR_DEFAULT, crColor); + crColor = SendMessage(hWndStatus, SB_SETBKCOLOR , 0, CLR_DEFAULT); + ok(crColor == RGB(255,0,0) || + broken(crColor == RGB(0,0,0)), /* win95 */ + "Expected 0x%.8x, got 0x%.8x\n", RGB(255,0,0), crColor); /* Add an icon to the status bar */ hIcon = LoadIcon(NULL, IDI_QUESTION); @@ -369,6 +370,7 @@ static void test_status_control(void) /* Set the Unicode format */ r = SendMessage(hWndStatus, SB_SETUNICODEFORMAT, FALSE, 0); + expect(FALSE,r); r = SendMessage(hWndStatus, SB_GETUNICODEFORMAT, 0, 0); expect(FALSE,r); r = SendMessage(hWndStatus, SB_SETUNICODEFORMAT, TRUE, 0); @@ -381,6 +383,12 @@ static void test_status_control(void) /* Reset number of parts */ r = SendMessage(hWndStatus, SB_SETPARTS, 2, (LPARAM)nParts); expect(TRUE,r); + r = SendMessage(hWndStatus, SB_GETPARTS, 0, 0); + ok(r == 2, "Expected 2, got %d\n", r); + r = SendMessage(hWndStatus, SB_SETPARTS, 0, 0); + expect(FALSE,r); + r = SendMessage(hWndStatus, SB_GETPARTS, 0, 0); + ok(r == 2, "Expected 2, got %d\n", r); /* Set the minimum height and get rectangle information again */ SendMessage(hWndStatus, SB_SETMINHEIGHT, 50, 0); @@ -399,15 +407,12 @@ static void test_status_control(void) expect(FALSE,r); /* Set the ToolTip text */ - todo_wine - { - SendMessage(hWndStatus, SB_SETTIPTEXT, 0,(LPARAM) "Tooltip Text"); - lstrcpyA(charArray, "apple"); - SendMessage(hWndStatus, SB_GETTIPTEXT, MAKEWPARAM (0, 20),(LPARAM) charArray); - ok(strcmp(charArray,"Tooltip Text") == 0 || - broken(!strcmp(charArray, "apple")), /* win95 */ - "Expected Tooltip Text, got %s\n", charArray); - } + SendMessage(hWndStatus, SB_SETTIPTEXT, 0,(LPARAM) "Tooltip Text"); + lstrcpyA(charArray, "apple"); + SendMessage(hWndStatus, SB_GETTIPTEXT, MAKEWPARAM (0, 20),(LPARAM) charArray); + ok(strcmp(charArray,"Tooltip Text") == 0 || + broken(!strcmp(charArray, "apple")), /* win95 */ + "Expected Tooltip Text, got %s\n", charArray); /* Make simple */ SendMessage(hWndStatus, SB_SIMPLE, TRUE, 0); @@ -455,7 +460,7 @@ static void test_status_ownerdraw(void) r = SendMessage(hWndStatus, SB_SETTEXT, SBT_OWNERDRAW, (LPARAM)statustext); ok( r == TRUE, "Sendmessage returned %d, expected 1\n", r); ok( 1 == g_wmdrawitm_ctr, "got %d drawitem messages expected 1\n", g_wmdrawitm_ctr); - /* ;and again */ + /* and again */ g_wmdrawitm_ctr = 0; r = SendMessage(hWndStatus, SB_SETTEXT, SBT_OWNERDRAW, (LPARAM)statustext); ok( r == TRUE, "Sendmessage returned %d, expected 1\n", r); diff --git a/rostests/winetests/comctl32/tab.c b/rostests/winetests/comctl32/tab.c index 6774d51a1a5..36179dcbc47 100644 --- a/rostests/winetests/comctl32/tab.c +++ b/rostests/winetests/comctl32/tab.c @@ -41,27 +41,44 @@ #define TabWidthPadded(padd_x, num) (DEFAULT_MIN_TAB_WIDTH - (TAB_PADDING_X - (padd_x)) * num) -#define TabCheckSetSize(hwnd, SetWidth, SetHeight, ExpWidth, ExpHeight, Msg)\ - SendMessage (hwnd, TCM_SETITEMSIZE, 0,\ - (LPARAM) MAKELPARAM((SetWidth >= 0) ? SetWidth:0, (SetHeight >= 0) ? SetHeight:0));\ - if (winetest_interactive) RedrawWindow (hwnd, NULL, 0, RDW_UPDATENOW);\ - CheckSize(hwnd, ExpWidth, ExpHeight, Msg); +static void CheckSize(HWND hwnd, INT width, INT height, const char *msg, int line) +{ + RECT r; -#define CheckSize(hwnd,width,height,msg)\ - SendMessage (hwnd, TCM_GETITEMRECT, 0, (LPARAM) &rTab);\ - if ((width >= 0) && (height < 0))\ - ok (width == rTab.right - rTab.left, "%s: Expected width [%d] got [%d]\n",\ - msg, (int)width, rTab.right - rTab.left);\ - else if ((height >= 0) && (width < 0))\ - ok (height == rTab.bottom - rTab.top, "%s: Expected height [%d] got [%d]\n",\ - msg, (int)height, rTab.bottom - rTab.top);\ - else\ - ok ((width == rTab.right - rTab.left) &&\ - (height == rTab.bottom - rTab.top ),\ - "%s: Expected [%d,%d] got [%d,%d]\n", msg, (int)width, (int)height,\ - rTab.right - rTab.left, rTab.bottom - rTab.top); + SendMessage(hwnd, TCM_GETITEMRECT, 0, (LPARAM)&r); + if (width >= 0 && height < 0) + { + ok_(__FILE__,line) (width == r.right - r.left, "%s: Expected width [%d] got [%d]\n",\ + msg, width, r.right - r.left); + } + else if (height >= 0 && width < 0) + { + ok_(__FILE__,line) (height == r.bottom - r.top, "%s: Expected height [%d] got [%d]\n",\ + msg, height, r.bottom - r.top); + } + else + ok_(__FILE__,line) ((width == r.right - r.left) && (height == r.bottom - r.top ), + "%s: Expected [%d,%d] got [%d,%d]\n", msg, width, height, + r.right - r.left, r.bottom - r.top); +} -static HFONT hFont = 0; +#define CHECKSIZE(hwnd,width,height,msg) CheckSize(hwnd,width,height,msg,__LINE__) + +static void TabCheckSetSize(HWND hwnd, INT set_width, INT set_height, INT exp_width, + INT exp_height, const char *msg, int line) +{ + SendMessage(hwnd, TCM_SETITEMSIZE, 0, + (LPARAM) MAKELPARAM((set_width >= 0) ? set_width : 0, (set_height >= 0) ? set_height : 0)); + if (winetest_interactive) RedrawWindow (hwnd, NULL, 0, RDW_UPDATENOW); + CheckSize(hwnd, exp_width, exp_height, msg, line); +} + +#define TABCHECKSETSIZE(hwnd,set_width,set_height,exp_width,exp_height,msg) \ + TabCheckSetSize(hwnd,set_width,set_height,exp_width,exp_height,msg,__LINE__) + +static HFONT hFont; +static DRAWITEMSTRUCT g_drawitem; +static HWND parent_wnd; static struct msg_sequence *sequences[NUM_MSG_SEQUENCES]; @@ -269,6 +286,11 @@ static const struct message delete_focus_seq[] = { { 0 } }; +static const struct message rbuttonup_seq[] = { + { WM_RBUTTONUP, sent|wparam|lparam, 0, 0 }, + { WM_CONTEXTMENU, sent|defwinproc }, + { 0 } +}; static HWND create_tabcontrol (DWORD style, DWORD mask) @@ -337,6 +359,10 @@ static LRESULT WINAPI parentWindowProcess(HWND hwnd, UINT message, WPARAM wParam add_message(sequences, PARENT_SEQ_INDEX, &msg); } + /* dump sent structure data */ + if (message == WM_DRAWITEM) + g_drawitem = *(DRAWITEMSTRUCT*)lParam; + defwndproc_counter++; ret = DefWindowProcA(hwnd, message, wParam, lParam); defwndproc_counter--; @@ -517,16 +543,16 @@ static void test_tab(INT nMinTabWidth) ReleaseDC(hwTab, hdc); trace (" TCS_FIXEDWIDTH tabs no icon...\n"); - CheckSize(hwTab, dpi, -1, "default width"); - TabCheckSetSize(hwTab, 50, 20, 50, 20, "set size"); - TabCheckSetSize(hwTab, 0, 1, 0, 1, "min size"); + CHECKSIZE(hwTab, dpi, -1, "default width"); + TABCHECKSETSIZE(hwTab, 50, 20, 50, 20, "set size"); + TABCHECKSETSIZE(hwTab, 0, 1, 0, 1, "min size"); SendMessage(hwTab, TCM_SETIMAGELIST, 0, (LPARAM)himl); trace (" TCS_FIXEDWIDTH tabs with icon...\n"); - TabCheckSetSize(hwTab, 50, 30, 50, 30, "set size > icon"); - TabCheckSetSize(hwTab, 20, 20, 25, 20, "set size < icon"); - TabCheckSetSize(hwTab, 0, 1, 25, 1, "min size"); + TABCHECKSETSIZE(hwTab, 50, 30, 50, 30, "set size > icon"); + TABCHECKSETSIZE(hwTab, 20, 20, 25, 20, "set size < icon"); + TABCHECKSETSIZE(hwTab, 0, 1, 25, 1, "min size"); DestroyWindow (hwTab); @@ -537,19 +563,19 @@ static void test_tab(INT nMinTabWidth) dpi = GetDeviceCaps(hdc, LOGPIXELSX); ReleaseDC(hwTab, hdc); trace (" TCS_FIXEDWIDTH buttons no icon...\n"); - CheckSize(hwTab, dpi, -1, "default width"); - TabCheckSetSize(hwTab, 20, 20, 20, 20, "set size 1"); - TabCheckSetSize(hwTab, 10, 50, 10, 50, "set size 2"); - TabCheckSetSize(hwTab, 0, 1, 0, 1, "min size"); + CHECKSIZE(hwTab, dpi, -1, "default width"); + TABCHECKSETSIZE(hwTab, 20, 20, 20, 20, "set size 1"); + TABCHECKSETSIZE(hwTab, 10, 50, 10, 50, "set size 2"); + TABCHECKSETSIZE(hwTab, 0, 1, 0, 1, "min size"); SendMessage(hwTab, TCM_SETIMAGELIST, 0, (LPARAM)himl); trace (" TCS_FIXEDWIDTH buttons with icon...\n"); - TabCheckSetSize(hwTab, 50, 30, 50, 30, "set size > icon"); - TabCheckSetSize(hwTab, 20, 20, 25, 20, "set size < icon"); - TabCheckSetSize(hwTab, 0, 1, 25, 1, "min size"); + TABCHECKSETSIZE(hwTab, 50, 30, 50, 30, "set size > icon"); + TABCHECKSETSIZE(hwTab, 20, 20, 25, 20, "set size < icon"); + TABCHECKSETSIZE(hwTab, 0, 1, 25, 1, "min size"); SendMessage(hwTab, TCM_SETPADDING, 0, MAKELPARAM(4,4)); - TabCheckSetSize(hwTab, 0, 1, 25, 1, "set padding, min size"); + TABCHECKSETSIZE(hwTab, 0, 1, 25, 1, "set padding, min size"); DestroyWindow (hwTab); @@ -560,19 +586,19 @@ static void test_tab(INT nMinTabWidth) dpi = GetDeviceCaps(hdc, LOGPIXELSX); ReleaseDC(hwTab, hdc); trace (" TCS_FIXEDWIDTH | TCS_BOTTOM tabs...\n"); - CheckSize(hwTab, dpi, -1, "no icon, default width"); + CHECKSIZE(hwTab, dpi, -1, "no icon, default width"); - TabCheckSetSize(hwTab, 20, 20, 20, 20, "no icon, set size 1"); - TabCheckSetSize(hwTab, 10, 50, 10, 50, "no icon, set size 2"); - TabCheckSetSize(hwTab, 0, 1, 0, 1, "no icon, min size"); + TABCHECKSETSIZE(hwTab, 20, 20, 20, 20, "no icon, set size 1"); + TABCHECKSETSIZE(hwTab, 10, 50, 10, 50, "no icon, set size 2"); + TABCHECKSETSIZE(hwTab, 0, 1, 0, 1, "no icon, min size"); SendMessage(hwTab, TCM_SETIMAGELIST, 0, (LPARAM)himl); - TabCheckSetSize(hwTab, 50, 30, 50, 30, "with icon, set size > icon"); - TabCheckSetSize(hwTab, 20, 20, 25, 20, "with icon, set size < icon"); - TabCheckSetSize(hwTab, 0, 1, 25, 1, "with icon, min size"); + TABCHECKSETSIZE(hwTab, 50, 30, 50, 30, "with icon, set size > icon"); + TABCHECKSETSIZE(hwTab, 20, 20, 25, 20, "with icon, set size < icon"); + TABCHECKSETSIZE(hwTab, 0, 1, 25, 1, "with icon, min size"); SendMessage(hwTab, TCM_SETPADDING, 0, MAKELPARAM(4,4)); - TabCheckSetSize(hwTab, 0, 1, 25, 1, "set padding, min size"); + TABCHECKSETSIZE(hwTab, 0, 1, 25, 1, "set padding, min size"); DestroyWindow (hwTab); @@ -592,15 +618,15 @@ static void test_tab(INT nMinTabWidth) SendMessage(hwTab, TCM_SETIMAGELIST, 0, 0); SendMessage(hwTab, TCM_SETPADDING, 0, MAKELPARAM(i,i)); - TabCheckSetSize(hwTab, 50, 20, max(size.cx + i*2, nTabWidth), 20, "no icon, set size"); - TabCheckSetSize(hwTab, 0, 1, max(size.cx + i*2, nTabWidth), 1, "no icon, min size"); + TABCHECKSETSIZE(hwTab, 50, 20, max(size.cx + i*2, nTabWidth), 20, "no icon, set size"); + TABCHECKSETSIZE(hwTab, 0, 1, max(size.cx + i*2, nTabWidth), 1, "no icon, min size"); SendMessage(hwTab, TCM_SETIMAGELIST, 0, (LPARAM)himl); nTabWidth = (nMinTabWidth < 0) ? TabWidthPadded(i, 3) : nMinTabWidth; - TabCheckSetSize(hwTab, 50, 30, max(size.cx + 21 + i*3, nTabWidth), 30, "with icon, set size > icon"); - TabCheckSetSize(hwTab, 20, 20, max(size.cx + 21 + i*3, nTabWidth), 20, "with icon, set size < icon"); - TabCheckSetSize(hwTab, 0, 1, max(size.cx + 21 + i*3, nTabWidth), 1, "with icon, min size"); + TABCHECKSETSIZE(hwTab, 50, 30, max(size.cx + 21 + i*3, nTabWidth), 30, "with icon, set size > icon"); + TABCHECKSETSIZE(hwTab, 20, 20, max(size.cx + 21 + i*3, nTabWidth), 20, "with icon, set size < icon"); + TABCHECKSETSIZE(hwTab, 0, 1, max(size.cx + 21 + i*3, nTabWidth), 1, "with icon, min size"); } DestroyWindow (hwTab); @@ -620,16 +646,16 @@ static void test_tab(INT nMinTabWidth) SendMessage(hwTab, TCM_SETIMAGELIST, 0, 0); SendMessage(hwTab, TCM_SETPADDING, 0, MAKELPARAM(i,i)); - TabCheckSetSize(hwTab, 50, 20, nTabWidth, 20, "no icon, set size"); - TabCheckSetSize(hwTab, 0, 1, nTabWidth, 1, "no icon, min size"); + TABCHECKSETSIZE(hwTab, 50, 20, nTabWidth, 20, "no icon, set size"); + TABCHECKSETSIZE(hwTab, 0, 1, nTabWidth, 1, "no icon, min size"); SendMessage(hwTab, TCM_SETIMAGELIST, 0, (LPARAM)himl); if (i > 1 && nMinTabWidth > 0 && nMinTabWidth < DEFAULT_MIN_TAB_WIDTH) nTabWidth += EXTRA_ICON_PADDING *(i-1); - TabCheckSetSize(hwTab, 50, 30, nTabWidth, 30, "with icon, set size > icon"); - TabCheckSetSize(hwTab, 20, 20, nTabWidth, 20, "with icon, set size < icon"); - TabCheckSetSize(hwTab, 0, 1, nTabWidth, 1, "with icon, min size"); + TABCHECKSETSIZE(hwTab, 50, 30, nTabWidth, 30, "with icon, set size > icon"); + TABCHECKSETSIZE(hwTab, 20, 20, nTabWidth, 20, "with icon, set size < icon"); + TABCHECKSETSIZE(hwTab, 0, 1, nTabWidth, 1, "with icon, min size"); } DestroyWindow (hwTab); @@ -638,8 +664,23 @@ static void test_tab(INT nMinTabWidth) DeleteObject(hFont); } -static void test_curfocus(HWND parent_wnd, INT nTabs) +static void test_width(void) { + trace ("Testing with default MinWidth\n"); + test_tab(-1); + trace ("Testing with MinWidth set to -3\n"); + test_tab(-3); + trace ("Testing with MinWidth set to 24\n"); + test_tab(24); + trace ("Testing with MinWidth set to 54\n"); + test_tab(54); + trace ("Testing with MinWidth set to 94\n"); + test_tab(94); +} + +static void test_curfocus(void) +{ + const INT nTabs = 5; INT focusIndex; HWND hTab; @@ -671,8 +712,9 @@ static void test_curfocus(HWND parent_wnd, INT nTabs) DestroyWindow(hTab); } -static void test_cursel(HWND parent_wnd, INT nTabs) +static void test_cursel(void) { + const INT nTabs = 5; INT selectionIndex; INT focusIndex; TCITEM tcItem; @@ -723,8 +765,9 @@ static void test_cursel(HWND parent_wnd, INT nTabs) DestroyWindow(hTab); } -static void test_extendedstyle(HWND parent_wnd, INT nTabs) +static void test_extendedstyle(void) { + const INT nTabs = 5; DWORD prevExtendedStyle; DWORD extendedStyle; HWND hTab; @@ -757,8 +800,9 @@ static void test_extendedstyle(HWND parent_wnd, INT nTabs) DestroyWindow(hTab); } -static void test_unicodeformat(HWND parent_wnd, INT nTabs) +static void test_unicodeformat(void) { + const INT nTabs = 5; INT unicodeFormat; HWND hTab; @@ -788,13 +832,46 @@ static void test_unicodeformat(HWND parent_wnd, INT nTabs) DestroyWindow(hTab); } -static void test_getset_item(HWND parent_wnd, INT nTabs) +static void test_getset_item(void) { - TCITEM tcItem; - DWORD ret; char szText[32] = "New Label"; + const INT nTabs = 5; + TCITEM tcItem; + LPARAM lparam; + DWORD ret; HWND hTab; + hTab = CreateWindowA( + WC_TABCONTROLA, + "TestTab", + WS_CLIPSIBLINGS | WS_CLIPCHILDREN | TCS_FOCUSNEVER | TCS_FIXEDWIDTH | TCS_OWNERDRAWFIXED, + 10, 10, 300, 100, + parent_wnd, NULL, NULL, 0); + + ok(GetParent(hTab) == NULL, "got %p, expected null parent\n", GetParent(hTab)); + + ret = SendMessageA(hTab, TCM_SETITEMEXTRA, sizeof(LPARAM)-1, 0); + ok(ret == TRUE, "got %d\n", ret); + + /* set some item data */ + tcItem.lParam = ~0; + tcItem.mask = TCIF_PARAM; + + ret = SendMessageA(hTab, TCM_INSERTITEMA, 0, (LPARAM)&tcItem); + ok(ret == 0, "got %d\n", ret); + + /* all sizeof(LPARAM) returned anyway when using sizeof(LPARAM)-1 size */ + memset(&lparam, 0xaa, sizeof(lparam)); + tcItem.lParam = lparam; + tcItem.mask = TCIF_PARAM; + ret = SendMessage(hTab, TCM_GETITEM, 0, (LPARAM)&tcItem); + expect(TRUE, ret); + /* everything higher specified size is preserved */ + memset(&lparam, 0xff, sizeof(lparam)-1); + ok(tcItem.lParam == lparam, "Expected 0x%lx, got 0x%lx\n", lparam, tcItem.lParam); + + DestroyWindow(hTab); + hTab = createFilledTabControl(parent_wnd, TCS_FIXEDWIDTH, TCIF_TEXT|TCIF_IMAGE, nTabs); ok(hTab != NULL, "Failed to create tab control\n"); @@ -898,10 +975,11 @@ static void test_getset_item(HWND parent_wnd, INT nTabs) DestroyWindow(hTab); } -static void test_getset_tooltips(HWND parent_wnd, INT nTabs) +static void test_getset_tooltips(void) { - HWND hTab, toolTip; char toolTipText[32] = "ToolTip Text Test"; + const INT nTabs = 5; + HWND hTab, toolTip; hTab = createFilledTabControl(parent_wnd, TCS_FIXEDWIDTH, TCIF_TEXT|TCIF_IMAGE, nTabs); ok(hTab != NULL, "Failed to create tab control\n"); @@ -921,8 +999,9 @@ static void test_getset_tooltips(HWND parent_wnd, INT nTabs) DestroyWindow(hTab); } -static void test_misc(HWND parent_wnd, INT nTabs) +static void test_misc(void) { + const INT nTabs = 5; HWND hTab; RECT rTab; INT nTabsRetrieved; @@ -975,14 +1054,14 @@ static void test_misc(HWND parent_wnd, INT nTabs) hdc = GetDC(hTab); dpi = GetDeviceCaps(hdc, LOGPIXELSX); ReleaseDC(hTab, hdc); - CheckSize(hTab, dpi, -1 , "Default Width"); + CHECKSIZE(hTab, dpi, -1 , "Default Width"); ok_sequence(sequences, TAB_SEQ_INDEX, get_item_rect_seq, "Get itemRect test sequence", FALSE); ok_sequence(sequences, PARENT_SEQ_INDEX, empty_sequence, "Get itemRect test parent sequence", FALSE); DestroyWindow(hTab); } -static void test_adjustrect(HWND parent_wnd) +static void test_adjustrect(void) { HWND hTab; INT r; @@ -999,7 +1078,7 @@ static void test_adjustrect(HWND parent_wnd) expect(-1, r); } -static void test_insert_focus(HWND parent_wnd) +static void test_insert_focus(void) { HWND hTab; INT nTabsRetrieved; @@ -1015,6 +1094,9 @@ static void test_insert_focus(HWND parent_wnd) hTab = createFilledTabControl(parent_wnd, TCS_FIXEDWIDTH, mask, 0); ok(hTab != NULL, "Failed to create tab control\n"); + r = SendMessage(hTab, TCM_GETCURSEL, 0, 0); + expect(-1, r); + flush_sequences(sequences, NUM_MSG_SEQUENCES); nTabsRetrieved = SendMessage(hTab, TCM_GETITEMCOUNT, 0, 0); @@ -1062,7 +1144,7 @@ static void test_insert_focus(HWND parent_wnd) DestroyWindow(hTab); } -static void test_delete_focus(HWND parent_wnd) +static void test_delete_focus(void) { HWND hTab; INT nTabsRetrieved; @@ -1111,7 +1193,7 @@ static void test_delete_focus(HWND parent_wnd) DestroyWindow(hTab); } -static void test_removeimage(HWND parent_wnd) +static void test_removeimage(void) { static const BYTE bits[32]; HWND hwTab; @@ -1174,10 +1256,10 @@ static void test_removeimage(HWND parent_wnd) DestroyIcon(hicon); } -static void test_delete_selection(HWND parent_wnd) +static void test_delete_selection(void) { HWND hTab; - DWORD ret; + INT ret; hTab = createFilledTabControl(parent_wnd, TCS_FIXEDWIDTH, TCIF_TEXT|TCIF_IMAGE, 4); ok(hTab != NULL, "Failed to create tab control\n"); @@ -1196,9 +1278,158 @@ static void test_delete_selection(HWND parent_wnd) DestroyWindow(hTab); } +static void test_TCM_SETITEMEXTRA(void) +{ + HWND hTab; + DWORD ret; + + hTab = CreateWindowA( + WC_TABCONTROLA, + "TestTab", + WS_CLIPSIBLINGS | WS_CLIPCHILDREN | TCS_FOCUSNEVER | TCS_FIXEDWIDTH, + 10, 10, 300, 100, + parent_wnd, NULL, NULL, 0); + + /* zero is valid size too */ + ret = SendMessageA(hTab, TCM_SETITEMEXTRA, 0, 0); + if (ret == FALSE) + { + win_skip("TCM_SETITEMEXTRA not supported\n"); + DestroyWindow(hTab); + return; + } + + ret = SendMessageA(hTab, TCM_SETITEMEXTRA, -1, 0); + ok(ret == FALSE, "got %d\n", ret); + + ret = SendMessageA(hTab, TCM_SETITEMEXTRA, 2, 0); + ok(ret == TRUE, "got %d\n", ret); + DestroyWindow(hTab); + + /* it's not possible to change extra data size for control with tabs */ + hTab = createFilledTabControl(parent_wnd, TCS_FIXEDWIDTH, TCIF_TEXT|TCIF_IMAGE, 4); + ok(hTab != NULL, "Failed to create tab control\n"); + + ret = SendMessageA(hTab, TCM_SETITEMEXTRA, 2, 0); + ok(ret == FALSE, "got %d\n", ret); + DestroyWindow(hTab); +} + +static void test_TCS_OWNERDRAWFIXED(void) +{ + LPARAM lparam; + ULONG_PTR itemdata, itemdata2; + TCITEMA item; + HWND hTab; + BOOL ret; + + hTab = createFilledTabControl(parent_wnd, TCS_FIXEDWIDTH|TCS_OWNERDRAWFIXED, TCIF_TEXT|TCIF_IMAGE, 4); + ok(hTab != NULL, "Failed to create tab control\n"); + + ok(GetParent(hTab) == NULL, "got %p, expected null parent\n", GetParent(hTab)); + + /* set some item data */ + memset(&lparam, 0xde, sizeof(LPARAM)); + + item.mask = TCIF_PARAM; + item.lParam = lparam; + ret = SendMessageA(hTab, TCM_SETITEMA, 0, (LPARAM)&item); + ok(ret == TRUE, "got %d\n", ret); + + memset(&g_drawitem, 0, sizeof(g_drawitem)); + + ShowWindow(hTab, SW_SHOW); + RedrawWindow(hTab, NULL, 0, RDW_UPDATENOW); + + itemdata = 0; + memset(&itemdata, 0xde, 4); + ok(g_drawitem.itemData == itemdata, "got 0x%lx, expected 0x%lx\n", g_drawitem.itemData, itemdata); + + DestroyWindow(hTab); + + /* now with custom extra data length */ + hTab = CreateWindowA( + WC_TABCONTROLA, + "TestTab", + WS_CLIPSIBLINGS | WS_CLIPCHILDREN | TCS_FOCUSNEVER | TCS_FIXEDWIDTH | TCS_OWNERDRAWFIXED, + 10, 10, 300, 100, + parent_wnd, NULL, NULL, 0); + + ok(GetParent(hTab) == NULL, "got %p, expected null parent\n", GetParent(hTab)); + + ret = SendMessageA(hTab, TCM_SETITEMEXTRA, sizeof(LPARAM)+1, 0); + ok(ret == TRUE, "got %d\n", ret); + + /* set some item data */ + memset(&lparam, 0xde, sizeof(LPARAM)); + item.mask = TCIF_PARAM; + item.lParam = lparam; + + ret = SendMessageA(hTab, TCM_INSERTITEMA, 0, (LPARAM)&item); + ok(ret == 0, "got %d\n", ret); + + memset(&g_drawitem, 0, sizeof(g_drawitem)); + + ShowWindow(hTab, SW_SHOW); + RedrawWindow(hTab, NULL, 0, RDW_UPDATENOW); + + memset(&itemdata, 0xde, sizeof(ULONG_PTR)); + ok(*(ULONG_PTR*)g_drawitem.itemData == itemdata, "got 0x%lx, expected 0x%lx\n", g_drawitem.itemData, itemdata); + + DestroyWindow(hTab); + + /* same thing, but size smaller than default */ + hTab = CreateWindowA( + WC_TABCONTROLA, + "TestTab", + WS_CLIPSIBLINGS | WS_CLIPCHILDREN | TCS_FOCUSNEVER | TCS_FIXEDWIDTH | TCS_OWNERDRAWFIXED, + 10, 10, 300, 100, + parent_wnd, NULL, NULL, 0); + + ok(GetParent(hTab) == NULL, "got %p, expected null parent\n", GetParent(hTab)); + + ret = SendMessageA(hTab, TCM_SETITEMEXTRA, sizeof(LPARAM)-1, 0); + ok(ret == TRUE, "got %d\n", ret); + + memset(&lparam, 0xde, sizeof(lparam)); + item.mask = TCIF_PARAM; + item.lParam = lparam; + + ret = SendMessageA(hTab, TCM_INSERTITEMA, 0, (LPARAM)&item); + ok(ret == 0, "got %d\n", ret); + + memset(&g_drawitem, 0, sizeof(g_drawitem)); + + ShowWindow(hTab, SW_SHOW); + RedrawWindow(hTab, NULL, 0, RDW_UPDATENOW); + + itemdata = itemdata2 = 0; + memset(&itemdata, 0xde, 4); + memset(&itemdata2, 0xde, sizeof(LPARAM)-1); + ok(g_drawitem.itemData == itemdata || broken(g_drawitem.itemData == itemdata2) /* win98 */, + "got 0x%lx, expected 0x%lx\n", g_drawitem.itemData, itemdata); + + DestroyWindow(hTab); +} + +static void test_WM_CONTEXTMENU(void) +{ + HWND hTab; + + hTab = createFilledTabControl(parent_wnd, TCS_FIXEDWIDTH, TCIF_TEXT|TCIF_IMAGE, 4); + ok(hTab != NULL, "Failed to create tab control\n"); + + flush_sequences(sequences, NUM_MSG_SEQUENCES); + + SendMessageA(hTab, WM_RBUTTONUP, 0, 0); + + ok_sequence(sequences, TAB_SEQ_INDEX, rbuttonup_seq, "WM_RBUTTONUP response sequence", FALSE); + + DestroyWindow(hTab); +} + START_TEST(tab) { - HWND parent_wnd; LOGFONTA logfont; lstrcpyA(logfont.lfFaceName, "Arial"); @@ -1210,36 +1441,30 @@ START_TEST(tab) InitCommonControls(); - trace ("Testing with default MinWidth\n"); - test_tab(-1); - trace ("Testing with MinWidth set to -3\n"); - test_tab(-3); - trace ("Testing with MinWidth set to 24\n"); - test_tab(24); - trace ("Testing with MinWidth set to 54\n"); - test_tab(54); - trace ("Testing with MinWidth set to 94\n"); - test_tab(94); + test_width(); init_msg_sequences(sequences, NUM_MSG_SEQUENCES); parent_wnd = createParentWindow(); ok(parent_wnd != NULL, "Failed to create parent window!\n"); - 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_curfocus(); + test_cursel(); + test_extendedstyle(); + test_unicodeformat(); + test_getset_item(); + test_getset_tooltips(); + test_misc(); - test_adjustrect(parent_wnd); + test_adjustrect(); - test_insert_focus(parent_wnd); - test_delete_focus(parent_wnd); - test_delete_selection(parent_wnd); - test_removeimage(parent_wnd); + test_insert_focus(); + test_delete_focus(); + test_delete_selection(); + test_removeimage(); + test_TCM_SETITEMEXTRA(); + test_TCS_OWNERDRAWFIXED(); + test_WM_CONTEXTMENU(); DestroyWindow(parent_wnd); } diff --git a/rostests/winetests/comctl32/toolbar.c b/rostests/winetests/comctl32/toolbar.c index 8311df575ec..5049ef66ea2 100644 --- a/rostests/winetests/comctl32/toolbar.c +++ b/rostests/winetests/comctl32/toolbar.c @@ -18,7 +18,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include #include #include "windef.h" @@ -57,12 +56,17 @@ static const struct message ttgetdispinfo_parent_seq[] = { #define expect(EXPECTED,GOT) ok((GOT)==(EXPECTED), "Expected %d, got %d\n", (EXPECTED), (GOT)) -#define check_rect(name, val, exp) ok(val.top == exp.top && val.bottom == exp.bottom && \ - val.left == exp.left && val.right == exp.right, "invalid rect (" name ") (%d,%d) (%d,%d) - expected (%d,%d) (%d,%d)\n", \ - val.left, val.top, val.right, val.bottom, exp.left, exp.top, exp.right, exp.bottom); +#define check_rect(name, val, exp, ...) ok(val.top == exp.top && val.bottom == exp.bottom && \ + val.left == exp.left && val.right == exp.right, "invalid rect (%d,%d) (%d,%d) - expected (%d,%d) (%d,%d) - (" name ")\n", \ + val.left, val.top, val.right, val.bottom, exp.left, exp.top, exp.right, exp.bottom, __VA_ARGS__); #define compare(val, exp, format) ok((val) == (exp), #val " value " format " expected " format "\n", (val), (exp)); +#define check_button_size(handle, width, height, ...) {\ + LRESULT bsize = SendMessageA(handle, TB_GETBUTTONSIZE, 0, 0);\ + ok(bsize == MAKELONG(width, height), "Unexpected button size - got size (%d, %d), expected (%d, %d)\n", LOWORD(bsize), HIWORD(bsize), width, height);\ + } + static void MakeButton(TBBUTTON *p, int idCommand, int fsStyle, int nString) { p->iBitmap = -2; p->idCommand = idCommand; @@ -160,6 +164,7 @@ static void basic_test(void) TBBUTTON buttons[9]; HWND hToolbar; int i; + for (i=0; i<9; i++) MakeButton(buttons+i, 1000+i, TBSTYLE_CHECKGROUP, 0); MakeButton(buttons+3, 1003, TBSTYLE_SEP|TBSTYLE_GROUP, 0); @@ -505,6 +510,14 @@ static void test_add_string(void) ok(ret == 2, "TB_ADDSTRINGA - unexpected return %d\n", ret); CHECK_STRING_TABLE(3, ret2); + /* null instance handle */ + ret = SendMessageA(hToolbar, TB_ADDSTRINGA, 0, IDS_TBADD1); + ok(ret == -1, "TB_ADDSTRINGA - unexpected return %d\n", ret); + + /* invalid instance handle */ + ret = SendMessageA(hToolbar, TB_ADDSTRINGA, 0xdeadbeef, IDS_TBADD1); + ok(ret == -1, "TB_ADDSTRINGA - unexpected return %d\n", ret); + ret = SendMessageA(hToolbar, TB_ADDSTRINGA, (WPARAM)GetModuleHandle(NULL), IDS_TBADD1); ok(ret == 3, "TB_ADDSTRINGA - unexpected return %d\n", ret); CHECK_STRING_TABLE(3, ret2); @@ -664,137 +677,312 @@ static void dump_sizes(HWND hToolbar) #else +static int system_font_height(void) { + HDC hDC; + TEXTMETRIC tm; + + hDC = CreateCompatibleDC(NULL); + GetTextMetrics(hDC, &tm); + DeleteDC(NULL); + + return tm.tmHeight; +} + +static int string_width(const CHAR *s) { + SIZE sz; + HDC hdc; + + hdc = CreateCompatibleDC(NULL); + GetTextExtentPoint32A(hdc, s, strlen(s), &sz); + DeleteDC(hdc); + + return sz.cx; +} + typedef struct { RECT rcClient; SIZE szMin; INT nButtons; - RECT rcButtons[100]; + RECT *prcButtons; } tbsize_result_t; -static tbsize_result_t tbsize_results[] = -{ - { {0, 0, 672, 26}, {100, 22}, 5, { - { 0, 2, 23, 24}, { 23, 2, 46, 24}, { 46, 2, 54, 24}, - { 54, 2, 77, 24}, { 77, 2, 100, 24}, - }, }, - { {0, 0, 672, 26}, {146, 22}, 7, { - { 0, 2, 23, 24}, { 23, 2, 46, 24}, { 46, 2, 54, 24}, - { 54, 2, 77, 24}, { 77, 2, 100, 24}, {100, 2, 123, 24}, - { 0, 24, 23, 46}, - }, }, - { {0, 0, 672, 48}, {146, 22}, 7, { - { 0, 2, 23, 24}, { 23, 2, 46, 24}, { 46, 2, 54, 24}, - { 54, 2, 77, 24}, { 77, 2, 100, 24}, {100, 2, 123, 24}, - { 0, 24, 23, 46}, - }, }, - { {0, 0, 672, 26}, {146, 22}, 7, { - { 0, 2, 23, 24}, { 23, 2, 46, 24}, { 46, 2, 54, 24}, - { 54, 2, 77, 24}, { 77, 2, 100, 24}, {100, 2, 123, 24}, - {123, 2, 146, 24}, - }, }, - { {0, 0, 672, 26}, {192, 22}, 9, { - { 0, 2, 23, 24}, { 23, 2, 46, 24}, { 46, 2, 54, 24}, - { 54, 2, 77, 24}, { 77, 2, 100, 24}, {100, 2, 123, 24}, - {123, 2, 146, 24}, {146, 2, 169, 24}, {169, 2, 192, 24}, - }, }, - { {0, 0, 672, 92}, {882, 22}, 39, { - { 0, 2, 23, 24}, { 23, 2, 46, 24}, { 0, 2, 8, 29}, - { 0, 29, 23, 51}, { 23, 29, 46, 51}, { 46, 29, 69, 51}, - { 69, 29, 92, 51}, { 92, 29, 115, 51}, {115, 29, 138, 51}, - {138, 29, 161, 51}, {161, 29, 184, 51}, {184, 29, 207, 51}, - {207, 29, 230, 51}, {230, 29, 253, 51}, {253, 29, 276, 51}, - {276, 29, 299, 51}, {299, 29, 322, 51}, {322, 29, 345, 51}, - {345, 29, 368, 51}, {368, 29, 391, 51}, {391, 29, 414, 51}, - {414, 29, 437, 51}, {437, 29, 460, 51}, {460, 29, 483, 51}, - {483, 29, 506, 51}, {506, 29, 529, 51}, {529, 29, 552, 51}, - {552, 29, 575, 51}, {575, 29, 598, 51}, {598, 29, 621, 51}, - {621, 29, 644, 51}, {644, 29, 667, 51}, { 0, 51, 23, 73}, - { 23, 51, 46, 73}, { 46, 51, 69, 73}, { 69, 51, 92, 73}, - { 92, 51, 115, 73}, {115, 51, 138, 73}, {138, 51, 161, 73}, - }, }, - { {0, 0, 48, 226}, {23, 140}, 7, { - { 0, 2, 23, 24}, { 23, 2, 46, 24}, { 46, 2, 94, 24}, - { 94, 2, 117, 24}, {117, 2, 140, 24}, {140, 2, 163, 24}, - { 0, 24, 23, 46}, - }, }, - { {0, 0, 92, 226}, {23, 140}, 7, { - { 0, 2, 23, 24}, { 23, 2, 46, 24}, { 0, 24, 92, 32}, - { 0, 32, 23, 54}, { 23, 32, 46, 54}, { 46, 32, 69, 54}, - { 69, 32, 92, 54}, - }, }, - { {0, 0, 672, 26}, {194, 30}, 7, { - { 0, 2, 31, 32}, { 31, 2, 62, 32}, { 62, 2, 70, 32}, - { 70, 2, 101, 32}, {101, 2, 132, 32}, {132, 2, 163, 32}, - { 0, 32, 31, 62}, - }, }, - { {0, 0, 672, 64}, {194, 30}, 7, { - { 0, 2, 31, 32}, { 31, 2, 62, 32}, { 62, 2, 70, 32}, - { 70, 2, 101, 32}, {101, 2, 132, 32}, {132, 2, 163, 32}, - { 0, 32, 31, 62}, - }, }, - { {0, 0, 672, 64}, {194, 30}, 7, { - { 0, 0, 31, 30}, { 31, 0, 62, 30}, { 62, 0, 70, 30}, - { 70, 0, 101, 30}, {101, 0, 132, 30}, {132, 0, 163, 30}, - { 0, 30, 31, 60}, - }, }, - { {0, 0, 124, 226}, {31, 188}, 7, { - { 0, 0, 31, 30}, { 31, 0, 62, 30}, { 0, 30, 124, 38}, - { 0, 38, 31, 68}, { 31, 38, 62, 68}, { 62, 38, 93, 68}, - { 93, 38, 124, 68}, - }, }, - { {0, 0, 672, 26}, {146, 22}, 7, { - { 0, 2, 23, 24}, { 23, 2, 46, 24}, { 46, 2, 54, 24}, - { 54, 2, 77, 24}, { 77, 2, 100, 24}, {100, 2, 123, 24}, - {123, 2, 146, 24}, - }, }, - { {0, 0, 672, 26}, {146, 100}, 7, { - { 0, 0, 23, 100}, { 23, 0, 46, 100}, { 46, 0, 54, 100}, - { 54, 0, 77, 100}, { 77, 0, 100, 100}, {100, 0, 123, 100}, - {123, 0, 146, 100}, - }, }, - { {0, 0, 672, 26}, {215, 100}, 10, { - { 0, 0, 23, 100}, { 23, 0, 46, 100}, { 46, 0, 54, 100}, - { 54, 0, 77, 100}, { 77, 0, 100, 100}, {100, 0, 123, 100}, - {123, 0, 146, 100}, {146, 0, 169, 100}, {169, 0, 192, 100}, - {192, 0, 215, 100}, - }, }, - { {0, 0, 672, 26}, {238, 39}, 11, { - { 0, 0, 23, 39}, { 23, 0, 46, 39}, { 46, 0, 54, 39}, - { 54, 0, 77, 39}, { 77, 0, 100, 39}, {100, 0, 123, 39}, - {123, 0, 146, 39}, {146, 0, 169, 39}, {169, 0, 192, 39}, - {192, 0, 215, 39}, {215, 0, 238, 39}, - }, }, - { {0, 0, 672, 26}, {238, 22}, 11, { - { 0, 0, 23, 22}, { 23, 0, 46, 22}, { 46, 0, 54, 22}, - { 54, 0, 77, 22}, { 77, 0, 100, 22}, {100, 0, 123, 22}, - {123, 0, 146, 22}, {146, 0, 169, 22}, {169, 0, 192, 22}, - {192, 0, 215, 22}, {215, 0, 238, 22}, - }, }, - { {0, 0, 672, 26}, {489, 39}, 3, { - { 0, 2, 163, 41}, {163, 2, 330, 41}, {330, 2, 493, 41}, - }, }, - { {0, 0, 672, 104}, {978, 24}, 6, { - { 0, 2, 163, 26}, {163, 2, 326, 26}, {326, 2, 489, 26}, - {489, 2, 652, 26}, {652, 2, 819, 26}, {819, 2, 850, 26}, - }, }, - { {0, 0, 672, 28}, {978, 38}, 6, { - { 0, 0, 163, 38}, {163, 0, 326, 38}, {326, 0, 489, 38}, - {489, 0, 652, 38}, {652, 0, 819, 38}, {819, 0, 850, 38}, - }, }, - { {0, 0, 672, 100}, {239, 102}, 3, { - { 0, 2, 100, 102}, {100, 2, 139, 102}, {139, 2, 239, 102}, - }, }, - { {0, 0, 672, 42}, {185, 40}, 3, { - { 0, 2, 75, 40}, {75, 2, 118, 40}, {118, 2, 185, 40}, - }, }, - { {0, 0, 672, 42}, {67, 40}, 1, { - { 0, 2, 67, 40}, - }, }, - { {0, 0, 672, 42}, {67, 41}, 2, { - { 0, 2, 672, 41}, { 0, 41, 672, 80}, - }, }, -}; +static tbsize_result_t init_tbsize_result(int nButtonsAlloc, int cleft, int ctop, int cright, int cbottom, int minx, int miny) { + tbsize_result_t ret; + + SetRect(&ret.rcClient, cleft, ctop, cright, cbottom); + ret.szMin.cx = minx; + ret.szMin.cy = miny; + ret.nButtons = 0; + ret.prcButtons = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, nButtonsAlloc*sizeof(RECT)); + + return ret; +} + +static void tbsize_addbutton(tbsize_result_t *tbsr, int left, int top, int right, int bottom) { + SetRect(&tbsr->prcButtons[tbsr->nButtons], left, top, right, bottom); + tbsr->nButtons++; +} + +#define STRING0 "A" +#define STRING1 "MMMMMMMMMMMMM" +#define STRING2 "Tst" + +static tbsize_result_t *tbsize_results; + +#define tbsize_results_num 24 + +static void init_tbsize_results(void) { + int fontheight = system_font_height(); + int buttonwidth; + + tbsize_results = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, tbsize_results_num*sizeof(tbsize_result_t)); + + tbsize_results[0] = init_tbsize_result(5, 0, 0 ,672 ,26, 100 ,22); + tbsize_addbutton(&tbsize_results[0], 0, 2, 23, 24); + tbsize_addbutton(&tbsize_results[0], 23, 2, 46, 24); + tbsize_addbutton(&tbsize_results[0], 46, 2, 54, 24); + tbsize_addbutton(&tbsize_results[0], 54, 2, 77, 24); + tbsize_addbutton(&tbsize_results[0], 77, 2, 100, 24); + + tbsize_results[1] = init_tbsize_result(7, 0, 0, 672, 26, 146, 22); + tbsize_addbutton(&tbsize_results[1], 0, 2, 23, 24); + tbsize_addbutton(&tbsize_results[1], 23, 2, 46, 24); + tbsize_addbutton(&tbsize_results[1], 46, 2, 54, 24); + tbsize_addbutton(&tbsize_results[1], 54, 2, 77, 24); + tbsize_addbutton(&tbsize_results[1], 77, 2, 100, 24); + tbsize_addbutton(&tbsize_results[1], 100, 2, 123, 24); + tbsize_addbutton(&tbsize_results[1], 0, 24, 23, 46); + + tbsize_results[2] = init_tbsize_result(7, 0, 0, 672, 26, 146, 22); + tbsize_addbutton(&tbsize_results[2], 0, 2, 23, 24); + tbsize_addbutton(&tbsize_results[2], 23, 2, 46, 24); + tbsize_addbutton(&tbsize_results[2], 46, 2, 54, 24); + tbsize_addbutton(&tbsize_results[2], 54, 2, 77, 24); + tbsize_addbutton(&tbsize_results[2], 77, 2, 100, 24); + tbsize_addbutton(&tbsize_results[2], 100, 2, 123, 24); + tbsize_addbutton(&tbsize_results[2], 0, 24, 23, 46); + + tbsize_results[3] = init_tbsize_result(7, 0, 0, 672, 26, 146, 22); + tbsize_addbutton(&tbsize_results[3], 0, 2, 23, 24); + tbsize_addbutton(&tbsize_results[3], 23, 2, 46, 24); + tbsize_addbutton(&tbsize_results[3], 46, 2, 54, 24); + tbsize_addbutton(&tbsize_results[3], 54, 2, 77, 24); + tbsize_addbutton(&tbsize_results[3], 77, 2, 100, 24); + tbsize_addbutton(&tbsize_results[3], 100, 2, 123, 24); + tbsize_addbutton(&tbsize_results[3], 123, 2, 146, 24); + + tbsize_results[4] = init_tbsize_result(9, 0, 0, 672, 26, 192, 22); + tbsize_addbutton(&tbsize_results[4], 0, 2, 23, 24); + tbsize_addbutton(&tbsize_results[4], 23, 2, 46, 24); + tbsize_addbutton(&tbsize_results[4], 46, 2, 54, 24); + tbsize_addbutton(&tbsize_results[4], 54, 2, 77, 24); + tbsize_addbutton(&tbsize_results[4], 77, 2, 100, 24); + tbsize_addbutton(&tbsize_results[4], 100, 2, 123, 24); + tbsize_addbutton(&tbsize_results[4], 123, 2, 146, 24); + tbsize_addbutton(&tbsize_results[4], 146, 2, 169, 24); + tbsize_addbutton(&tbsize_results[4], 169, 2, 192, 24); + + tbsize_results[5] = init_tbsize_result(39, 0, 0, 672, 92, 882, 22); + tbsize_addbutton(&tbsize_results[5], 0, 2, 23, 24); + tbsize_addbutton(&tbsize_results[5], 23, 2, 46, 24); + tbsize_addbutton(&tbsize_results[5], 0, 2, 8, 29); + tbsize_addbutton(&tbsize_results[5], 0, 29, 23, 51); + tbsize_addbutton(&tbsize_results[5], 23, 29, 46, 51); + tbsize_addbutton(&tbsize_results[5], 46, 29, 69, 51); + tbsize_addbutton(&tbsize_results[5], 69, 29, 92, 51); + tbsize_addbutton(&tbsize_results[5], 92, 29, 115, 51); + tbsize_addbutton(&tbsize_results[5], 115, 29, 138, 51); + tbsize_addbutton(&tbsize_results[5], 138, 29, 161, 51); + tbsize_addbutton(&tbsize_results[5], 161, 29, 184, 51); + tbsize_addbutton(&tbsize_results[5], 184, 29, 207, 51); + tbsize_addbutton(&tbsize_results[5], 207, 29, 230, 51); + tbsize_addbutton(&tbsize_results[5], 230, 29, 253, 51); + tbsize_addbutton(&tbsize_results[5], 253, 29, 276, 51); + tbsize_addbutton(&tbsize_results[5], 276, 29, 299, 51); + tbsize_addbutton(&tbsize_results[5], 299, 29, 322, 51); + tbsize_addbutton(&tbsize_results[5], 322, 29, 345, 51); + tbsize_addbutton(&tbsize_results[5], 345, 29, 368, 51); + tbsize_addbutton(&tbsize_results[5], 368, 29, 391, 51); + tbsize_addbutton(&tbsize_results[5], 391, 29, 414, 51); + tbsize_addbutton(&tbsize_results[5], 414, 29, 437, 51); + tbsize_addbutton(&tbsize_results[5], 437, 29, 460, 51); + tbsize_addbutton(&tbsize_results[5], 460, 29, 483, 51); + tbsize_addbutton(&tbsize_results[5], 483, 29, 506, 51); + tbsize_addbutton(&tbsize_results[5], 506, 29, 529, 51); + tbsize_addbutton(&tbsize_results[5], 529, 29, 552, 51); + tbsize_addbutton(&tbsize_results[5], 552, 29, 575, 51); + tbsize_addbutton(&tbsize_results[5], 575, 29, 598, 51); + tbsize_addbutton(&tbsize_results[5], 598, 29, 621, 51); + tbsize_addbutton(&tbsize_results[5], 621, 29, 644, 51); + tbsize_addbutton(&tbsize_results[5], 644, 29, 667, 51); + tbsize_addbutton(&tbsize_results[5], 0, 51, 23, 73); + tbsize_addbutton(&tbsize_results[5], 23, 51, 46, 73); + tbsize_addbutton(&tbsize_results[5], 46, 51, 69, 73); + tbsize_addbutton(&tbsize_results[5], 69, 51, 92, 73); + tbsize_addbutton(&tbsize_results[5], 92, 51, 115, 73); + tbsize_addbutton(&tbsize_results[5], 115, 51, 138, 73); + tbsize_addbutton(&tbsize_results[5], 138, 51, 161, 73); + + tbsize_results[6] = init_tbsize_result(7, 0, 0, 48, 226, 23, 140); + tbsize_addbutton(&tbsize_results[6], 0, 2, 23, 24); + tbsize_addbutton(&tbsize_results[6], 23, 2, 46, 24); + tbsize_addbutton(&tbsize_results[6], 46, 2, 94, 24); + tbsize_addbutton(&tbsize_results[6], 94, 2, 117, 24); + tbsize_addbutton(&tbsize_results[6], 117, 2, 140, 24); + tbsize_addbutton(&tbsize_results[6], 140, 2, 163, 24); + tbsize_addbutton(&tbsize_results[6], 0, 24, 23, 46); + + tbsize_results[7] = init_tbsize_result(7, 0, 0, 92, 226, 23, 140); + tbsize_addbutton(&tbsize_results[7], 0, 2, 23, 24); + tbsize_addbutton(&tbsize_results[7], 23, 2, 46, 24); + tbsize_addbutton(&tbsize_results[7], 0, 24, 92, 32); + tbsize_addbutton(&tbsize_results[7], 0, 32, 23, 54); + tbsize_addbutton(&tbsize_results[7], 23, 32, 46, 54); + tbsize_addbutton(&tbsize_results[7], 46, 32, 69, 54); + tbsize_addbutton(&tbsize_results[7], 69, 32, 92, 54); + + tbsize_results[8] = init_tbsize_result(7, 0, 0, 672, 26, 194, 30); + tbsize_addbutton(&tbsize_results[8], 0, 2, 31, 32); + tbsize_addbutton(&tbsize_results[8], 31, 2, 62, 32); + tbsize_addbutton(&tbsize_results[8], 62, 2, 70, 32); + tbsize_addbutton(&tbsize_results[8], 70, 2, 101, 32); + tbsize_addbutton(&tbsize_results[8], 101, 2, 132, 32); + tbsize_addbutton(&tbsize_results[8], 132, 2, 163, 32); + tbsize_addbutton(&tbsize_results[8], 0, 32, 31, 62); + + tbsize_results[9] = init_tbsize_result(7, 0, 0, 672, 64, 194, 30); + tbsize_addbutton(&tbsize_results[9], 0, 2, 31, 32); + tbsize_addbutton(&tbsize_results[9], 31, 2, 62, 32); + tbsize_addbutton(&tbsize_results[9], 62, 2, 70, 32); + tbsize_addbutton(&tbsize_results[9], 70, 2, 101, 32); + tbsize_addbutton(&tbsize_results[9], 101, 2, 132, 32); + tbsize_addbutton(&tbsize_results[9], 132, 2, 163, 32); + tbsize_addbutton(&tbsize_results[9], 0, 32, 31, 62); + + tbsize_results[10] = init_tbsize_result(7, 0, 0, 672, 64, 194, 30); + tbsize_addbutton(&tbsize_results[10], 0, 0, 31, 30); + tbsize_addbutton(&tbsize_results[10], 31, 0, 62, 30); + tbsize_addbutton(&tbsize_results[10], 62, 0, 70, 30); + tbsize_addbutton(&tbsize_results[10], 70, 0, 101, 30); + tbsize_addbutton(&tbsize_results[10], 101, 0, 132, 30); + tbsize_addbutton(&tbsize_results[10], 132, 0, 163, 30); + tbsize_addbutton(&tbsize_results[10], 0, 30, 31, 60); + + tbsize_results[11] = init_tbsize_result(7, 0, 0, 124, 226, 31, 188); + tbsize_addbutton(&tbsize_results[11], 0, 0, 31, 30); + tbsize_addbutton(&tbsize_results[11], 31, 0, 62, 30); + tbsize_addbutton(&tbsize_results[11], 0, 30, 124, 38); + tbsize_addbutton(&tbsize_results[11], 0, 38, 31, 68); + tbsize_addbutton(&tbsize_results[11], 31, 38, 62, 68); + tbsize_addbutton(&tbsize_results[11], 62, 38, 93, 68); + tbsize_addbutton(&tbsize_results[11], 93, 38, 124, 68); + + tbsize_results[12] = init_tbsize_result(7, 0, 0, 672, 26, 146, 22); + tbsize_addbutton(&tbsize_results[12], 0, 2, 23, 24); + tbsize_addbutton(&tbsize_results[12], 23, 2, 46, 24); + tbsize_addbutton(&tbsize_results[12], 46, 2, 54, 24); + tbsize_addbutton(&tbsize_results[12], 54, 2, 77, 24); + tbsize_addbutton(&tbsize_results[12], 77, 2, 100, 24); + tbsize_addbutton(&tbsize_results[12], 100, 2, 123, 24); + tbsize_addbutton(&tbsize_results[12], 123, 2, 146, 24); + + tbsize_results[13] = init_tbsize_result(7, 0, 0, 672, 26, 146, 100); + tbsize_addbutton(&tbsize_results[13], 0, 0, 23, 100); + tbsize_addbutton(&tbsize_results[13], 23, 0, 46, 100); + tbsize_addbutton(&tbsize_results[13], 46, 0, 54, 100); + tbsize_addbutton(&tbsize_results[13], 54, 0, 77, 100); + tbsize_addbutton(&tbsize_results[13], 77, 0, 100, 100); + tbsize_addbutton(&tbsize_results[13], 100, 0, 123, 100); + tbsize_addbutton(&tbsize_results[13], 123, 0, 146, 100); + + tbsize_results[14] = init_tbsize_result(10, 0, 0, 672, 26, 146, 100); + tbsize_addbutton(&tbsize_results[14], 0, 0, 23, 100); + tbsize_addbutton(&tbsize_results[14], 23, 0, 46, 100); + tbsize_addbutton(&tbsize_results[14], 46, 0, 54, 100); + tbsize_addbutton(&tbsize_results[14], 54, 0, 77, 100); + tbsize_addbutton(&tbsize_results[14], 77, 0, 100, 100); + tbsize_addbutton(&tbsize_results[14], 100, 0, 123, 100); + tbsize_addbutton(&tbsize_results[14], 123, 0, 146, 100); + tbsize_addbutton(&tbsize_results[14], 146, 0, 169, 100); + tbsize_addbutton(&tbsize_results[14], 169, 0, 192, 100); + tbsize_addbutton(&tbsize_results[14], 192, 0, 215, 100); + + tbsize_results[15] = init_tbsize_result(11, 0, 0, 672, 26, 238, 39); + tbsize_addbutton(&tbsize_results[15], 0, 0, 23, 23 + fontheight); + tbsize_addbutton(&tbsize_results[15], 23, 0, 46, 23 + fontheight); + tbsize_addbutton(&tbsize_results[15], 46, 0, 54, 23 + fontheight); + tbsize_addbutton(&tbsize_results[15], 54, 0, 77, 23 + fontheight); + tbsize_addbutton(&tbsize_results[15], 77, 0, 100, 23 + fontheight); + tbsize_addbutton(&tbsize_results[15], 100, 0, 123, 23 + fontheight); + tbsize_addbutton(&tbsize_results[15], 123, 0, 146, 23 + fontheight); + tbsize_addbutton(&tbsize_results[15], 146, 0, 169, 23 + fontheight); + tbsize_addbutton(&tbsize_results[15], 169, 0, 192, 23 + fontheight); + tbsize_addbutton(&tbsize_results[15], 192, 0, 215, 23 + fontheight); + tbsize_addbutton(&tbsize_results[15], 215, 0, 238, 23 + fontheight); + + tbsize_results[16] = init_tbsize_result(11, 0, 0, 672, 26, 239, 22); + tbsize_addbutton(&tbsize_results[16], 0, 0, 23, 22); + tbsize_addbutton(&tbsize_results[16], 23, 0, 46, 22); + tbsize_addbutton(&tbsize_results[16], 46, 0, 54, 22); + tbsize_addbutton(&tbsize_results[16], 54, 0, 77, 22); + tbsize_addbutton(&tbsize_results[16], 77, 0, 100, 22); + tbsize_addbutton(&tbsize_results[16], 100, 0, 123, 22); + tbsize_addbutton(&tbsize_results[16], 123, 0, 146, 22); + tbsize_addbutton(&tbsize_results[16], 146, 0, 169, 22); + tbsize_addbutton(&tbsize_results[16], 169, 0, 192, 22); + tbsize_addbutton(&tbsize_results[16], 192, 0, 215, 22); + tbsize_addbutton(&tbsize_results[16], 215, 0, 238, 22); + + buttonwidth = 7 + string_width(STRING1); + + tbsize_results[17] = init_tbsize_result(3, 0, 0, 672, 26, 489, 39); + tbsize_addbutton(&tbsize_results[17], 0, 2, buttonwidth, 25 + fontheight); + tbsize_addbutton(&tbsize_results[17], buttonwidth, 2, 2*buttonwidth + 4, 25 + fontheight); + tbsize_addbutton(&tbsize_results[17], 2*buttonwidth + 4, 2, 3*buttonwidth + 4, 25 + fontheight); + + tbsize_results[18] = init_tbsize_result(6, 0, 0, 672, 104, 978, 24); + tbsize_addbutton(&tbsize_results[18], 0, 2, buttonwidth, 10 + fontheight); + tbsize_addbutton(&tbsize_results[18], buttonwidth, 2, 2*buttonwidth, 10 + fontheight); + tbsize_addbutton(&tbsize_results[18], 2*buttonwidth, 2, 3*buttonwidth, 10 + fontheight); + tbsize_addbutton(&tbsize_results[18], 3*buttonwidth, 2, 4*buttonwidth, 10 + fontheight); + tbsize_addbutton(&tbsize_results[18], 4*buttonwidth, 2, 5*buttonwidth + 4, 10 + fontheight); + tbsize_addbutton(&tbsize_results[18], 5*buttonwidth + 4, 2, 5*buttonwidth + 4 + string_width(STRING2) + 11, 10 + fontheight); + + tbsize_results[19] = init_tbsize_result(6, 0, 0, 672, 28, 978, 38); + tbsize_addbutton(&tbsize_results[19], 0, 0, buttonwidth, 22 + fontheight); + tbsize_addbutton(&tbsize_results[19], buttonwidth, 0, 2*buttonwidth, 22 + fontheight); + tbsize_addbutton(&tbsize_results[19], 2*buttonwidth, 0, 3*buttonwidth, 22 + fontheight); + tbsize_addbutton(&tbsize_results[19], 3*buttonwidth, 0, 4*buttonwidth, 22 + fontheight); + tbsize_addbutton(&tbsize_results[19], 4*buttonwidth, 0, 5*buttonwidth + 4, 22 + fontheight); + tbsize_addbutton(&tbsize_results[19], 5*buttonwidth + 4, 0, 5*buttonwidth + 4 + string_width(STRING2) + 11, 22 + fontheight); + + tbsize_results[20] = init_tbsize_result(3, 0, 0, 672, 100, 239, 102); + tbsize_addbutton(&tbsize_results[20], 0, 2, 100, 102); + tbsize_addbutton(&tbsize_results[20], 100, 2, 139, 102); + tbsize_addbutton(&tbsize_results[20], 139, 2, 239, 102); + + tbsize_results[21] = init_tbsize_result(3, 0, 0, 672, 42, 185, 40); + tbsize_addbutton(&tbsize_results[21], 0, 2, 75, 40); + tbsize_addbutton(&tbsize_results[21], 75, 2, 118, 40); + tbsize_addbutton(&tbsize_results[21], 118, 2, 165 + string_width(STRING2), 40); + + tbsize_results[22] = init_tbsize_result(1, 0, 0, 672, 42, 67, 40); + tbsize_addbutton(&tbsize_results[22], 0, 2, 47 + string_width(STRING2), 40); + + tbsize_results[23] = init_tbsize_result(2, 0, 0, 672, 42, 67, 41); + tbsize_addbutton(&tbsize_results[23], 0, 2, 672, 25 + fontheight); + tbsize_addbutton(&tbsize_results[23], 0, 25 + fontheight, 672, 48 + 2*fontheight); +} + +static void free_tbsize_results(void) { + int i; + + for (i = 0; i < tbsize_results_num; i++) + HeapFree(GetProcessHeap(), 0, tbsize_results[i].prcButtons); + HeapFree(GetProcessHeap(), 0, tbsize_results); + tbsize_results = NULL; +} static int tbsize_numtests = 0; @@ -812,13 +1000,12 @@ static tbsize_alt_result_t tbsize_alt_results[] = { 20, 2, { 107, 2, 207, 102 } } }; -static int tbsize_alt_numtests = 0; +static DWORD tbsize_alt_numtests = 0; #define check_sizes_todo(todomask) { \ RECT rc; \ int buttonCount, i, mask=(todomask); \ tbsize_result_t *res = &tbsize_results[tbsize_numtests]; \ - assert(tbsize_numtests < sizeof(tbsize_results)/sizeof(tbsize_results[0])); \ GetClientRect(hToolbar, &rc); \ /*check_rect("client", rc, res->rcClient);*/ \ buttonCount = SendMessage(hToolbar, TB_BUTTONCOUNT, 0, 0); \ @@ -830,9 +1017,9 @@ static int tbsize_alt_numtests = 0; win_skip("Alternate rect found\n"); \ tbsize_alt_numtests++; \ } else if (!(mask&1)) { \ - check_rect("button", rc, res->rcButtons[i]); \ + check_rect("button = %d, tbsize_numtests = %d", rc, res->prcButtons[i], i, tbsize_numtests); \ } else {\ - todo_wine { check_rect("button", rc, res->rcButtons[i]); } \ + todo_wine { check_rect("button = %d, tbsize_numtests = %d", rc, res->prcButtons[i], i, tbsize_numtests); } \ } \ mask >>= 1; \ } \ @@ -855,7 +1042,7 @@ static TBBUTTON buttons3[] = { {0, 30, TBSTATE_ENABLED, 0, {0, }, 0, 0}, {0, 31, TBSTATE_ENABLED, 0, {0, }, 0, 1}, {0, 32, TBSTATE_ENABLED, BTNS_AUTOSIZE, {0, }, 0, 1}, - {0, 33, TBSTATE_ENABLED, BTNS_AUTOSIZE, {0, }, 0, (UINT_PTR)"Tst"} + {0, 33, TBSTATE_ENABLED, BTNS_AUTOSIZE, {0, }, 0, (UINT_PTR)STRING2} }; static void test_sizes(void) @@ -865,6 +1052,9 @@ static void test_sizes(void) TBBUTTONINFO tbinfo; int style; int i; + int fontheight = system_font_height(); + + init_tbsize_results(); rebuild_toolbar_with_buttons(&hToolbar); style = GetWindowLong(hToolbar, GWL_STYLE); @@ -922,15 +1112,15 @@ static void test_sizes(void) SendMessageA(hToolbar, TB_ADDBUTTONS, 2, (LPARAM)buttons2); check_sizes(); /* TB_SETBUTTONSIZE can't be used to reduce the size of a button below the default */ - ok(SendMessageA(hToolbar, TB_GETBUTTONSIZE, 0, 0) == MAKELONG(23, 22), "Unexpected button size\n"); + check_button_size(hToolbar, 23, 22); ok(SendMessageA(hToolbar, TB_SETBUTTONSIZE, 0, MAKELONG(22, 21))==1, "TB_SETBUTTONSIZE\n"); - ok(SendMessageA(hToolbar, TB_GETBUTTONSIZE, 0, 0) == MAKELONG(23, 22), "Unexpected button size\n"); + check_button_size(hToolbar, 23, 22); ok(SendMessageA(hToolbar, TB_SETBUTTONSIZE, 0, MAKELONG(5, 100))==1, "TB_SETBUTTONSIZE\n"); - ok(SendMessageA(hToolbar, TB_GETBUTTONSIZE, 0, 0) == MAKELONG(23, 100), "Unexpected button size\n"); + check_button_size(hToolbar, 23, 100); ok(SendMessageA(hToolbar, TB_SETBUTTONSIZE, 0, MAKELONG(3, 3))==1, "TB_SETBUTTONSIZE\n"); - ok(SendMessageA(hToolbar, TB_GETBUTTONSIZE, 0, 0) == MAKELONG(23, 22), "Unexpected button size\n"); + check_button_size(hToolbar, 23, 22); ok(SendMessageA(hToolbar, TB_SETBUTTONSIZE, 0, MAKELONG(5, 100))==1, "TB_SETBUTTONSIZE\n"); - ok(SendMessageA(hToolbar, TB_GETBUTTONSIZE, 0, 0) == MAKELONG(23, 100), "Unexpected button size\n"); + check_button_size(hToolbar, 23, 100); check_sizes(); /* add some buttons with non-default sizes */ SendMessageA(hToolbar, TB_ADDBUTTONS, 2, (LPARAM)buttons2); @@ -938,26 +1128,26 @@ static void test_sizes(void) check_sizes(); SendMessageA(hToolbar, TB_ADDBUTTONS, 1, (LPARAM)&buttons3[0]); /* TB_ADDSTRING resets the size */ - SendMessageA(hToolbar, TB_ADDSTRING, 0, (LPARAM)"A\0MMMMMMMMMMMMM\0"); - ok(SendMessageA(hToolbar, TB_GETBUTTONSIZE, 0, 0) == MAKELONG(23, 39), "Unexpected button size\n"); + SendMessageA(hToolbar, TB_ADDSTRING, 0, (LPARAM) STRING0 "\0" STRING1 "\0"); + check_button_size(hToolbar, 23, 23 + fontheight); check_sizes(); /* TB_SETBUTTONSIZE can be used to crop the text */ SendMessageA(hToolbar, TB_SETBUTTONSIZE, 0, MAKELONG(3, 3)); - ok(SendMessageA(hToolbar, TB_GETBUTTONSIZE, 0, 0) == MAKELONG(23, 22), "Unexpected button size\n"); + check_button_size(hToolbar, 23, 22); check_sizes(); /* the default size is bitmap size + padding */ SendMessageA(hToolbar, TB_SETPADDING, 0, MAKELONG(1, 1)); SendMessageA(hToolbar, TB_SETBUTTONSIZE, 0, MAKELONG(3, 3)); - ok(SendMessageA(hToolbar, TB_GETBUTTONSIZE, 0, 0) == MAKELONG(17, 17), "Unexpected button size\n"); + check_button_size(hToolbar, 17, 17); SendMessageA(hToolbar, TB_SETBITMAPSIZE, 0, MAKELONG(3, 3)); SendMessageA(hToolbar, TB_SETBUTTONSIZE, 0, MAKELONG(3, 3)); - ok(SendMessageA(hToolbar, TB_GETBUTTONSIZE, 0, 0) == MAKELONG(4, 4), "Unexpected button size\n"); + check_button_size(hToolbar, 4, 4); rebuild_toolbar(&hToolbar); /* sending a TB_SETBITMAPSIZE with the same sizes is enough to make the button smaller */ - ok(SendMessageA(hToolbar, TB_GETBUTTONSIZE, 0, 0) == MAKELONG(23, 22), "Unexpected button size\n"); + check_button_size(hToolbar, 23, 22); SendMessageA(hToolbar, TB_SETBITMAPSIZE, 0, MAKELONG(16, 15)); - ok(SendMessageA(hToolbar, TB_GETBUTTONSIZE, 0, 0) == MAKELONG(23, 21), "Unexpected button size\n"); + check_button_size(hToolbar, 23, 21); /* -1 in TB_SETBITMAPSIZE is a special code meaning that the coordinate shouldn't be changed */ add_128x15_bitmap(hToolbar, 16); ok(SendMessageA(hToolbar, TB_SETBITMAPSIZE, 0, MAKELONG(14, -1)), "TB_SETBITMAPSIZE failed\n"); @@ -972,64 +1162,64 @@ static void test_sizes(void) CHECK_IMAGELIST(16, 14, 12); rebuild_toolbar(&hToolbar); - SendMessageA(hToolbar, TB_ADDSTRINGA, 0, (LPARAM)"A\0MMMMMMMMMMMMM\0"); + SendMessageA(hToolbar, TB_ADDSTRINGA, 0, (LPARAM)STRING0 "\0" STRING1 "\0"); /* the height is increased after a TB_ADDSTRING */ - ok(SendMessageA(hToolbar, TB_GETBUTTONSIZE, 0, 0) == MAKELONG(23, 39), "Unexpected button size\n"); + check_button_size(hToolbar, 23, 23 + fontheight); SendMessageA(hToolbar, TB_SETBUTTONSIZE, 0, MAKELONG(100, 100)); /* if a string is in the pool, even adding a button without a string resets the size */ SendMessageA(hToolbar, TB_ADDBUTTONS, 1, (LPARAM)&buttons2[0]); - ok(SendMessageA(hToolbar, TB_GETBUTTONSIZE, 0, 0) == MAKELONG(23, 22), "Unexpected button size\n"); + check_button_size(hToolbar, 23, 22); SendMessageA(hToolbar, TB_SETBUTTONSIZE, 0, MAKELONG(100, 100)); /* an BTNS_AUTOSIZE button is also considered when computing the new size */ SendMessageA(hToolbar, TB_ADDBUTTONS, 1, (LPARAM)&buttons3[2]); - ok(SendMessageA(hToolbar, TB_GETBUTTONSIZE, 0, 0) == MAKELONG(163, 39), "Unexpected button size\n"); + check_button_size(hToolbar, 7 + string_width(STRING1), 23 + fontheight); SendMessageA(hToolbar, TB_ADDBUTTONS, 1, (LPARAM)&buttons3[0]); check_sizes(); /* delete button doesn't change the buttons size */ SendMessageA(hToolbar, TB_DELETEBUTTON, 2, 0); SendMessageA(hToolbar, TB_DELETEBUTTON, 1, 0); - ok(SendMessageA(hToolbar, TB_GETBUTTONSIZE, 0, 0) == MAKELONG(163, 39), "Unexpected button size\n"); + check_button_size(hToolbar, 7 + string_width(STRING1), 23 + fontheight); /* TB_INSERTBUTTONS will */ SendMessageA(hToolbar, TB_INSERTBUTTON, 1, (LPARAM)&buttons2[0]); - ok(SendMessageA(hToolbar, TB_GETBUTTONSIZE, 0, 0) == MAKELONG(23, 22), "Unexpected button size\n"); + check_button_size(hToolbar, 23, 22); /* TB_HIDEBUTTON and TB_MOVEBUTTON doesn't force a recalc */ SendMessageA(hToolbar, TB_SETBUTTONSIZE, 0, MAKELONG(100, 100)); ok(SendMessageA(hToolbar, TB_MOVEBUTTON, 0, 1), "TB_MOVEBUTTON failed\n"); - ok(SendMessageA(hToolbar, TB_GETBUTTONSIZE, 0, 0) == MAKELONG(100, 100), "Unexpected button size\n"); + check_button_size(hToolbar, 100, 100); ok(SendMessageA(hToolbar, TB_HIDEBUTTON, 20, TRUE), "TB_HIDEBUTTON failed\n"); - ok(SendMessageA(hToolbar, TB_GETBUTTONSIZE, 0, 0) == MAKELONG(100, 100), "Unexpected button size\n"); + check_button_size(hToolbar, 100, 100); /* however changing the hidden flag with TB_SETSTATE does */ ok(SendMessageA(hToolbar, TB_SETSTATE, 20, TBSTATE_ENABLED|TBSTATE_HIDDEN), "TB_SETSTATE failed\n"); - ok(SendMessageA(hToolbar, TB_GETBUTTONSIZE, 0, 0) == MAKELONG(100, 100), "Unexpected button size\n"); + check_button_size(hToolbar, 100, 100); ok(SendMessageA(hToolbar, TB_SETSTATE, 20, TBSTATE_ENABLED), "TB_SETSTATE failed\n"); - ok(SendMessageA(hToolbar, TB_GETBUTTONSIZE, 0, 0) == MAKELONG(23, 22), "Unexpected button size\n"); + check_button_size(hToolbar, 23, 22); /* TB_SETIMAGELIST always changes the height but the width only if necessary */ SendMessageA(hToolbar, TB_SETBUTTONSIZE, 0, MAKELONG(100, 100)); himl = ImageList_LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(IDB_BITMAP_80x15), 20, 2, CLR_NONE, IMAGE_BITMAP, LR_DEFAULTCOLOR); ok(SendMessageA(hToolbar, TB_SETIMAGELIST, 0, (LPARAM)himl) == 0, "TB_SETIMAGELIST failed\n"); - ok(SendMessageA(hToolbar, TB_GETBUTTONSIZE, 0, 0) == MAKELONG(100, 21), "Unexpected button size\n"); + check_button_size(hToolbar, 100, 21); SendMessageA(hToolbar, TB_SETBUTTONSIZE, 0, MAKELONG(100, 100)); - ok(SendMessageA(hToolbar, TB_GETBUTTONSIZE, 0, 0) == MAKELONG(100, 100), "Unexpected button size\n"); + check_button_size(hToolbar, 100, 100); /* But there are no update when we change imagelist, and image sizes are the same */ himl2 = ImageList_LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(IDB_BITMAP_128x15), 20, 2, CLR_NONE, IMAGE_BITMAP, LR_DEFAULTCOLOR); ok(SendMessageA(hToolbar, TB_SETIMAGELIST, 0, (LRESULT)himl2) == (LRESULT)himl, "TB_SETIMAGELIST failed\n"); - ok(SendMessageA(hToolbar, TB_GETBUTTONSIZE, 0, 0) == MAKELONG(100, 100), "Unexpected button size\n"); + check_button_size(hToolbar, 100, 100); SendMessageA(hToolbar, TB_SETBUTTONSIZE, 0, MAKELONG(1, 1)); - ok(SendMessageA(hToolbar, TB_GETBUTTONSIZE, 0, 0) == MAKELONG(27, 21), "Unexpected button size\n"); + check_button_size(hToolbar, 27, 21); ok(SendMessageA(hToolbar, TB_SETIMAGELIST, 0, 0) == (LRESULT)himl2, "TB_SETIMAGELIST failed\n"); - ok(SendMessageA(hToolbar, TB_GETBUTTONSIZE, 0, 0) == MAKELONG(27, 7), "Unexpected button size\n"); + check_button_size(hToolbar, 27, 7); SendMessageA(hToolbar, TB_SETBUTTONSIZE, 0, MAKELONG(1, 1)); - ok(SendMessageA(hToolbar, TB_GETBUTTONSIZE, 0, 0) == MAKELONG(8, 7), "Unexpected button size\n"); + check_button_size(hToolbar, 8, 7) ok(SendMessageA(hToolbar, TB_SETIMAGELIST, 0, (LPARAM)himl) == 0, "TB_SETIMAGELIST failed\n"); - ok(SendMessageA(hToolbar, TB_GETBUTTONSIZE, 0, 0) == MAKELONG(27, 21), "Unexpected button size\n"); + check_button_size(hToolbar, 27, 21) /* the text is taken into account */ - SendMessageA(hToolbar, TB_ADDSTRINGA, 0, (LPARAM)"A\0MMMMMMMMMMMMM\0"); + SendMessageA(hToolbar, TB_ADDSTRINGA, 0, (LPARAM)STRING0 "\0" STRING1 "\0"); SendMessageA(hToolbar, TB_ADDBUTTONS, 4, (LPARAM)buttons3); - ok(SendMessageA(hToolbar, TB_GETBUTTONSIZE, 0, 0) == MAKELONG(163, 38), "Unexpected button size\n"); + check_button_size(hToolbar, 7 + string_width(STRING1), 22 + fontheight); ok(SendMessageA(hToolbar, TB_SETIMAGELIST, 0, 0) == (LRESULT)himl, "TB_SETIMAGELIST failed\n"); - ok(SendMessageA(hToolbar, TB_GETBUTTONSIZE, 0, 0) == MAKELONG(163, 24), "Unexpected button size\n"); + check_button_size(hToolbar, 7 + string_width(STRING1), 8 + fontheight); /* the style change also comes into effect */ check_sizes(); SetWindowLong(hToolbar, GWL_STYLE, GetWindowLong(hToolbar, GWL_STYLE) | TBSTYLE_FLAT); @@ -1041,9 +1231,9 @@ static void test_sizes(void) 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"); + check_button_size(hToolbar, 7 + string_width(STRING2), 23 + fontheight); SendMessageA(hToolbar, TB_DELETEBUTTON, 0, 0); - ok(SendMessageA(hToolbar, TB_GETBUTTONSIZE, 0, 0) == MAKELONG(27, 39), "Unexpected button size\n"); + check_button_size(hToolbar, 7 + string_width(STRING2), 23 + fontheight); rebuild_toolbar(&hToolbar); @@ -1092,6 +1282,7 @@ static void test_sizes(void) ok(SendMessageA(hToolbar, TB_SETBUTTONINFO, 33, (LPARAM)&tbinfo) != 0, "TB_SETBUTTONINFO failed\n"); } + free_tbsize_results(); DestroyWindow(hToolbar); } @@ -1338,7 +1529,7 @@ static void test_setrows(void) { TBBUTTON buttons[9]; HWND hToolbar; - int i; + DWORD i; for (i=0; i<9; i++) MakeButton(buttons+i, 1000+i, TBSTYLE_FLAT | TBSTYLE_CHECKGROUP, 0); @@ -1443,6 +1634,53 @@ static void test_tooltip(void) DestroyWindow(hToolbar); } +static void test_get_set_style(void) +{ + TBBUTTON buttons[9]; + DWORD style, style2, ret; + HWND hToolbar; + int i; + + for (i=0; i<9; i++) + MakeButton(buttons+i, 1000+i, TBSTYLE_CHECKGROUP, 0); + MakeButton(buttons+3, 1003, TBSTYLE_SEP|TBSTYLE_GROUP, 0); + MakeButton(buttons+6, 1006, TBSTYLE_SEP, 0); + + hToolbar = CreateToolbarEx(hMainWnd, + WS_VISIBLE | WS_CLIPCHILDREN | CCS_TOP | + WS_CHILD | TBSTYLE_LIST, + 100, + 0, NULL, 0, + buttons, sizeof(buttons)/sizeof(buttons[0]), + 0, 0, 20, 16, sizeof(TBBUTTON)); + ok(hToolbar != NULL, "Toolbar creation\n"); + SendMessage(hToolbar, TB_ADDSTRINGA, 0, (LPARAM)"test\000"); + + style = SendMessageA(hToolbar, TB_GETSTYLE, 0, 0); + style2 = GetWindowLongA(hToolbar, GWL_STYLE); + ok(style == style2, "got 0x%08x, expected 0x%08x\n", style, style2); + + /* try to alter common window bits */ + style2 |= WS_BORDER; + ret = SendMessageA(hToolbar, TB_SETSTYLE, 0, style2); + ok(ret == 0, "got %d\n", ret); + style = SendMessageA(hToolbar, TB_GETSTYLE, 0, 0); + style2 = GetWindowLongA(hToolbar, GWL_STYLE); + ok((style != style2) && (style == (style2 | WS_BORDER)), + "got 0x%08x, expected 0x%08x\n", style, style2); + ok(style & WS_BORDER, "got 0x%08x\n", style); + + /* now styles are the same, alter window style */ + ret = SendMessageA(hToolbar, TB_SETSTYLE, 0, style2); + ok(ret == 0, "got %d\n", ret); + style2 |= WS_BORDER; + SetWindowLongA(hToolbar, GWL_STYLE, style2); + style = SendMessageA(hToolbar, TB_GETSTYLE, 0, 0); + ok(style == style2, "got 0x%08x, expected 0x%08x\n", style, style2); + + DestroyWindow(hToolbar); +} + START_TEST(toolbar) { WNDCLASSA wc; @@ -1482,6 +1720,7 @@ START_TEST(toolbar) test_setrows(); test_getstring(); test_tooltip(); + test_get_set_style(); PostQuitMessage(0); while(GetMessageA(&msg,0,0,0)) { diff --git a/rostests/winetests/comctl32/tooltips.c b/rostests/winetests/comctl32/tooltips.c index 8ca3f7bb903..596598f1ade 100644 --- a/rostests/winetests/comctl32/tooltips.c +++ b/rostests/winetests/comctl32/tooltips.c @@ -148,7 +148,7 @@ static void test_customdraw(void) { {CDRF_NEWFONT, TEST_CDDS_PREPAINT} }; - int iterationNumber; + DWORD iterationNumber; WNDCLASSA wc; LRESULT lResult; @@ -435,7 +435,7 @@ static void test_ttm_gettoolinfo(void) ti.uFlags = 0; ti.uId = 0x1234ABCD; ti.lpszText = NULL; - ti.lParam = 0xdeadbeef; + ti.lParam = 0x1abe11ed; GetClientRect(hwnd, &ti.rect); r = SendMessageA(hwnd, TTM_ADDTOOLA, 0, (LPARAM)&ti); ok(r, "Adding the tool to the tooltip failed\n"); @@ -444,9 +444,9 @@ static void test_ttm_gettoolinfo(void) 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); + ok(0x1abe11ed == ti.lParam || + broken(0x1abe11ed != ti.lParam), /* comctl32 < 5.81 */ + "Expected 0x1abe11ed, got %lx\n", ti.lParam); tiW.cbSize = TTTOOLINFOW_V2_SIZE; tiW.hwnd = NULL; @@ -454,22 +454,22 @@ static void test_ttm_gettoolinfo(void) 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); + ok(0x1abe11ed == tiW.lParam || + broken(0x1abe11ed != tiW.lParam), /* comctl32 < 5.81 */ + "Expected 0x1abe11ed, got %lx\n", tiW.lParam); ti.cbSize = TTTOOLINFOA_V2_SIZE; ti.uId = 0x1234ABCD; - ti.lParam = 0xaaaaaaaa; + ti.lParam = 0x55555555; 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); + ok(0x55555555 == ti.lParam || + broken(0x55555555 != ti.lParam), /* comctl32 < 5.81 */ + "Expected 0x55555555, got %lx\n", ti.lParam); DestroyWindow(hwnd); diff --git a/rostests/winetests/comctl32/trackbar.c b/rostests/winetests/comctl32/trackbar.c index 68261d833fb..725490f6b82 100644 --- a/rostests/winetests/comctl32/trackbar.c +++ b/rostests/winetests/comctl32/trackbar.c @@ -17,7 +17,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include #include #include #include @@ -30,7 +29,7 @@ #define PARENT_SEQ_INDEX 0 #define TRACKBAR_SEQ_INDEX 1 -HWND hWndParent; +static HWND hWndParent; static struct msg_sequence *sequences[NUM_MSG_SEQUENCE]; @@ -527,6 +526,7 @@ static void test_line_size(HWND hWndTrackbar){ /* test TBM_SETLINESIZE */ r = SendMessage(hWndTrackbar, TBM_SETLINESIZE, 0, 10); + expect(1,r); r = SendMessage(hWndTrackbar, TBM_SETLINESIZE, 0, 4); expect(10, r); @@ -953,7 +953,7 @@ static void test_ignore_selection(HWND hWndTrackbar){ static void test_initial_state(void) { HWND hWnd; - DWORD ret; + int ret; hWnd = create_trackbar(0, hWndParent); diff --git a/rostests/winetests/comctl32/treeview.c b/rostests/winetests/comctl32/treeview.c index 320deba0e0e..51d4bc4b232 100644 --- a/rostests/winetests/comctl32/treeview.c +++ b/rostests/winetests/comctl32/treeview.c @@ -30,9 +30,21 @@ #include "commctrl.h" #include "wine/test.h" +#include "v6util.h" #include "msg.h" -const char *TEST_CALLBACK_TEXT = "callback_text"; +// Hack wine! Not in Sdk CommCtrl.h! +#define TVIS_FOCUSED 0x0001 +// + +static const char *TEST_CALLBACK_TEXT = "callback_text"; + +static TVITEMA g_item_expanding, g_item_expanded; +static BOOL g_get_from_expand; +static BOOL g_get_rect_in_expand; +static BOOL g_disp_A_to_W; +static BOOL g_disp_set_stateimage; +static BOOL g_beginedit_alter_text; #define NUM_MSG_SEQUENCES 2 #define TREEVIEW_SEQ_INDEX 0 @@ -41,6 +53,7 @@ const char *TEST_CALLBACK_TEXT = "callback_text"; #define expect(expected, got) ok(got == expected, "Expected %d, got %d\n", expected, got) static struct msg_sequence *sequences[NUM_MSG_SEQUENCES]; +static struct msg_sequence *item_sequence[1]; static const struct message FillRootSeq[] = { { TVM_INSERTITEM, sent }, @@ -69,8 +82,8 @@ static const struct message rootchild_select_seq[] = { }; static const struct message getitemtext_seq[] = { - { TVM_INSERTITEM, sent }, - { TVM_GETITEM, sent }, + { TVM_INSERTITEMA, sent }, + { TVM_GETITEMA, sent }, { TVM_DELETEITEM, sent }, { 0 } }; @@ -84,10 +97,14 @@ static const struct message focus_seq[] = { { WM_NCCALCSIZE, sent|wparam|defwinproc, TRUE }, { WM_WINDOWPOSCHANGED, sent|defwinproc }, { WM_SIZE, sent|defwinproc }, + { WM_WINDOWPOSCHANGING, sent|defwinproc|optional }, + { WM_NCCALCSIZE, sent|wparam|defwinproc|optional, TRUE }, + { WM_WINDOWPOSCHANGED, sent|defwinproc|optional }, + { WM_SIZE, sent|defwinproc|optional }, { WM_PAINT, sent|defwinproc }, { WM_NCPAINT, sent|wparam|defwinproc, 1 }, { WM_ERASEBKGND, sent|defwinproc }, - { TVM_EDITLABEL, sent }, + { TVM_EDITLABELA, sent }, { WM_COMMAND, sent|wparam|defwinproc, MAKEWPARAM(0, EN_UPDATE) }, { WM_COMMAND, sent|wparam|defwinproc, MAKEWPARAM(0, EN_CHANGE) }, { WM_PARENTNOTIFY, sent|wparam|defwinproc, MAKEWPARAM(WM_CREATE, 0) }, @@ -133,10 +150,10 @@ static const struct message test_get_set_insertmarkcolor_seq[] = { }; static const struct message test_get_set_item_seq[] = { - { TVM_GETITEM, sent }, - { TVM_SETITEM, sent }, - { TVM_GETITEM, sent }, - { TVM_SETITEM, sent }, + { TVM_GETITEMA, sent }, + { TVM_SETITEMA, sent }, + { TVM_GETITEMA, sent }, + { TVM_SETITEMA, sent }, { 0 } }; @@ -186,8 +203,22 @@ static const struct message test_get_set_unicodeformat_seq[] = { }; static const struct message parent_expand_seq[] = { - { WM_NOTIFY, sent|id, 0, 0, TVN_ITEMEXPANDING }, - { WM_NOTIFY, sent|id, 0, 0, TVN_ITEMEXPANDED }, + { WM_NOTIFY, sent|id, 0, 0, TVN_ITEMEXPANDINGA }, + { WM_NOTIFY, sent|id, 0, 0, TVN_ITEMEXPANDEDA }, + { 0 } +}; + +static const struct message parent_singleexpand_seq[] = { + { WM_NOTIFY, sent|id, 0, 0, TVN_SELCHANGINGA }, + { WM_NOTIFY, sent|id, 0, 0, TVN_SELCHANGEDA }, + { WM_NOTIFY, sent|id, 0, 0, TVN_SINGLEEXPAND }, + { WM_NOTIFY, sent|id, 0, 0, TVN_ITEMEXPANDINGA }, + { WM_NOTIFY, sent|id, 0, 0, TVN_ITEMEXPANDEDA }, + { 0 } +}; + +static const struct message parent_get_dispinfo_seq[] = { + { WM_NOTIFY, sent|id, 0, 0, TVN_GETDISPINFOA }, { 0 } }; @@ -253,13 +284,13 @@ static LRESULT WINAPI TreeviewWndProc(HWND hwnd, UINT message, WPARAM wParam, LP return ret; } -static HWND create_treeview_control(void) +static HWND create_treeview_control(DWORD style) { WNDPROC pOldWndProc; HWND hTree; hTree = CreateWindowExA(WS_EX_CLIENTEDGE, WC_TREEVIEWA, NULL, WS_CHILD|WS_VISIBLE| - TVS_LINESATROOT|TVS_HASLINES|TVS_HASBUTTONS|TVS_EDITLABELS, + TVS_LINESATROOT|TVS_HASLINES|TVS_HASBUTTONS|TVS_EDITLABELS|style, 0, 0, 120, 100, hMainWnd, (HMENU)100, GetModuleHandleA(0), 0); SetFocus(hTree); @@ -292,10 +323,10 @@ static void fill_tree(HWND hTree) static void test_fillroot(void) { - TVITEM tvi; + TVITEMA tvi; HWND hTree; - hTree = create_treeview_control(); + hTree = create_treeview_control(0); flush_sequences(sequences, NUM_MSG_SEQUENCES); @@ -313,7 +344,7 @@ static void test_fillroot(void) /* UMLPad 1.15 depends on this being not -1 (I_IMAGECALLBACK) */ tvi.hItem = hRoot; tvi.mask = TVIF_IMAGE | TVIF_SELECTEDIMAGE; - SendMessage( hTree, TVM_GETITEM, 0, (LPARAM)&tvi ); + SendMessage( hTree, TVM_GETITEMA, 0, (LPARAM)&tvi ); ok(tvi.iImage == 0, "tvi.iImage=%d\n", tvi.iImage); ok(tvi.iSelectedImage == 0, "tvi.iSelectedImage=%d\n", tvi.iSelectedImage); @@ -325,17 +356,17 @@ static void test_callback(void) HTREEITEM hRoot; HTREEITEM hItem1, hItem2; TVINSERTSTRUCTA ins; - TVITEM tvi; + TVITEMA tvi; CHAR test_string[] = "Test_string"; + static const CHAR test2A[] = "TEST2"; CHAR buf[128]; - LRESULT ret; HWND hTree; + DWORD ret; - hTree = create_treeview_control(); - fill_tree(hTree); + hTree = create_treeview_control(0); ret = TreeView_DeleteAllItems(hTree); - ok(ret == TRUE, "ret\n"); + expect(TRUE, ret); ins.hParent = TVI_ROOT; ins.hInsertAfter = TVI_ROOT; U(ins).item.mask = TVIF_TEXT; @@ -348,7 +379,7 @@ static void test_callback(void) tvi.pszText = buf; tvi.cchTextMax = sizeof(buf)/sizeof(buf[0]); ret = TreeView_GetItem(hTree, &tvi); - ok(ret == 1, "ret\n"); + expect(TRUE, ret); ok(strcmp(tvi.pszText, TEST_CALLBACK_TEXT) == 0, "Callback item text mismatch %s vs %s\n", tvi.pszText, TEST_CALLBACK_TEXT); @@ -361,17 +392,17 @@ static void test_callback(void) tvi.hItem = hItem1; ret = TreeView_GetItem(hTree, &tvi); - ok(ret == TRUE, "ret\n"); + expect(TRUE, ret); ok(strcmp(tvi.pszText, test_string) == 0, "Item text mismatch %s vs %s\n", tvi.pszText, test_string); /* undocumented: pszText of NULL also means LPSTR_CALLBACK: */ tvi.pszText = NULL; ret = TreeView_SetItem(hTree, &tvi); - ok(ret == 1, "Expected SetItem return 1, got %ld\n", ret); + expect(TRUE, ret); tvi.pszText = buf; ret = TreeView_GetItem(hTree, &tvi); - ok(ret == TRUE, "Expected GetItem return TRUE, got %ld\n", ret); + expect(TRUE, ret); ok(strcmp(tvi.pszText, TEST_CALLBACK_TEXT) == 0, "Item text mismatch %s vs %s\n", tvi.pszText, TEST_CALLBACK_TEXT); @@ -381,10 +412,77 @@ static void test_callback(void) tvi.hItem = hItem2; memset(buf, 0, sizeof(buf)); ret = TreeView_GetItem(hTree, &tvi); - ok(ret == TRUE, "Expected GetItem return TRUE, got %ld\n", ret); + expect(TRUE, ret); ok(strcmp(tvi.pszText, TEST_CALLBACK_TEXT) == 0, "Item text mismatch %s vs %s\n", tvi.pszText, TEST_CALLBACK_TEXT); + /* notification handler changed A->W */ + g_disp_A_to_W = TRUE; + tvi.hItem = hItem2; + memset(buf, 0, sizeof(buf)); + ret = TreeView_GetItem(hTree, &tvi); + expect(TRUE, ret); + ok(strcmp(tvi.pszText, test2A) == 0, "got %s, expected %s\n", + tvi.pszText, test2A); + g_disp_A_to_W = FALSE; + + /* handler changes state image index */ + SetWindowLongA(hTree, GWL_STYLE, GetWindowLongA(hTree, GWL_STYLE) | TVS_CHECKBOXES); + + /* clear selection, handler will set selected state */ + ret = SendMessageA(hTree, TVM_SELECTITEM, TVGN_CARET, 0); + expect(TRUE, ret); + + flush_sequences(sequences, NUM_MSG_SEQUENCES); + + tvi.hItem = hRoot; + tvi.mask = TVIF_STATE; + tvi.state = TVIS_SELECTED; + ret = TreeView_GetItem(hTree, &tvi); + expect(TRUE, ret); + ok(tvi.state == INDEXTOSTATEIMAGEMASK(1), "got 0x%x\n", tvi.state); + + ok_sequence(sequences, PARENT_SEQ_INDEX, empty_seq, + "no TVN_GETDISPINFO for a state seq", FALSE); + + tvi.hItem = hRoot; + tvi.mask = TVIF_IMAGE | TVIF_STATE; + tvi.state = TVIS_FOCUSED; + tvi.stateMask = TVIS_FOCUSED; + tvi.iImage = I_IMAGECALLBACK; + ret = TreeView_SetItem(hTree, &tvi); + expect(TRUE, ret); + + /* ask for item image index through callback - state is also set with state image index */ + flush_sequences(sequences, NUM_MSG_SEQUENCES); + + tvi.hItem = hRoot; + tvi.mask = TVIF_IMAGE; + tvi.state = 0; + ret = TreeView_GetItem(hTree, &tvi); + expect(TRUE, ret); + ok(tvi.state == (INDEXTOSTATEIMAGEMASK(1) | TVIS_FOCUSED), "got 0x%x\n", tvi.state); + + ok_sequence(sequences, PARENT_SEQ_INDEX, parent_get_dispinfo_seq, + "callback for state/overlay image index, noop seq", FALSE); + + /* ask for image again and overwrite state to some value in handler */ + flush_sequences(sequences, NUM_MSG_SEQUENCES); + + g_disp_set_stateimage = TRUE; + tvi.hItem = hRoot; + tvi.mask = TVIF_IMAGE; + tvi.state = INDEXTOSTATEIMAGEMASK(1); + tvi.stateMask = 0; + ret = TreeView_GetItem(hTree, &tvi); + expect(TRUE, ret); + /* handler sets TVIS_SELECTED as well */ + ok(tvi.state == (TVIS_FOCUSED | TVIS_SELECTED | INDEXTOSTATEIMAGEMASK(2) | INDEXTOOVERLAYMASK(3)), "got 0x%x\n", tvi.state); + g_disp_set_stateimage = FALSE; + + ok_sequence(sequences, PARENT_SEQ_INDEX, parent_get_dispinfo_seq, + "callback for state/overlay image index seq", FALSE); + DestroyWindow(hTree); } @@ -393,7 +491,7 @@ static void test_select(void) BOOL r; HWND hTree; - hTree = create_treeview_control(); + hTree = create_treeview_control(0); fill_tree(hTree); /* root-none select tests */ @@ -454,13 +552,13 @@ static void test_getitemtext(void) { TVINSERTSTRUCTA ins; HTREEITEM hChild; - TVITEM tvi; + TVITEMA tvi; HWND hTree; CHAR szBuffer[80] = "Blah"; int nBufferSize = sizeof(szBuffer)/sizeof(CHAR); - hTree = create_treeview_control(); + hTree = create_treeview_control(0); fill_tree(hTree); flush_sequences(sequences, NUM_MSG_SEQUENCES); @@ -480,7 +578,7 @@ static void test_getitemtext(void) tvi.cchTextMax = nBufferSize; tvi.pszText = szBuffer; - SendMessageA( hTree, TVM_GETITEM, 0, (LPARAM)&tvi ); + SendMessageA( hTree, TVM_GETITEMA, 0, (LPARAM)&tvi ); ok(!strcmp(szBuffer, ""), "szBuffer=\"%s\", expected \"\"\n", szBuffer); ok(SendMessageA(hTree, TVM_DELETEITEM, 0, (LPARAM)hChild), "DeleteItem failed\n"); ok_sequence(sequences, TREEVIEW_SEQ_INDEX, getitemtext_seq, "get item text seq", FALSE); @@ -497,7 +595,7 @@ static void test_focus(void) HWND hTree; HWND hEdit; - hTree = create_treeview_control(); + hTree = create_treeview_control(0); fill_tree(hTree); flush_sequences(sequences, NUM_MSG_SEQUENCES); @@ -534,14 +632,14 @@ static void test_get_set_bkcolor(void) COLORREF crColor = RGB(0,0,0); HWND hTree; - hTree = create_treeview_control(); + hTree = create_treeview_control(0); fill_tree(hTree); flush_sequences(sequences, NUM_MSG_SEQUENCES); /* If the value is -1, the control is using the system color for the background color. */ crColor = (COLORREF)SendMessage( hTree, TVM_GETBKCOLOR, 0, 0 ); - ok(crColor == -1, "Default background color reported as 0x%.8x\n", crColor); + ok(crColor == ~0u, "Default background color reported as 0x%.8x\n", crColor); /* Test for black background */ SendMessage( hTree, TVM_SETBKCOLOR, 0, RGB(0,0,0) ); @@ -564,18 +662,18 @@ static void test_get_set_bkcolor(void) static void test_get_set_imagelist(void) { - HIMAGELIST hImageList = NULL; + HIMAGELIST himl; HWND hTree; - hTree = create_treeview_control(); + hTree = create_treeview_control(0); fill_tree(hTree); flush_sequences(sequences, NUM_MSG_SEQUENCES); /* Test a NULL HIMAGELIST */ - SendMessage( hTree, TVM_SETIMAGELIST, TVSIL_NORMAL, (LPARAM)hImageList ); - hImageList = (HIMAGELIST)SendMessage( hTree, TVM_GETIMAGELIST, TVSIL_NORMAL, 0 ); - ok(hImageList == NULL, "NULL image list, reported as 0x%p, expected 0.\n", hImageList); + SendMessage( hTree, TVM_SETIMAGELIST, TVSIL_NORMAL, 0 ); + himl = (HIMAGELIST)SendMessage( hTree, TVM_GETIMAGELIST, TVSIL_NORMAL, 0 ); + ok(himl == NULL, "NULL image list, reported as %p, expected 0.\n", himl); /* TODO: Test an actual image list */ @@ -592,7 +690,7 @@ static void test_get_set_indent(void) int ulMoreThanTwiceMin = -1; HWND hTree; - hTree = create_treeview_control(); + hTree = create_treeview_control(0); fill_tree(hTree); flush_sequences(sequences, NUM_MSG_SEQUENCES); @@ -618,7 +716,7 @@ static void test_get_set_insertmark(void) COLORREF crColor = RGB(0,0,0); HWND hTree; - hTree = create_treeview_control(); + hTree = create_treeview_control(0); fill_tree(hTree); flush_sequences(sequences, NUM_MSG_SEQUENCES); @@ -635,35 +733,50 @@ static void test_get_set_insertmark(void) static void test_get_set_item(void) { - TVITEM tviRoot = {0}; + TVITEMA tviRoot = {0}; int nBufferSize = 80; char szBuffer[80] = {0}; + DWORD ret; HWND hTree; - hTree = create_treeview_control(); + hTree = create_treeview_control(0); fill_tree(hTree); + tviRoot.hItem = hRoot; + tviRoot.mask = TVIF_STATE; + tviRoot.state = TVIS_FOCUSED; + tviRoot.stateMask = TVIS_FOCUSED; + ret = SendMessage( hTree, TVM_SETITEMA, 0, (LPARAM)&tviRoot ); + expect(TRUE, ret); + flush_sequences(sequences, NUM_MSG_SEQUENCES); - /* Test the root item */ + /* Test the root item, state is set even when not requested */ tviRoot.hItem = hRoot; tviRoot.mask = TVIF_TEXT; + tviRoot.state = 0; + tviRoot.stateMask = 0; tviRoot.cchTextMax = nBufferSize; tviRoot.pszText = szBuffer; - SendMessage( hTree, TVM_GETITEM, 0, (LPARAM)&tviRoot ); + ret = SendMessage( hTree, TVM_GETITEMA, 0, (LPARAM)&tviRoot ); + expect(TRUE, ret); ok(!strcmp("Root", szBuffer), "GetItem: szBuffer=\"%s\", expected \"Root\"\n", szBuffer); + ok(tviRoot.state == TVIS_FOCUSED, "got 0x%0x\n", tviRoot.state); /* Change the root text */ strncpy(szBuffer, "Testing123", nBufferSize); - SendMessage( hTree, TVM_SETITEM, 0, (LPARAM)&tviRoot ); + ret = SendMessage( hTree, TVM_SETITEMA, 0, (LPARAM)&tviRoot ); + expect(TRUE, ret); memset(szBuffer, 0, nBufferSize); - SendMessage( hTree, TVM_GETITEM, 0, (LPARAM)&tviRoot ); + ret = SendMessage( hTree, TVM_GETITEMA, 0, (LPARAM)&tviRoot ); + expect(TRUE, ret); ok(!strcmp("Testing123", szBuffer), "GetItem: szBuffer=\"%s\", expected \"Testing123\"\n", szBuffer); /* Reset the root text */ memset(szBuffer, 0, nBufferSize); strncpy(szBuffer, "Root", nBufferSize); - SendMessage( hTree, TVM_SETITEM, 0, (LPARAM)&tviRoot ); + ret = SendMessage( hTree, TVM_SETITEMA, 0, (LPARAM)&tviRoot ); + expect(TRUE, ret); ok_sequence(sequences, TREEVIEW_SEQ_INDEX, test_get_set_item_seq, "test get set item", FALSE); @@ -677,7 +790,7 @@ static void test_get_set_itemheight(void) int ulNewHeight = 0; HWND hTree; - hTree = create_treeview_control(); + hTree = create_treeview_control(0); fill_tree(hTree); flush_sequences(sequences, NUM_MSG_SEQUENCES); @@ -703,6 +816,32 @@ static void test_get_set_itemheight(void) ok_sequence(sequences, TREEVIEW_SEQ_INDEX, test_get_set_itemheight_seq, "test get set item height", FALSE); + /* without TVS_NONEVENHEIGHT */ + SetWindowLong(hTree, GWL_STYLE, GetWindowLong(hTree, GWL_STYLE) & ~TVS_NONEVENHEIGHT); + /* odd value */ + ulOldHeight = SendMessage( hTree, TVM_SETITEMHEIGHT, 3, 0); + ok(ulOldHeight == 8, "got %d, expected %d\n", ulOldHeight, 8); + ulNewHeight = (int) SendMessage( hTree, TVM_GETITEMHEIGHT, 0, 0 ); + ok(ulNewHeight == 2, "got %d, expected %d\n", ulNewHeight, 2); + + ulOldHeight = SendMessage( hTree, TVM_SETITEMHEIGHT, 4, 0); + ok(ulOldHeight == 2, "got %d, expected %d\n", ulOldHeight, 2); + ulNewHeight = (int) SendMessage( hTree, TVM_GETITEMHEIGHT, 0, 0 ); + ok(ulNewHeight == 4, "got %d, expected %d\n", ulNewHeight, 4); + + /* with TVS_NONEVENHEIGHT */ + SetWindowLong(hTree, GWL_STYLE, GetWindowLong(hTree, GWL_STYLE) | TVS_NONEVENHEIGHT); + /* odd value */ + ulOldHeight = SendMessage( hTree, TVM_SETITEMHEIGHT, 3, 0); + ok(ulOldHeight == 4, "got %d, expected %d\n", ulOldHeight, 4); + ulNewHeight = (int) SendMessage( hTree, TVM_GETITEMHEIGHT, 0, 0 ); + ok(ulNewHeight == 3, "got %d, expected %d\n", ulNewHeight, 3); + /* even value */ + ulOldHeight = SendMessage( hTree, TVM_SETITEMHEIGHT, 10, 0); + ok(ulOldHeight == 3, "got %d, expected %d\n", ulOldHeight, 3); + ulNewHeight = (int) SendMessage( hTree, TVM_GETITEMHEIGHT, 0, 0 ); + ok(ulNewHeight == 10, "got %d, expected %d\n", ulNewHeight, 10); + DestroyWindow(hTree); } @@ -712,7 +851,7 @@ static void test_get_set_scrolltime(void) int ulTime = 0; HWND hTree; - hTree = create_treeview_control(); + hTree = create_treeview_control(0); fill_tree(hTree); flush_sequences(sequences, NUM_MSG_SEQUENCES); @@ -733,13 +872,13 @@ static void test_get_set_textcolor(void) COLORREF crColor = RGB(0,0,0); HWND hTree; - hTree = create_treeview_control(); + hTree = create_treeview_control(0); fill_tree(hTree); flush_sequences(sequences, NUM_MSG_SEQUENCES); crColor = (COLORREF)SendMessage( hTree, TVM_GETTEXTCOLOR, 0, 0 ); - ok(crColor == -1, "Default text color reported as 0x%.8x\n", crColor); + ok(crColor == ~0u, "Default text color reported as 0x%.8x\n", crColor); /* Test for black text */ SendMessage( hTree, TVM_SETTEXTCOLOR, 0, RGB(0,0,0) ); @@ -766,7 +905,7 @@ static void test_get_set_tooltips(void) HWND hPopupTreeView; HWND hTree; - hTree = create_treeview_control(); + hTree = create_treeview_control(0); fill_tree(hTree); flush_sequences(sequences, NUM_MSG_SEQUENCES); @@ -793,7 +932,7 @@ static void test_get_set_unicodeformat(void) BOOL bNewSetting = 0; HWND hTree; - hTree = create_treeview_control(); + hTree = create_treeview_control(0); fill_tree(hTree); flush_sequences(sequences, NUM_MSG_SEQUENCES); @@ -817,10 +956,6 @@ static void test_get_set_unicodeformat(void) DestroyWindow(hTree); } -static TVITEMA g_item_expanding, g_item_expanded; -static BOOL g_get_from_expand; -static BOOL g_get_rect_in_expand; - static LRESULT CALLBACK parent_wnd_proc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { static LONG defwndproc_counter = 0; @@ -876,10 +1011,42 @@ static LRESULT CALLBACK parent_wnd_proc(HWND hWnd, UINT message, WPARAM wParam, if (disp->item.mask & TVIF_TEXT) { lstrcpyn(disp->item.pszText, TEST_CALLBACK_TEXT, disp->item.cchTextMax); } + + if (g_disp_A_to_W && (disp->item.mask & TVIF_TEXT)) { + static const WCHAR testW[] = {'T','E','S','T','2',0}; + + disp->hdr.code = TVN_GETDISPINFOW; + memcpy(disp->item.pszText, testW, sizeof(testW)); + } + + if (g_disp_set_stateimage) + { + ok(disp->item.mask == TVIF_IMAGE, "got %x\n", disp->item.mask); + /* both masks set here are necessary to change state bits */ + disp->item.mask |= TVIF_STATE; + disp->item.state = TVIS_SELECTED | INDEXTOSTATEIMAGEMASK(2) | INDEXTOOVERLAYMASK(3); + disp->item.stateMask = TVIS_SELECTED | TVIS_OVERLAYMASK | TVIS_STATEIMAGEMASK; + } + break; } + case TVN_BEGINLABELEDIT: + { + if (g_beginedit_alter_text) + { + static const char* textA = ""; + HWND edit; + + edit = (HWND)SendMessageA(pHdr->hwndFrom, TVM_GETEDITCONTROL, 0, 0); + ok(IsWindow(edit), "failed to get edit handle\n"); + SetWindowTextA(edit, textA); + } + + break; + } + case TVN_ENDLABELEDIT: return TRUE; - case TVN_ITEMEXPANDING: + case TVN_ITEMEXPANDINGA: ok(pTreeView->itemNew.mask == (TVIF_HANDLE | TVIF_SELECTEDIMAGE | TVIF_IMAGE | TVIF_PARAM | TVIF_STATE), "got wrong mask %x\n", pTreeView->itemNew.mask); @@ -896,7 +1063,7 @@ static LRESULT CALLBACK parent_wnd_proc(HWND hWnd, UINT message, WPARAM wParam, ok(ret == TRUE, "got %lu\n", ret); } break; - case TVN_ITEMEXPANDED: + case TVN_ITEMEXPANDEDA: ok(pTreeView->itemNew.mask & TVIF_STATE, "got wrong mask %x\n", pTreeView->itemNew.mask); ok(pTreeView->itemNew.state & (TVIS_EXPANDED|TVIS_EXPANDEDONCE), "got wrong mask %x\n", pTreeView->itemNew.mask); @@ -910,7 +1077,8 @@ static LRESULT CALLBACK parent_wnd_proc(HWND hWnd, UINT message, WPARAM wParam, ret = SendMessageA(pHdr->hwndFrom, TVM_GETITEMA, 0, (LPARAM)&g_item_expanded); ok(ret == TRUE, "got %lu\n", ret); } - if (g_get_rect_in_expand) { + if (g_get_rect_in_expand) + { visibleItem = TreeView_GetNextItem(pHdr->hwndFrom, NULL, TVGN_FIRSTVISIBLE); ok(pTreeView->itemNew.hItem == visibleItem, "expanded item == first visible item\n"); *(HTREEITEM*)&rect = visibleItem; @@ -918,12 +1086,27 @@ static LRESULT CALLBACK parent_wnd_proc(HWND hWnd, UINT message, WPARAM wParam, visibleItem = TreeView_GetNextItem(pHdr->hwndFrom, visibleItem, TVGN_NEXTVISIBLE); *(HTREEITEM*)&rect = visibleItem; ok(visibleItem != NULL, "There must be a visible item after the first visisble item.\n"); - todo_wine ok(SendMessage(pHdr->hwndFrom, TVM_GETITEMRECT, TRUE, (LPARAM)&rect), "Failed to get rect for second visible item.\n"); } break; + case TVN_DELETEITEMA: + { + struct message item; + + ok(pTreeView->itemNew.mask == 0, "got wrong mask 0x%x\n", pTreeView->itemNew.mask); + + ok(pTreeView->itemOld.mask == (TVIF_HANDLE | TVIF_PARAM), "got wrong mask 0x%x\n", pTreeView->itemOld.mask); + ok(pTreeView->itemOld.hItem != NULL, "got %p\n", pTreeView->itemOld.hItem); + + memset(&item, 0, sizeof(item)); + item.lParam = (LPARAM)pTreeView->itemOld.hItem; + add_message(item_sequence, 0, &item); + + break; + } } } + break; } case WM_DESTROY: @@ -948,9 +1131,9 @@ static void test_expandinvisible(void) LRESULT ret; HWND hTree; - hTree = create_treeview_control(); + hTree = create_treeview_control(0); - /* The test builds the following tree and expands then node 1, while node 0 is collapsed. + /* The test builds the following tree and expands node 1, while node 0 is collapsed. * * 0 * |- 1 @@ -1018,18 +1201,18 @@ static void test_itemedit(void) DWORD r; HWND edit; TVITEMA item; - CHAR buff[2]; + CHAR buffA[20]; HWND hTree; - hTree = create_treeview_control(); + hTree = create_treeview_control(0); fill_tree(hTree); /* try with null item */ - edit = (HWND)SendMessage(hTree, TVM_EDITLABEL, 0, 0); + edit = (HWND)SendMessage(hTree, TVM_EDITLABELA, 0, 0); ok(!IsWindow(edit), "Expected valid handle\n"); /* trigger edit */ - edit = (HWND)SendMessage(hTree, TVM_EDITLABEL, 0, (LPARAM)hRoot); + edit = (HWND)SendMessage(hTree, TVM_EDITLABELA, 0, (LPARAM)hRoot); ok(IsWindow(edit), "Expected valid handle\n"); /* item shouldn't be selected automatically after TVM_EDITLABEL */ r = SendMessage(hTree, TVM_GETITEMSTATE, (WPARAM)hRoot, TVIS_SELECTED); @@ -1046,7 +1229,7 @@ static void test_itemedit(void) expect(0, r); /* try to cancel with wrong (not null) handle */ - edit = (HWND)SendMessage(hTree, TVM_EDITLABEL, 0, (LPARAM)hRoot); + edit = (HWND)SendMessage(hTree, TVM_EDITLABELA, 0, (LPARAM)hRoot); ok(IsWindow(edit), "Expected valid handle\n"); r = SendMessage(hTree, WM_COMMAND, MAKEWPARAM(0, EN_KILLFOCUS), (LPARAM)hTree); expect(0, r); @@ -1057,13 +1240,13 @@ static void test_itemedit(void) /* remove selection after starting edit */ r = TreeView_SelectItem(hTree, hRoot); expect(TRUE, r); - edit = (HWND)SendMessage(hTree, TVM_EDITLABEL, 0, (LPARAM)hRoot); + edit = (HWND)SendMessage(hTree, TVM_EDITLABELA, 0, (LPARAM)hRoot); ok(IsWindow(edit), "Expected valid handle\n"); r = TreeView_SelectItem(hTree, NULL); expect(TRUE, r); /* alter text */ - strncpy(buff, "x", sizeof(buff)/sizeof(CHAR)); - r = SendMessage(edit, WM_SETTEXT, 0, (LPARAM)buff); + strcpy(buffA, "x"); + r = SendMessage(edit, WM_SETTEXT, 0, (LPARAM)buffA); expect(TRUE, r); r = SendMessage(hTree, WM_COMMAND, MAKEWPARAM(0, EN_KILLFOCUS), (LPARAM)edit); expect(0, r); @@ -1071,11 +1254,43 @@ static void test_itemedit(void) /* check that text is saved */ item.mask = TVIF_TEXT; item.hItem = hRoot; - item.pszText = buff; - item.cchTextMax = sizeof(buff)/sizeof(CHAR); - r = SendMessage(hTree, TVM_GETITEM, 0, (LPARAM)&item); + item.pszText = buffA; + item.cchTextMax = sizeof(buffA)/sizeof(CHAR); + r = SendMessage(hTree, TVM_GETITEMA, 0, (LPARAM)&item); expect(TRUE, r); - ok(!strcmp("x", buff), "Expected item text to change\n"); + ok(!strcmp("x", buffA), "Expected item text to change\n"); + + /* try A/W messages */ + edit = (HWND)SendMessageA(hTree, TVM_EDITLABELA, 0, (LPARAM)hRoot); + ok(IsWindow(edit), "Expected valid handle\n"); + ok(IsWindowUnicode(edit), "got ansi window\n"); + r = SendMessage(hTree, WM_COMMAND, MAKEWPARAM(0, EN_KILLFOCUS), (LPARAM)edit); + expect(0, r); + ok(!IsWindow(edit), "expected invalid handle\n"); + + edit = (HWND)SendMessageA(hTree, TVM_EDITLABELW, 0, (LPARAM)hRoot); + ok(IsWindow(edit), "Expected valid handle\n"); + ok(IsWindowUnicode(edit), "got ansi window\n"); + r = SendMessage(hTree, WM_COMMAND, MAKEWPARAM(0, EN_KILLFOCUS), (LPARAM)edit); + expect(0, r); + + /* alter text during TVM_BEGINLABELEDIT, check that it's preserved */ + strcpy(buffA, ""); + + item.mask = TVIF_TEXT; + item.hItem = hRoot; + item.pszText = buffA; + item.cchTextMax = 0; + r = SendMessage(hTree, TVM_SETITEMA, 0, (LPARAM)&item); + expect(TRUE, r); + + g_beginedit_alter_text = TRUE; + edit = (HWND)SendMessageA(hTree, TVM_EDITLABELA, 0, (LPARAM)hRoot); + ok(IsWindow(edit), "Expected valid handle\n"); + g_beginedit_alter_text = FALSE; + + GetWindowTextA(edit, buffA, sizeof(buffA)/sizeof(CHAR)); + ok(!strcmp(buffA, ""), "got string %s\n", buffA); DestroyWindow(hTree); } @@ -1096,7 +1311,7 @@ static void test_get_linecolor(void) COLORREF clr; HWND hTree; - hTree = create_treeview_control(); + hTree = create_treeview_control(0); /* newly created control has default color */ clr = (COLORREF)SendMessage(hTree, TVM_GETLINECOLOR, 0, 0); @@ -1113,7 +1328,7 @@ static void test_get_insertmarkcolor(void) COLORREF clr; HWND hTree; - hTree = create_treeview_control(); + hTree = create_treeview_control(0); /* newly created control has default color */ clr = (COLORREF)SendMessage(hTree, TVM_GETINSERTMARKCOLOR, 0, 0); @@ -1131,7 +1346,7 @@ static void test_expandnotify(void) BOOL ret; TVITEMA item; - hTree = create_treeview_control(); + hTree = create_treeview_control(0); fill_tree(hTree); item.hItem = hRoot; @@ -1139,12 +1354,12 @@ static void test_expandnotify(void) item.state = TVIS_EXPANDED; ret = SendMessageA(hTree, TVM_GETITEMA, 0, (LPARAM)&item); - ok(ret == TRUE, "got %d\n", ret); + expect(TRUE, ret); ok((item.state & TVIS_EXPANDED) == 0, "expected collapsed\n"); /* preselect root node here */ ret = SendMessageA(hTree, TVM_SELECTITEM, TVGN_CARET, (LPARAM)hRoot); - ok(ret == TRUE, "got %d\n", ret); + expect(TRUE, ret); g_get_from_expand = TRUE; /* expand */ @@ -1152,7 +1367,7 @@ static void test_expandnotify(void) g_item_expanding.state = 0xdeadbeef; g_item_expanded.state = 0xdeadbeef; ret = SendMessageA(hTree, TVM_EXPAND, TVE_EXPAND, (LPARAM)hRoot); - ok(ret == TRUE, "got %d\n", ret); + expect(TRUE, ret); ok(g_item_expanding.state == TVIS_SELECTED, "got state on TVN_ITEMEXPANDING 0x%08x\n", g_item_expanding.state); ok(g_item_expanded.state == (TVIS_SELECTED|TVIS_EXPANDED), "got state on TVN_ITEMEXPANDED 0x%08x\n", @@ -1163,33 +1378,356 @@ static void test_expandnotify(void) /* check that it's expanded */ item.state = TVIS_EXPANDED; ret = SendMessageA(hTree, TVM_GETITEMA, 0, (LPARAM)&item); - ok(ret == TRUE, "got %d\n", ret); + expect(TRUE, ret); ok((item.state & TVIS_EXPANDED) == TVIS_EXPANDED, "expected expanded\n"); /* collapse */ flush_sequences(sequences, NUM_MSG_SEQUENCES); ret = SendMessageA(hTree, TVM_EXPAND, TVE_COLLAPSE, (LPARAM)hRoot); - ok(ret == TRUE, "got %d\n", ret); + expect(TRUE, ret); item.state = TVIS_EXPANDED; ret = SendMessageA(hTree, TVM_GETITEMA, 0, (LPARAM)&item); - ok(ret == TRUE, "got %d\n", ret); + expect(TRUE, ret); ok((item.state & TVIS_EXPANDED) == 0, "expected collapsed\n"); - /* all next collapse/expand attempts won't produce any notifications, + /* all further collapse/expand attempts won't produce any notifications, the only way is to reset with all children removed */ ok_sequence(sequences, PARENT_SEQ_INDEX, empty_seq, "collapse after expand notifications", FALSE); + /* try to toggle child that doesn't have children itself */ + flush_sequences(sequences, NUM_MSG_SEQUENCES); + ret = SendMessageA(hTree, TVM_EXPAND, TVE_TOGGLE, (LPARAM)hChild); + expect(FALSE, ret); + ok_sequence(sequences, PARENT_SEQ_INDEX, empty_seq, "toggle node without children", FALSE); + + DestroyWindow(hTree); + + /* test TVM_GETITEMRECT inside TVN_ITEMEXPANDED notification */ + hTree = create_treeview_control(0); + fill_tree(hTree); + g_get_rect_in_expand = TRUE; + ret = TreeView_Select(hTree, hChild, TVGN_CARET); + expect(TRUE, ret); + g_get_rect_in_expand = FALSE; + + DestroyWindow(hTree); + + /* TVE_TOGGLE acts as any other TVM_EXPAND */ + hTree = create_treeview_control(0); + fill_tree(hTree); + + flush_sequences(sequences, NUM_MSG_SEQUENCES); + ret = SendMessageA(hTree, TVM_EXPAND, TVE_TOGGLE, (LPARAM)hRoot); + expect(TRUE, ret); + ok_sequence(sequences, PARENT_SEQ_INDEX, parent_expand_seq, "toggle node (expand)", FALSE); + + /* toggle again - no notifications */ + flush_sequences(sequences, NUM_MSG_SEQUENCES); + ret = SendMessageA(hTree, TVM_EXPAND, TVE_TOGGLE, (LPARAM)hRoot); + expect(TRUE, ret); + ok_sequence(sequences, PARENT_SEQ_INDEX, empty_seq, "toggle node (collapse)", FALSE); + DestroyWindow(hTree); } -static void test_rect_retrieval_after_expand_with_select(void) { - BOOL ret; - HWND hTree; - hTree = create_treeview_control(); - fill_tree(hTree); - g_get_rect_in_expand = TRUE; - ret = TreeView_Select(hTree, hChild, TVGN_CARET); - g_get_rect_in_expand = FALSE; - ok(ret,"TreeView_Select should return true\n"); +static void test_expandedimage(void) +{ + TVITEMEXA item; + HWND hTree; + BOOL ret; + + hTree = create_treeview_control(0); + fill_tree(hTree); + + item.mask = TVIF_EXPANDEDIMAGE; + item.iExpandedImage = 1; + item.hItem = hRoot; + ret = SendMessageA(hTree, TVM_SETITEMA, 0, (LPARAM)&item); + ok(ret, "got %d\n", ret); + + item.mask = TVIF_EXPANDEDIMAGE; + item.iExpandedImage = -1; + item.hItem = hRoot; + ret = SendMessageA(hTree, TVM_GETITEMA, 0, (LPARAM)&item); + ok(ret, "got %d\n", ret); + + if (item.iExpandedImage != 1) + { + win_skip("TVIF_EXPANDEDIMAGE not supported\n"); + DestroyWindow(hTree); + return; + } + + /* test for default iExpandedImage value */ + item.mask = TVIF_EXPANDEDIMAGE; + item.iExpandedImage = -1; + item.hItem = hChild; + ret = SendMessageA(hTree, TVM_GETITEMA, 0, (LPARAM)&item); + ok(ret, "got %d\n", ret); + ok(item.iExpandedImage == (WORD)I_IMAGENONE, "got %d\n", item.iExpandedImage); + + DestroyWindow(hTree); +} + +static void test_TVS_SINGLEEXPAND(void) +{ + HWND hTree; + BOOL ret; + + hTree = create_treeview_control(0); + SetWindowLongA(hTree, GWL_STYLE, GetWindowLong(hTree, GWL_STYLE) | TVS_SINGLEEXPAND); + /* to avoid painting related notifications */ + ShowWindow(hTree, SW_HIDE); + fill_tree(hTree); + + flush_sequences(sequences, NUM_MSG_SEQUENCES); + ret = SendMessageA(hTree, TVM_SELECTITEM, TVGN_CARET, (LPARAM)hRoot); + ok(ret, "got %d\n", ret); + ok_sequence(sequences, PARENT_SEQ_INDEX, parent_singleexpand_seq, "singleexpand notifications", FALSE); + + /* a workaround for NT4 that sends expand notifications when nothing is about to expand */ + ret = SendMessageA(hTree, TVM_DELETEITEM, 0, (LPARAM)hRoot); + ok(ret, "got %d\n", ret); + fill_tree(hTree); + ret = SendMessageA(hTree, TVM_SELECTITEM, TVGN_CARET, 0); + ok(ret, "got %d\n", ret); + + DestroyWindow(hTree); +} + +static void test_WM_PAINT(void) +{ + HWND hTree; + COLORREF clr; + LONG ret; + RECT rc; + HDC hdc; + + hTree = create_treeview_control(0); + + clr = SendMessageA(hTree, TVM_SETBKCOLOR, 0, RGB(255, 0, 0)); + ok(clr == ~0u, "got %d, expected -1\n", clr); + + hdc = GetDC(hMainWnd); + + GetClientRect(hMainWnd, &rc); + FillRect(hdc, &rc, GetStockObject(BLACK_BRUSH)); + + clr = GetPixel(hdc, 1, 1); + ok(clr == RGB(0, 0, 0), "got 0x%x\n", clr); + + ret = SendMessageA(hTree, WM_PAINT, (WPARAM)hdc, 0); + ok(ret == 0, "got %d\n", ret); + + clr = GetPixel(hdc, 1, 1); + ok(clr == RGB(255, 0, 0) || broken(clr == RGB(0, 0, 0)) /* win98 */, + "got 0x%x\n", clr); + + ReleaseDC(hMainWnd, hdc); + + DestroyWindow(hTree); +} + +static void test_delete_items(void) +{ + const struct message *msg; + HWND hTree; + INT ret; + + hTree = create_treeview_control(0); + fill_tree(hTree); + + /* check delete order */ + flush_sequences(item_sequence, 1); + ret = SendMessage(hTree, TVM_DELETEITEM, 0, 0); + ok(ret == TRUE, "got %d\n", ret); + + msg = item_sequence[0]->sequence; + ok(item_sequence[0]->count == 2, "expected 2 items, got %d\n", item_sequence[0]->count); + + if (item_sequence[0]->count == 2) + { + ok(msg[0].lParam == (LPARAM)hChild, "expected %p, got 0x%lx\n", hChild, msg[0].lParam); + ok(msg[1].lParam == (LPARAM)hRoot, "expected %p, got 0x%lx\n", hRoot, msg[1].lParam); + } + + ret = SendMessageA(hTree, TVM_GETCOUNT, 0, 0); + ok(ret == 0, "got %d\n", ret); + + DestroyWindow(hTree); +} + +struct _ITEM_DATA +{ + HTREEITEM parent; /* for root value of parent field is unidetified */ + HTREEITEM nextsibling; + HTREEITEM firstchild; +}; + +static void _check_item(HTREEITEM item, HTREEITEM parent, HTREEITEM nextsibling, HTREEITEM firstchild, int line) +{ + struct _ITEM_DATA *data = (struct _ITEM_DATA*)item; + + ok_(__FILE__, line)(data->parent == parent, "parent %p, got %p\n", parent, data->parent); + ok_(__FILE__, line)(data->nextsibling == nextsibling, "sibling %p, got %p\n", nextsibling, data->nextsibling); + ok_(__FILE__, line)(data->firstchild == firstchild, "firstchild %p, got %p\n", firstchild, data->firstchild); +} + +#define check_item(a, b, c, d) _check_item(a, b, c, d, __LINE__) + +static void test_htreeitem_layout(void) +{ + TVINSERTSTRUCTA ins; + HTREEITEM item1, item2; + HWND hTree; + + hTree = create_treeview_control(0); + fill_tree(hTree); + + /* root has some special pointer in parent field */ + check_item(hRoot, ((struct _ITEM_DATA*)hRoot)->parent, 0, hChild); + check_item(hChild, hRoot, 0, 0); + + ins.hParent = hChild; + ins.hInsertAfter = TVI_FIRST; + U(ins).item.mask = 0; + item1 = TreeView_InsertItem(hTree, &ins); + + check_item(item1, hChild, 0, 0); + + ins.hParent = hRoot; + ins.hInsertAfter = TVI_FIRST; + U(ins).item.mask = 0; + item2 = TreeView_InsertItem(hTree, &ins); + + check_item(item2, hRoot, hChild, 0); + + SendMessage(hTree, TVM_DELETEITEM, 0, (LPARAM)hChild); + + /* without children now */ + check_item(hRoot, ((struct _ITEM_DATA*)hRoot)->parent, 0, item2); + + DestroyWindow(hTree); +} + +static void test_TVS_CHECKBOXES(void) +{ + HIMAGELIST himl; + TVITEMA item; + HWND hTree; + DWORD ret; + + hTree = create_treeview_control(0); + fill_tree(hTree); + + himl = (HIMAGELIST)SendMessageA(hTree, TVM_GETIMAGELIST, TVSIL_STATE, 0); + ok(himl == NULL, "got %p\n", himl); + + item.hItem = hRoot; + item.mask = TVIF_STATE; + item.state = INDEXTOSTATEIMAGEMASK(1); + item.stateMask = TVIS_STATEIMAGEMASK; + ret = SendMessageA(hTree, TVM_GETITEMA, 0, (LPARAM)&item); + expect(TRUE, ret); + ok(item.state == 0, "got 0x%x\n", item.state); + + /* set some index for a child */ + item.hItem = hChild; + item.mask = TVIF_STATE; + item.state = INDEXTOSTATEIMAGEMASK(4); + item.stateMask = TVIS_STATEIMAGEMASK; + ret = SendMessageA(hTree, TVM_SETITEMA, 0, (LPARAM)&item); + expect(TRUE, ret); + + /* enabling check boxes set all items to 1 state image index */ + SetWindowLongA(hTree, GWL_STYLE, GetWindowLongA(hTree, GWL_STYLE) | TVS_CHECKBOXES); + himl = (HIMAGELIST)SendMessageA(hTree, TVM_GETIMAGELIST, TVSIL_STATE, 0); + ok(himl != NULL, "got %p\n", himl); + + item.hItem = hRoot; + item.mask = TVIF_STATE; + item.state = 0; + item.stateMask = TVIS_STATEIMAGEMASK; + ret = SendMessageA(hTree, TVM_GETITEMA, 0, (LPARAM)&item); + expect(TRUE, ret); + ok(item.state == INDEXTOSTATEIMAGEMASK(1), "got 0x%x\n", item.state); + + item.hItem = hChild; + item.mask = TVIF_STATE; + item.state = 0; + item.stateMask = TVIS_STATEIMAGEMASK; + ret = SendMessageA(hTree, TVM_GETITEMA, 0, (LPARAM)&item); + expect(TRUE, ret); + ok(item.state == INDEXTOSTATEIMAGEMASK(1), "got 0x%x\n", item.state); + + DestroyWindow(hTree); + + /* the same, but initially created with TVS_CHECKBOXES */ + hTree = create_treeview_control(0); + fill_tree(hTree); + himl = (HIMAGELIST)SendMessageA(hTree, TVM_GETIMAGELIST, TVSIL_STATE, 0); + ok(himl == NULL, "got %p\n", himl); + DestroyWindow(hTree); + + hTree = create_treeview_control(TVS_CHECKBOXES); + fill_tree(hTree); + himl = (HIMAGELIST)SendMessageA(hTree, TVM_GETIMAGELIST, TVSIL_STATE, 0); + todo_wine ok(himl == NULL, "got %p\n", himl); + + item.hItem = hRoot; + item.mask = TVIF_STATE; + item.state = 0; + item.stateMask = TVIS_STATEIMAGEMASK; + ret = SendMessageA(hTree, TVM_GETITEMA, 0, (LPARAM)&item); + expect(TRUE, ret); + ok(item.state == INDEXTOSTATEIMAGEMASK(1), "got 0x%x\n", item.state); + + item.hItem = hChild; + item.mask = TVIF_STATE; + item.state = 0; + item.stateMask = TVIS_STATEIMAGEMASK; + ret = SendMessageA(hTree, TVM_GETITEMA, 0, (LPARAM)&item); + expect(TRUE, ret); + ok(item.state == INDEXTOSTATEIMAGEMASK(1), "got 0x%x\n", item.state); + + DestroyWindow(hTree); +} + +static void test_TVM_GETNEXTITEM(void) +{ + HTREEITEM item; + HWND hTree; + + hTree = create_treeview_control(0); + fill_tree(hTree); + + item = (HTREEITEM)SendMessageA(hTree, TVM_GETNEXTITEM, TVGN_ROOT, 0); + ok(item == hRoot, "got %p, expected %p\n", item, hRoot); + + item = (HTREEITEM)SendMessageA(hTree, TVM_GETNEXTITEM, TVGN_ROOT, (LPARAM)TVI_ROOT); + ok(item == hRoot, "got %p, expected %p\n", item, hRoot); + + item = (HTREEITEM)SendMessageA(hTree, TVM_GETNEXTITEM, TVGN_ROOT, (LPARAM)hRoot); + ok(item == hRoot, "got %p, expected %p\n", item, hRoot); + + item = (HTREEITEM)SendMessageA(hTree, TVM_GETNEXTITEM, TVGN_ROOT, (LPARAM)hChild); + ok(item == hRoot, "got %p, expected %p\n", item, hRoot); + + item = (HTREEITEM)SendMessageA(hTree, TVM_GETNEXTITEM, TVGN_CHILD, 0); + ok(item == hRoot, "got %p, expected %p\n", item, hRoot); + + item = (HTREEITEM)SendMessageA(hTree, TVM_GETNEXTITEM, TVGN_CHILD, (LPARAM)hRoot); + ok(item == hChild, "got %p, expected %p\n", item, hChild); + + item = (HTREEITEM)SendMessageA(hTree, TVM_GETNEXTITEM, TVGN_CHILD, (LPARAM)TVI_ROOT); + ok(item == hRoot, "got %p, expected %p\n", item, hRoot); + + item = (HTREEITEM)SendMessageA(hTree, TVM_GETNEXTITEM, TVGN_PARENT, 0); + ok(item == NULL, "got %p\n", item); + + item = (HTREEITEM)SendMessageA(hTree, TVM_GETNEXTITEM, TVGN_PARENT, (LPARAM)hChild); + ok(item == hRoot, "got %p, expected %p\n", item, hRoot); + + DestroyWindow(hTree); } START_TEST(treeview) @@ -1198,6 +1736,10 @@ START_TEST(treeview) BOOL (WINAPI *pInitCommonControlsEx)(const INITCOMMONCONTROLSEX*); WNDCLASSA wc; MSG msg; + + ULONG_PTR ctx_cookie; + HANDLE hCtx; + HWND hwnd; hComctl32 = GetModuleHandleA("comctl32.dll"); pInitCommonControlsEx = (void*)GetProcAddress(hComctl32, "InitCommonControlsEx"); @@ -1212,6 +1754,7 @@ START_TEST(treeview) InitCommonControls(); init_msg_sequences(sequences, NUM_MSG_SEQUENCES); + init_msg_sequences(item_sequence, 1); wc.style = CS_HREDRAW | CS_VREDRAW; wc.cbClsExtra = 0; @@ -1252,10 +1795,43 @@ START_TEST(treeview) test_itemedit(); test_treeview_classinfo(); test_expandnotify(); - test_rect_retrieval_after_expand_with_select(); + test_TVS_SINGLEEXPAND(); + test_WM_PAINT(); + test_delete_items(); + test_htreeitem_layout(); + test_TVS_CHECKBOXES(); + test_TVM_GETNEXTITEM(); + + if (!load_v6_module(&ctx_cookie, &hCtx)) + { + DestroyWindow(hMainWnd); + return; + } + + /* this is a XP SP3 failure workaround */ + hwnd = CreateWindowExA(0, WC_TREEVIEW, "foo", + WS_CHILD | WS_BORDER | WS_VISIBLE, + 0, 0, 100, 100, + hMainWnd, NULL, GetModuleHandleA(NULL), NULL); + if (!IsWindow(hwnd)) + { + win_skip("FIXME: failed to create TreeView window.\n"); + unload_v6_module(ctx_cookie, hCtx); + DestroyWindow(hMainWnd); + return; + } + else + DestroyWindow(hwnd); + + /* comctl32 version 6 tests start here */ + test_expandedimage(); + test_htreeitem_layout(); + + unload_v6_module(ctx_cookie, hCtx); PostMessageA(hMainWnd, WM_CLOSE, 0, 0); - while(GetMessageA(&msg,0,0,0)) { + while(GetMessageA(&msg, 0, 0, 0)) + { TranslateMessage(&msg); DispatchMessageA(&msg); } diff --git a/rostests/winetests/comctl32/updown.c b/rostests/winetests/comctl32/updown.c index 859b3a0a988..e2a640f8d56 100644 --- a/rostests/winetests/comctl32/updown.c +++ b/rostests/winetests/comctl32/updown.c @@ -44,7 +44,6 @@ * - more stuff to test */ -#include #include #include #include @@ -406,6 +405,7 @@ static void test_updown_pos32(void) low = high = -1; r = SendMessage(updown, UDM_GETRANGE32, (WPARAM) &low , (LPARAM) &high ); + expect(0,r); if (low == -1) { win_skip("UDM_SETRANGE32/UDM_GETRANGE32 not available\n");