From 62d3be772ddbedc9295a4dd848b003599dc67ed1 Mon Sep 17 00:00:00 2001 From: Hagop Hagopian Date: Sat, 17 Mar 2007 14:12:13 -0800 Subject: [PATCH] comctl32: tab: Added message sequence tests for the tab control. --- dlls/comctl32/tests/tab.c | 358 +++++++++++++++++++++++++++++++++++++- 1 file changed, 352 insertions(+), 6 deletions(-) diff --git a/dlls/comctl32/tests/tab.c b/dlls/comctl32/tests/tab.c index 9b519d2484f..c4fa1c3d039 100644 --- a/dlls/comctl32/tests/tab.c +++ b/dlls/comctl32/tests/tab.c @@ -24,6 +24,7 @@ #include #include "wine/test.h" +#include "msg.h" #define DEFAULT_MIN_TAB_WIDTH 54 #define TAB_DEFAULT_WIDTH 96 @@ -31,6 +32,10 @@ #define EXTRA_ICON_PADDING 3 #define MAX_TABLEN 32 +#define NUM_MSG_SEQUENCES 2 +#define PARENT_SEQ_INDEX 0 +#define TAB_SEQ_INDEX 1 + #define expect(expected, got) ok ( expected == got, "Expected %d, got %d\n", expected, got) #define expect_str(expected, got)\ ok ( strcmp(expected, got) == 0, "Expected '%s', got '%s'\n", expected, got) @@ -59,6 +64,174 @@ static HFONT hFont = 0; +static struct msg_sequence *sequences[NUM_MSG_SEQUENCES]; + +static const struct message create_parent_wnd_seq[] = { + { WM_GETMINMAXINFO, sent }, + { WM_NCCREATE, sent }, + { WM_NCCALCSIZE, sent|wparam, 0 }, + { WM_CREATE, sent }, + { WM_SHOWWINDOW, sent|wparam, 1 }, + { WM_WINDOWPOSCHANGING, sent|wparam, 0 }, + { WM_WINDOWPOSCHANGING, sent|wparam, 0 }, + { WM_ACTIVATEAPP, sent|wparam, 1 }, + { WM_NCACTIVATE, sent|wparam, 1 }, + { WM_ACTIVATE, sent|wparam, 1 }, + { WM_IME_SETCONTEXT, sent|wparam|defwinproc|optional, 1 }, + { WM_IME_NOTIFY, sent|defwinproc|optional }, + { WM_SETFOCUS, sent|wparam|defwinproc, 0 }, + /* Win9x adds SWP_NOZORDER below */ + { WM_WINDOWPOSCHANGED, sent}, + { WM_NCCALCSIZE, sent|wparam|optional, 1 }, + { WM_SIZE, sent }, + { WM_MOVE, sent }, + { 0 } +}; + +static const struct message add_tab_to_parent[] = { + { TCM_INSERTITEMA, sent }, + { TCM_INSERTITEMA, sent }, + { WM_NOTIFYFORMAT, sent|defwinproc }, + { WM_QUERYUISTATE, sent|wparam|lparam|defwinproc, 0, 0 }, + { WM_PARENTNOTIFY, sent|defwinproc }, + { TCM_INSERTITEMA, sent }, + { TCM_INSERTITEMA, sent }, + { TCM_INSERTITEMA, sent }, + { 0 } +}; + +static const struct message add_tab_to_parent_interactive[] = { + { TCM_INSERTITEMA, sent }, + { TCM_INSERTITEMA, sent }, + { WM_NOTIFYFORMAT, sent|defwinproc }, + { WM_QUERYUISTATE, sent|wparam|lparam|defwinproc, 0, 0 }, + { WM_PARENTNOTIFY, sent|defwinproc }, + { TCM_INSERTITEMA, sent }, + { TCM_INSERTITEMA, sent }, + { TCM_INSERTITEMA, sent }, + { WM_SHOWWINDOW, sent}, + { WM_WINDOWPOSCHANGING, sent}, + { WM_WINDOWPOSCHANGING, sent}, + { WM_NCACTIVATE, sent}, + { WM_ACTIVATE, sent}, + { WM_IME_SETCONTEXT, sent|defwinproc|optional}, + { WM_IME_NOTIFY, sent|defwinproc|optional}, + { WM_SETFOCUS, sent|defwinproc}, + { WM_WINDOWPOSCHANGED, sent}, + { WM_SIZE, sent}, + { WM_MOVE, sent}, + { 0 } +}; + +static const struct message add_tab_control_parent_seq[] = { + { WM_NOTIFYFORMAT, sent }, + { WM_QUERYUISTATE, sent|wparam|lparam, 0, 0 }, + { 0 } +}; + +static const struct message add_tab_control_parent_seq_interactive[] = { + { WM_NOTIFYFORMAT, sent }, + { WM_QUERYUISTATE, sent|wparam|lparam, 0, 0 }, + { WM_WINDOWPOSCHANGING, sent|optional}, + { WM_NCACTIVATE, sent}, + { WM_ACTIVATE, sent}, + { WM_WINDOWPOSCHANGING, sent|optional}, + { WM_KILLFOCUS, sent}, + { WM_IME_SETCONTEXT, sent|optional}, + { WM_IME_NOTIFY, sent|optional}, + { 0 } +}; + +static const struct message empty_sequence[] = { + { 0 } +}; + +static const struct message set_min_tab_width_seq[] = { + { TCM_SETMINTABWIDTH, sent|wparam, 0 }, + { TCM_SETMINTABWIDTH, sent|wparam, 0 }, + { 0 } +}; + +static const struct message get_item_count_seq[] = { + { TCM_GETITEMCOUNT, sent|wparam|lparam, 0, 0 }, + { 0 } +}; + +static const struct message get_row_count_seq[] = { + { TCM_GETROWCOUNT, sent|wparam|lparam, 0, 0 }, + { 0 } +}; + +static const struct message get_item_rect_seq[] = { + { TCM_GETITEMRECT, sent }, + { TCM_GETITEMRECT, sent }, + { 0 } +}; + +static const struct message getset_cur_focus_seq[] = { + { TCM_SETCURFOCUS, sent|lparam, 0 }, + { TCM_GETCURFOCUS, sent|wparam|lparam, 0, 0 }, + { TCM_SETCURFOCUS, sent|lparam, 0 }, + { TCM_GETCURFOCUS, sent|wparam|lparam, 0, 0 }, + { TCM_SETCURSEL, sent|lparam, 0 }, + { TCM_SETCURFOCUS, sent|lparam, 0 }, + { TCM_GETCURFOCUS, sent|wparam|lparam, 0, 0 }, + { 0 } +}; + +static const struct message getset_cur_sel_seq[] = { + { TCM_SETCURSEL, sent|lparam, 0 }, + { TCM_GETCURSEL, sent|wparam|lparam, 0, 0 }, + { TCM_SETCURSEL, sent|lparam, 0 }, + { TCM_GETCURSEL, sent|wparam|lparam, 0, 0 }, + { TCM_SETCURSEL, sent|lparam, 0 }, + { TCM_SETCURSEL, sent|lparam, 0 }, + { TCM_GETCURFOCUS, sent|wparam|lparam, 0, 0 }, + { 0 } +}; + +static const struct message getset_extended_style_seq[] = { + { TCM_GETEXTENDEDSTYLE, sent|wparam|lparam, 0, 0 }, + { TCM_SETEXTENDEDSTYLE, sent }, + { TCM_GETEXTENDEDSTYLE, sent|wparam|lparam, 0, 0 }, + { TCM_SETEXTENDEDSTYLE, sent }, + { TCM_GETEXTENDEDSTYLE, sent|wparam|lparam, 0, 0 }, + { 0 } +}; + +static const struct message getset_unicode_format_seq[] = { + { CCM_SETUNICODEFORMAT, sent|lparam, 0 }, + { CCM_GETUNICODEFORMAT, sent|wparam|lparam, 0, 0 }, + { CCM_SETUNICODEFORMAT, sent|lparam, 0 }, + { CCM_GETUNICODEFORMAT, sent|wparam|lparam, 0, 0 }, + { CCM_SETUNICODEFORMAT, sent|lparam, 0 }, + { 0 } +}; + +static const struct message getset_item_seq[] = { + { TCM_SETITEMA, sent }, + { TCM_GETITEMA, sent }, + { TCM_GETITEMA, sent }, + { 0 } +}; + +static const struct message getset_tooltip_seq[] = { + { WM_NOTIFYFORMAT, sent }, + { WM_QUERYUISTATE, sent|wparam|lparam, 0, 0 }, + { WM_WINDOWPOSCHANGING, sent|wparam, 0 }, + { WM_NOTIFYFORMAT, sent }, + { TCM_SETTOOLTIPS, sent|lparam, 0 }, + { TCM_GETTOOLTIPS, sent|wparam|lparam, 0, 0 }, + { TCM_SETTOOLTIPS, sent|lparam, 0 }, + { TCM_GETTOOLTIPS, sent|wparam|lparam, 0, 0 }, + { 0 } +}; + +static const struct message getset_tooltip_parent_seq[] = { + { WM_WINDOWPOSCHANGING, sent|wparam, 0 }, + { 0 } +}; + static HWND create_tabcontrol (DWORD style, DWORD mask) { @@ -101,23 +274,131 @@ create_tabcontrol (DWORD style, DWORD mask) return handle; } -static HWND createFilledTabControl(DWORD style, DWORD mask, INT nTabs) +static LRESULT WINAPI parentWindowProcess(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + static long defwndproc_counter = 0; + LRESULT ret; + struct message msg; + + /* do not log painting messages */ + if (message != WM_PAINT && + message != WM_ERASEBKGND && + message != WM_NCPAINT && + message != WM_NCHITTEST && + message != WM_GETTEXT && + message != WM_GETICON && + message != WM_DEVICECHANGE) + { + trace("parent: %p, %04x, %08x, %08lx\n", hwnd, message, wParam, lParam); + + msg.message = message; + msg.flags = sent|wparam|lparam; + if (defwndproc_counter) msg.flags |= defwinproc; + msg.wParam = wParam; + msg.lParam = lParam; + add_message(sequences, PARENT_SEQ_INDEX, &msg); + } + + defwndproc_counter++; + ret = DefWindowProcA(hwnd, message, wParam, lParam); + defwndproc_counter--; + + return ret; +} + +static BOOL registerParentWindowClass(void) +{ + WNDCLASSA cls; + + cls.style = 0; + cls.lpfnWndProc = parentWindowProcess; + cls.cbClsExtra = 0; + cls.cbWndExtra = 0; + cls.hInstance = GetModuleHandleA(NULL); + cls.hIcon = 0; + cls.hCursor = LoadCursorA(0, (LPSTR)IDC_ARROW); + cls.hbrBackground = GetStockObject(WHITE_BRUSH); + cls.lpszMenuName = NULL; + cls.lpszClassName = "Tab test parent class"; + return RegisterClassA(&cls); +} + +static HWND createParentWindow(void) +{ + if (!registerParentWindowClass()) + return NULL; + + return CreateWindowEx(0, "Tab test parent class", + "Tab test parent window", + WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | + WS_MAXIMIZEBOX | WS_VISIBLE, + 0, 0, 100, 100, + GetDesktopWindow(), NULL, GetModuleHandleA(NULL), NULL); +} + +struct subclass_info +{ + WNDPROC oldproc; +}; + +static LRESULT WINAPI tabSubclassProcess(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + struct subclass_info *info = (struct subclass_info *)GetWindowLongA(hwnd, GWL_USERDATA); + static long defwndproc_counter = 0; + LRESULT ret; + struct message msg; + + /* do not log painting messages */ + if (message != WM_PAINT && + message != WM_ERASEBKGND && + message != WM_NCPAINT && + message != WM_NCHITTEST && + message != WM_GETTEXT && + message != WM_GETICON && + message != WM_DEVICECHANGE) + { + trace("tab: %p, %04x, %08x, %08lx\n", hwnd, message, wParam, lParam); + + msg.message = message; + msg.flags = sent|wparam|lparam; + if (defwndproc_counter) msg.flags |= defwinproc; + msg.wParam = wParam; + msg.lParam = lParam; + add_message(sequences, TAB_SEQ_INDEX, &msg); + } + + defwndproc_counter++; + ret = CallWindowProcA(info->oldproc, hwnd, message, wParam, lParam); + defwndproc_counter--; + + return ret; +} + +static HWND createFilledTabControl(HWND parent_wnd, DWORD style, DWORD mask, INT nTabs) { HWND tabHandle; TCITEM tcNewTab; + struct subclass_info *info; + RECT rect; INT i; + info = HeapAlloc(GetProcessHeap(), 0, sizeof(struct subclass_info)); + if (!info) + return NULL; + + GetClientRect(parent_wnd, &rect); + tabHandle = CreateWindow ( WC_TABCONTROLA, "TestTab", WS_CLIPSIBLINGS | WS_CLIPCHILDREN | TCS_FOCUSNEVER | style, - 0, 0, 300, 100, - NULL, NULL, NULL, 0); + 0, 0, rect.right, rect.bottom, + parent_wnd, NULL, NULL, 0); assert(tabHandle); - SetWindowLong(tabHandle, GWL_STYLE, WS_CLIPSIBLINGS | WS_CLIPCHILDREN | TCS_FOCUSNEVER | style); - SendMessage (tabHandle, WM_SETFONT, 0, (LPARAM) hFont); + info->oldproc = (WNDPROC)SetWindowLongA(tabHandle, GWL_WNDPROC, (LONG)tabSubclassProcess); + SetWindowLongA(tabHandle, GWL_USERDATA, (LONG)info); tcNewTab.mask = mask; @@ -314,32 +595,66 @@ static void test_tab(INT nMinTabWidth) static void test_getters_setters(INT nTabs) { HWND hTab; + HWND parent_wnd; RECT rTab; INT nTabsRetrieved; INT rowCount; - hTab = createFilledTabControl(TCS_FIXEDWIDTH, TCIF_TEXT|TCIF_IMAGE, nTabs); + parent_wnd = createParentWindow(); + ok(parent_wnd != NULL, "Failed to create parent window!\n"); + flush_sequences(sequences, NUM_MSG_SEQUENCES); + + hTab = createFilledTabControl(parent_wnd, TCS_FIXEDWIDTH, TCIF_TEXT|TCIF_IMAGE, nTabs); ok(hTab != NULL, "Failed to create tab control\n"); + if(!winetest_interactive) + ok_sequence(sequences, TAB_SEQ_INDEX, add_tab_to_parent, + "Tab sequence, after adding tab control to parent", TRUE); + else + ok_sequence(sequences, TAB_SEQ_INDEX, add_tab_to_parent_interactive, + "Tab sequence, after adding tab control to parent", TRUE); + + if(!winetest_interactive) + ok_sequence(sequences, PARENT_SEQ_INDEX, add_tab_control_parent_seq, + "Parent after sequence, adding tab control to parent", TRUE); + else + ok_sequence(sequences, PARENT_SEQ_INDEX, add_tab_control_parent_seq_interactive, + "Parent after sequence, adding tab control to parent", TRUE); + + flush_sequences(sequences, NUM_MSG_SEQUENCES); todo_wine{ expect(DEFAULT_MIN_TAB_WIDTH, (int)SendMessage(hTab, TCM_SETMINTABWIDTH, 0, -1)); } + ok_sequence(sequences, TAB_SEQ_INDEX, set_min_tab_width_seq, "Set minTabWidth test sequence", FALSE); + ok_sequence(sequences, PARENT_SEQ_INDEX, empty_sequence, "Set minTabWidth test parent sequence", FALSE); + /* Testing GetItemCount */ + flush_sequences(sequences, NUM_MSG_SEQUENCES); nTabsRetrieved = SendMessage(hTab, TCM_GETITEMCOUNT, 0, 0); expect(nTabs, nTabsRetrieved); + ok_sequence(sequences, TAB_SEQ_INDEX, get_item_count_seq, "Get itemCount test sequence", FALSE); + ok_sequence(sequences, PARENT_SEQ_INDEX, empty_sequence, "Getset itemCount test parent sequence", FALSE); /* Testing GetRowCount */ + flush_sequences(sequences, NUM_MSG_SEQUENCES); rowCount = SendMessage(hTab, TCM_GETROWCOUNT, 0, 0); expect(1, rowCount); + ok_sequence(sequences, TAB_SEQ_INDEX, get_row_count_seq, "Get rowCount test sequence", FALSE); + ok_sequence(sequences, PARENT_SEQ_INDEX, empty_sequence, "Get rowCount test parent sequence", FALSE); /* Testing GetItemRect */ + flush_sequences(sequences, NUM_MSG_SEQUENCES); ok(SendMessage(hTab, TCM_GETITEMRECT, 0, (LPARAM) &rTab), "GetItemRect failed.\n"); CheckSize(hTab, TAB_DEFAULT_WIDTH, -1 , "Default Width"); + ok_sequence(sequences, TAB_SEQ_INDEX, get_item_rect_seq, "Get itemRect test sequence", FALSE); + ok_sequence(sequences, PARENT_SEQ_INDEX, empty_sequence, "Get itemRect test parent sequence", FALSE); /* Testing CurFocus */ { INT focusIndex; + flush_sequences(sequences, NUM_MSG_SEQUENCES); + /* Testing CurFocus with largest appropriate value */ SendMessage(hTab, TCM_SETCURFOCUS, nTabs-1, 0); focusIndex = SendMessage(hTab, TCM_GETCURFOCUS, 0, 0); @@ -357,17 +672,22 @@ static void test_getters_setters(INT nTabs) todo_wine{ expect(-1, focusIndex); } + SendMessage(hTab, TCM_SETCURFOCUS, nTabs+1, 0); focusIndex = SendMessage(hTab, TCM_GETCURFOCUS, 0, 0); todo_wine{ expect(1, focusIndex); } + + ok_sequence(sequences, TAB_SEQ_INDEX, getset_cur_focus_seq, "Getset curFoc test sequence", FALSE); } /* Testing CurSel */ { INT selectionIndex; + flush_sequences(sequences, NUM_MSG_SEQUENCES); + /* Testing CurSel with largest appropriate value */ selectionIndex = SendMessage(hTab, TCM_SETCURSEL, nTabs-1, 0); expect(1, selectionIndex); @@ -392,6 +712,9 @@ static void test_getters_setters(INT nTabs) todo_wine{ expect(1, selectionIndex); } + + ok_sequence(sequences, TAB_SEQ_INDEX, getset_cur_sel_seq, "Getset curSel test sequence", FALSE); + ok_sequence(sequences, PARENT_SEQ_INDEX, empty_sequence, "Getset curSel test parent sequence", FALSE); } /* Testing ExtendedStyle */ @@ -399,6 +722,8 @@ static void test_getters_setters(INT nTabs) DWORD prevExtendedStyle; DWORD extendedStyle; + flush_sequences(sequences, NUM_MSG_SEQUENCES); + /* Testing Flat Seperators */ extendedStyle = SendMessage(hTab, TCM_GETEXTENDEDSTYLE, 0, 0); prevExtendedStyle = SendMessage(hTab, TCM_SETEXTENDEDSTYLE, 0, TCS_EX_FLATSEPARATORS); @@ -417,12 +742,17 @@ static void test_getters_setters(INT nTabs) todo_wine{ expect(TCS_EX_REGISTERDROP, extendedStyle); } + + ok_sequence(sequences, TAB_SEQ_INDEX, getset_extended_style_seq, "Getset extendedStyle test sequence", FALSE); + ok_sequence(sequences, PARENT_SEQ_INDEX, empty_sequence, "Getset extendedStyle test parent sequence", FALSE); } /* Testing UnicodeFormat */ { INT unicodeFormat; + flush_sequences(sequences, NUM_MSG_SEQUENCES); + unicodeFormat = SendMessage(hTab, TCM_SETUNICODEFORMAT, TRUE, 0); todo_wine{ expect(0, unicodeFormat); @@ -437,6 +767,9 @@ static void test_getters_setters(INT nTabs) unicodeFormat = SendMessage(hTab, TCM_SETUNICODEFORMAT, TRUE, 0); expect(0, unicodeFormat); + + ok_sequence(sequences, TAB_SEQ_INDEX, getset_unicode_format_seq, "Getset unicodeFormat test sequence", FALSE); + ok_sequence(sequences, PARENT_SEQ_INDEX, empty_sequence, "Getset unicodeFormat test parent sequence", FALSE); } /* Testing GetSet Item */ @@ -444,6 +777,8 @@ static void test_getters_setters(INT nTabs) TCITEM tcItem; char szText[32] = "New Label"; + flush_sequences(sequences, NUM_MSG_SEQUENCES); + tcItem.mask = TCIF_TEXT; tcItem.pszText = &szText[0]; tcItem.cchTextMax = sizeof(szText); @@ -454,6 +789,9 @@ static void test_getters_setters(INT nTabs) ok ( SendMessage(hTab, TCM_GETITEM, 1, (LPARAM) &tcItem), "Getting item failed.\n"); expect_str("Tab 2", tcItem.pszText); + + ok_sequence(sequences, TAB_SEQ_INDEX, getset_item_seq, "Getset item test sequence", FALSE); + ok_sequence(sequences, PARENT_SEQ_INDEX, empty_sequence, "Getset item test parent sequence", FALSE); } /* Testing GetSet ToolTip */ @@ -461,15 +799,21 @@ static void test_getters_setters(INT nTabs) HWND toolTip; char toolTipText[32] = "ToolTip Text Test"; + flush_sequences(sequences, NUM_MSG_SEQUENCES); + toolTip = create_tooltip(hTab, toolTipText); SendMessage(hTab, TCM_SETTOOLTIPS, (LPARAM) toolTip, 0); ok (toolTip == (HWND) SendMessage(hTab,TCM_GETTOOLTIPS,0,0), "ToolTip was set incorrectly.\n"); SendMessage(hTab, TCM_SETTOOLTIPS, (LPARAM) NULL, 0); ok (NULL == (HWND) SendMessage(hTab,TCM_GETTOOLTIPS,0,0), "ToolTip was set incorrectly.\n"); + + ok_sequence(sequences, TAB_SEQ_INDEX, getset_tooltip_seq, "Getset tooltip test sequence", TRUE); + ok_sequence(sequences, PARENT_SEQ_INDEX, getset_tooltip_parent_seq, "Getset tooltip test parent sequence", TRUE); } DestroyWindow(hTab); + DestroyWindow(parent_wnd); } START_TEST(tab) @@ -496,6 +840,8 @@ START_TEST(tab) trace ("Testing with MinWidth set to 94\n"); test_tab(94); + init_msg_sequences(sequences, NUM_MSG_SEQUENCES); + /* Testing getters and setters with 5 tabs */ test_getters_setters(5); }