1*c2c66affSColin Finck /* Unit tests for treeview. 2*c2c66affSColin Finck * 3*c2c66affSColin Finck * Copyright 2005 Krzysztof Foltman 4*c2c66affSColin Finck * Copyright 2007 Christopher James Peterson 5*c2c66affSColin Finck * 6*c2c66affSColin Finck * This library is free software; you can redistribute it and/or 7*c2c66affSColin Finck * modify it under the terms of the GNU Lesser General Public 8*c2c66affSColin Finck * License as published by the Free Software Foundation; either 9*c2c66affSColin Finck * version 2.1 of the License, or (at your option) any later version. 10*c2c66affSColin Finck * 11*c2c66affSColin Finck * This library is distributed in the hope that it will be useful, 12*c2c66affSColin Finck * but WITHOUT ANY WARRANTY; without even the implied warranty of 13*c2c66affSColin Finck * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14*c2c66affSColin Finck * Lesser General Public License for more details. 15*c2c66affSColin Finck * 16*c2c66affSColin Finck * You should have received a copy of the GNU Lesser General Public 17*c2c66affSColin Finck * License along with this library; if not, write to the Free Software 18*c2c66affSColin Finck * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 19*c2c66affSColin Finck */ 20*c2c66affSColin Finck 21*c2c66affSColin Finck #include <stdarg.h> 22*c2c66affSColin Finck #include <stdio.h> 23*c2c66affSColin Finck 24*c2c66affSColin Finck #include "windef.h" 25*c2c66affSColin Finck #include "winbase.h" 26*c2c66affSColin Finck #include "wingdi.h" 27*c2c66affSColin Finck #include "winuser.h" 28*c2c66affSColin Finck #include "winnls.h" 29*c2c66affSColin Finck #include "winreg.h" 30*c2c66affSColin Finck #include "wine/commctrl.h" 31*c2c66affSColin Finck 32*c2c66affSColin Finck #include "wine/test.h" 33*c2c66affSColin Finck #include "v6util.h" 34*c2c66affSColin Finck #include "msg.h" 35*c2c66affSColin Finck 36*c2c66affSColin Finck static const char *TEST_CALLBACK_TEXT = "callback_text"; 37*c2c66affSColin Finck 38*c2c66affSColin Finck static TVITEMA g_item_expanding, g_item_expanded; 39*c2c66affSColin Finck static BOOL g_get_from_expand; 40*c2c66affSColin Finck static BOOL g_get_rect_in_expand; 41*c2c66affSColin Finck static BOOL g_disp_A_to_W; 42*c2c66affSColin Finck static BOOL g_disp_set_stateimage; 43*c2c66affSColin Finck static BOOL g_beginedit_alter_text; 44*c2c66affSColin Finck static HFONT g_customdraw_font; 45*c2c66affSColin Finck static BOOL g_v6; 46*c2c66affSColin Finck 47*c2c66affSColin Finck #define NUM_MSG_SEQUENCES 3 48*c2c66affSColin Finck #define TREEVIEW_SEQ_INDEX 0 49*c2c66affSColin Finck #define PARENT_SEQ_INDEX 1 50*c2c66affSColin Finck #define PARENT_CD_SEQ_INDEX 2 51*c2c66affSColin Finck 52*c2c66affSColin Finck #define expect(expected, got) ok(got == expected, "Expected %d, got %d\n", expected, got) 53*c2c66affSColin Finck 54*c2c66affSColin Finck static struct msg_sequence *sequences[NUM_MSG_SEQUENCES]; 55*c2c66affSColin Finck static struct msg_sequence *item_sequence[1]; 56*c2c66affSColin Finck 57*c2c66affSColin Finck static void flush_events(void) 58*c2c66affSColin Finck { 59*c2c66affSColin Finck MSG msg; 60*c2c66affSColin Finck int diff = 200; 61*c2c66affSColin Finck int min_timeout = 100; 62*c2c66affSColin Finck DWORD time = GetTickCount() + diff; 63*c2c66affSColin Finck 64*c2c66affSColin Finck while (diff > 0) 65*c2c66affSColin Finck { 66*c2c66affSColin Finck if (MsgWaitForMultipleObjects(0, NULL, FALSE, min_timeout, QS_ALLINPUT) == WAIT_TIMEOUT) break; 67*c2c66affSColin Finck while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg); 68*c2c66affSColin Finck diff = time - GetTickCount(); 69*c2c66affSColin Finck } 70*c2c66affSColin Finck } 71*c2c66affSColin Finck 72*c2c66affSColin Finck static const struct message FillRootSeq[] = { 73*c2c66affSColin Finck { TVM_INSERTITEMA, sent }, 74*c2c66affSColin Finck { TVM_INSERTITEMA, sent }, 75*c2c66affSColin Finck { 0 } 76*c2c66affSColin Finck }; 77*c2c66affSColin Finck 78*c2c66affSColin Finck static const struct message rootnone_select_seq[] = { 79*c2c66affSColin Finck { TVM_SELECTITEM, sent|wparam, 9 }, 80*c2c66affSColin Finck { TVM_SELECTITEM, sent|wparam, 9 }, 81*c2c66affSColin Finck { TVM_SELECTITEM, sent|wparam, 9 }, 82*c2c66affSColin Finck { TVM_SELECTITEM, sent|wparam, 9 }, 83*c2c66affSColin Finck { TVM_SELECTITEM, sent|wparam, 9 }, 84*c2c66affSColin Finck { TVM_SELECTITEM, sent|wparam, 9 }, 85*c2c66affSColin Finck { 0 } 86*c2c66affSColin Finck }; 87*c2c66affSColin Finck 88*c2c66affSColin Finck static const struct message rootchild_select_seq[] = { 89*c2c66affSColin Finck { TVM_SELECTITEM, sent|wparam, 9 }, 90*c2c66affSColin Finck { TVM_SELECTITEM, sent|wparam, 9 }, 91*c2c66affSColin Finck { TVM_SELECTITEM, sent|wparam, 9 }, 92*c2c66affSColin Finck { TVM_SELECTITEM, sent|wparam, 9 }, 93*c2c66affSColin Finck { TVM_SELECTITEM, sent|wparam, 9 }, 94*c2c66affSColin Finck { TVM_SELECTITEM, sent|wparam, 9 }, 95*c2c66affSColin Finck { 0 } 96*c2c66affSColin Finck }; 97*c2c66affSColin Finck 98*c2c66affSColin Finck static const struct message getitemtext_seq[] = { 99*c2c66affSColin Finck { TVM_INSERTITEMA, sent }, 100*c2c66affSColin Finck { TVM_GETITEMA, sent }, 101*c2c66affSColin Finck { TVM_DELETEITEM, sent }, 102*c2c66affSColin Finck { 0 } 103*c2c66affSColin Finck }; 104*c2c66affSColin Finck 105*c2c66affSColin Finck static const struct message focus_seq[] = { 106*c2c66affSColin Finck { TVM_INSERTITEMA, sent }, 107*c2c66affSColin Finck { TVM_INSERTITEMA, sent }, 108*c2c66affSColin Finck { TVM_SELECTITEM, sent|wparam, 9 }, 109*c2c66affSColin Finck /* The following end up out of order in wine */ 110*c2c66affSColin Finck { WM_WINDOWPOSCHANGING, sent|defwinproc }, 111*c2c66affSColin Finck { WM_NCCALCSIZE, sent|wparam|defwinproc, TRUE }, 112*c2c66affSColin Finck { WM_WINDOWPOSCHANGED, sent|defwinproc }, 113*c2c66affSColin Finck { WM_SIZE, sent|defwinproc }, 114*c2c66affSColin Finck { WM_WINDOWPOSCHANGING, sent|defwinproc|optional }, 115*c2c66affSColin Finck { WM_NCCALCSIZE, sent|wparam|defwinproc|optional, TRUE }, 116*c2c66affSColin Finck { WM_WINDOWPOSCHANGED, sent|defwinproc|optional }, 117*c2c66affSColin Finck { WM_SIZE, sent|defwinproc|optional }, 118*c2c66affSColin Finck { WM_PAINT, sent|defwinproc }, 119*c2c66affSColin Finck { WM_NCPAINT, sent|wparam|defwinproc, 1 }, 120*c2c66affSColin Finck { WM_ERASEBKGND, sent|defwinproc }, 121*c2c66affSColin Finck { TVM_EDITLABELA, sent }, 122*c2c66affSColin Finck { WM_COMMAND, sent|wparam|defwinproc, MAKEWPARAM(0, EN_UPDATE) }, 123*c2c66affSColin Finck { WM_COMMAND, sent|wparam|defwinproc, MAKEWPARAM(0, EN_CHANGE) }, 124*c2c66affSColin Finck { WM_PARENTNOTIFY, sent|wparam|defwinproc, MAKEWPARAM(WM_CREATE, 0) }, 125*c2c66affSColin Finck { WM_KILLFOCUS, sent|defwinproc }, 126*c2c66affSColin Finck { WM_PAINT, sent|defwinproc }, 127*c2c66affSColin Finck { WM_IME_SETCONTEXT, sent|defwinproc|optional }, 128*c2c66affSColin Finck { WM_COMMAND, sent|wparam|defwinproc, MAKEWPARAM(0, EN_SETFOCUS) }, 129*c2c66affSColin Finck { WM_ERASEBKGND, sent|defwinproc|optional }, 130*c2c66affSColin Finck { WM_CTLCOLOREDIT, sent|defwinproc|optional }, 131*c2c66affSColin Finck { WM_CTLCOLOREDIT, sent|defwinproc|optional }, 132*c2c66affSColin Finck { 0 } 133*c2c66affSColin Finck }; 134*c2c66affSColin Finck 135*c2c66affSColin Finck static const struct message test_get_set_bkcolor_seq[] = { 136*c2c66affSColin Finck { TVM_GETBKCOLOR, sent|wparam|lparam, 0, 0 }, 137*c2c66affSColin Finck { TVM_SETBKCOLOR, sent|wparam|lparam, 0, 0 }, 138*c2c66affSColin Finck { TVM_GETBKCOLOR, sent|wparam|lparam, 0, 0 }, 139*c2c66affSColin Finck { TVM_SETBKCOLOR, sent|wparam|lparam, 0, 0x00ffffff }, 140*c2c66affSColin Finck { TVM_GETBKCOLOR, sent|wparam|lparam, 0, 0 }, 141*c2c66affSColin Finck { TVM_SETBKCOLOR, sent|wparam|lparam, 0, -1 }, 142*c2c66affSColin Finck { 0 } 143*c2c66affSColin Finck }; 144*c2c66affSColin Finck 145*c2c66affSColin Finck static const struct message test_get_set_imagelist_seq[] = { 146*c2c66affSColin Finck { TVM_SETIMAGELIST, sent|wparam|lparam, 0, 0 }, 147*c2c66affSColin Finck { TVM_GETIMAGELIST, sent|wparam|lparam, 0, 0 }, 148*c2c66affSColin Finck { 0 } 149*c2c66affSColin Finck }; 150*c2c66affSColin Finck 151*c2c66affSColin Finck static const struct message test_get_set_indent_seq[] = { 152*c2c66affSColin Finck { TVM_SETINDENT, sent|wparam|lparam, 0, 0 }, 153*c2c66affSColin Finck { TVM_GETINDENT, sent|wparam|lparam, 0, 0 }, 154*c2c66affSColin Finck /* The actual amount to indent is dependent on the system for this message */ 155*c2c66affSColin Finck { TVM_SETINDENT, sent }, 156*c2c66affSColin Finck { TVM_GETINDENT, sent|wparam|lparam, 0, 0 }, 157*c2c66affSColin Finck { 0 } 158*c2c66affSColin Finck }; 159*c2c66affSColin Finck 160*c2c66affSColin Finck static const struct message test_get_set_insertmarkcolor_seq[] = { 161*c2c66affSColin Finck { TVM_SETINSERTMARKCOLOR, sent|wparam|lparam, 0, 0 }, 162*c2c66affSColin Finck { TVM_GETINSERTMARKCOLOR, sent|wparam|lparam, 0, 0 }, 163*c2c66affSColin Finck { 0 } 164*c2c66affSColin Finck }; 165*c2c66affSColin Finck 166*c2c66affSColin Finck static const struct message test_get_set_item_seq[] = { 167*c2c66affSColin Finck { TVM_GETITEMA, sent }, 168*c2c66affSColin Finck { TVM_SETITEMA, sent }, 169*c2c66affSColin Finck { TVM_GETITEMA, sent }, 170*c2c66affSColin Finck { TVM_SETITEMA, sent }, 171*c2c66affSColin Finck { 0 } 172*c2c66affSColin Finck }; 173*c2c66affSColin Finck 174*c2c66affSColin Finck static const struct message test_get_set_itemheight_seq[] = { 175*c2c66affSColin Finck { TVM_GETITEMHEIGHT, sent|wparam|lparam, 0, 0 }, 176*c2c66affSColin Finck { TVM_SETITEMHEIGHT, sent|wparam|lparam, -1, 0 }, 177*c2c66affSColin Finck { TVM_GETITEMHEIGHT, sent|wparam|lparam, 0, 0 }, 178*c2c66affSColin Finck { TVM_SETITEMHEIGHT, sent|lparam, 0xcccccccc, 0 }, 179*c2c66affSColin Finck { TVM_GETITEMHEIGHT, sent|wparam|lparam|optional, 0, 0 }, 180*c2c66affSColin Finck { TVM_SETITEMHEIGHT, sent|wparam|lparam|optional, 9, 0 }, 181*c2c66affSColin Finck { TVM_GETITEMHEIGHT, sent|wparam|lparam, 0, 0 }, 182*c2c66affSColin Finck { 0 } 183*c2c66affSColin Finck }; 184*c2c66affSColin Finck 185*c2c66affSColin Finck static const struct message test_get_set_scrolltime_seq[] = { 186*c2c66affSColin Finck { TVM_SETSCROLLTIME, sent|wparam|lparam, 20, 0 }, 187*c2c66affSColin Finck { TVM_GETSCROLLTIME, sent|wparam|lparam, 0, 0 }, 188*c2c66affSColin Finck { 0 } 189*c2c66affSColin Finck }; 190*c2c66affSColin Finck 191*c2c66affSColin Finck static const struct message test_get_set_textcolor_seq[] = { 192*c2c66affSColin Finck { TVM_GETTEXTCOLOR, sent|wparam|lparam, 0, 0 }, 193*c2c66affSColin Finck { TVM_SETTEXTCOLOR, sent|wparam|lparam, 0, 0 }, 194*c2c66affSColin Finck { TVM_GETTEXTCOLOR, sent|wparam|lparam, 0, 0 }, 195*c2c66affSColin Finck { TVM_SETTEXTCOLOR, sent|wparam|lparam, 0, RGB(255, 255, 255) }, 196*c2c66affSColin Finck { TVM_GETTEXTCOLOR, sent|wparam|lparam, 0, 0 }, 197*c2c66affSColin Finck { TVM_SETTEXTCOLOR, sent|wparam|lparam, 0, CLR_NONE }, 198*c2c66affSColin Finck { 0 } 199*c2c66affSColin Finck }; 200*c2c66affSColin Finck 201*c2c66affSColin Finck static const struct message test_get_set_tooltips_seq[] = { 202*c2c66affSColin Finck { WM_KILLFOCUS, sent }, 203*c2c66affSColin Finck { WM_IME_SETCONTEXT, sent|optional }, 204*c2c66affSColin Finck { WM_IME_NOTIFY, sent|optional }, 205*c2c66affSColin Finck { TVM_SETTOOLTIPS, sent|wparam|lparam, 0, 0 }, 206*c2c66affSColin Finck { TVM_GETTOOLTIPS, sent|wparam|lparam, 0, 0 }, 207*c2c66affSColin Finck { 0 } 208*c2c66affSColin Finck }; 209*c2c66affSColin Finck 210*c2c66affSColin Finck static const struct message test_get_set_unicodeformat_seq[] = { 211*c2c66affSColin Finck { TVM_SETUNICODEFORMAT, sent|wparam|lparam, TRUE, 0 }, 212*c2c66affSColin Finck { TVM_GETUNICODEFORMAT, sent|wparam|lparam, 0, 0 }, 213*c2c66affSColin Finck { TVM_SETUNICODEFORMAT, sent|wparam|lparam, 0, 0 }, 214*c2c66affSColin Finck { TVM_GETUNICODEFORMAT, sent|wparam|lparam, 0, 0 }, 215*c2c66affSColin Finck { TVM_SETUNICODEFORMAT, sent|wparam|lparam, 0, 0 }, 216*c2c66affSColin Finck { 0 } 217*c2c66affSColin Finck }; 218*c2c66affSColin Finck 219*c2c66affSColin Finck static const struct message test_right_click_seq[] = { 220*c2c66affSColin Finck { WM_RBUTTONDOWN, sent|wparam, MK_RBUTTON }, 221*c2c66affSColin Finck { WM_CAPTURECHANGED, sent|defwinproc }, 222*c2c66affSColin Finck { TVM_GETNEXTITEM, sent|wparam|lparam|defwinproc, TVGN_CARET, 0 }, 223*c2c66affSColin Finck { 0 } 224*c2c66affSColin Finck }; 225*c2c66affSColin Finck 226*c2c66affSColin Finck static const struct message parent_expand_seq[] = { 227*c2c66affSColin Finck { WM_NOTIFY, sent|id, 0, 0, TVN_ITEMEXPANDINGA }, 228*c2c66affSColin Finck { WM_NOTIFY, sent|id, 0, 0, TVN_ITEMEXPANDEDA }, 229*c2c66affSColin Finck { 0 } 230*c2c66affSColin Finck }; 231*c2c66affSColin Finck 232*c2c66affSColin Finck static const struct message parent_expand_kb_seq[] = { 233*c2c66affSColin Finck { WM_NOTIFY, sent|id, 0, 0, TVN_KEYDOWN }, 234*c2c66affSColin Finck { WM_NOTIFY, sent|id, 0, 0, TVN_ITEMEXPANDINGA }, 235*c2c66affSColin Finck { WM_NOTIFY, sent|id, 0, 0, TVN_ITEMEXPANDEDA }, 236*c2c66affSColin Finck { WM_CHANGEUISTATE, sent|optional }, 237*c2c66affSColin Finck { 0 } 238*c2c66affSColin Finck }; 239*c2c66affSColin Finck 240*c2c66affSColin Finck static const struct message parent_collapse_2nd_kb_seq[] = { 241*c2c66affSColin Finck { WM_NOTIFY, sent|id|optional, 0, 0, TVN_KEYDOWN }, 242*c2c66affSColin Finck { WM_NOTIFY, sent|id, 0, 0, TVN_ITEMEXPANDINGA }, 243*c2c66affSColin Finck { WM_CHANGEUISTATE, sent|optional }, 244*c2c66affSColin Finck { 0 } 245*c2c66affSColin Finck }; 246*c2c66affSColin Finck 247*c2c66affSColin Finck static const struct message parent_expand_empty_kb_seq[] = { 248*c2c66affSColin Finck { WM_NOTIFY, sent|id, 0, 0, TVN_KEYDOWN }, 249*c2c66affSColin Finck { WM_CHANGEUISTATE, sent|optional }, 250*c2c66affSColin Finck { 0 } 251*c2c66affSColin Finck }; 252*c2c66affSColin Finck 253*c2c66affSColin Finck static const struct message parent_singleexpand_seq0[] = { 254*c2c66affSColin Finck /* alpha expands */ 255*c2c66affSColin Finck { WM_NOTIFY, sent|id, 0, 0, TVN_SELCHANGINGA }, 256*c2c66affSColin Finck { WM_NOTIFY, sent|id, 0, 0, TVN_SELCHANGEDA }, 257*c2c66affSColin Finck { WM_NOTIFY, sent|id, 0, 0, TVN_SINGLEEXPAND }, 258*c2c66affSColin Finck { WM_NOTIFY, sent|id, 0, 0, TVN_ITEMEXPANDINGA }, 259*c2c66affSColin Finck { WM_NOTIFY, sent|id, 0, 0, TVN_ITEMEXPANDEDA }, 260*c2c66affSColin Finck { 0 } 261*c2c66affSColin Finck }; 262*c2c66affSColin Finck 263*c2c66affSColin Finck static const struct message parent_singleexpand_seq1[] = { 264*c2c66affSColin Finck /* bravo expands */ 265*c2c66affSColin Finck { WM_NOTIFY, sent|id, 0, 0, TVN_SELCHANGINGA }, 266*c2c66affSColin Finck { WM_NOTIFY, sent|id, 0, 0, TVN_SELCHANGEDA }, 267*c2c66affSColin Finck { WM_NOTIFY, sent|id, 0, 0, TVN_SINGLEEXPAND }, 268*c2c66affSColin Finck { WM_NOTIFY, sent|id, 0, 0, TVN_ITEMEXPANDINGA }, 269*c2c66affSColin Finck { WM_NOTIFY, sent|id, 0, 0, TVN_ITEMEXPANDEDA }, 270*c2c66affSColin Finck { 0 } 271*c2c66affSColin Finck }; 272*c2c66affSColin Finck 273*c2c66affSColin Finck static const struct message parent_singleexpand_seq2[] = { 274*c2c66affSColin Finck /* delta expands, bravo collapses */ 275*c2c66affSColin Finck { WM_NOTIFY, sent|id, 0, 0, TVN_SELCHANGINGA }, 276*c2c66affSColin Finck { WM_NOTIFY, sent|id, 0, 0, TVN_SELCHANGEDA }, 277*c2c66affSColin Finck { WM_NOTIFY, sent|id, 0, 0, TVN_SINGLEEXPAND }, 278*c2c66affSColin Finck { WM_NOTIFY, sent|id, 0, 0, TVN_ITEMEXPANDINGA }, 279*c2c66affSColin Finck { WM_NOTIFY, sent|id, 0, 0, TVN_ITEMEXPANDEDA }, 280*c2c66affSColin Finck { WM_NOTIFY, sent|id, 0, 0, TVN_ITEMEXPANDINGA }, 281*c2c66affSColin Finck { WM_NOTIFY, sent|id, 0, 0, TVN_ITEMEXPANDEDA }, 282*c2c66affSColin Finck { 0 } 283*c2c66affSColin Finck }; 284*c2c66affSColin Finck 285*c2c66affSColin Finck static const struct message parent_singleexpand_seq3[] = { 286*c2c66affSColin Finck /* foxtrot expands, alpha and delta collapse */ 287*c2c66affSColin Finck { WM_NOTIFY, sent|id, 0, 0, TVN_SELCHANGINGA }, 288*c2c66affSColin Finck { WM_NOTIFY, sent|id, 0, 0, TVN_SELCHANGEDA }, 289*c2c66affSColin Finck { WM_NOTIFY, sent|id, 0, 0, TVN_SINGLEEXPAND }, 290*c2c66affSColin Finck { WM_NOTIFY, sent|id, 0, 0, TVN_ITEMEXPANDINGA }, 291*c2c66affSColin Finck { WM_NOTIFY, sent|id, 0, 0, TVN_ITEMEXPANDEDA }, 292*c2c66affSColin Finck { WM_NOTIFY, sent|id, 0, 0, TVN_ITEMEXPANDINGA }, 293*c2c66affSColin Finck { WM_NOTIFY, sent|id, 0, 0, TVN_ITEMEXPANDEDA }, 294*c2c66affSColin Finck { WM_NOTIFY, sent|id, 0, 0, TVN_ITEMEXPANDINGA }, 295*c2c66affSColin Finck { WM_NOTIFY, sent|id, 0, 0, TVN_ITEMEXPANDEDA }, 296*c2c66affSColin Finck { 0 } 297*c2c66affSColin Finck }; 298*c2c66affSColin Finck 299*c2c66affSColin Finck static const struct message parent_singleexpand_seq4[] = { 300*c2c66affSColin Finck /* alpha expands, foxtrot collapses */ 301*c2c66affSColin Finck { WM_NOTIFY, sent|id, 0, 0, TVN_SELCHANGINGA }, 302*c2c66affSColin Finck { WM_NOTIFY, sent|id, 0, 0, TVN_SELCHANGEDA }, 303*c2c66affSColin Finck { WM_NOTIFY, sent|id, 0, 0, TVN_SINGLEEXPAND }, 304*c2c66affSColin Finck { WM_NOTIFY, sent|id, 0, 0, TVN_ITEMEXPANDINGA }, 305*c2c66affSColin Finck { WM_NOTIFY, sent|id, 0, 0, TVN_ITEMEXPANDEDA }, 306*c2c66affSColin Finck { WM_NOTIFY, sent|id, 0, 0, TVN_ITEMEXPANDINGA }, 307*c2c66affSColin Finck { WM_NOTIFY, sent|id, 0, 0, TVN_ITEMEXPANDEDA }, 308*c2c66affSColin Finck { 0 } 309*c2c66affSColin Finck }; 310*c2c66affSColin Finck 311*c2c66affSColin Finck static const struct message parent_singleexpand_seq5[] = { 312*c2c66affSColin Finck /* foxtrot expands while golf is selected, then golf expands and alpha collapses */ 313*c2c66affSColin Finck { WM_NOTIFY, sent|id, 0, 0, TVN_SELCHANGINGA }, 314*c2c66affSColin Finck { WM_NOTIFY, sent|id, 0, 0, TVN_ITEMEXPANDINGA }, 315*c2c66affSColin Finck { WM_NOTIFY, sent|id, 0, 0, TVN_ITEMEXPANDEDA }, 316*c2c66affSColin Finck { WM_NOTIFY, sent|id, 0, 0, TVN_SELCHANGEDA }, 317*c2c66affSColin Finck { WM_NOTIFY, sent|id, 0, 0, TVN_SINGLEEXPAND }, 318*c2c66affSColin Finck { WM_NOTIFY, sent|id, 0, 0, TVN_ITEMEXPANDINGA }, 319*c2c66affSColin Finck { WM_NOTIFY, sent|id, 0, 0, TVN_ITEMEXPANDEDA }, 320*c2c66affSColin Finck { WM_NOTIFY, sent|id, 0, 0, TVN_ITEMEXPANDINGA }, 321*c2c66affSColin Finck { WM_NOTIFY, sent|id, 0, 0, TVN_ITEMEXPANDEDA }, 322*c2c66affSColin Finck { 0 } 323*c2c66affSColin Finck }; 324*c2c66affSColin Finck 325*c2c66affSColin Finck static const struct message parent_singleexpand_seq6[] = { 326*c2c66affSColin Finck /* hotel does not expand and india does not collapse because they have no children */ 327*c2c66affSColin Finck { WM_NOTIFY, sent|id, 0, 0, TVN_SELCHANGINGA }, 328*c2c66affSColin Finck { WM_NOTIFY, sent|id, 0, 0, TVN_SELCHANGEDA }, 329*c2c66affSColin Finck { WM_NOTIFY, sent|id, 0, 0, TVN_SINGLEEXPAND }, 330*c2c66affSColin Finck { 0 } 331*c2c66affSColin Finck }; 332*c2c66affSColin Finck 333*c2c66affSColin Finck static const struct message parent_singleexpand_seq7[] = { 334*c2c66affSColin Finck /* india does not expand and hotel does not collapse because they have no children */ 335*c2c66affSColin Finck { WM_NOTIFY, sent|id, 0, 0, TVN_SELCHANGINGA }, 336*c2c66affSColin Finck { WM_NOTIFY, sent|id, 0, 0, TVN_SELCHANGEDA }, 337*c2c66affSColin Finck { WM_NOTIFY, sent|id, 0, 0, TVN_SINGLEEXPAND }, 338*c2c66affSColin Finck { 0 } 339*c2c66affSColin Finck }; 340*c2c66affSColin Finck 341*c2c66affSColin Finck static const struct message parent_get_dispinfo_seq[] = { 342*c2c66affSColin Finck { WM_NOTIFY, sent|id, 0, 0, TVN_GETDISPINFOA }, 343*c2c66affSColin Finck { 0 } 344*c2c66affSColin Finck }; 345*c2c66affSColin Finck 346*c2c66affSColin Finck static const struct message empty_seq[] = { 347*c2c66affSColin Finck { 0 } 348*c2c66affSColin Finck }; 349*c2c66affSColin Finck 350*c2c66affSColin Finck static const struct message parent_cd_seq[] = { 351*c2c66affSColin Finck { WM_NOTIFY, sent|id|custdraw, 0, 0, NM_CUSTOMDRAW, CDDS_PREPAINT }, 352*c2c66affSColin Finck { WM_NOTIFY, sent|id|custdraw, 0, 0, NM_CUSTOMDRAW, CDDS_ITEMPREPAINT }, 353*c2c66affSColin Finck { WM_NOTIFY, sent|id|custdraw, 0, 0, NM_CUSTOMDRAW, CDDS_ITEMPOSTPAINT }, 354*c2c66affSColin Finck { WM_NOTIFY, sent|id|custdraw, 0, 0, NM_CUSTOMDRAW, CDDS_ITEMPREPAINT }, 355*c2c66affSColin Finck { WM_NOTIFY, sent|id|custdraw, 0, 0, NM_CUSTOMDRAW, CDDS_ITEMPOSTPAINT }, 356*c2c66affSColin Finck { WM_NOTIFY, sent|id|custdraw, 0, 0, NM_CUSTOMDRAW, CDDS_POSTPAINT }, 357*c2c66affSColin Finck { 0 } 358*c2c66affSColin Finck }; 359*c2c66affSColin Finck 360*c2c66affSColin Finck static const struct message parent_vk_return_seq[] = { 361*c2c66affSColin Finck { WM_NOTIFY, sent|id, 0, 0, TVN_KEYDOWN }, 362*c2c66affSColin Finck { WM_NOTIFY, sent|id, 0, 0, NM_RETURN }, 363*c2c66affSColin Finck { WM_CHANGEUISTATE, sent|optional }, 364*c2c66affSColin Finck { 0 } 365*c2c66affSColin Finck }; 366*c2c66affSColin Finck 367*c2c66affSColin Finck static const struct message parent_right_click_seq[] = { 368*c2c66affSColin Finck { WM_NOTIFY, sent|id, 0, 0, NM_RCLICK }, 369*c2c66affSColin Finck { WM_CONTEXTMENU, sent }, 370*c2c66affSColin Finck { 0 } 371*c2c66affSColin Finck }; 372*c2c66affSColin Finck 373*c2c66affSColin Finck static HWND hMainWnd; 374*c2c66affSColin Finck 375*c2c66affSColin Finck static HTREEITEM hRoot, hChild; 376*c2c66affSColin Finck 377*c2c66affSColin Finck static int pos = 0; 378*c2c66affSColin Finck static char sequence[256]; 379*c2c66affSColin Finck 380*c2c66affSColin Finck static void Clear(void) 381*c2c66affSColin Finck { 382*c2c66affSColin Finck pos = 0; 383*c2c66affSColin Finck sequence[0] = '\0'; 384*c2c66affSColin Finck } 385*c2c66affSColin Finck 386*c2c66affSColin Finck static void AddItem(char ch) 387*c2c66affSColin Finck { 388*c2c66affSColin Finck sequence[pos++] = ch; 389*c2c66affSColin Finck sequence[pos] = '\0'; 390*c2c66affSColin Finck } 391*c2c66affSColin Finck 392*c2c66affSColin Finck static void IdentifyItem(HTREEITEM hItem) 393*c2c66affSColin Finck { 394*c2c66affSColin Finck if (hItem == hRoot) { 395*c2c66affSColin Finck AddItem('R'); 396*c2c66affSColin Finck return; 397*c2c66affSColin Finck } 398*c2c66affSColin Finck if (hItem == hChild) { 399*c2c66affSColin Finck AddItem('C'); 400*c2c66affSColin Finck return; 401*c2c66affSColin Finck } 402*c2c66affSColin Finck if (hItem == NULL) { 403*c2c66affSColin Finck AddItem('n'); 404*c2c66affSColin Finck return; 405*c2c66affSColin Finck } 406*c2c66affSColin Finck AddItem('?'); 407*c2c66affSColin Finck } 408*c2c66affSColin Finck 409*c2c66affSColin Finck /* This function hooks in and records all messages to the treeview control */ 410*c2c66affSColin Finck static LRESULT WINAPI TreeviewWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) 411*c2c66affSColin Finck { 412*c2c66affSColin Finck static LONG defwndproc_counter = 0; 413*c2c66affSColin Finck LRESULT ret; 414*c2c66affSColin Finck WNDPROC lpOldProc = (WNDPROC)GetWindowLongPtrA(hwnd, GWLP_USERDATA); 415*c2c66affSColin Finck struct message msg = { 0 }; 416*c2c66affSColin Finck 417*c2c66affSColin Finck msg.message = message; 418*c2c66affSColin Finck msg.flags = sent|wparam|lparam; 419*c2c66affSColin Finck if (defwndproc_counter) msg.flags |= defwinproc; 420*c2c66affSColin Finck msg.wParam = wParam; 421*c2c66affSColin Finck msg.lParam = lParam; 422*c2c66affSColin Finck add_message(sequences, TREEVIEW_SEQ_INDEX, &msg); 423*c2c66affSColin Finck 424*c2c66affSColin Finck defwndproc_counter++; 425*c2c66affSColin Finck ret = CallWindowProcA(lpOldProc, hwnd, message, wParam, lParam); 426*c2c66affSColin Finck defwndproc_counter--; 427*c2c66affSColin Finck 428*c2c66affSColin Finck return ret; 429*c2c66affSColin Finck } 430*c2c66affSColin Finck 431*c2c66affSColin Finck static HWND create_treeview_control(DWORD style) 432*c2c66affSColin Finck { 433*c2c66affSColin Finck WNDPROC pOldWndProc; 434*c2c66affSColin Finck HWND hTree; 435*c2c66affSColin Finck 436*c2c66affSColin Finck hTree = CreateWindowExA(WS_EX_CLIENTEDGE, WC_TREEVIEWA, NULL, WS_CHILD|WS_VISIBLE| 437*c2c66affSColin Finck TVS_LINESATROOT|TVS_HASLINES|TVS_HASBUTTONS|TVS_EDITLABELS|style, 438*c2c66affSColin Finck 0, 0, 120, 100, hMainWnd, (HMENU)100, GetModuleHandleA(0), 0); 439*c2c66affSColin Finck 440*c2c66affSColin Finck SetFocus(hTree); 441*c2c66affSColin Finck 442*c2c66affSColin Finck /* Record the old WNDPROC so we can call it after recording the messages */ 443*c2c66affSColin Finck pOldWndProc = (WNDPROC)SetWindowLongPtrA(hTree, GWLP_WNDPROC, (LONG_PTR)TreeviewWndProc); 444*c2c66affSColin Finck SetWindowLongPtrA(hTree, GWLP_USERDATA, (LONG_PTR)pOldWndProc); 445*c2c66affSColin Finck 446*c2c66affSColin Finck return hTree; 447*c2c66affSColin Finck } 448*c2c66affSColin Finck 449*c2c66affSColin Finck static void fill_tree(HWND hTree) 450*c2c66affSColin Finck { 451*c2c66affSColin Finck TVINSERTSTRUCTA ins; 452*c2c66affSColin Finck static CHAR root[] = "Root", 453*c2c66affSColin Finck child[] = "Child"; 454*c2c66affSColin Finck 455*c2c66affSColin Finck ins.hParent = TVI_ROOT; 456*c2c66affSColin Finck ins.hInsertAfter = TVI_ROOT; 457*c2c66affSColin Finck U(ins).item.mask = TVIF_TEXT; 458*c2c66affSColin Finck U(ins).item.pszText = root; 459*c2c66affSColin Finck hRoot = TreeView_InsertItemA(hTree, &ins); 460*c2c66affSColin Finck 461*c2c66affSColin Finck ins.hParent = hRoot; 462*c2c66affSColin Finck ins.hInsertAfter = TVI_FIRST; 463*c2c66affSColin Finck U(ins).item.mask = TVIF_TEXT; 464*c2c66affSColin Finck U(ins).item.pszText = child; 465*c2c66affSColin Finck hChild = TreeView_InsertItemA(hTree, &ins); 466*c2c66affSColin Finck } 467*c2c66affSColin Finck 468*c2c66affSColin Finck static void test_fillroot(void) 469*c2c66affSColin Finck { 470*c2c66affSColin Finck TVITEMA tvi; 471*c2c66affSColin Finck HWND hTree; 472*c2c66affSColin Finck 473*c2c66affSColin Finck hTree = create_treeview_control(0); 474*c2c66affSColin Finck 475*c2c66affSColin Finck flush_sequences(sequences, NUM_MSG_SEQUENCES); 476*c2c66affSColin Finck 477*c2c66affSColin Finck fill_tree(hTree); 478*c2c66affSColin Finck 479*c2c66affSColin Finck Clear(); 480*c2c66affSColin Finck AddItem('A'); 481*c2c66affSColin Finck ok(hRoot != NULL, "failed to set root\n"); 482*c2c66affSColin Finck AddItem('B'); 483*c2c66affSColin Finck ok(hChild != NULL, "failed to set child\n"); 484*c2c66affSColin Finck AddItem('.'); 485*c2c66affSColin Finck ok_sequence(sequences, TREEVIEW_SEQ_INDEX, FillRootSeq, "FillRoot", FALSE); 486*c2c66affSColin Finck ok(!strcmp(sequence, "AB."), "Item creation\n"); 487*c2c66affSColin Finck 488*c2c66affSColin Finck /* UMLPad 1.15 depends on this being not -1 (I_IMAGECALLBACK) */ 489*c2c66affSColin Finck tvi.hItem = hRoot; 490*c2c66affSColin Finck tvi.mask = TVIF_IMAGE | TVIF_SELECTEDIMAGE; 491*c2c66affSColin Finck SendMessageA(hTree, TVM_GETITEMA, 0, (LPARAM)&tvi); 492*c2c66affSColin Finck ok(tvi.iImage == 0, "tvi.iImage=%d\n", tvi.iImage); 493*c2c66affSColin Finck ok(tvi.iSelectedImage == 0, "tvi.iSelectedImage=%d\n", tvi.iSelectedImage); 494*c2c66affSColin Finck 495*c2c66affSColin Finck DestroyWindow(hTree); 496*c2c66affSColin Finck } 497*c2c66affSColin Finck 498*c2c66affSColin Finck static void test_callback(void) 499*c2c66affSColin Finck { 500*c2c66affSColin Finck HTREEITEM hRoot; 501*c2c66affSColin Finck HTREEITEM hItem1, hItem2; 502*c2c66affSColin Finck TVINSERTSTRUCTA ins; 503*c2c66affSColin Finck TVITEMA tvi; 504*c2c66affSColin Finck CHAR test_string[] = "Test_string"; 505*c2c66affSColin Finck static const CHAR test2A[] = "TEST2"; 506*c2c66affSColin Finck CHAR buf[128]; 507*c2c66affSColin Finck HWND hTree; 508*c2c66affSColin Finck DWORD ret; 509*c2c66affSColin Finck 510*c2c66affSColin Finck hTree = create_treeview_control(0); 511*c2c66affSColin Finck 512*c2c66affSColin Finck ret = SendMessageA(hTree, TVM_DELETEITEM, 0, (LPARAM)TVI_ROOT); 513*c2c66affSColin Finck expect(TRUE, ret); 514*c2c66affSColin Finck ins.hParent = TVI_ROOT; 515*c2c66affSColin Finck ins.hInsertAfter = TVI_ROOT; 516*c2c66affSColin Finck U(ins).item.mask = TVIF_TEXT; 517*c2c66affSColin Finck U(ins).item.pszText = LPSTR_TEXTCALLBACKA; 518*c2c66affSColin Finck hRoot = TreeView_InsertItemA(hTree, &ins); 519*c2c66affSColin Finck ok(hRoot != NULL, "failed to set root\n"); 520*c2c66affSColin Finck 521*c2c66affSColin Finck tvi.hItem = hRoot; 522*c2c66affSColin Finck tvi.mask = TVIF_TEXT; 523*c2c66affSColin Finck tvi.pszText = buf; 524*c2c66affSColin Finck tvi.cchTextMax = sizeof(buf)/sizeof(buf[0]); 525*c2c66affSColin Finck ret = TreeView_GetItemA(hTree, &tvi); 526*c2c66affSColin Finck expect(TRUE, ret); 527*c2c66affSColin Finck ok(strcmp(tvi.pszText, TEST_CALLBACK_TEXT) == 0, "Callback item text mismatch %s vs %s\n", 528*c2c66affSColin Finck tvi.pszText, TEST_CALLBACK_TEXT); 529*c2c66affSColin Finck 530*c2c66affSColin Finck ins.hParent = hRoot; 531*c2c66affSColin Finck ins.hInsertAfter = TVI_FIRST; 532*c2c66affSColin Finck U(ins).item.mask = TVIF_TEXT; 533*c2c66affSColin Finck U(ins).item.pszText = test_string; 534*c2c66affSColin Finck hItem1 = TreeView_InsertItemA(hTree, &ins); 535*c2c66affSColin Finck ok(hItem1 != NULL, "failed to set Item1\n"); 536*c2c66affSColin Finck 537*c2c66affSColin Finck tvi.hItem = hItem1; 538*c2c66affSColin Finck ret = TreeView_GetItemA(hTree, &tvi); 539*c2c66affSColin Finck expect(TRUE, ret); 540*c2c66affSColin Finck ok(strcmp(tvi.pszText, test_string) == 0, "Item text mismatch %s vs %s\n", 541*c2c66affSColin Finck tvi.pszText, test_string); 542*c2c66affSColin Finck 543*c2c66affSColin Finck /* undocumented: pszText of NULL also means LPSTR_CALLBACK: */ 544*c2c66affSColin Finck tvi.pszText = NULL; 545*c2c66affSColin Finck ret = TreeView_SetItemA(hTree, &tvi); 546*c2c66affSColin Finck expect(TRUE, ret); 547*c2c66affSColin Finck tvi.pszText = buf; 548*c2c66affSColin Finck ret = TreeView_GetItemA(hTree, &tvi); 549*c2c66affSColin Finck expect(TRUE, ret); 550*c2c66affSColin Finck ok(strcmp(tvi.pszText, TEST_CALLBACK_TEXT) == 0, "Item text mismatch %s vs %s\n", 551*c2c66affSColin Finck tvi.pszText, TEST_CALLBACK_TEXT); 552*c2c66affSColin Finck 553*c2c66affSColin Finck U(ins).item.pszText = NULL; 554*c2c66affSColin Finck hItem2 = TreeView_InsertItemA(hTree, &ins); 555*c2c66affSColin Finck ok(hItem2 != NULL, "failed to set Item2\n"); 556*c2c66affSColin Finck tvi.hItem = hItem2; 557*c2c66affSColin Finck memset(buf, 0, sizeof(buf)); 558*c2c66affSColin Finck ret = TreeView_GetItemA(hTree, &tvi); 559*c2c66affSColin Finck expect(TRUE, ret); 560*c2c66affSColin Finck ok(strcmp(tvi.pszText, TEST_CALLBACK_TEXT) == 0, "Item text mismatch %s vs %s\n", 561*c2c66affSColin Finck tvi.pszText, TEST_CALLBACK_TEXT); 562*c2c66affSColin Finck 563*c2c66affSColin Finck /* notification handler changed A->W */ 564*c2c66affSColin Finck g_disp_A_to_W = TRUE; 565*c2c66affSColin Finck tvi.hItem = hItem2; 566*c2c66affSColin Finck memset(buf, 0, sizeof(buf)); 567*c2c66affSColin Finck ret = TreeView_GetItemA(hTree, &tvi); 568*c2c66affSColin Finck expect(TRUE, ret); 569*c2c66affSColin Finck ok(strcmp(tvi.pszText, test2A) == 0, "got %s, expected %s\n", 570*c2c66affSColin Finck tvi.pszText, test2A); 571*c2c66affSColin Finck g_disp_A_to_W = FALSE; 572*c2c66affSColin Finck 573*c2c66affSColin Finck /* handler changes state image index */ 574*c2c66affSColin Finck SetWindowLongA(hTree, GWL_STYLE, GetWindowLongA(hTree, GWL_STYLE) | TVS_CHECKBOXES); 575*c2c66affSColin Finck 576*c2c66affSColin Finck /* clear selection, handler will set selected state */ 577*c2c66affSColin Finck ret = SendMessageA(hTree, TVM_SELECTITEM, TVGN_CARET, 0); 578*c2c66affSColin Finck expect(TRUE, ret); 579*c2c66affSColin Finck 580*c2c66affSColin Finck flush_sequences(sequences, NUM_MSG_SEQUENCES); 581*c2c66affSColin Finck 582*c2c66affSColin Finck tvi.hItem = hRoot; 583*c2c66affSColin Finck tvi.mask = TVIF_STATE; 584*c2c66affSColin Finck tvi.state = TVIS_SELECTED; 585*c2c66affSColin Finck ret = TreeView_GetItemA(hTree, &tvi); 586*c2c66affSColin Finck expect(TRUE, ret); 587*c2c66affSColin Finck ok(tvi.state == INDEXTOSTATEIMAGEMASK(1), "got 0x%x\n", tvi.state); 588*c2c66affSColin Finck 589*c2c66affSColin Finck ok_sequence(sequences, PARENT_SEQ_INDEX, empty_seq, 590*c2c66affSColin Finck "no TVN_GETDISPINFO for a state seq", FALSE); 591*c2c66affSColin Finck 592*c2c66affSColin Finck tvi.hItem = hRoot; 593*c2c66affSColin Finck tvi.mask = TVIF_IMAGE | TVIF_STATE; 594*c2c66affSColin Finck tvi.state = TVIS_FOCUSED; 595*c2c66affSColin Finck tvi.stateMask = TVIS_FOCUSED; 596*c2c66affSColin Finck tvi.iImage = I_IMAGECALLBACK; 597*c2c66affSColin Finck ret = TreeView_SetItemA(hTree, &tvi); 598*c2c66affSColin Finck expect(TRUE, ret); 599*c2c66affSColin Finck 600*c2c66affSColin Finck /* ask for item image index through callback - state is also set with state image index */ 601*c2c66affSColin Finck flush_sequences(sequences, NUM_MSG_SEQUENCES); 602*c2c66affSColin Finck 603*c2c66affSColin Finck tvi.hItem = hRoot; 604*c2c66affSColin Finck tvi.mask = TVIF_IMAGE; 605*c2c66affSColin Finck tvi.state = 0; 606*c2c66affSColin Finck ret = TreeView_GetItemA(hTree, &tvi); 607*c2c66affSColin Finck expect(TRUE, ret); 608*c2c66affSColin Finck ok(tvi.state == (INDEXTOSTATEIMAGEMASK(1) | TVIS_FOCUSED), "got 0x%x\n", tvi.state); 609*c2c66affSColin Finck 610*c2c66affSColin Finck ok_sequence(sequences, PARENT_SEQ_INDEX, parent_get_dispinfo_seq, 611*c2c66affSColin Finck "callback for state/overlay image index, noop seq", FALSE); 612*c2c66affSColin Finck 613*c2c66affSColin Finck /* ask for image again and overwrite state to some value in handler */ 614*c2c66affSColin Finck flush_sequences(sequences, NUM_MSG_SEQUENCES); 615*c2c66affSColin Finck 616*c2c66affSColin Finck g_disp_set_stateimage = TRUE; 617*c2c66affSColin Finck tvi.hItem = hRoot; 618*c2c66affSColin Finck tvi.mask = TVIF_IMAGE; 619*c2c66affSColin Finck tvi.state = INDEXTOSTATEIMAGEMASK(1); 620*c2c66affSColin Finck tvi.stateMask = 0; 621*c2c66affSColin Finck ret = TreeView_GetItemA(hTree, &tvi); 622*c2c66affSColin Finck expect(TRUE, ret); 623*c2c66affSColin Finck /* handler sets TVIS_SELECTED as well */ 624*c2c66affSColin Finck ok(tvi.state == (TVIS_FOCUSED | TVIS_SELECTED | INDEXTOSTATEIMAGEMASK(2) | INDEXTOOVERLAYMASK(3)), "got 0x%x\n", tvi.state); 625*c2c66affSColin Finck g_disp_set_stateimage = FALSE; 626*c2c66affSColin Finck 627*c2c66affSColin Finck ok_sequence(sequences, PARENT_SEQ_INDEX, parent_get_dispinfo_seq, 628*c2c66affSColin Finck "callback for state/overlay image index seq", FALSE); 629*c2c66affSColin Finck 630*c2c66affSColin Finck DestroyWindow(hTree); 631*c2c66affSColin Finck } 632*c2c66affSColin Finck 633*c2c66affSColin Finck static void test_select(void) 634*c2c66affSColin Finck { 635*c2c66affSColin Finck BOOL r; 636*c2c66affSColin Finck HWND hTree; 637*c2c66affSColin Finck 638*c2c66affSColin Finck hTree = create_treeview_control(0); 639*c2c66affSColin Finck fill_tree(hTree); 640*c2c66affSColin Finck 641*c2c66affSColin Finck /* root-none select tests */ 642*c2c66affSColin Finck flush_sequences(sequences, NUM_MSG_SEQUENCES); 643*c2c66affSColin Finck r = SendMessageA(hTree, TVM_SELECTITEM, TVGN_CARET, 0); 644*c2c66affSColin Finck expect(TRUE, r); 645*c2c66affSColin Finck Clear(); 646*c2c66affSColin Finck AddItem('1'); 647*c2c66affSColin Finck r = SendMessageA(hTree, TVM_SELECTITEM, TVGN_CARET, (LPARAM)hRoot); 648*c2c66affSColin Finck expect(TRUE, r); 649*c2c66affSColin Finck AddItem('2'); 650*c2c66affSColin Finck r = SendMessageA(hTree, TVM_SELECTITEM, TVGN_CARET, (LPARAM)hRoot); 651*c2c66affSColin Finck expect(TRUE, r); 652*c2c66affSColin Finck AddItem('3'); 653*c2c66affSColin Finck r = SendMessageA(hTree, TVM_SELECTITEM, TVGN_CARET, 0); 654*c2c66affSColin Finck expect(TRUE, r); 655*c2c66affSColin Finck AddItem('4'); 656*c2c66affSColin Finck r = SendMessageA(hTree, TVM_SELECTITEM, TVGN_CARET, 0); 657*c2c66affSColin Finck expect(TRUE, r); 658*c2c66affSColin Finck AddItem('5'); 659*c2c66affSColin Finck r = SendMessageA(hTree, TVM_SELECTITEM, TVGN_CARET, (LPARAM)hRoot); 660*c2c66affSColin Finck expect(TRUE, r); 661*c2c66affSColin Finck AddItem('.'); 662*c2c66affSColin Finck ok(!strcmp(sequence, "1(nR)nR23(Rn)Rn45(nR)nR."), "root-none select test\n"); 663*c2c66affSColin Finck ok_sequence(sequences, TREEVIEW_SEQ_INDEX, rootnone_select_seq, 664*c2c66affSColin Finck "root-none select seq", FALSE); 665*c2c66affSColin Finck 666*c2c66affSColin Finck /* root-child select tests */ 667*c2c66affSColin Finck flush_sequences(sequences, NUM_MSG_SEQUENCES); 668*c2c66affSColin Finck r = SendMessageA(hTree, TVM_SELECTITEM, TVGN_CARET, 0); 669*c2c66affSColin Finck expect(TRUE, r); 670*c2c66affSColin Finck 671*c2c66affSColin Finck Clear(); 672*c2c66affSColin Finck AddItem('1'); 673*c2c66affSColin Finck r = SendMessageA(hTree, TVM_SELECTITEM, TVGN_CARET, (LPARAM)hRoot); 674*c2c66affSColin Finck expect(TRUE, r); 675*c2c66affSColin Finck AddItem('2'); 676*c2c66affSColin Finck r = SendMessageA(hTree, TVM_SELECTITEM, TVGN_CARET, (LPARAM)hRoot); 677*c2c66affSColin Finck expect(TRUE, r); 678*c2c66affSColin Finck AddItem('3'); 679*c2c66affSColin Finck r = SendMessageA(hTree, TVM_SELECTITEM, TVGN_CARET, (LPARAM)hChild); 680*c2c66affSColin Finck expect(TRUE, r); 681*c2c66affSColin Finck AddItem('4'); 682*c2c66affSColin Finck r = SendMessageA(hTree, TVM_SELECTITEM, TVGN_CARET, (LPARAM)hChild); 683*c2c66affSColin Finck expect(TRUE, r); 684*c2c66affSColin Finck AddItem('5'); 685*c2c66affSColin Finck r = SendMessageA(hTree, TVM_SELECTITEM, TVGN_CARET, (LPARAM)hRoot); 686*c2c66affSColin Finck expect(TRUE, r); 687*c2c66affSColin Finck AddItem('.'); 688*c2c66affSColin Finck ok(!strcmp(sequence, "1(nR)nR23(RC)RC45(CR)CR."), "root-child select test\n"); 689*c2c66affSColin Finck ok_sequence(sequences, TREEVIEW_SEQ_INDEX, rootchild_select_seq, 690*c2c66affSColin Finck "root-child select seq", FALSE); 691*c2c66affSColin Finck 692*c2c66affSColin Finck DestroyWindow(hTree); 693*c2c66affSColin Finck } 694*c2c66affSColin Finck 695*c2c66affSColin Finck static void test_getitemtext(void) 696*c2c66affSColin Finck { 697*c2c66affSColin Finck TVINSERTSTRUCTA ins; 698*c2c66affSColin Finck HTREEITEM hChild; 699*c2c66affSColin Finck TVITEMA tvi; 700*c2c66affSColin Finck HWND hTree; 701*c2c66affSColin Finck 702*c2c66affSColin Finck CHAR szBuffer[80] = "Blah"; 703*c2c66affSColin Finck int nBufferSize = sizeof(szBuffer)/sizeof(CHAR); 704*c2c66affSColin Finck 705*c2c66affSColin Finck hTree = create_treeview_control(0); 706*c2c66affSColin Finck fill_tree(hTree); 707*c2c66affSColin Finck 708*c2c66affSColin Finck flush_sequences(sequences, NUM_MSG_SEQUENCES); 709*c2c66affSColin Finck 710*c2c66affSColin Finck /* add an item without TVIF_TEXT mask and pszText == NULL */ 711*c2c66affSColin Finck ins.hParent = hRoot; 712*c2c66affSColin Finck ins.hInsertAfter = TVI_ROOT; 713*c2c66affSColin Finck U(ins).item.mask = 0; 714*c2c66affSColin Finck U(ins).item.pszText = NULL; 715*c2c66affSColin Finck U(ins).item.cchTextMax = 0; 716*c2c66affSColin Finck hChild = TreeView_InsertItemA(hTree, &ins); 717*c2c66affSColin Finck ok(hChild != NULL, "failed to set hChild\n"); 718*c2c66affSColin Finck 719*c2c66affSColin Finck /* retrieve it with TVIF_TEXT mask */ 720*c2c66affSColin Finck tvi.hItem = hChild; 721*c2c66affSColin Finck tvi.mask = TVIF_TEXT; 722*c2c66affSColin Finck tvi.cchTextMax = nBufferSize; 723*c2c66affSColin Finck tvi.pszText = szBuffer; 724*c2c66affSColin Finck 725*c2c66affSColin Finck SendMessageA( hTree, TVM_GETITEMA, 0, (LPARAM)&tvi ); 726*c2c66affSColin Finck ok(!strcmp(szBuffer, ""), "szBuffer=\"%s\", expected \"\"\n", szBuffer); 727*c2c66affSColin Finck ok(SendMessageA(hTree, TVM_DELETEITEM, 0, (LPARAM)hChild), "DeleteItem failed\n"); 728*c2c66affSColin Finck ok_sequence(sequences, TREEVIEW_SEQ_INDEX, getitemtext_seq, "get item text seq", FALSE); 729*c2c66affSColin Finck 730*c2c66affSColin Finck DestroyWindow(hTree); 731*c2c66affSColin Finck } 732*c2c66affSColin Finck 733*c2c66affSColin Finck static void test_focus(void) 734*c2c66affSColin Finck { 735*c2c66affSColin Finck TVINSERTSTRUCTA ins; 736*c2c66affSColin Finck static CHAR child1[] = "Edit", 737*c2c66affSColin Finck child2[] = "A really long string"; 738*c2c66affSColin Finck HTREEITEM hChild1, hChild2; 739*c2c66affSColin Finck HWND hTree; 740*c2c66affSColin Finck HWND hEdit; 741*c2c66affSColin Finck 742*c2c66affSColin Finck hTree = create_treeview_control(0); 743*c2c66affSColin Finck fill_tree(hTree); 744*c2c66affSColin Finck 745*c2c66affSColin Finck flush_sequences(sequences, NUM_MSG_SEQUENCES); 746*c2c66affSColin Finck 747*c2c66affSColin Finck /* This test verifies that when a label is being edited, scrolling 748*c2c66affSColin Finck * the treeview does not cause the label to lose focus. To test 749*c2c66affSColin Finck * this, first some additional entries are added to generate 750*c2c66affSColin Finck * scrollbars. 751*c2c66affSColin Finck */ 752*c2c66affSColin Finck ins.hParent = hRoot; 753*c2c66affSColin Finck ins.hInsertAfter = hChild; 754*c2c66affSColin Finck U(ins).item.mask = TVIF_TEXT; 755*c2c66affSColin Finck U(ins).item.pszText = child1; 756*c2c66affSColin Finck hChild1 = TreeView_InsertItemA(hTree, &ins); 757*c2c66affSColin Finck ok(hChild1 != NULL, "failed to set hChild1\n"); 758*c2c66affSColin Finck ins.hInsertAfter = hChild1; 759*c2c66affSColin Finck U(ins).item.mask = TVIF_TEXT; 760*c2c66affSColin Finck U(ins).item.pszText = child2; 761*c2c66affSColin Finck hChild2 = TreeView_InsertItemA(hTree, &ins); 762*c2c66affSColin Finck ok(hChild2 != NULL, "failed to set hChild2\n"); 763*c2c66affSColin Finck 764*c2c66affSColin Finck ShowWindow(hMainWnd,SW_SHOW); 765*c2c66affSColin Finck SendMessageA(hTree, TVM_SELECTITEM, TVGN_CARET, (LPARAM)hChild); 766*c2c66affSColin Finck hEdit = (HWND)SendMessageA(hTree, TVM_EDITLABELA, 0, (LPARAM)hChild); 767*c2c66affSColin Finck ScrollWindowEx(hTree, -10, 0, NULL, NULL, NULL, NULL, SW_SCROLLCHILDREN); 768*c2c66affSColin Finck ok(GetFocus() == hEdit, "Edit control should have focus\n"); 769*c2c66affSColin Finck ok_sequence(sequences, TREEVIEW_SEQ_INDEX, focus_seq, "focus test", TRUE); 770*c2c66affSColin Finck 771*c2c66affSColin Finck DestroyWindow(hTree); 772*c2c66affSColin Finck } 773*c2c66affSColin Finck 774*c2c66affSColin Finck static void test_get_set_bkcolor(void) 775*c2c66affSColin Finck { 776*c2c66affSColin Finck COLORREF crColor; 777*c2c66affSColin Finck HWND hTree; 778*c2c66affSColin Finck 779*c2c66affSColin Finck hTree = create_treeview_control(0); 780*c2c66affSColin Finck fill_tree(hTree); 781*c2c66affSColin Finck 782*c2c66affSColin Finck flush_sequences(sequences, NUM_MSG_SEQUENCES); 783*c2c66affSColin Finck 784*c2c66affSColin Finck /* If the value is -1, the control is using the system color for the background color. */ 785*c2c66affSColin Finck crColor = SendMessageA(hTree, TVM_GETBKCOLOR, 0, 0); 786*c2c66affSColin Finck ok(crColor == ~0u, "Default background color reported as 0x%.8x\n", crColor); 787*c2c66affSColin Finck 788*c2c66affSColin Finck /* Test for black background */ 789*c2c66affSColin Finck SendMessageA(hTree, TVM_SETBKCOLOR, 0, RGB(0,0,0)); 790*c2c66affSColin Finck crColor = SendMessageA(hTree, TVM_GETBKCOLOR, 0, 0); 791*c2c66affSColin Finck ok(crColor == RGB(0,0,0), "Black background color reported as 0x%.8x\n", crColor); 792*c2c66affSColin Finck 793*c2c66affSColin Finck /* Test for white background */ 794*c2c66affSColin Finck SendMessageA(hTree, TVM_SETBKCOLOR, 0, RGB(255,255,255)); 795*c2c66affSColin Finck crColor = SendMessageA(hTree, TVM_GETBKCOLOR, 0, 0); 796*c2c66affSColin Finck ok(crColor == RGB(255,255,255), "White background color reported as 0x%.8x\n", crColor); 797*c2c66affSColin Finck 798*c2c66affSColin Finck /* Reset the default background */ 799*c2c66affSColin Finck SendMessageA(hTree, TVM_SETBKCOLOR, 0, -1); 800*c2c66affSColin Finck 801*c2c66affSColin Finck ok_sequence(sequences, TREEVIEW_SEQ_INDEX, test_get_set_bkcolor_seq, 802*c2c66affSColin Finck "test get set bkcolor", FALSE); 803*c2c66affSColin Finck 804*c2c66affSColin Finck DestroyWindow(hTree); 805*c2c66affSColin Finck } 806*c2c66affSColin Finck 807*c2c66affSColin Finck static void test_get_set_imagelist(void) 808*c2c66affSColin Finck { 809*c2c66affSColin Finck HIMAGELIST himl; 810*c2c66affSColin Finck HWND hTree; 811*c2c66affSColin Finck 812*c2c66affSColin Finck hTree = create_treeview_control(0); 813*c2c66affSColin Finck fill_tree(hTree); 814*c2c66affSColin Finck 815*c2c66affSColin Finck flush_sequences(sequences, NUM_MSG_SEQUENCES); 816*c2c66affSColin Finck 817*c2c66affSColin Finck /* Test a NULL HIMAGELIST */ 818*c2c66affSColin Finck SendMessageA(hTree, TVM_SETIMAGELIST, TVSIL_NORMAL, 0); 819*c2c66affSColin Finck himl = (HIMAGELIST)SendMessageA(hTree, TVM_GETIMAGELIST, TVSIL_NORMAL, 0); 820*c2c66affSColin Finck ok(himl == NULL, "NULL image list, reported as %p, expected 0.\n", himl); 821*c2c66affSColin Finck 822*c2c66affSColin Finck /* TODO: Test an actual image list */ 823*c2c66affSColin Finck 824*c2c66affSColin Finck ok_sequence(sequences, TREEVIEW_SEQ_INDEX, test_get_set_imagelist_seq, 825*c2c66affSColin Finck "test get imagelist", FALSE); 826*c2c66affSColin Finck 827*c2c66affSColin Finck DestroyWindow(hTree); 828*c2c66affSColin Finck } 829*c2c66affSColin Finck 830*c2c66affSColin Finck static void test_get_set_indent(void) 831*c2c66affSColin Finck { 832*c2c66affSColin Finck int ulIndent; 833*c2c66affSColin Finck int ulMinIndent; 834*c2c66affSColin Finck int ulMoreThanTwiceMin; 835*c2c66affSColin Finck HWND hTree; 836*c2c66affSColin Finck 837*c2c66affSColin Finck hTree = create_treeview_control(0); 838*c2c66affSColin Finck fill_tree(hTree); 839*c2c66affSColin Finck 840*c2c66affSColin Finck flush_sequences(sequences, NUM_MSG_SEQUENCES); 841*c2c66affSColin Finck 842*c2c66affSColin Finck /* Finding the minimum indent */ 843*c2c66affSColin Finck SendMessageA(hTree, TVM_SETINDENT, 0, 0); 844*c2c66affSColin Finck ulMinIndent = SendMessageA(hTree, TVM_GETINDENT, 0, 0); 845*c2c66affSColin Finck 846*c2c66affSColin Finck /* Checking an indent that is more than twice the default indent */ 847*c2c66affSColin Finck ulMoreThanTwiceMin = 2*ulMinIndent+1; 848*c2c66affSColin Finck SendMessageA(hTree, TVM_SETINDENT, ulMoreThanTwiceMin, 0); 849*c2c66affSColin Finck ulIndent = SendMessageA(hTree, TVM_GETINDENT, 0, 0); 850*c2c66affSColin Finck ok(ulIndent == ulMoreThanTwiceMin, "Indent reported as %d, expected %d\n", ulIndent, ulMoreThanTwiceMin); 851*c2c66affSColin Finck 852*c2c66affSColin Finck ok_sequence(sequences, TREEVIEW_SEQ_INDEX, test_get_set_indent_seq, 853*c2c66affSColin Finck "test get set indent", FALSE); 854*c2c66affSColin Finck 855*c2c66affSColin Finck DestroyWindow(hTree); 856*c2c66affSColin Finck } 857*c2c66affSColin Finck 858*c2c66affSColin Finck static void test_get_set_insertmark(void) 859*c2c66affSColin Finck { 860*c2c66affSColin Finck COLORREF crColor = RGB(0,0,0); 861*c2c66affSColin Finck HWND hTree; 862*c2c66affSColin Finck 863*c2c66affSColin Finck hTree = create_treeview_control(0); 864*c2c66affSColin Finck fill_tree(hTree); 865*c2c66affSColin Finck 866*c2c66affSColin Finck flush_sequences(sequences, NUM_MSG_SEQUENCES); 867*c2c66affSColin Finck 868*c2c66affSColin Finck SendMessageA(hTree, TVM_SETINSERTMARKCOLOR, 0, crColor); 869*c2c66affSColin Finck crColor = SendMessageA(hTree, TVM_GETINSERTMARKCOLOR, 0, 0); 870*c2c66affSColin Finck ok(crColor == RGB(0,0,0), "Insert mark color reported as 0x%.8x, expected 0x00000000\n", crColor); 871*c2c66affSColin Finck 872*c2c66affSColin Finck ok_sequence(sequences, TREEVIEW_SEQ_INDEX, test_get_set_insertmarkcolor_seq, 873*c2c66affSColin Finck "test get set insertmark color", FALSE); 874*c2c66affSColin Finck 875*c2c66affSColin Finck DestroyWindow(hTree); 876*c2c66affSColin Finck } 877*c2c66affSColin Finck 878*c2c66affSColin Finck static void test_get_set_item(void) 879*c2c66affSColin Finck { 880*c2c66affSColin Finck TVITEMA tviRoot = {0}; 881*c2c66affSColin Finck int nBufferSize = 80; 882*c2c66affSColin Finck char szBuffer[80] = {0}; 883*c2c66affSColin Finck HWND hTree, hTree2; 884*c2c66affSColin Finck DWORD ret; 885*c2c66affSColin Finck 886*c2c66affSColin Finck hTree = create_treeview_control(0); 887*c2c66affSColin Finck fill_tree(hTree); 888*c2c66affSColin Finck 889*c2c66affSColin Finck tviRoot.hItem = hRoot; 890*c2c66affSColin Finck tviRoot.mask = TVIF_STATE; 891*c2c66affSColin Finck tviRoot.state = TVIS_FOCUSED; 892*c2c66affSColin Finck tviRoot.stateMask = TVIS_FOCUSED; 893*c2c66affSColin Finck ret = SendMessageA(hTree, TVM_SETITEMA, 0, (LPARAM)&tviRoot); 894*c2c66affSColin Finck expect(TRUE, ret); 895*c2c66affSColin Finck 896*c2c66affSColin Finck flush_sequences(sequences, NUM_MSG_SEQUENCES); 897*c2c66affSColin Finck 898*c2c66affSColin Finck /* Test the root item, state is set even when not requested */ 899*c2c66affSColin Finck tviRoot.hItem = hRoot; 900*c2c66affSColin Finck tviRoot.mask = TVIF_TEXT; 901*c2c66affSColin Finck tviRoot.state = 0; 902*c2c66affSColin Finck tviRoot.stateMask = 0; 903*c2c66affSColin Finck tviRoot.cchTextMax = nBufferSize; 904*c2c66affSColin Finck tviRoot.pszText = szBuffer; 905*c2c66affSColin Finck ret = SendMessageA(hTree, TVM_GETITEMA, 0, (LPARAM)&tviRoot); 906*c2c66affSColin Finck expect(TRUE, ret); 907*c2c66affSColin Finck ok(!strcmp("Root", szBuffer), "GetItem: szBuffer=\"%s\", expected \"Root\"\n", szBuffer); 908*c2c66affSColin Finck ok(tviRoot.state == TVIS_FOCUSED, "got 0x%0x\n", tviRoot.state); 909*c2c66affSColin Finck 910*c2c66affSColin Finck /* Change the root text */ 911*c2c66affSColin Finck lstrcpynA(szBuffer, "Testing123", nBufferSize); 912*c2c66affSColin Finck ret = SendMessageA(hTree, TVM_SETITEMA, 0, (LPARAM)&tviRoot); 913*c2c66affSColin Finck expect(TRUE, ret); 914*c2c66affSColin Finck memset(szBuffer, 0, nBufferSize); 915*c2c66affSColin Finck ret = SendMessageA(hTree, TVM_GETITEMA, 0, (LPARAM)&tviRoot); 916*c2c66affSColin Finck expect(TRUE, ret); 917*c2c66affSColin Finck ok(!strcmp("Testing123", szBuffer), "GetItem: szBuffer=\"%s\", expected \"Testing123\"\n", szBuffer); 918*c2c66affSColin Finck 919*c2c66affSColin Finck /* Reset the root text */ 920*c2c66affSColin Finck memset(szBuffer, 0, nBufferSize); 921*c2c66affSColin Finck lstrcpynA(szBuffer, "Root", nBufferSize); 922*c2c66affSColin Finck ret = SendMessageA(hTree, TVM_SETITEMA, 0, (LPARAM)&tviRoot); 923*c2c66affSColin Finck expect(TRUE, ret); 924*c2c66affSColin Finck 925*c2c66affSColin Finck ok_sequence(sequences, TREEVIEW_SEQ_INDEX, test_get_set_item_seq, 926*c2c66affSColin Finck "test get set item", FALSE); 927*c2c66affSColin Finck 928*c2c66affSColin Finck /* get item from a different tree */ 929*c2c66affSColin Finck hTree2 = create_treeview_control(0); 930*c2c66affSColin Finck 931*c2c66affSColin Finck tviRoot.hItem = hRoot; 932*c2c66affSColin Finck tviRoot.mask = TVIF_STATE; 933*c2c66affSColin Finck tviRoot.state = 0; 934*c2c66affSColin Finck ret = SendMessageA(hTree2, TVM_GETITEMA, 0, (LPARAM)&tviRoot); 935*c2c66affSColin Finck expect(TRUE, ret); 936*c2c66affSColin Finck ok(tviRoot.state == TVIS_FOCUSED, "got state 0x%0x\n", tviRoot.state); 937*c2c66affSColin Finck 938*c2c66affSColin Finck /* invalid item pointer, nt4 crashes here but later versions just return 0 */ 939*c2c66affSColin Finck tviRoot.hItem = (HTREEITEM)0xdeadbeef; 940*c2c66affSColin Finck tviRoot.mask = TVIF_STATE; 941*c2c66affSColin Finck tviRoot.state = 0; 942*c2c66affSColin Finck ret = SendMessageA(hTree2, TVM_GETITEMA, 0, (LPARAM)&tviRoot); 943*c2c66affSColin Finck expect(FALSE, ret); 944*c2c66affSColin Finck 945*c2c66affSColin Finck DestroyWindow(hTree); 946*c2c66affSColin Finck DestroyWindow(hTree2); 947*c2c66affSColin Finck } 948*c2c66affSColin Finck 949*c2c66affSColin Finck static void test_get_set_itemheight(void) 950*c2c66affSColin Finck { 951*c2c66affSColin Finck int ulOldHeight = 0; 952*c2c66affSColin Finck int ulNewHeight = 0; 953*c2c66affSColin Finck HWND hTree; 954*c2c66affSColin Finck 955*c2c66affSColin Finck hTree = create_treeview_control(0); 956*c2c66affSColin Finck fill_tree(hTree); 957*c2c66affSColin Finck 958*c2c66affSColin Finck flush_sequences(sequences, NUM_MSG_SEQUENCES); 959*c2c66affSColin Finck 960*c2c66affSColin Finck /* Assuming default height to begin with */ 961*c2c66affSColin Finck ulOldHeight = SendMessageA(hTree, TVM_GETITEMHEIGHT, 0, 0); 962*c2c66affSColin Finck 963*c2c66affSColin Finck /* Explicitly setting and getting the default height */ 964*c2c66affSColin Finck SendMessageA(hTree, TVM_SETITEMHEIGHT, -1, 0); 965*c2c66affSColin Finck ulNewHeight = SendMessageA(hTree, TVM_GETITEMHEIGHT, 0, 0); 966*c2c66affSColin Finck ok(ulNewHeight == ulOldHeight, "Default height not set properly, reported %d, expected %d\n", ulNewHeight, ulOldHeight); 967*c2c66affSColin Finck 968*c2c66affSColin Finck /* Explicitly setting and getting the height of twice the normal */ 969*c2c66affSColin Finck SendMessageA(hTree, TVM_SETITEMHEIGHT, 2*ulOldHeight, 0); 970*c2c66affSColin Finck ulNewHeight = SendMessageA(hTree, TVM_GETITEMHEIGHT, 0, 0); 971*c2c66affSColin Finck ok(ulNewHeight == 2*ulOldHeight, "New height not set properly, reported %d, expected %d\n", ulNewHeight, 2*ulOldHeight); 972*c2c66affSColin Finck 973*c2c66affSColin Finck /* Assuming tree doesn't have TVS_NONEVENHEIGHT set, so a set of 9 will round down to 8 */ 974*c2c66affSColin Finck SendMessageA(hTree, TVM_SETITEMHEIGHT, 9, 0); 975*c2c66affSColin Finck ulNewHeight = SendMessageA(hTree, TVM_GETITEMHEIGHT, 0, 0); 976*c2c66affSColin Finck ok(ulNewHeight == 8, "Uneven height not set properly, reported %d, expected %d\n", ulNewHeight, 8); 977*c2c66affSColin Finck 978*c2c66affSColin Finck ok_sequence(sequences, TREEVIEW_SEQ_INDEX, test_get_set_itemheight_seq, 979*c2c66affSColin Finck "test get set item height", FALSE); 980*c2c66affSColin Finck 981*c2c66affSColin Finck /* without TVS_NONEVENHEIGHT */ 982*c2c66affSColin Finck SetWindowLongA(hTree, GWL_STYLE, GetWindowLongA(hTree, GWL_STYLE) & ~TVS_NONEVENHEIGHT); 983*c2c66affSColin Finck /* odd value */ 984*c2c66affSColin Finck ulOldHeight = SendMessageA(hTree, TVM_SETITEMHEIGHT, 3, 0); 985*c2c66affSColin Finck ok(ulOldHeight == 8, "got %d, expected %d\n", ulOldHeight, 8); 986*c2c66affSColin Finck ulNewHeight = SendMessageA(hTree, TVM_GETITEMHEIGHT, 0, 0); 987*c2c66affSColin Finck ok(ulNewHeight == 2, "got %d, expected %d\n", ulNewHeight, 2); 988*c2c66affSColin Finck 989*c2c66affSColin Finck ulOldHeight = SendMessageA(hTree, TVM_SETITEMHEIGHT, 4, 0); 990*c2c66affSColin Finck ok(ulOldHeight == 2, "got %d, expected %d\n", ulOldHeight, 2); 991*c2c66affSColin Finck ulNewHeight = SendMessageA(hTree, TVM_GETITEMHEIGHT, 0, 0); 992*c2c66affSColin Finck ok(ulNewHeight == 4, "got %d, expected %d\n", ulNewHeight, 4); 993*c2c66affSColin Finck 994*c2c66affSColin Finck /* with TVS_NONEVENHEIGHT */ 995*c2c66affSColin Finck SetWindowLongA(hTree, GWL_STYLE, GetWindowLongA(hTree, GWL_STYLE) | TVS_NONEVENHEIGHT); 996*c2c66affSColin Finck /* odd value */ 997*c2c66affSColin Finck ulOldHeight = SendMessageA(hTree, TVM_SETITEMHEIGHT, 3, 0); 998*c2c66affSColin Finck ok(ulOldHeight == 4, "got %d, expected %d\n", ulOldHeight, 4); 999*c2c66affSColin Finck ulNewHeight = SendMessageA(hTree, TVM_GETITEMHEIGHT, 0, 0); 1000*c2c66affSColin Finck ok(ulNewHeight == 3, "got %d, expected %d\n", ulNewHeight, 3); 1001*c2c66affSColin Finck /* even value */ 1002*c2c66affSColin Finck ulOldHeight = SendMessageA(hTree, TVM_SETITEMHEIGHT, 10, 0); 1003*c2c66affSColin Finck ok(ulOldHeight == 3, "got %d, expected %d\n", ulOldHeight, 3); 1004*c2c66affSColin Finck ulNewHeight = SendMessageA(hTree, TVM_GETITEMHEIGHT, 0, 0); 1005*c2c66affSColin Finck ok(ulNewHeight == 10, "got %d, expected %d\n", ulNewHeight, 10); 1006*c2c66affSColin Finck 1007*c2c66affSColin Finck DestroyWindow(hTree); 1008*c2c66affSColin Finck } 1009*c2c66affSColin Finck 1010*c2c66affSColin Finck static void test_get_set_scrolltime(void) 1011*c2c66affSColin Finck { 1012*c2c66affSColin Finck int ulExpectedTime = 20; 1013*c2c66affSColin Finck int ulTime = 0; 1014*c2c66affSColin Finck HWND hTree; 1015*c2c66affSColin Finck 1016*c2c66affSColin Finck hTree = create_treeview_control(0); 1017*c2c66affSColin Finck fill_tree(hTree); 1018*c2c66affSColin Finck 1019*c2c66affSColin Finck flush_sequences(sequences, NUM_MSG_SEQUENCES); 1020*c2c66affSColin Finck 1021*c2c66affSColin Finck SendMessageA(hTree, TVM_SETSCROLLTIME, ulExpectedTime, 0); 1022*c2c66affSColin Finck ulTime = SendMessageA(hTree, TVM_GETSCROLLTIME, 0, 0); 1023*c2c66affSColin Finck ok(ulTime == ulExpectedTime, "Scroll time reported as %d, expected %d\n", ulTime, ulExpectedTime); 1024*c2c66affSColin Finck 1025*c2c66affSColin Finck ok_sequence(sequences, TREEVIEW_SEQ_INDEX, test_get_set_scrolltime_seq, 1026*c2c66affSColin Finck "test get set scroll time", FALSE); 1027*c2c66affSColin Finck 1028*c2c66affSColin Finck DestroyWindow(hTree); 1029*c2c66affSColin Finck } 1030*c2c66affSColin Finck 1031*c2c66affSColin Finck static void test_get_set_textcolor(void) 1032*c2c66affSColin Finck { 1033*c2c66affSColin Finck /* If the value is -1, the control is using the system color for the text color. */ 1034*c2c66affSColin Finck COLORREF crColor; 1035*c2c66affSColin Finck HWND hTree; 1036*c2c66affSColin Finck 1037*c2c66affSColin Finck hTree = create_treeview_control(0); 1038*c2c66affSColin Finck fill_tree(hTree); 1039*c2c66affSColin Finck 1040*c2c66affSColin Finck flush_sequences(sequences, NUM_MSG_SEQUENCES); 1041*c2c66affSColin Finck 1042*c2c66affSColin Finck crColor = SendMessageA(hTree, TVM_GETTEXTCOLOR, 0, 0); 1043*c2c66affSColin Finck ok(crColor == ~0u, "Default text color reported as 0x%.8x\n", crColor); 1044*c2c66affSColin Finck 1045*c2c66affSColin Finck /* Test for black text */ 1046*c2c66affSColin Finck SendMessageA(hTree, TVM_SETTEXTCOLOR, 0, RGB(0,0,0)); 1047*c2c66affSColin Finck crColor = SendMessageA(hTree, TVM_GETTEXTCOLOR, 0, 0); 1048*c2c66affSColin Finck ok(crColor == RGB(0,0,0), "Black text color reported as 0x%.8x\n", crColor); 1049*c2c66affSColin Finck 1050*c2c66affSColin Finck /* Test for white text */ 1051*c2c66affSColin Finck SendMessageA(hTree, TVM_SETTEXTCOLOR, 0, RGB(255,255,255)); 1052*c2c66affSColin Finck crColor = SendMessageA(hTree, TVM_GETTEXTCOLOR, 0, 0); 1053*c2c66affSColin Finck ok(crColor == RGB(255,255,255), "White text color reported as 0x%.8x\n", crColor); 1054*c2c66affSColin Finck 1055*c2c66affSColin Finck /* Reset the default text color */ 1056*c2c66affSColin Finck SendMessageA(hTree, TVM_SETTEXTCOLOR, 0, CLR_NONE); 1057*c2c66affSColin Finck 1058*c2c66affSColin Finck ok_sequence(sequences, TREEVIEW_SEQ_INDEX, test_get_set_textcolor_seq, 1059*c2c66affSColin Finck "test get set text color", FALSE); 1060*c2c66affSColin Finck 1061*c2c66affSColin Finck DestroyWindow(hTree); 1062*c2c66affSColin Finck } 1063*c2c66affSColin Finck 1064*c2c66affSColin Finck static void test_get_set_tooltips(void) 1065*c2c66affSColin Finck { 1066*c2c66affSColin Finck HWND hwndLastToolTip = NULL; 1067*c2c66affSColin Finck HWND hPopupTreeView; 1068*c2c66affSColin Finck HWND hTree; 1069*c2c66affSColin Finck 1070*c2c66affSColin Finck hTree = create_treeview_control(0); 1071*c2c66affSColin Finck fill_tree(hTree); 1072*c2c66affSColin Finck 1073*c2c66affSColin Finck flush_sequences(sequences, NUM_MSG_SEQUENCES); 1074*c2c66affSColin Finck 1075*c2c66affSColin Finck /* show even WS_POPUP treeview don't send NM_TOOLTIPSCREATED */ 1076*c2c66affSColin Finck hPopupTreeView = CreateWindowA(WC_TREEVIEWA, NULL, WS_POPUP|WS_VISIBLE, 0, 0, 100, 100, 1077*c2c66affSColin Finck hMainWnd, NULL, NULL, NULL); 1078*c2c66affSColin Finck DestroyWindow(hPopupTreeView); 1079*c2c66affSColin Finck 1080*c2c66affSColin Finck /* Testing setting a NULL ToolTip */ 1081*c2c66affSColin Finck SendMessageA(hTree, TVM_SETTOOLTIPS, 0, 0); 1082*c2c66affSColin Finck hwndLastToolTip = (HWND)SendMessageA(hTree, TVM_GETTOOLTIPS, 0, 0); 1083*c2c66affSColin Finck ok(hwndLastToolTip == NULL, "NULL tool tip, reported as 0x%p, expected 0.\n", hwndLastToolTip); 1084*c2c66affSColin Finck 1085*c2c66affSColin Finck ok_sequence(sequences, TREEVIEW_SEQ_INDEX, test_get_set_tooltips_seq, 1086*c2c66affSColin Finck "test get set tooltips", TRUE); 1087*c2c66affSColin Finck 1088*c2c66affSColin Finck /* TODO: Add a test of an actual tooltip */ 1089*c2c66affSColin Finck DestroyWindow(hTree); 1090*c2c66affSColin Finck } 1091*c2c66affSColin Finck 1092*c2c66affSColin Finck static void test_get_set_unicodeformat(void) 1093*c2c66affSColin Finck { 1094*c2c66affSColin Finck BOOL bPreviousSetting; 1095*c2c66affSColin Finck BOOL bNewSetting; 1096*c2c66affSColin Finck HWND hTree; 1097*c2c66affSColin Finck 1098*c2c66affSColin Finck hTree = create_treeview_control(0); 1099*c2c66affSColin Finck fill_tree(hTree); 1100*c2c66affSColin Finck 1101*c2c66affSColin Finck /* Check that an invalid format returned by NF_QUERY defaults to ANSI */ 1102*c2c66affSColin Finck bPreviousSetting = SendMessageA(hTree, TVM_GETUNICODEFORMAT, 0, 0); 1103*c2c66affSColin Finck ok(bPreviousSetting == FALSE, "Format should be ANSI.\n"); 1104*c2c66affSColin Finck 1105*c2c66affSColin Finck flush_sequences(sequences, NUM_MSG_SEQUENCES); 1106*c2c66affSColin Finck 1107*c2c66affSColin Finck /* Set to Unicode */ 1108*c2c66affSColin Finck bPreviousSetting = SendMessageA(hTree, TVM_SETUNICODEFORMAT, 1, 0); 1109*c2c66affSColin Finck bNewSetting = SendMessageA(hTree, TVM_GETUNICODEFORMAT, 0, 0); 1110*c2c66affSColin Finck ok(bNewSetting == TRUE, "Unicode setting did not work.\n"); 1111*c2c66affSColin Finck 1112*c2c66affSColin Finck /* Set to ANSI */ 1113*c2c66affSColin Finck SendMessageA(hTree, TVM_SETUNICODEFORMAT, 0, 0); 1114*c2c66affSColin Finck bNewSetting = SendMessageA(hTree, TVM_GETUNICODEFORMAT, 0, 0); 1115*c2c66affSColin Finck ok(bNewSetting == FALSE, "ANSI setting did not work.\n"); 1116*c2c66affSColin Finck 1117*c2c66affSColin Finck /* Revert to original setting */ 1118*c2c66affSColin Finck SendMessageA(hTree, TVM_SETUNICODEFORMAT, bPreviousSetting, 0); 1119*c2c66affSColin Finck 1120*c2c66affSColin Finck ok_sequence(sequences, TREEVIEW_SEQ_INDEX, test_get_set_unicodeformat_seq, 1121*c2c66affSColin Finck "test get set unicode format", FALSE); 1122*c2c66affSColin Finck 1123*c2c66affSColin Finck DestroyWindow(hTree); 1124*c2c66affSColin Finck } 1125*c2c66affSColin Finck 1126*c2c66affSColin Finck static LRESULT CALLBACK parent_wnd_proc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) 1127*c2c66affSColin Finck { 1128*c2c66affSColin Finck static LONG defwndproc_counter = 0; 1129*c2c66affSColin Finck struct message msg = { 0 }; 1130*c2c66affSColin Finck LRESULT ret; 1131*c2c66affSColin Finck RECT rect; 1132*c2c66affSColin Finck HTREEITEM visibleItem; 1133*c2c66affSColin Finck 1134*c2c66affSColin Finck msg.message = message; 1135*c2c66affSColin Finck msg.flags = sent|wparam|lparam; 1136*c2c66affSColin Finck if (defwndproc_counter) msg.flags |= defwinproc; 1137*c2c66affSColin Finck msg.wParam = wParam; 1138*c2c66affSColin Finck msg.lParam = lParam; 1139*c2c66affSColin Finck if (message == WM_NOTIFY && lParam) 1140*c2c66affSColin Finck msg.id = ((NMHDR*)lParam)->code; 1141*c2c66affSColin Finck 1142*c2c66affSColin Finck /* log system messages, except for painting */ 1143*c2c66affSColin Finck if (message < WM_USER && 1144*c2c66affSColin Finck message != WM_PAINT && 1145*c2c66affSColin Finck message != WM_ERASEBKGND && 1146*c2c66affSColin Finck message != WM_NCPAINT && 1147*c2c66affSColin Finck message != WM_NCHITTEST && 1148*c2c66affSColin Finck message != WM_GETTEXT && 1149*c2c66affSColin Finck message != WM_GETICON && 1150*c2c66affSColin Finck message != WM_DEVICECHANGE) 1151*c2c66affSColin Finck { 1152*c2c66affSColin Finck add_message(sequences, PARENT_SEQ_INDEX, &msg); 1153*c2c66affSColin Finck } 1154*c2c66affSColin Finck 1155*c2c66affSColin Finck switch(message) { 1156*c2c66affSColin Finck case WM_NOTIFYFORMAT: 1157*c2c66affSColin Finck { 1158*c2c66affSColin Finck /* Make NF_QUERY return an invalid format to show that it defaults to ANSI */ 1159*c2c66affSColin Finck if (lParam == NF_QUERY) return 0; 1160*c2c66affSColin Finck break; 1161*c2c66affSColin Finck } 1162*c2c66affSColin Finck 1163*c2c66affSColin Finck case WM_NOTIFY: 1164*c2c66affSColin Finck { 1165*c2c66affSColin Finck NMHDR *pHdr = (NMHDR *)lParam; 1166*c2c66affSColin Finck 1167*c2c66affSColin Finck ok(pHdr->code != NM_TOOLTIPSCREATED, "Treeview should not send NM_TOOLTIPSCREATED\n"); 1168*c2c66affSColin Finck if (pHdr->idFrom == 100) 1169*c2c66affSColin Finck { 1170*c2c66affSColin Finck NMTREEVIEWA *pTreeView = (LPNMTREEVIEWA) lParam; 1171*c2c66affSColin Finck switch(pHdr->code) 1172*c2c66affSColin Finck { 1173*c2c66affSColin Finck case TVN_SELCHANGINGA: 1174*c2c66affSColin Finck AddItem('('); 1175*c2c66affSColin Finck IdentifyItem(pTreeView->itemOld.hItem); 1176*c2c66affSColin Finck IdentifyItem(pTreeView->itemNew.hItem); 1177*c2c66affSColin Finck break; 1178*c2c66affSColin Finck case TVN_SELCHANGEDA: 1179*c2c66affSColin Finck AddItem(')'); 1180*c2c66affSColin Finck IdentifyItem(pTreeView->itemOld.hItem); 1181*c2c66affSColin Finck IdentifyItem(pTreeView->itemNew.hItem); 1182*c2c66affSColin Finck break; 1183*c2c66affSColin Finck case TVN_GETDISPINFOA: { 1184*c2c66affSColin Finck NMTVDISPINFOA *disp = (NMTVDISPINFOA *)lParam; 1185*c2c66affSColin Finck if (disp->item.mask & TVIF_TEXT) { 1186*c2c66affSColin Finck lstrcpynA(disp->item.pszText, TEST_CALLBACK_TEXT, disp->item.cchTextMax); 1187*c2c66affSColin Finck } 1188*c2c66affSColin Finck 1189*c2c66affSColin Finck if (g_disp_A_to_W && (disp->item.mask & TVIF_TEXT)) { 1190*c2c66affSColin Finck static const WCHAR testW[] = {'T','E','S','T','2',0}; 1191*c2c66affSColin Finck 1192*c2c66affSColin Finck disp->hdr.code = TVN_GETDISPINFOW; 1193*c2c66affSColin Finck memcpy(disp->item.pszText, testW, sizeof(testW)); 1194*c2c66affSColin Finck } 1195*c2c66affSColin Finck 1196*c2c66affSColin Finck if (g_disp_set_stateimage) 1197*c2c66affSColin Finck { 1198*c2c66affSColin Finck ok(disp->item.mask == TVIF_IMAGE, "got %x\n", disp->item.mask); 1199*c2c66affSColin Finck /* both masks set here are necessary to change state bits */ 1200*c2c66affSColin Finck disp->item.mask |= TVIF_STATE; 1201*c2c66affSColin Finck disp->item.state = TVIS_SELECTED | INDEXTOSTATEIMAGEMASK(2) | INDEXTOOVERLAYMASK(3); 1202*c2c66affSColin Finck disp->item.stateMask = TVIS_SELECTED | TVIS_OVERLAYMASK | TVIS_STATEIMAGEMASK; 1203*c2c66affSColin Finck } 1204*c2c66affSColin Finck 1205*c2c66affSColin Finck break; 1206*c2c66affSColin Finck } 1207*c2c66affSColin Finck case TVN_BEGINLABELEDITA: 1208*c2c66affSColin Finck { 1209*c2c66affSColin Finck if (g_beginedit_alter_text) 1210*c2c66affSColin Finck { 1211*c2c66affSColin Finck static const char* textA = "<edittextaltered>"; 1212*c2c66affSColin Finck HWND edit; 1213*c2c66affSColin Finck 1214*c2c66affSColin Finck edit = (HWND)SendMessageA(pHdr->hwndFrom, TVM_GETEDITCONTROL, 0, 0); 1215*c2c66affSColin Finck ok(IsWindow(edit), "failed to get edit handle\n"); 1216*c2c66affSColin Finck SetWindowTextA(edit, textA); 1217*c2c66affSColin Finck } 1218*c2c66affSColin Finck 1219*c2c66affSColin Finck break; 1220*c2c66affSColin Finck } 1221*c2c66affSColin Finck 1222*c2c66affSColin Finck case TVN_ENDLABELEDITA: return TRUE; 1223*c2c66affSColin Finck case TVN_ITEMEXPANDINGA: 1224*c2c66affSColin Finck { 1225*c2c66affSColin Finck UINT newmask = pTreeView->itemNew.mask & ~TVIF_CHILDREN; 1226*c2c66affSColin Finck ok(newmask == 1227*c2c66affSColin Finck (TVIF_HANDLE | TVIF_SELECTEDIMAGE | TVIF_IMAGE | TVIF_PARAM | TVIF_STATE), 1228*c2c66affSColin Finck "got wrong mask %x\n", pTreeView->itemNew.mask); 1229*c2c66affSColin Finck ok(pTreeView->itemOld.mask == 0, 1230*c2c66affSColin Finck "got wrong mask %x\n", pTreeView->itemOld.mask); 1231*c2c66affSColin Finck 1232*c2c66affSColin Finck if (g_get_from_expand) 1233*c2c66affSColin Finck { 1234*c2c66affSColin Finck g_item_expanding.mask = TVIF_STATE; 1235*c2c66affSColin Finck g_item_expanding.hItem = hRoot; 1236*c2c66affSColin Finck ret = SendMessageA(pHdr->hwndFrom, TVM_GETITEMA, 0, (LPARAM)&g_item_expanding); 1237*c2c66affSColin Finck ok(ret == TRUE, "got %lu\n", ret); 1238*c2c66affSColin Finck } 1239*c2c66affSColin Finck break; 1240*c2c66affSColin Finck } 1241*c2c66affSColin Finck case TVN_ITEMEXPANDEDA: 1242*c2c66affSColin Finck ok(pTreeView->itemNew.mask & TVIF_STATE, "got wrong mask %x\n", pTreeView->itemNew.mask); 1243*c2c66affSColin Finck ok(pTreeView->itemNew.state & (TVIS_EXPANDED|TVIS_EXPANDEDONCE), 1244*c2c66affSColin Finck "got wrong mask %x\n", pTreeView->itemNew.mask); 1245*c2c66affSColin Finck ok(pTreeView->itemOld.mask == 0, 1246*c2c66affSColin Finck "got wrong mask %x\n", pTreeView->itemOld.mask); 1247*c2c66affSColin Finck 1248*c2c66affSColin Finck if (g_get_from_expand) 1249*c2c66affSColin Finck { 1250*c2c66affSColin Finck g_item_expanded.mask = TVIF_STATE; 1251*c2c66affSColin Finck g_item_expanded.hItem = hRoot; 1252*c2c66affSColin Finck ret = SendMessageA(pHdr->hwndFrom, TVM_GETITEMA, 0, (LPARAM)&g_item_expanded); 1253*c2c66affSColin Finck ok(ret == TRUE, "got %lu\n", ret); 1254*c2c66affSColin Finck } 1255*c2c66affSColin Finck if (g_get_rect_in_expand) 1256*c2c66affSColin Finck { 1257*c2c66affSColin Finck visibleItem = (HTREEITEM)SendMessageA(pHdr->hwndFrom, TVM_GETNEXTITEM, 1258*c2c66affSColin Finck TVGN_FIRSTVISIBLE, 0); 1259*c2c66affSColin Finck ok(pTreeView->itemNew.hItem == visibleItem, "expanded item == first visible item\n"); 1260*c2c66affSColin Finck *(HTREEITEM*)&rect = visibleItem; 1261*c2c66affSColin Finck ok(SendMessageA(pHdr->hwndFrom, TVM_GETITEMRECT, TRUE, (LPARAM)&rect), 1262*c2c66affSColin Finck "Failed to get rect for first visible item.\n"); 1263*c2c66affSColin Finck visibleItem = (HTREEITEM)SendMessageA(pHdr->hwndFrom, TVM_GETNEXTITEM, 1264*c2c66affSColin Finck TVGN_NEXTVISIBLE, (LPARAM)visibleItem); 1265*c2c66affSColin Finck *(HTREEITEM*)&rect = visibleItem; 1266*c2c66affSColin Finck ok(visibleItem != NULL, "There must be a visible item after the first visisble item.\n"); 1267*c2c66affSColin Finck ok(SendMessageA(pHdr->hwndFrom, TVM_GETITEMRECT, TRUE, (LPARAM)&rect), 1268*c2c66affSColin Finck "Failed to get rect for second visible item.\n"); 1269*c2c66affSColin Finck } 1270*c2c66affSColin Finck break; 1271*c2c66affSColin Finck case TVN_DELETEITEMA: 1272*c2c66affSColin Finck { 1273*c2c66affSColin Finck struct message item; 1274*c2c66affSColin Finck 1275*c2c66affSColin Finck ok(pTreeView->itemNew.mask == 0, "got wrong mask 0x%x\n", pTreeView->itemNew.mask); 1276*c2c66affSColin Finck 1277*c2c66affSColin Finck ok(pTreeView->itemOld.mask == (TVIF_HANDLE | TVIF_PARAM), "got wrong mask 0x%x\n", pTreeView->itemOld.mask); 1278*c2c66affSColin Finck ok(pTreeView->itemOld.hItem != NULL, "got %p\n", pTreeView->itemOld.hItem); 1279*c2c66affSColin Finck 1280*c2c66affSColin Finck memset(&item, 0, sizeof(item)); 1281*c2c66affSColin Finck item.lParam = (LPARAM)pTreeView->itemOld.hItem; 1282*c2c66affSColin Finck add_message(item_sequence, 0, &item); 1283*c2c66affSColin Finck 1284*c2c66affSColin Finck break; 1285*c2c66affSColin Finck } 1286*c2c66affSColin Finck case NM_CUSTOMDRAW: 1287*c2c66affSColin Finck { 1288*c2c66affSColin Finck NMTVCUSTOMDRAW *nmcd = (NMTVCUSTOMDRAW*)lParam; 1289*c2c66affSColin Finck COLORREF c0ffee = RGB(0xc0,0xff,0xee), cafe = RGB(0xca,0xfe,0x00); 1290*c2c66affSColin Finck COLORREF text = GetTextColor(nmcd->nmcd.hdc), bkgnd = GetBkColor(nmcd->nmcd.hdc); 1291*c2c66affSColin Finck 1292*c2c66affSColin Finck msg.flags |= custdraw; 1293*c2c66affSColin Finck msg.stage = nmcd->nmcd.dwDrawStage; 1294*c2c66affSColin Finck add_message(sequences, PARENT_CD_SEQ_INDEX, &msg); 1295*c2c66affSColin Finck 1296*c2c66affSColin Finck switch (msg.stage) 1297*c2c66affSColin Finck { 1298*c2c66affSColin Finck case CDDS_PREPAINT: 1299*c2c66affSColin Finck return CDRF_NOTIFYITEMDRAW|CDRF_NOTIFYITEMERASE|CDRF_NOTIFYPOSTPAINT; 1300*c2c66affSColin Finck case CDDS_ITEMPREPAINT: 1301*c2c66affSColin Finck ok(text == nmcd->clrText || (g_v6 && nmcd->clrText == 0xffffffff), 1302*c2c66affSColin Finck "got %08x vs %08x\n", text, nmcd->clrText); 1303*c2c66affSColin Finck ok(bkgnd == nmcd->clrTextBk || (g_v6 && nmcd->clrTextBk == 0xffffffff), 1304*c2c66affSColin Finck "got %08x vs %08x\n", bkgnd, nmcd->clrTextBk); 1305*c2c66affSColin Finck nmcd->clrText = cafe; 1306*c2c66affSColin Finck nmcd->clrTextBk = c0ffee; 1307*c2c66affSColin Finck SetTextColor(nmcd->nmcd.hdc, c0ffee); 1308*c2c66affSColin Finck SetBkColor(nmcd->nmcd.hdc, cafe); 1309*c2c66affSColin Finck if (g_customdraw_font) 1310*c2c66affSColin Finck SelectObject(nmcd->nmcd.hdc, g_customdraw_font); 1311*c2c66affSColin Finck return CDRF_NOTIFYPOSTPAINT|CDRF_NEWFONT; 1312*c2c66affSColin Finck case CDDS_ITEMPOSTPAINT: 1313*c2c66affSColin Finck /* at the point of post paint notification colors are already restored */ 1314*c2c66affSColin Finck ok(nmcd->clrText == cafe, "got 0%x\n", nmcd->clrText); 1315*c2c66affSColin Finck ok(nmcd->clrTextBk == c0ffee, "got 0%x\n", nmcd->clrTextBk); 1316*c2c66affSColin Finck ok(text != cafe, "got 0%x\n", text); 1317*c2c66affSColin Finck ok(bkgnd != c0ffee, "got 0%x\n", bkgnd); 1318*c2c66affSColin Finck if (g_customdraw_font) 1319*c2c66affSColin Finck ok(GetCurrentObject(nmcd->nmcd.hdc, OBJ_FONT) != g_customdraw_font, "got %p\n", 1320*c2c66affSColin Finck GetCurrentObject(nmcd->nmcd.hdc, OBJ_FONT)); 1321*c2c66affSColin Finck break; 1322*c2c66affSColin Finck default: 1323*c2c66affSColin Finck ; 1324*c2c66affSColin Finck } 1325*c2c66affSColin Finck break; 1326*c2c66affSColin Finck } 1327*c2c66affSColin Finck case NM_RCLICK: 1328*c2c66affSColin Finck { 1329*c2c66affSColin Finck HTREEITEM selected = (HTREEITEM)SendMessageA(((NMHDR *)lParam)->hwndFrom, 1330*c2c66affSColin Finck TVM_GETNEXTITEM, TVGN_CARET, 0); 1331*c2c66affSColin Finck ok(selected == hChild, "child item should still be selected\n"); 1332*c2c66affSColin Finck break; 1333*c2c66affSColin Finck } 1334*c2c66affSColin Finck } 1335*c2c66affSColin Finck } 1336*c2c66affSColin Finck break; 1337*c2c66affSColin Finck } 1338*c2c66affSColin Finck 1339*c2c66affSColin Finck case WM_DESTROY: 1340*c2c66affSColin Finck PostQuitMessage(0); 1341*c2c66affSColin Finck break; 1342*c2c66affSColin Finck } 1343*c2c66affSColin Finck 1344*c2c66affSColin Finck defwndproc_counter++; 1345*c2c66affSColin Finck ret = DefWindowProcA(hWnd, message, wParam, lParam); 1346*c2c66affSColin Finck defwndproc_counter--; 1347*c2c66affSColin Finck 1348*c2c66affSColin Finck return ret; 1349*c2c66affSColin Finck } 1350*c2c66affSColin Finck 1351*c2c66affSColin Finck static void test_expandinvisible(void) 1352*c2c66affSColin Finck { 1353*c2c66affSColin Finck static CHAR nodeText[][5] = {"0", "1", "2", "3", "4"}; 1354*c2c66affSColin Finck TVINSERTSTRUCTA ins; 1355*c2c66affSColin Finck HTREEITEM node[5]; 1356*c2c66affSColin Finck RECT dummyRect; 1357*c2c66affSColin Finck BOOL nodeVisible; 1358*c2c66affSColin Finck LRESULT ret; 1359*c2c66affSColin Finck HWND hTree; 1360*c2c66affSColin Finck 1361*c2c66affSColin Finck hTree = create_treeview_control(0); 1362*c2c66affSColin Finck 1363*c2c66affSColin Finck /* The test builds the following tree and expands node 1, while node 0 is collapsed. 1364*c2c66affSColin Finck * 1365*c2c66affSColin Finck * 0 1366*c2c66affSColin Finck * |- 1 1367*c2c66affSColin Finck * | |- 2 1368*c2c66affSColin Finck * | |- 3 1369*c2c66affSColin Finck * |- 4 1370*c2c66affSColin Finck * 1371*c2c66affSColin Finck */ 1372*c2c66affSColin Finck 1373*c2c66affSColin Finck ret = SendMessageA(hTree, TVM_DELETEITEM, 0, (LPARAM)TVI_ROOT); 1374*c2c66affSColin Finck ok(ret == TRUE, "ret\n"); 1375*c2c66affSColin Finck ins.hParent = TVI_ROOT; 1376*c2c66affSColin Finck ins.hInsertAfter = TVI_ROOT; 1377*c2c66affSColin Finck U(ins).item.mask = TVIF_TEXT; 1378*c2c66affSColin Finck U(ins).item.pszText = nodeText[0]; 1379*c2c66affSColin Finck node[0] = TreeView_InsertItemA(hTree, &ins); 1380*c2c66affSColin Finck ok(node[0] != NULL, "failed to set node[0]\n"); 1381*c2c66affSColin Finck 1382*c2c66affSColin Finck ins.hInsertAfter = TVI_LAST; 1383*c2c66affSColin Finck U(ins).item.mask = TVIF_TEXT; 1384*c2c66affSColin Finck ins.hParent = node[0]; 1385*c2c66affSColin Finck 1386*c2c66affSColin Finck U(ins).item.pszText = nodeText[1]; 1387*c2c66affSColin Finck node[1] = TreeView_InsertItemA(hTree, &ins); 1388*c2c66affSColin Finck ok(node[1] != NULL, "failed to set node[1]\n"); 1389*c2c66affSColin Finck U(ins).item.pszText = nodeText[4]; 1390*c2c66affSColin Finck node[4] = TreeView_InsertItemA(hTree, &ins); 1391*c2c66affSColin Finck ok(node[4] != NULL, "failed to set node[4]\n"); 1392*c2c66affSColin Finck 1393*c2c66affSColin Finck ins.hParent = node[1]; 1394*c2c66affSColin Finck 1395*c2c66affSColin Finck U(ins).item.pszText = nodeText[2]; 1396*c2c66affSColin Finck node[2] = TreeView_InsertItemA(hTree, &ins); 1397*c2c66affSColin Finck ok(node[2] != NULL, "failed to set node[2]\n"); 1398*c2c66affSColin Finck U(ins).item.pszText = nodeText[3]; 1399*c2c66affSColin Finck node[3] = TreeView_InsertItemA(hTree, &ins); 1400*c2c66affSColin Finck ok(node[3] != NULL, "failed to set node[3]\n"); 1401*c2c66affSColin Finck 1402*c2c66affSColin Finck *(HTREEITEM *)&dummyRect = node[1]; 1403*c2c66affSColin Finck nodeVisible = SendMessageA(hTree, TVM_GETITEMRECT, FALSE, (LPARAM)&dummyRect); 1404*c2c66affSColin Finck ok(!nodeVisible, "Node 1 should not be visible.\n"); 1405*c2c66affSColin Finck *(HTREEITEM *)&dummyRect = node[2]; 1406*c2c66affSColin Finck nodeVisible = SendMessageA(hTree, TVM_GETITEMRECT, FALSE, (LPARAM)&dummyRect); 1407*c2c66affSColin Finck ok(!nodeVisible, "Node 2 should not be visible.\n"); 1408*c2c66affSColin Finck *(HTREEITEM *)&dummyRect = node[3]; 1409*c2c66affSColin Finck nodeVisible = SendMessageA(hTree, TVM_GETITEMRECT, FALSE, (LPARAM)&dummyRect); 1410*c2c66affSColin Finck ok(!nodeVisible, "Node 3 should not be visible.\n"); 1411*c2c66affSColin Finck *(HTREEITEM *)&dummyRect = node[4]; 1412*c2c66affSColin Finck nodeVisible = SendMessageA(hTree, TVM_GETITEMRECT, FALSE, (LPARAM)&dummyRect); 1413*c2c66affSColin Finck ok(!nodeVisible, "Node 4 should not be visible.\n"); 1414*c2c66affSColin Finck 1415*c2c66affSColin Finck ok(SendMessageA(hTree, TVM_EXPAND, TVE_EXPAND, (LPARAM)node[1]), "Expand of node 1 failed.\n"); 1416*c2c66affSColin Finck 1417*c2c66affSColin Finck *(HTREEITEM *)&dummyRect = node[1]; 1418*c2c66affSColin Finck nodeVisible = SendMessageA(hTree, TVM_GETITEMRECT, FALSE, (LPARAM)&dummyRect); 1419*c2c66affSColin Finck ok(!nodeVisible, "Node 1 should not be visible.\n"); 1420*c2c66affSColin Finck *(HTREEITEM *)&dummyRect = node[2]; 1421*c2c66affSColin Finck nodeVisible = SendMessageA(hTree, TVM_GETITEMRECT, FALSE, (LPARAM)&dummyRect); 1422*c2c66affSColin Finck ok(!nodeVisible, "Node 2 should not be visible.\n"); 1423*c2c66affSColin Finck *(HTREEITEM *)&dummyRect = node[3]; 1424*c2c66affSColin Finck nodeVisible = SendMessageA(hTree, TVM_GETITEMRECT, FALSE, (LPARAM)&dummyRect); 1425*c2c66affSColin Finck ok(!nodeVisible, "Node 3 should not be visible.\n"); 1426*c2c66affSColin Finck *(HTREEITEM *)&dummyRect = node[4]; 1427*c2c66affSColin Finck nodeVisible = SendMessageA(hTree, TVM_GETITEMRECT, FALSE, (LPARAM)&dummyRect); 1428*c2c66affSColin Finck ok(!nodeVisible, "Node 4 should not be visible.\n"); 1429*c2c66affSColin Finck 1430*c2c66affSColin Finck DestroyWindow(hTree); 1431*c2c66affSColin Finck } 1432*c2c66affSColin Finck 1433*c2c66affSColin Finck static void test_itemedit(void) 1434*c2c66affSColin Finck { 1435*c2c66affSColin Finck DWORD r; 1436*c2c66affSColin Finck HWND edit; 1437*c2c66affSColin Finck TVITEMA item; 1438*c2c66affSColin Finck CHAR buffA[20]; 1439*c2c66affSColin Finck HWND hTree; 1440*c2c66affSColin Finck 1441*c2c66affSColin Finck hTree = create_treeview_control(0); 1442*c2c66affSColin Finck fill_tree(hTree); 1443*c2c66affSColin Finck 1444*c2c66affSColin Finck /* try with null item */ 1445*c2c66affSColin Finck edit = (HWND)SendMessageA(hTree, TVM_EDITLABELA, 0, 0); 1446*c2c66affSColin Finck ok(!IsWindow(edit), "Expected valid handle\n"); 1447*c2c66affSColin Finck 1448*c2c66affSColin Finck /* trigger edit */ 1449*c2c66affSColin Finck edit = (HWND)SendMessageA(hTree, TVM_EDITLABELA, 0, (LPARAM)hRoot); 1450*c2c66affSColin Finck ok(IsWindow(edit), "Expected valid handle\n"); 1451*c2c66affSColin Finck /* item shouldn't be selected automatically after TVM_EDITLABELA */ 1452*c2c66affSColin Finck r = SendMessageA(hTree, TVM_GETITEMSTATE, (WPARAM)hRoot, TVIS_SELECTED); 1453*c2c66affSColin Finck expect(0, r); 1454*c2c66affSColin Finck /* try to cancel with wrong edit handle */ 1455*c2c66affSColin Finck r = SendMessageA(hTree, WM_COMMAND, MAKEWPARAM(0, EN_KILLFOCUS), 0); 1456*c2c66affSColin Finck expect(0, r); 1457*c2c66affSColin Finck ok(IsWindow(edit), "Expected edit control to be valid\n"); 1458*c2c66affSColin Finck r = SendMessageA(hTree, WM_COMMAND, MAKEWPARAM(0, EN_KILLFOCUS), (LPARAM)edit); 1459*c2c66affSColin Finck expect(0, r); 1460*c2c66affSColin Finck ok(!IsWindow(edit), "Expected edit control to be destroyed\n"); 1461*c2c66affSColin Finck /* try to cancel without creating edit */ 1462*c2c66affSColin Finck r = SendMessageA(hTree, WM_COMMAND, MAKEWPARAM(0, EN_KILLFOCUS), 0); 1463*c2c66affSColin Finck expect(0, r); 1464*c2c66affSColin Finck 1465*c2c66affSColin Finck /* try to cancel with wrong (not null) handle */ 1466*c2c66affSColin Finck edit = (HWND)SendMessageA(hTree, TVM_EDITLABELA, 0, (LPARAM)hRoot); 1467*c2c66affSColin Finck ok(IsWindow(edit), "Expected valid handle\n"); 1468*c2c66affSColin Finck r = SendMessageA(hTree, WM_COMMAND, MAKEWPARAM(0, EN_KILLFOCUS), (LPARAM)hTree); 1469*c2c66affSColin Finck expect(0, r); 1470*c2c66affSColin Finck ok(IsWindow(edit), "Expected edit control to be valid\n"); 1471*c2c66affSColin Finck r = SendMessageA(hTree, WM_COMMAND, MAKEWPARAM(0, EN_KILLFOCUS), (LPARAM)edit); 1472*c2c66affSColin Finck expect(0, r); 1473*c2c66affSColin Finck 1474*c2c66affSColin Finck /* remove selection after starting edit */ 1475*c2c66affSColin Finck r = SendMessageA(hTree, TVM_SELECTITEM, TVGN_CARET, (LPARAM)hRoot); 1476*c2c66affSColin Finck expect(TRUE, r); 1477*c2c66affSColin Finck edit = (HWND)SendMessageA(hTree, TVM_EDITLABELA, 0, (LPARAM)hRoot); 1478*c2c66affSColin Finck ok(IsWindow(edit), "Expected valid handle\n"); 1479*c2c66affSColin Finck r = SendMessageA(hTree, TVM_SELECTITEM, TVGN_CARET, 0); 1480*c2c66affSColin Finck expect(TRUE, r); 1481*c2c66affSColin Finck /* alter text */ 1482*c2c66affSColin Finck strcpy(buffA, "x"); 1483*c2c66affSColin Finck r = SendMessageA(edit, WM_SETTEXT, 0, (LPARAM)buffA); 1484*c2c66affSColin Finck expect(TRUE, r); 1485*c2c66affSColin Finck r = SendMessageA(hTree, WM_COMMAND, MAKEWPARAM(0, EN_KILLFOCUS), (LPARAM)edit); 1486*c2c66affSColin Finck expect(0, r); 1487*c2c66affSColin Finck ok(!IsWindow(edit), "Expected edit control to be destroyed\n"); 1488*c2c66affSColin Finck /* check that text is saved */ 1489*c2c66affSColin Finck item.mask = TVIF_TEXT; 1490*c2c66affSColin Finck item.hItem = hRoot; 1491*c2c66affSColin Finck item.pszText = buffA; 1492*c2c66affSColin Finck item.cchTextMax = sizeof(buffA)/sizeof(CHAR); 1493*c2c66affSColin Finck r = SendMessageA(hTree, TVM_GETITEMA, 0, (LPARAM)&item); 1494*c2c66affSColin Finck expect(TRUE, r); 1495*c2c66affSColin Finck ok(!strcmp("x", buffA), "Expected item text to change\n"); 1496*c2c66affSColin Finck 1497*c2c66affSColin Finck /* try A/W messages */ 1498*c2c66affSColin Finck edit = (HWND)SendMessageA(hTree, TVM_EDITLABELA, 0, (LPARAM)hRoot); 1499*c2c66affSColin Finck ok(IsWindow(edit), "Expected valid handle\n"); 1500*c2c66affSColin Finck ok(IsWindowUnicode(edit), "got ansi window\n"); 1501*c2c66affSColin Finck r = SendMessageA(hTree, WM_COMMAND, MAKEWPARAM(0, EN_KILLFOCUS), (LPARAM)edit); 1502*c2c66affSColin Finck expect(0, r); 1503*c2c66affSColin Finck ok(!IsWindow(edit), "expected invalid handle\n"); 1504*c2c66affSColin Finck 1505*c2c66affSColin Finck edit = (HWND)SendMessageA(hTree, TVM_EDITLABELW, 0, (LPARAM)hRoot); 1506*c2c66affSColin Finck ok(IsWindow(edit), "Expected valid handle\n"); 1507*c2c66affSColin Finck ok(IsWindowUnicode(edit), "got ansi window\n"); 1508*c2c66affSColin Finck r = SendMessageA(hTree, WM_COMMAND, MAKEWPARAM(0, EN_KILLFOCUS), (LPARAM)edit); 1509*c2c66affSColin Finck expect(0, r); 1510*c2c66affSColin Finck 1511*c2c66affSColin Finck /* alter text during TVM_BEGINLABELEDIT, check that it's preserved */ 1512*c2c66affSColin Finck strcpy(buffA, "<root>"); 1513*c2c66affSColin Finck 1514*c2c66affSColin Finck item.mask = TVIF_TEXT; 1515*c2c66affSColin Finck item.hItem = hRoot; 1516*c2c66affSColin Finck item.pszText = buffA; 1517*c2c66affSColin Finck item.cchTextMax = 0; 1518*c2c66affSColin Finck r = SendMessageA(hTree, TVM_SETITEMA, 0, (LPARAM)&item); 1519*c2c66affSColin Finck expect(TRUE, r); 1520*c2c66affSColin Finck 1521*c2c66affSColin Finck g_beginedit_alter_text = TRUE; 1522*c2c66affSColin Finck edit = (HWND)SendMessageA(hTree, TVM_EDITLABELA, 0, (LPARAM)hRoot); 1523*c2c66affSColin Finck ok(IsWindow(edit), "Expected valid handle\n"); 1524*c2c66affSColin Finck g_beginedit_alter_text = FALSE; 1525*c2c66affSColin Finck 1526*c2c66affSColin Finck GetWindowTextA(edit, buffA, sizeof(buffA)/sizeof(CHAR)); 1527*c2c66affSColin Finck ok(!strcmp(buffA, "<edittextaltered>"), "got string %s\n", buffA); 1528*c2c66affSColin Finck 1529*c2c66affSColin Finck DestroyWindow(hTree); 1530*c2c66affSColin Finck } 1531*c2c66affSColin Finck 1532*c2c66affSColin Finck static void test_treeview_classinfo(void) 1533*c2c66affSColin Finck { 1534*c2c66affSColin Finck WNDCLASSA cls; 1535*c2c66affSColin Finck 1536*c2c66affSColin Finck memset(&cls, 0, sizeof(cls)); 1537*c2c66affSColin Finck GetClassInfoA(GetModuleHandleA("comctl32.dll"), WC_TREEVIEWA, &cls); 1538*c2c66affSColin Finck ok(cls.hbrBackground == NULL, "Expected NULL background brush, got %p\n", cls.hbrBackground); 1539*c2c66affSColin Finck ok(cls.style == (CS_GLOBALCLASS | CS_DBLCLKS), "Expected got %x\n", cls.style); 1540*c2c66affSColin Finck expect(0, cls.cbClsExtra); 1541*c2c66affSColin Finck } 1542*c2c66affSColin Finck 1543*c2c66affSColin Finck static void test_get_linecolor(void) 1544*c2c66affSColin Finck { 1545*c2c66affSColin Finck COLORREF clr; 1546*c2c66affSColin Finck HWND hTree; 1547*c2c66affSColin Finck 1548*c2c66affSColin Finck hTree = create_treeview_control(0); 1549*c2c66affSColin Finck 1550*c2c66affSColin Finck /* newly created control has default color */ 1551*c2c66affSColin Finck clr = SendMessageA(hTree, TVM_GETLINECOLOR, 0, 0); 1552*c2c66affSColin Finck if (clr == 0) 1553*c2c66affSColin Finck win_skip("TVM_GETLINECOLOR is not supported on comctl32 < 5.80\n"); 1554*c2c66affSColin Finck else 1555*c2c66affSColin Finck expect(CLR_DEFAULT, clr); 1556*c2c66affSColin Finck 1557*c2c66affSColin Finck DestroyWindow(hTree); 1558*c2c66affSColin Finck } 1559*c2c66affSColin Finck 1560*c2c66affSColin Finck static void test_get_insertmarkcolor(void) 1561*c2c66affSColin Finck { 1562*c2c66affSColin Finck COLORREF clr; 1563*c2c66affSColin Finck HWND hTree; 1564*c2c66affSColin Finck 1565*c2c66affSColin Finck hTree = create_treeview_control(0); 1566*c2c66affSColin Finck 1567*c2c66affSColin Finck /* newly created control has default color */ 1568*c2c66affSColin Finck clr = SendMessageA(hTree, TVM_GETINSERTMARKCOLOR, 0, 0); 1569*c2c66affSColin Finck if (clr == 0) 1570*c2c66affSColin Finck win_skip("TVM_GETINSERTMARKCOLOR is not supported on comctl32 < 5.80\n"); 1571*c2c66affSColin Finck else 1572*c2c66affSColin Finck expect(CLR_DEFAULT, clr); 1573*c2c66affSColin Finck 1574*c2c66affSColin Finck DestroyWindow(hTree); 1575*c2c66affSColin Finck } 1576*c2c66affSColin Finck 1577*c2c66affSColin Finck static void test_expandnotify(void) 1578*c2c66affSColin Finck { 1579*c2c66affSColin Finck HTREEITEM hitem; 1580*c2c66affSColin Finck HWND hTree; 1581*c2c66affSColin Finck BOOL ret; 1582*c2c66affSColin Finck TVITEMA item; 1583*c2c66affSColin Finck 1584*c2c66affSColin Finck hTree = create_treeview_control(0); 1585*c2c66affSColin Finck fill_tree(hTree); 1586*c2c66affSColin Finck 1587*c2c66affSColin Finck item.hItem = hRoot; 1588*c2c66affSColin Finck item.mask = TVIF_STATE; 1589*c2c66affSColin Finck 1590*c2c66affSColin Finck item.state = TVIS_EXPANDED; 1591*c2c66affSColin Finck ret = SendMessageA(hTree, TVM_GETITEMA, 0, (LPARAM)&item); 1592*c2c66affSColin Finck expect(TRUE, ret); 1593*c2c66affSColin Finck ok((item.state & TVIS_EXPANDED) == 0, "expected collapsed\n"); 1594*c2c66affSColin Finck 1595*c2c66affSColin Finck /* preselect root node here */ 1596*c2c66affSColin Finck ret = SendMessageA(hTree, TVM_SELECTITEM, TVGN_CARET, (LPARAM)hRoot); 1597*c2c66affSColin Finck expect(TRUE, ret); 1598*c2c66affSColin Finck 1599*c2c66affSColin Finck flush_sequences(sequences, NUM_MSG_SEQUENCES); 1600*c2c66affSColin Finck ret = SendMessageA(hTree, TVM_EXPAND, TVE_COLLAPSE, (LPARAM)hRoot); 1601*c2c66affSColin Finck expect(FALSE, ret); 1602*c2c66affSColin Finck ok_sequence(sequences, PARENT_SEQ_INDEX, empty_seq, "no collapse notifications", FALSE); 1603*c2c66affSColin Finck 1604*c2c66affSColin Finck g_get_from_expand = TRUE; 1605*c2c66affSColin Finck /* expand */ 1606*c2c66affSColin Finck flush_sequences(sequences, NUM_MSG_SEQUENCES); 1607*c2c66affSColin Finck g_item_expanding.state = 0xdeadbeef; 1608*c2c66affSColin Finck g_item_expanded.state = 0xdeadbeef; 1609*c2c66affSColin Finck ret = SendMessageA(hTree, TVM_EXPAND, TVE_EXPAND, (LPARAM)hRoot); 1610*c2c66affSColin Finck expect(TRUE, ret); 1611*c2c66affSColin Finck ok(g_item_expanding.state == TVIS_SELECTED, "got state on TVN_ITEMEXPANDING 0x%08x\n", 1612*c2c66affSColin Finck g_item_expanding.state); 1613*c2c66affSColin Finck ok(g_item_expanded.state == (TVIS_SELECTED|TVIS_EXPANDED), "got state on TVN_ITEMEXPANDED 0x%08x\n", 1614*c2c66affSColin Finck g_item_expanded.state); 1615*c2c66affSColin Finck ok_sequence(sequences, PARENT_SEQ_INDEX, parent_expand_seq, "expand notifications", FALSE); 1616*c2c66affSColin Finck g_get_from_expand = FALSE; 1617*c2c66affSColin Finck 1618*c2c66affSColin Finck /* check that it's expanded */ 1619*c2c66affSColin Finck item.state = TVIS_EXPANDED; 1620*c2c66affSColin Finck ret = SendMessageA(hTree, TVM_GETITEMA, 0, (LPARAM)&item); 1621*c2c66affSColin Finck expect(TRUE, ret); 1622*c2c66affSColin Finck ok((item.state & TVIS_EXPANDED) == TVIS_EXPANDED, "expected expanded\n"); 1623*c2c66affSColin Finck 1624*c2c66affSColin Finck /* collapse */ 1625*c2c66affSColin Finck flush_sequences(sequences, NUM_MSG_SEQUENCES); 1626*c2c66affSColin Finck ret = SendMessageA(hTree, TVM_EXPAND, TVE_COLLAPSE, (LPARAM)hRoot); 1627*c2c66affSColin Finck expect(TRUE, ret); 1628*c2c66affSColin Finck item.state = TVIS_EXPANDED; 1629*c2c66affSColin Finck ret = SendMessageA(hTree, TVM_GETITEMA, 0, (LPARAM)&item); 1630*c2c66affSColin Finck expect(TRUE, ret); 1631*c2c66affSColin Finck ok((item.state & TVIS_EXPANDED) == 0, "expected collapsed\n"); 1632*c2c66affSColin Finck /* all further collapse/expand attempts won't produce any notifications, 1633*c2c66affSColin Finck the only way is to reset with all children removed */ 1634*c2c66affSColin Finck ok_sequence(sequences, PARENT_SEQ_INDEX, empty_seq, "collapse after expand notifications", FALSE); 1635*c2c66affSColin Finck 1636*c2c66affSColin Finck /* try to toggle child that doesn't have children itself */ 1637*c2c66affSColin Finck flush_sequences(sequences, NUM_MSG_SEQUENCES); 1638*c2c66affSColin Finck ret = SendMessageA(hTree, TVM_EXPAND, TVE_TOGGLE, (LPARAM)hChild); 1639*c2c66affSColin Finck expect(FALSE, ret); 1640*c2c66affSColin Finck ok_sequence(sequences, PARENT_SEQ_INDEX, empty_seq, "toggle node without children", FALSE); 1641*c2c66affSColin Finck 1642*c2c66affSColin Finck DestroyWindow(hTree); 1643*c2c66affSColin Finck 1644*c2c66affSColin Finck /* test TVM_GETITEMRECT inside TVN_ITEMEXPANDED notification */ 1645*c2c66affSColin Finck hTree = create_treeview_control(0); 1646*c2c66affSColin Finck fill_tree(hTree); 1647*c2c66affSColin Finck g_get_rect_in_expand = TRUE; 1648*c2c66affSColin Finck ret = SendMessageA(hTree, TVM_SELECTITEM, TVGN_CARET, (LPARAM)hChild); 1649*c2c66affSColin Finck expect(TRUE, ret); 1650*c2c66affSColin Finck g_get_rect_in_expand = FALSE; 1651*c2c66affSColin Finck 1652*c2c66affSColin Finck DestroyWindow(hTree); 1653*c2c66affSColin Finck 1654*c2c66affSColin Finck /* TVE_TOGGLE acts as any other TVM_EXPAND */ 1655*c2c66affSColin Finck hTree = create_treeview_control(0); 1656*c2c66affSColin Finck fill_tree(hTree); 1657*c2c66affSColin Finck 1658*c2c66affSColin Finck flush_sequences(sequences, NUM_MSG_SEQUENCES); 1659*c2c66affSColin Finck ret = SendMessageA(hTree, TVM_EXPAND, TVE_TOGGLE, (LPARAM)hRoot); 1660*c2c66affSColin Finck expect(TRUE, ret); 1661*c2c66affSColin Finck ok_sequence(sequences, PARENT_SEQ_INDEX, parent_expand_seq, "toggle node (expand)", FALSE); 1662*c2c66affSColin Finck 1663*c2c66affSColin Finck /* toggle again - no notifications */ 1664*c2c66affSColin Finck flush_sequences(sequences, NUM_MSG_SEQUENCES); 1665*c2c66affSColin Finck ret = SendMessageA(hTree, TVM_EXPAND, TVE_TOGGLE, (LPARAM)hRoot); 1666*c2c66affSColin Finck expect(TRUE, ret); 1667*c2c66affSColin Finck ok_sequence(sequences, PARENT_SEQ_INDEX, empty_seq, "toggle node (collapse)", FALSE); 1668*c2c66affSColin Finck 1669*c2c66affSColin Finck DestroyWindow(hTree); 1670*c2c66affSColin Finck 1671*c2c66affSColin Finck /* some keyboard events are also translated to expand */ 1672*c2c66affSColin Finck hTree = create_treeview_control(0); 1673*c2c66affSColin Finck fill_tree(hTree); 1674*c2c66affSColin Finck 1675*c2c66affSColin Finck /* preselect root node here */ 1676*c2c66affSColin Finck ret = SendMessageA(hTree, TVM_SELECTITEM, TVGN_CARET, (LPARAM)hRoot); 1677*c2c66affSColin Finck expect(TRUE, ret); 1678*c2c66affSColin Finck 1679*c2c66affSColin Finck g_get_from_expand = TRUE; 1680*c2c66affSColin Finck flush_sequences(sequences, NUM_MSG_SEQUENCES); 1681*c2c66affSColin Finck ret = SendMessageA(hTree, WM_KEYDOWN, VK_ADD, 0); 1682*c2c66affSColin Finck expect(FALSE, ret); 1683*c2c66affSColin Finck ok_sequence(sequences, PARENT_SEQ_INDEX, parent_expand_kb_seq, "expand node", FALSE); 1684*c2c66affSColin Finck ok(g_item_expanding.state == TVIS_SELECTED, "got state on TVN_ITEMEXPANDING 0x%08x\n", 1685*c2c66affSColin Finck g_item_expanding.state); 1686*c2c66affSColin Finck ok(g_item_expanded.state == (TVIS_SELECTED|TVIS_EXPANDED), "got state on TVN_ITEMEXPANDED 0x%08x\n", 1687*c2c66affSColin Finck g_item_expanded.state); 1688*c2c66affSColin Finck 1689*c2c66affSColin Finck flush_sequences(sequences, NUM_MSG_SEQUENCES); 1690*c2c66affSColin Finck ret = SendMessageA(hTree, WM_KEYDOWN, VK_ADD, 0); 1691*c2c66affSColin Finck expect(FALSE, ret); 1692*c2c66affSColin Finck ok_sequence(sequences, PARENT_SEQ_INDEX, parent_expand_kb_seq, "expand node again", FALSE); 1693*c2c66affSColin Finck ok(g_item_expanding.state == (TVIS_SELECTED|TVIS_EXPANDED|TVIS_EXPANDEDONCE), "got state on TVN_ITEMEXPANDING 0x%08x\n", 1694*c2c66affSColin Finck g_item_expanding.state); 1695*c2c66affSColin Finck ok(g_item_expanded.state == (TVIS_SELECTED|TVIS_EXPANDED|TVIS_EXPANDEDONCE), "got state on TVN_ITEMEXPANDED 0x%08x\n", 1696*c2c66affSColin Finck g_item_expanded.state); 1697*c2c66affSColin Finck 1698*c2c66affSColin Finck flush_sequences(sequences, NUM_MSG_SEQUENCES); 1699*c2c66affSColin Finck ret = SendMessageA(hTree, WM_KEYDOWN, VK_SUBTRACT, 0); 1700*c2c66affSColin Finck expect(FALSE, ret); 1701*c2c66affSColin Finck ok_sequence(sequences, PARENT_SEQ_INDEX, parent_expand_kb_seq, "collapse node", FALSE); 1702*c2c66affSColin Finck ok(g_item_expanding.state == (TVIS_SELECTED|TVIS_EXPANDED|TVIS_EXPANDEDONCE), "got state on TVN_ITEMEXPANDING 0x%08x\n", 1703*c2c66affSColin Finck g_item_expanding.state); 1704*c2c66affSColin Finck ok(g_item_expanded.state == (TVIS_SELECTED|TVIS_EXPANDEDONCE), "got state on TVN_ITEMEXPANDED 0x%08x\n", 1705*c2c66affSColin Finck g_item_expanded.state); 1706*c2c66affSColin Finck 1707*c2c66affSColin Finck flush_sequences(sequences, NUM_MSG_SEQUENCES); 1708*c2c66affSColin Finck ret = SendMessageA(hTree, WM_KEYDOWN, VK_SUBTRACT, 0); 1709*c2c66affSColin Finck expect(FALSE, ret); 1710*c2c66affSColin Finck ok_sequence(sequences, PARENT_SEQ_INDEX, parent_collapse_2nd_kb_seq, "collapse node again", FALSE); 1711*c2c66affSColin Finck ok(g_item_expanding.state == (TVIS_SELECTED|TVIS_EXPANDEDONCE), "got state on TVN_ITEMEXPANDING 0x%08x\n", 1712*c2c66affSColin Finck g_item_expanding.state); 1713*c2c66affSColin Finck g_get_from_expand = FALSE; 1714*c2c66affSColin Finck 1715*c2c66affSColin Finck flush_sequences(sequences, NUM_MSG_SEQUENCES); 1716*c2c66affSColin Finck ret = SendMessageA(hTree, WM_KEYDOWN, VK_ADD, 0); 1717*c2c66affSColin Finck expect(FALSE, ret); 1718*c2c66affSColin Finck ok_sequence(sequences, PARENT_SEQ_INDEX, parent_expand_kb_seq, "expand node", FALSE); 1719*c2c66affSColin Finck 1720*c2c66affSColin Finck /* go to child */ 1721*c2c66affSColin Finck ret = SendMessageA(hTree, WM_KEYDOWN, VK_RIGHT, 0); 1722*c2c66affSColin Finck expect(FALSE, ret); 1723*c2c66affSColin Finck 1724*c2c66affSColin Finck /* try to expand child that doesn't have children itself */ 1725*c2c66affSColin Finck flush_sequences(sequences, NUM_MSG_SEQUENCES); 1726*c2c66affSColin Finck ret = SendMessageA(hTree, WM_KEYDOWN, VK_ADD, 0); 1727*c2c66affSColin Finck expect(FALSE, ret); 1728*c2c66affSColin Finck ok_sequence(sequences, PARENT_SEQ_INDEX, parent_expand_empty_kb_seq, "expand node with no children", FALSE); 1729*c2c66affSColin Finck 1730*c2c66affSColin Finck /* stay on current selection and set non-zero children count */ 1731*c2c66affSColin Finck hitem = (HTREEITEM)SendMessageA(hTree, TVM_GETNEXTITEM, TVGN_CARET, 0); 1732*c2c66affSColin Finck ok(hitem != NULL, "got %p\n", hitem); 1733*c2c66affSColin Finck 1734*c2c66affSColin Finck item.hItem = hitem; 1735*c2c66affSColin Finck item.mask = TVIF_CHILDREN; 1736*c2c66affSColin Finck item.cChildren = 0x80000000; 1737*c2c66affSColin Finck 1738*c2c66affSColin Finck ret = SendMessageA(hTree, TVM_SETITEMA, 0, (LPARAM)&item); 1739*c2c66affSColin Finck expect(TRUE, ret); 1740*c2c66affSColin Finck 1741*c2c66affSColin Finck flush_sequences(sequences, NUM_MSG_SEQUENCES); 1742*c2c66affSColin Finck ret = SendMessageA(hTree, WM_KEYDOWN, VK_ADD, 0); 1743*c2c66affSColin Finck expect(FALSE, ret); 1744*c2c66affSColin Finck ok_sequence(sequences, PARENT_SEQ_INDEX, parent_collapse_2nd_kb_seq, "expand node with children", FALSE); 1745*c2c66affSColin Finck 1746*c2c66affSColin Finck DestroyWindow(hTree); 1747*c2c66affSColin Finck } 1748*c2c66affSColin Finck 1749*c2c66affSColin Finck static void test_expandedimage(void) 1750*c2c66affSColin Finck { 1751*c2c66affSColin Finck TVITEMEXA item; 1752*c2c66affSColin Finck HWND hTree; 1753*c2c66affSColin Finck BOOL ret; 1754*c2c66affSColin Finck 1755*c2c66affSColin Finck hTree = create_treeview_control(0); 1756*c2c66affSColin Finck fill_tree(hTree); 1757*c2c66affSColin Finck 1758*c2c66affSColin Finck item.mask = TVIF_EXPANDEDIMAGE; 1759*c2c66affSColin Finck item.iExpandedImage = 1; 1760*c2c66affSColin Finck item.hItem = hRoot; 1761*c2c66affSColin Finck ret = SendMessageA(hTree, TVM_SETITEMA, 0, (LPARAM)&item); 1762*c2c66affSColin Finck ok(ret, "got %d\n", ret); 1763*c2c66affSColin Finck 1764*c2c66affSColin Finck item.mask = TVIF_EXPANDEDIMAGE; 1765*c2c66affSColin Finck item.iExpandedImage = -1; 1766*c2c66affSColin Finck item.hItem = hRoot; 1767*c2c66affSColin Finck ret = SendMessageA(hTree, TVM_GETITEMA, 0, (LPARAM)&item); 1768*c2c66affSColin Finck ok(ret, "got %d\n", ret); 1769*c2c66affSColin Finck 1770*c2c66affSColin Finck if (item.iExpandedImage != 1) 1771*c2c66affSColin Finck { 1772*c2c66affSColin Finck win_skip("TVIF_EXPANDEDIMAGE not supported\n"); 1773*c2c66affSColin Finck DestroyWindow(hTree); 1774*c2c66affSColin Finck return; 1775*c2c66affSColin Finck } 1776*c2c66affSColin Finck 1777*c2c66affSColin Finck /* test for default iExpandedImage value */ 1778*c2c66affSColin Finck item.mask = TVIF_EXPANDEDIMAGE; 1779*c2c66affSColin Finck item.iExpandedImage = -1; 1780*c2c66affSColin Finck item.hItem = hChild; 1781*c2c66affSColin Finck ret = SendMessageA(hTree, TVM_GETITEMA, 0, (LPARAM)&item); 1782*c2c66affSColin Finck ok(ret, "got %d\n", ret); 1783*c2c66affSColin Finck ok(item.iExpandedImage == (WORD)I_IMAGENONE, "got %d\n", item.iExpandedImage); 1784*c2c66affSColin Finck 1785*c2c66affSColin Finck DestroyWindow(hTree); 1786*c2c66affSColin Finck } 1787*c2c66affSColin Finck 1788*c2c66affSColin Finck static void test_TVS_SINGLEEXPAND(void) 1789*c2c66affSColin Finck { 1790*c2c66affSColin Finck HWND hTree; 1791*c2c66affSColin Finck HTREEITEM alpha, bravo, charlie, delta, echo, foxtrot, golf, hotel, india, juliet; 1792*c2c66affSColin Finck TVINSERTSTRUCTA ins; 1793*c2c66affSColin Finck char foo[] = "foo"; 1794*c2c66affSColin Finck char context[32]; 1795*c2c66affSColin Finck int i; 1796*c2c66affSColin Finck BOOL ret; 1797*c2c66affSColin Finck 1798*c2c66affSColin Finck /* build a fairly complex tree 1799*c2c66affSColin Finck * - TVI_ROOT 1800*c2c66affSColin Finck * - alpha 1801*c2c66affSColin Finck * - bravo 1802*c2c66affSColin Finck * - charlie 1803*c2c66affSColin Finck * - delta 1804*c2c66affSColin Finck * - echo 1805*c2c66affSColin Finck * - foxtrot 1806*c2c66affSColin Finck * - golf 1807*c2c66affSColin Finck * - hotel 1808*c2c66affSColin Finck * - india 1809*c2c66affSColin Finck * - juliet 1810*c2c66affSColin Finck */ 1811*c2c66affSColin Finck struct 1812*c2c66affSColin Finck { 1813*c2c66affSColin Finck HTREEITEM *handle; 1814*c2c66affSColin Finck HTREEITEM *parent; 1815*c2c66affSColin Finck UINT final_state; 1816*c2c66affSColin Finck } 1817*c2c66affSColin Finck items[] = 1818*c2c66affSColin Finck { 1819*c2c66affSColin Finck { &alpha, NULL, TVIS_EXPANDEDONCE }, 1820*c2c66affSColin Finck { &bravo, &alpha, TVIS_EXPANDEDONCE }, 1821*c2c66affSColin Finck { &charlie, &bravo, 0 }, 1822*c2c66affSColin Finck { &delta, &alpha, TVIS_EXPANDEDONCE }, 1823*c2c66affSColin Finck { &echo, &delta, 0 }, 1824*c2c66affSColin Finck { &foxtrot, NULL, TVIS_EXPANDEDONCE|TVIS_EXPANDED }, 1825*c2c66affSColin Finck { &golf, &foxtrot, TVIS_EXPANDEDONCE|TVIS_EXPANDED }, 1826*c2c66affSColin Finck { &hotel, &golf, 0 }, 1827*c2c66affSColin Finck { &india, &golf, TVIS_SELECTED }, 1828*c2c66affSColin Finck { &juliet, &foxtrot, 0 } 1829*c2c66affSColin Finck }; 1830*c2c66affSColin Finck 1831*c2c66affSColin Finck struct 1832*c2c66affSColin Finck { 1833*c2c66affSColin Finck HTREEITEM *select; 1834*c2c66affSColin Finck const struct message *sequence; 1835*c2c66affSColin Finck } 1836*c2c66affSColin Finck sequence_tests[] = 1837*c2c66affSColin Finck { 1838*c2c66affSColin Finck { &alpha, parent_singleexpand_seq0 }, 1839*c2c66affSColin Finck { &bravo, parent_singleexpand_seq1 }, 1840*c2c66affSColin Finck { &delta, parent_singleexpand_seq2 }, 1841*c2c66affSColin Finck { &foxtrot, parent_singleexpand_seq3 }, 1842*c2c66affSColin Finck { &alpha, parent_singleexpand_seq4 }, 1843*c2c66affSColin Finck { &golf, parent_singleexpand_seq5 }, 1844*c2c66affSColin Finck { &hotel, parent_singleexpand_seq6 }, 1845*c2c66affSColin Finck { &india, parent_singleexpand_seq7 }, 1846*c2c66affSColin Finck { &india, empty_seq } 1847*c2c66affSColin Finck }; 1848*c2c66affSColin Finck 1849*c2c66affSColin Finck hTree = create_treeview_control(0); 1850*c2c66affSColin Finck SetWindowLongA(hTree, GWL_STYLE, GetWindowLongA(hTree, GWL_STYLE) | TVS_SINGLEEXPAND); 1851*c2c66affSColin Finck /* to avoid painting related notifications */ 1852*c2c66affSColin Finck ShowWindow(hTree, SW_HIDE); 1853*c2c66affSColin Finck for (i = 0; i < sizeof(items)/sizeof(items[0]); i++) 1854*c2c66affSColin Finck { 1855*c2c66affSColin Finck ins.hParent = items[i].parent ? *items[i].parent : TVI_ROOT; 1856*c2c66affSColin Finck ins.hInsertAfter = TVI_FIRST; 1857*c2c66affSColin Finck U(ins).item.mask = TVIF_TEXT; 1858*c2c66affSColin Finck U(ins).item.pszText = foo; 1859*c2c66affSColin Finck *items[i].handle = TreeView_InsertItemA(hTree, &ins); 1860*c2c66affSColin Finck } 1861*c2c66affSColin Finck 1862*c2c66affSColin Finck for (i = 0; i < sizeof(sequence_tests)/sizeof(sequence_tests[0]); i++) 1863*c2c66affSColin Finck { 1864*c2c66affSColin Finck flush_sequences(sequences, NUM_MSG_SEQUENCES); 1865*c2c66affSColin Finck ret = SendMessageA(hTree, TVM_SELECTITEM, TVGN_CARET, (LPARAM)(*sequence_tests[i].select)); 1866*c2c66affSColin Finck ok(ret, "got %d\n", ret); 1867*c2c66affSColin Finck sprintf(context, "singleexpand notifications %d", i); 1868*c2c66affSColin Finck ok_sequence(sequences, PARENT_SEQ_INDEX, sequence_tests[i].sequence, context, FALSE); 1869*c2c66affSColin Finck } 1870*c2c66affSColin Finck 1871*c2c66affSColin Finck for (i = 0; i < sizeof(items)/sizeof(items[0]); i++) 1872*c2c66affSColin Finck { 1873*c2c66affSColin Finck ret = SendMessageA(hTree, TVM_GETITEMSTATE, (WPARAM)(*items[i].handle), 0xFFFF); 1874*c2c66affSColin Finck ok(ret == items[i].final_state, "singleexpand items[%d]: expected state 0x%x got 0x%x\n", 1875*c2c66affSColin Finck i, items[i].final_state, ret); 1876*c2c66affSColin Finck } 1877*c2c66affSColin Finck 1878*c2c66affSColin Finck /* a workaround for NT4 that sends expand notifications when nothing is about to expand */ 1879*c2c66affSColin Finck ret = SendMessageA(hTree, TVM_DELETEITEM, 0, (LPARAM)TVI_ROOT); 1880*c2c66affSColin Finck ok(ret, "got %d\n", ret); 1881*c2c66affSColin Finck fill_tree(hTree); 1882*c2c66affSColin Finck ret = SendMessageA(hTree, TVM_SELECTITEM, TVGN_CARET, 0); 1883*c2c66affSColin Finck ok(ret, "got %d\n", ret); 1884*c2c66affSColin Finck 1885*c2c66affSColin Finck DestroyWindow(hTree); 1886*c2c66affSColin Finck } 1887*c2c66affSColin Finck 1888*c2c66affSColin Finck static void test_WM_PAINT(void) 1889*c2c66affSColin Finck { 1890*c2c66affSColin Finck HWND hTree; 1891*c2c66affSColin Finck COLORREF clr; 1892*c2c66affSColin Finck LONG ret; 1893*c2c66affSColin Finck RECT rc; 1894*c2c66affSColin Finck HDC hdc; 1895*c2c66affSColin Finck 1896*c2c66affSColin Finck hTree = create_treeview_control(0); 1897*c2c66affSColin Finck 1898*c2c66affSColin Finck clr = SendMessageA(hTree, TVM_SETBKCOLOR, 0, RGB(255, 0, 0)); 1899*c2c66affSColin Finck ok(clr == ~0u, "got %d, expected -1\n", clr); 1900*c2c66affSColin Finck 1901*c2c66affSColin Finck hdc = GetDC(hMainWnd); 1902*c2c66affSColin Finck 1903*c2c66affSColin Finck GetClientRect(hMainWnd, &rc); 1904*c2c66affSColin Finck FillRect(hdc, &rc, GetStockObject(BLACK_BRUSH)); 1905*c2c66affSColin Finck 1906*c2c66affSColin Finck clr = GetPixel(hdc, 1, 1); 1907*c2c66affSColin Finck ok(clr == RGB(0, 0, 0), "got 0x%x\n", clr); 1908*c2c66affSColin Finck 1909*c2c66affSColin Finck ret = SendMessageA(hTree, WM_PAINT, (WPARAM)hdc, 0); 1910*c2c66affSColin Finck ok(ret == 0, "got %d\n", ret); 1911*c2c66affSColin Finck 1912*c2c66affSColin Finck clr = GetPixel(hdc, 1, 1); 1913*c2c66affSColin Finck ok(clr == RGB(255, 0, 0) || broken(clr == RGB(0, 0, 0)) /* win98 */, 1914*c2c66affSColin Finck "got 0x%x\n", clr); 1915*c2c66affSColin Finck 1916*c2c66affSColin Finck ReleaseDC(hMainWnd, hdc); 1917*c2c66affSColin Finck 1918*c2c66affSColin Finck DestroyWindow(hTree); 1919*c2c66affSColin Finck } 1920*c2c66affSColin Finck 1921*c2c66affSColin Finck static void test_delete_items(void) 1922*c2c66affSColin Finck { 1923*c2c66affSColin Finck const struct message *msg; 1924*c2c66affSColin Finck HWND hTree; 1925*c2c66affSColin Finck HTREEITEM hItem1, hItem2; 1926*c2c66affSColin Finck TVINSERTSTRUCTA ins; 1927*c2c66affSColin Finck INT ret; 1928*c2c66affSColin Finck 1929*c2c66affSColin Finck static CHAR item1[] = "Item 1"; 1930*c2c66affSColin Finck static CHAR item2[] = "Item 2"; 1931*c2c66affSColin Finck 1932*c2c66affSColin Finck hTree = create_treeview_control(0); 1933*c2c66affSColin Finck fill_tree(hTree); 1934*c2c66affSColin Finck 1935*c2c66affSColin Finck /* check delete order */ 1936*c2c66affSColin Finck flush_sequences(item_sequence, 1); 1937*c2c66affSColin Finck ret = SendMessageA(hTree, TVM_DELETEITEM, 0, 0); 1938*c2c66affSColin Finck ok(ret == TRUE, "got %d\n", ret); 1939*c2c66affSColin Finck 1940*c2c66affSColin Finck msg = item_sequence[0]->sequence; 1941*c2c66affSColin Finck ok(item_sequence[0]->count == 2, "expected 2 items, got %d\n", item_sequence[0]->count); 1942*c2c66affSColin Finck 1943*c2c66affSColin Finck if (item_sequence[0]->count == 2) 1944*c2c66affSColin Finck { 1945*c2c66affSColin Finck ok(msg[0].lParam == (LPARAM)hChild, "expected %p, got 0x%lx\n", hChild, msg[0].lParam); 1946*c2c66affSColin Finck ok(msg[1].lParam == (LPARAM)hRoot, "expected %p, got 0x%lx\n", hRoot, msg[1].lParam); 1947*c2c66affSColin Finck } 1948*c2c66affSColin Finck 1949*c2c66affSColin Finck ret = SendMessageA(hTree, TVM_GETCOUNT, 0, 0); 1950*c2c66affSColin Finck ok(ret == 0, "got %d\n", ret); 1951*c2c66affSColin Finck 1952*c2c66affSColin Finck DestroyWindow(hTree); 1953*c2c66affSColin Finck 1954*c2c66affSColin Finck /* Regression test for a crash when deleting the first visible item while bRedraw == false. */ 1955*c2c66affSColin Finck hTree = create_treeview_control(0); 1956*c2c66affSColin Finck 1957*c2c66affSColin Finck ret = SendMessageA(hTree, WM_SETREDRAW, FALSE, 0); 1958*c2c66affSColin Finck ok(ret == 0, "got %d\n", ret); 1959*c2c66affSColin Finck 1960*c2c66affSColin Finck ins.hParent = TVI_ROOT; 1961*c2c66affSColin Finck ins.hInsertAfter = TVI_ROOT; 1962*c2c66affSColin Finck U(ins).item.mask = TVIF_TEXT; 1963*c2c66affSColin Finck U(ins).item.pszText = item1; 1964*c2c66affSColin Finck hItem1 = TreeView_InsertItemA(hTree, &ins); 1965*c2c66affSColin Finck ok(hItem1 != NULL, "InsertItem failed\n"); 1966*c2c66affSColin Finck 1967*c2c66affSColin Finck ins.hParent = TVI_ROOT; 1968*c2c66affSColin Finck ins.hInsertAfter = hItem1; 1969*c2c66affSColin Finck U(ins).item.mask = TVIF_TEXT; 1970*c2c66affSColin Finck U(ins).item.pszText = item2; 1971*c2c66affSColin Finck hItem2 = TreeView_InsertItemA(hTree, &ins); 1972*c2c66affSColin Finck ok(hItem2 != NULL, "InsertItem failed\n"); 1973*c2c66affSColin Finck 1974*c2c66affSColin Finck ret = SendMessageA(hTree, TVM_DELETEITEM, 0, (LPARAM)hItem1); 1975*c2c66affSColin Finck ok(ret == TRUE, "got %d\n", ret); 1976*c2c66affSColin Finck 1977*c2c66affSColin Finck ret = SendMessageA(hTree, WM_SETREDRAW, TRUE, 0); 1978*c2c66affSColin Finck ok(ret == 0, "got %d\n", ret); 1979*c2c66affSColin Finck 1980*c2c66affSColin Finck DestroyWindow(hTree); 1981*c2c66affSColin Finck } 1982*c2c66affSColin Finck 1983*c2c66affSColin Finck static void test_cchildren(void) 1984*c2c66affSColin Finck { 1985*c2c66affSColin Finck HWND hTree; 1986*c2c66affSColin Finck INT ret; 1987*c2c66affSColin Finck TVITEMA item; 1988*c2c66affSColin Finck 1989*c2c66affSColin Finck hTree = create_treeview_control(0); 1990*c2c66affSColin Finck fill_tree(hTree); 1991*c2c66affSColin Finck 1992*c2c66affSColin Finck ret = SendMessageA(hTree, TVM_DELETEITEM, 0, (LPARAM)hChild); 1993*c2c66affSColin Finck expect(TRUE, ret); 1994*c2c66affSColin Finck 1995*c2c66affSColin Finck /* check cChildren - automatic mode */ 1996*c2c66affSColin Finck item.hItem = hRoot; 1997*c2c66affSColin Finck item.mask = TVIF_CHILDREN; 1998*c2c66affSColin Finck 1999*c2c66affSColin Finck ret = SendMessageA(hTree, TVM_GETITEMA, 0, (LPARAM)&item); 2000*c2c66affSColin Finck expect(TRUE, ret); 2001*c2c66affSColin Finck expect(0, item.cChildren); 2002*c2c66affSColin Finck 2003*c2c66affSColin Finck DestroyWindow(hTree); 2004*c2c66affSColin Finck 2005*c2c66affSColin Finck /* start over */ 2006*c2c66affSColin Finck hTree = create_treeview_control(0); 2007*c2c66affSColin Finck fill_tree(hTree); 2008*c2c66affSColin Finck 2009*c2c66affSColin Finck /* turn off automatic mode by setting cChildren explicitly */ 2010*c2c66affSColin Finck item.hItem = hRoot; 2011*c2c66affSColin Finck item.mask = TVIF_CHILDREN; 2012*c2c66affSColin Finck 2013*c2c66affSColin Finck ret = SendMessageA(hTree, TVM_GETITEMA, 0, (LPARAM)&item); 2014*c2c66affSColin Finck expect(TRUE, ret); 2015*c2c66affSColin Finck expect(1, item.cChildren); 2016*c2c66affSColin Finck 2017*c2c66affSColin Finck ret = SendMessageA(hTree, TVM_SETITEMA, 0, (LPARAM)&item); 2018*c2c66affSColin Finck expect(TRUE, ret); 2019*c2c66affSColin Finck 2020*c2c66affSColin Finck ret = SendMessageA(hTree, TVM_DELETEITEM, 0, (LPARAM)hChild); 2021*c2c66affSColin Finck expect(TRUE, ret); 2022*c2c66affSColin Finck 2023*c2c66affSColin Finck /* check cChildren */ 2024*c2c66affSColin Finck ret = SendMessageA(hTree, TVM_GETITEMA, 0, (LPARAM)&item); 2025*c2c66affSColin Finck expect(TRUE, ret); 2026*c2c66affSColin Finck todo_wine 2027*c2c66affSColin Finck expect(1, item.cChildren); 2028*c2c66affSColin Finck 2029*c2c66affSColin Finck DestroyWindow(hTree); 2030*c2c66affSColin Finck } 2031*c2c66affSColin Finck 2032*c2c66affSColin Finck struct _ITEM_DATA 2033*c2c66affSColin Finck { 2034*c2c66affSColin Finck HTREEITEM parent; /* for root value of parent field is unidetified */ 2035*c2c66affSColin Finck HTREEITEM nextsibling; 2036*c2c66affSColin Finck HTREEITEM firstchild; 2037*c2c66affSColin Finck }; 2038*c2c66affSColin Finck 2039*c2c66affSColin Finck static void _check_item(HTREEITEM item, HTREEITEM parent, HTREEITEM nextsibling, HTREEITEM firstchild, int line) 2040*c2c66affSColin Finck { 2041*c2c66affSColin Finck struct _ITEM_DATA *data = (struct _ITEM_DATA*)item; 2042*c2c66affSColin Finck 2043*c2c66affSColin Finck ok_(__FILE__, line)(data->parent == parent, "parent %p, got %p\n", parent, data->parent); 2044*c2c66affSColin Finck ok_(__FILE__, line)(data->nextsibling == nextsibling, "sibling %p, got %p\n", nextsibling, data->nextsibling); 2045*c2c66affSColin Finck ok_(__FILE__, line)(data->firstchild == firstchild, "firstchild %p, got %p\n", firstchild, data->firstchild); 2046*c2c66affSColin Finck } 2047*c2c66affSColin Finck 2048*c2c66affSColin Finck #define check_item(a, b, c, d) _check_item(a, b, c, d, __LINE__) 2049*c2c66affSColin Finck 2050*c2c66affSColin Finck static void test_htreeitem_layout(void) 2051*c2c66affSColin Finck { 2052*c2c66affSColin Finck TVINSERTSTRUCTA ins; 2053*c2c66affSColin Finck HTREEITEM item1, item2; 2054*c2c66affSColin Finck HWND hTree; 2055*c2c66affSColin Finck 2056*c2c66affSColin Finck hTree = create_treeview_control(0); 2057*c2c66affSColin Finck fill_tree(hTree); 2058*c2c66affSColin Finck 2059*c2c66affSColin Finck /* root has some special pointer in parent field */ 2060*c2c66affSColin Finck check_item(hRoot, ((struct _ITEM_DATA*)hRoot)->parent, 0, hChild); 2061*c2c66affSColin Finck check_item(hChild, hRoot, 0, 0); 2062*c2c66affSColin Finck 2063*c2c66affSColin Finck ins.hParent = hChild; 2064*c2c66affSColin Finck ins.hInsertAfter = TVI_FIRST; 2065*c2c66affSColin Finck U(ins).item.mask = 0; 2066*c2c66affSColin Finck item1 = TreeView_InsertItemA(hTree, &ins); 2067*c2c66affSColin Finck 2068*c2c66affSColin Finck check_item(item1, hChild, 0, 0); 2069*c2c66affSColin Finck 2070*c2c66affSColin Finck ins.hParent = hRoot; 2071*c2c66affSColin Finck ins.hInsertAfter = TVI_FIRST; 2072*c2c66affSColin Finck U(ins).item.mask = 0; 2073*c2c66affSColin Finck item2 = TreeView_InsertItemA(hTree, &ins); 2074*c2c66affSColin Finck 2075*c2c66affSColin Finck check_item(item2, hRoot, hChild, 0); 2076*c2c66affSColin Finck 2077*c2c66affSColin Finck SendMessageA(hTree, TVM_DELETEITEM, 0, (LPARAM)hChild); 2078*c2c66affSColin Finck 2079*c2c66affSColin Finck /* without children now */ 2080*c2c66affSColin Finck check_item(hRoot, ((struct _ITEM_DATA*)hRoot)->parent, 0, item2); 2081*c2c66affSColin Finck 2082*c2c66affSColin Finck DestroyWindow(hTree); 2083*c2c66affSColin Finck } 2084*c2c66affSColin Finck 2085*c2c66affSColin Finck static void test_TVS_CHECKBOXES(void) 2086*c2c66affSColin Finck { 2087*c2c66affSColin Finck HIMAGELIST himl, himl2; 2088*c2c66affSColin Finck HWND hTree, hTree2; 2089*c2c66affSColin Finck TVITEMA item; 2090*c2c66affSColin Finck DWORD ret; 2091*c2c66affSColin Finck MSG msg; 2092*c2c66affSColin Finck 2093*c2c66affSColin Finck hTree = create_treeview_control(0); 2094*c2c66affSColin Finck fill_tree(hTree); 2095*c2c66affSColin Finck 2096*c2c66affSColin Finck himl = (HIMAGELIST)SendMessageA(hTree, TVM_GETIMAGELIST, TVSIL_STATE, 0); 2097*c2c66affSColin Finck ok(himl == NULL, "got %p\n", himl); 2098*c2c66affSColin Finck 2099*c2c66affSColin Finck item.hItem = hRoot; 2100*c2c66affSColin Finck item.mask = TVIF_STATE; 2101*c2c66affSColin Finck item.state = INDEXTOSTATEIMAGEMASK(1); 2102*c2c66affSColin Finck item.stateMask = TVIS_STATEIMAGEMASK; 2103*c2c66affSColin Finck ret = SendMessageA(hTree, TVM_GETITEMA, 0, (LPARAM)&item); 2104*c2c66affSColin Finck expect(TRUE, ret); 2105*c2c66affSColin Finck ok(item.state == 0, "got 0x%x\n", item.state); 2106*c2c66affSColin Finck 2107*c2c66affSColin Finck /* set some index for a child */ 2108*c2c66affSColin Finck item.hItem = hChild; 2109*c2c66affSColin Finck item.mask = TVIF_STATE; 2110*c2c66affSColin Finck item.state = INDEXTOSTATEIMAGEMASK(4); 2111*c2c66affSColin Finck item.stateMask = TVIS_STATEIMAGEMASK; 2112*c2c66affSColin Finck ret = SendMessageA(hTree, TVM_SETITEMA, 0, (LPARAM)&item); 2113*c2c66affSColin Finck expect(TRUE, ret); 2114*c2c66affSColin Finck 2115*c2c66affSColin Finck /* enabling check boxes set all items to 1 state image index */ 2116*c2c66affSColin Finck SetWindowLongA(hTree, GWL_STYLE, GetWindowLongA(hTree, GWL_STYLE) | TVS_CHECKBOXES); 2117*c2c66affSColin Finck himl = (HIMAGELIST)SendMessageA(hTree, TVM_GETIMAGELIST, TVSIL_STATE, 0); 2118*c2c66affSColin Finck ok(himl != NULL, "got %p\n", himl); 2119*c2c66affSColin Finck 2120*c2c66affSColin Finck himl2 = (HIMAGELIST)SendMessageA(hTree, TVM_GETIMAGELIST, TVSIL_STATE, 0); 2121*c2c66affSColin Finck ok(himl2 != NULL, "got %p\n", himl2); 2122*c2c66affSColin Finck ok(himl2 == himl, "got %p, expected %p\n", himl2, himl); 2123*c2c66affSColin Finck 2124*c2c66affSColin Finck item.hItem = hRoot; 2125*c2c66affSColin Finck item.mask = TVIF_STATE; 2126*c2c66affSColin Finck item.state = 0; 2127*c2c66affSColin Finck item.stateMask = TVIS_STATEIMAGEMASK; 2128*c2c66affSColin Finck ret = SendMessageA(hTree, TVM_GETITEMA, 0, (LPARAM)&item); 2129*c2c66affSColin Finck expect(TRUE, ret); 2130*c2c66affSColin Finck ok(item.state == INDEXTOSTATEIMAGEMASK(1), "got 0x%x\n", item.state); 2131*c2c66affSColin Finck 2132*c2c66affSColin Finck item.hItem = hChild; 2133*c2c66affSColin Finck item.mask = TVIF_STATE; 2134*c2c66affSColin Finck item.state = 0; 2135*c2c66affSColin Finck item.stateMask = TVIS_STATEIMAGEMASK; 2136*c2c66affSColin Finck ret = SendMessageA(hTree, TVM_GETITEMA, 0, (LPARAM)&item); 2137*c2c66affSColin Finck expect(TRUE, ret); 2138*c2c66affSColin Finck ok(item.state == INDEXTOSTATEIMAGEMASK(1), "got 0x%x\n", item.state); 2139*c2c66affSColin Finck 2140*c2c66affSColin Finck /* create another control and check its checkbox list */ 2141*c2c66affSColin Finck hTree2 = create_treeview_control(0); 2142*c2c66affSColin Finck fill_tree(hTree2); 2143*c2c66affSColin Finck 2144*c2c66affSColin Finck /* set some index for a child */ 2145*c2c66affSColin Finck item.hItem = hChild; 2146*c2c66affSColin Finck item.mask = TVIF_STATE; 2147*c2c66affSColin Finck item.state = INDEXTOSTATEIMAGEMASK(4); 2148*c2c66affSColin Finck item.stateMask = TVIS_STATEIMAGEMASK; 2149*c2c66affSColin Finck ret = SendMessageA(hTree2, TVM_SETITEMA, 0, (LPARAM)&item); 2150*c2c66affSColin Finck expect(TRUE, ret); 2151*c2c66affSColin Finck 2152*c2c66affSColin Finck /* enabling check boxes set all items to 1 state image index */ 2153*c2c66affSColin Finck SetWindowLongA(hTree2, GWL_STYLE, GetWindowLongA(hTree, GWL_STYLE) | TVS_CHECKBOXES); 2154*c2c66affSColin Finck himl2 = (HIMAGELIST)SendMessageA(hTree2, TVM_GETIMAGELIST, TVSIL_STATE, 0); 2155*c2c66affSColin Finck ok(himl2 != NULL, "got %p\n", himl2); 2156*c2c66affSColin Finck ok(himl != himl2, "got %p, expected %p\n", himl2, himl); 2157*c2c66affSColin Finck 2158*c2c66affSColin Finck DestroyWindow(hTree2); 2159*c2c66affSColin Finck DestroyWindow(hTree); 2160*c2c66affSColin Finck 2161*c2c66affSColin Finck /* the same, but initially created with TVS_CHECKBOXES */ 2162*c2c66affSColin Finck hTree = create_treeview_control(TVS_CHECKBOXES); 2163*c2c66affSColin Finck fill_tree(hTree); 2164*c2c66affSColin Finck himl = (HIMAGELIST)SendMessageA(hTree, TVM_GETIMAGELIST, TVSIL_STATE, 0); 2165*c2c66affSColin Finck ok(himl == NULL, "got %p\n", himl); 2166*c2c66affSColin Finck 2167*c2c66affSColin Finck item.hItem = hRoot; 2168*c2c66affSColin Finck item.mask = TVIF_STATE; 2169*c2c66affSColin Finck item.state = 0; 2170*c2c66affSColin Finck item.stateMask = TVIS_STATEIMAGEMASK; 2171*c2c66affSColin Finck ret = SendMessageA(hTree, TVM_GETITEMA, 0, (LPARAM)&item); 2172*c2c66affSColin Finck expect(TRUE, ret); 2173*c2c66affSColin Finck ok(item.state == INDEXTOSTATEIMAGEMASK(1), "got 0x%x\n", item.state); 2174*c2c66affSColin Finck 2175*c2c66affSColin Finck item.hItem = hChild; 2176*c2c66affSColin Finck item.mask = TVIF_STATE; 2177*c2c66affSColin Finck item.state = 0; 2178*c2c66affSColin Finck item.stateMask = TVIS_STATEIMAGEMASK; 2179*c2c66affSColin Finck ret = SendMessageA(hTree, TVM_GETITEMA, 0, (LPARAM)&item); 2180*c2c66affSColin Finck expect(TRUE, ret); 2181*c2c66affSColin Finck ok(item.state == INDEXTOSTATEIMAGEMASK(1), "got 0x%x\n", item.state); 2182*c2c66affSColin Finck 2183*c2c66affSColin Finck item.hItem = hChild; 2184*c2c66affSColin Finck item.mask = TVIF_STATE; 2185*c2c66affSColin Finck item.state = INDEXTOSTATEIMAGEMASK(2); 2186*c2c66affSColin Finck item.stateMask = TVIS_STATEIMAGEMASK; 2187*c2c66affSColin Finck ret = SendMessageA(hTree, TVM_SETITEMA, 0, (LPARAM)&item); 2188*c2c66affSColin Finck expect(TRUE, ret); 2189*c2c66affSColin Finck 2190*c2c66affSColin Finck item.hItem = hChild; 2191*c2c66affSColin Finck item.mask = TVIF_STATE; 2192*c2c66affSColin Finck item.state = 0; 2193*c2c66affSColin Finck ret = SendMessageA(hTree, TVM_GETITEMA, 0, (LPARAM)&item); 2194*c2c66affSColin Finck expect(TRUE, ret); 2195*c2c66affSColin Finck ok(item.state == INDEXTOSTATEIMAGEMASK(2), "got 0x%x\n", item.state); 2196*c2c66affSColin Finck 2197*c2c66affSColin Finck while(GetMessageA(&msg, 0, 0, 0)) 2198*c2c66affSColin Finck { 2199*c2c66affSColin Finck TranslateMessage(&msg); 2200*c2c66affSColin Finck DispatchMessageA(&msg); 2201*c2c66affSColin Finck 2202*c2c66affSColin Finck if((msg.hwnd == hTree) && (msg.message == WM_PAINT)) 2203*c2c66affSColin Finck break; 2204*c2c66affSColin Finck } 2205*c2c66affSColin Finck 2206*c2c66affSColin Finck item.hItem = hChild; 2207*c2c66affSColin Finck item.mask = TVIF_STATE; 2208*c2c66affSColin Finck item.state = 0; 2209*c2c66affSColin Finck ret = SendMessageA(hTree, TVM_GETITEMA, 0, (LPARAM)&item); 2210*c2c66affSColin Finck expect(TRUE, ret); 2211*c2c66affSColin Finck ok(item.state == INDEXTOSTATEIMAGEMASK(1), "got 0x%x\n", item.state); 2212*c2c66affSColin Finck 2213*c2c66affSColin Finck himl = (HIMAGELIST)SendMessageA(hTree, TVM_GETIMAGELIST, TVSIL_STATE, 0); 2214*c2c66affSColin Finck ok(himl != NULL, "got %p\n", himl); 2215*c2c66affSColin Finck 2216*c2c66affSColin Finck DestroyWindow(hTree); 2217*c2c66affSColin Finck 2218*c2c66affSColin Finck /* check what happens if TVSIL_STATE image list is removed */ 2219*c2c66affSColin Finck hTree = create_treeview_control(0); 2220*c2c66affSColin Finck fill_tree(hTree); 2221*c2c66affSColin Finck himl = (HIMAGELIST)SendMessageA(hTree, TVM_GETIMAGELIST, TVSIL_STATE, 0); 2222*c2c66affSColin Finck ok(himl == NULL, "got %p\n", himl); 2223*c2c66affSColin Finck 2224*c2c66affSColin Finck SetWindowLongA(hTree, GWL_STYLE, GetWindowLongA(hTree, GWL_STYLE) | TVS_CHECKBOXES); 2225*c2c66affSColin Finck himl = (HIMAGELIST)SendMessageA(hTree, TVM_GETIMAGELIST, TVSIL_STATE, 0); 2226*c2c66affSColin Finck ok(himl != NULL, "got %p\n", himl); 2227*c2c66affSColin Finck 2228*c2c66affSColin Finck himl2 = (HIMAGELIST)SendMessageA(hTree, TVM_SETIMAGELIST, TVSIL_STATE, 0); 2229*c2c66affSColin Finck ok(himl2 == himl, "got %p\n", himl2); 2230*c2c66affSColin Finck 2231*c2c66affSColin Finck himl2 = (HIMAGELIST)SendMessageA(hTree, TVM_GETIMAGELIST, TVSIL_STATE, 0); 2232*c2c66affSColin Finck ok(himl2 == NULL, "got %p\n", himl2); 2233*c2c66affSColin Finck 2234*c2c66affSColin Finck item.hItem = hChild; 2235*c2c66affSColin Finck item.mask = TVIF_STATE; 2236*c2c66affSColin Finck item.state = INDEXTOSTATEIMAGEMASK(2); 2237*c2c66affSColin Finck item.stateMask = TVIS_STATEIMAGEMASK; 2238*c2c66affSColin Finck ret = SendMessageA(hTree, TVM_SETITEMA, 0, (LPARAM)&item); 2239*c2c66affSColin Finck expect(TRUE, ret); 2240*c2c66affSColin Finck 2241*c2c66affSColin Finck item.hItem = hChild; 2242*c2c66affSColin Finck item.mask = TVIF_STATE; 2243*c2c66affSColin Finck item.state = 0; 2244*c2c66affSColin Finck ret = SendMessageA(hTree, TVM_GETITEMA, 0, (LPARAM)&item); 2245*c2c66affSColin Finck expect(TRUE, ret); 2246*c2c66affSColin Finck ok(item.state == INDEXTOSTATEIMAGEMASK(2), "got 0x%x\n", item.state); 2247*c2c66affSColin Finck 2248*c2c66affSColin Finck while(GetMessageA(&msg, 0, 0, 0)) 2249*c2c66affSColin Finck { 2250*c2c66affSColin Finck TranslateMessage(&msg); 2251*c2c66affSColin Finck DispatchMessageA(&msg); 2252*c2c66affSColin Finck 2253*c2c66affSColin Finck if((msg.hwnd == hTree) && (msg.message == WM_PAINT)) 2254*c2c66affSColin Finck break; 2255*c2c66affSColin Finck } 2256*c2c66affSColin Finck 2257*c2c66affSColin Finck item.hItem = hChild; 2258*c2c66affSColin Finck item.mask = TVIF_STATE; 2259*c2c66affSColin Finck item.state = 0; 2260*c2c66affSColin Finck ret = SendMessageA(hTree, TVM_GETITEMA, 0, (LPARAM)&item); 2261*c2c66affSColin Finck expect(TRUE, ret); 2262*c2c66affSColin Finck ok(item.state == INDEXTOSTATEIMAGEMASK(1), "got 0x%x\n", item.state); 2263*c2c66affSColin Finck 2264*c2c66affSColin Finck himl = (HIMAGELIST)SendMessageA(hTree, TVM_GETIMAGELIST, TVSIL_STATE, 0); 2265*c2c66affSColin Finck ok(himl != NULL, "got %p\n", himl); 2266*c2c66affSColin Finck 2267*c2c66affSColin Finck DestroyWindow(hTree); 2268*c2c66affSColin Finck } 2269*c2c66affSColin Finck 2270*c2c66affSColin Finck static void test_TVM_GETNEXTITEM(void) 2271*c2c66affSColin Finck { 2272*c2c66affSColin Finck HTREEITEM item; 2273*c2c66affSColin Finck HWND hTree; 2274*c2c66affSColin Finck 2275*c2c66affSColin Finck hTree = create_treeview_control(0); 2276*c2c66affSColin Finck fill_tree(hTree); 2277*c2c66affSColin Finck 2278*c2c66affSColin Finck item = (HTREEITEM)SendMessageA(hTree, TVM_GETNEXTITEM, TVGN_ROOT, 0); 2279*c2c66affSColin Finck ok(item == hRoot, "got %p, expected %p\n", item, hRoot); 2280*c2c66affSColin Finck 2281*c2c66affSColin Finck item = (HTREEITEM)SendMessageA(hTree, TVM_GETNEXTITEM, TVGN_ROOT, (LPARAM)TVI_ROOT); 2282*c2c66affSColin Finck ok(item == hRoot, "got %p, expected %p\n", item, hRoot); 2283*c2c66affSColin Finck 2284*c2c66affSColin Finck item = (HTREEITEM)SendMessageA(hTree, TVM_GETNEXTITEM, TVGN_ROOT, (LPARAM)hRoot); 2285*c2c66affSColin Finck ok(item == hRoot, "got %p, expected %p\n", item, hRoot); 2286*c2c66affSColin Finck 2287*c2c66affSColin Finck item = (HTREEITEM)SendMessageA(hTree, TVM_GETNEXTITEM, TVGN_ROOT, (LPARAM)hChild); 2288*c2c66affSColin Finck ok(item == hRoot, "got %p, expected %p\n", item, hRoot); 2289*c2c66affSColin Finck 2290*c2c66affSColin Finck item = (HTREEITEM)SendMessageA(hTree, TVM_GETNEXTITEM, TVGN_CHILD, 0); 2291*c2c66affSColin Finck ok(item == hRoot, "got %p, expected %p\n", item, hRoot); 2292*c2c66affSColin Finck 2293*c2c66affSColin Finck item = (HTREEITEM)SendMessageA(hTree, TVM_GETNEXTITEM, TVGN_CHILD, (LPARAM)hRoot); 2294*c2c66affSColin Finck ok(item == hChild, "got %p, expected %p\n", item, hChild); 2295*c2c66affSColin Finck 2296*c2c66affSColin Finck item = (HTREEITEM)SendMessageA(hTree, TVM_GETNEXTITEM, TVGN_CHILD, (LPARAM)TVI_ROOT); 2297*c2c66affSColin Finck ok(item == hRoot, "got %p, expected %p\n", item, hRoot); 2298*c2c66affSColin Finck 2299*c2c66affSColin Finck item = (HTREEITEM)SendMessageA(hTree, TVM_GETNEXTITEM, TVGN_PARENT, 0); 2300*c2c66affSColin Finck ok(item == NULL, "got %p\n", item); 2301*c2c66affSColin Finck 2302*c2c66affSColin Finck item = (HTREEITEM)SendMessageA(hTree, TVM_GETNEXTITEM, TVGN_PARENT, (LPARAM)hChild); 2303*c2c66affSColin Finck ok(item == hRoot, "got %p, expected %p\n", item, hRoot); 2304*c2c66affSColin Finck 2305*c2c66affSColin Finck DestroyWindow(hTree); 2306*c2c66affSColin Finck } 2307*c2c66affSColin Finck 2308*c2c66affSColin Finck static void test_TVM_HITTEST(void) 2309*c2c66affSColin Finck { 2310*c2c66affSColin Finck HWND hTree; 2311*c2c66affSColin Finck LRESULT ret; 2312*c2c66affSColin Finck RECT rc; 2313*c2c66affSColin Finck TVHITTESTINFO ht; 2314*c2c66affSColin Finck 2315*c2c66affSColin Finck hTree = create_treeview_control(0); 2316*c2c66affSColin Finck fill_tree(hTree); 2317*c2c66affSColin Finck 2318*c2c66affSColin Finck *(HTREEITEM*)&rc = hRoot; 2319*c2c66affSColin Finck ret = SendMessageA(hTree, TVM_GETITEMRECT, TRUE, (LPARAM)&rc); 2320*c2c66affSColin Finck expect(TRUE, (BOOL)ret); 2321*c2c66affSColin Finck 2322*c2c66affSColin Finck ht.pt.x = rc.left-1; 2323*c2c66affSColin Finck ht.pt.y = rc.top; 2324*c2c66affSColin Finck 2325*c2c66affSColin Finck ret = SendMessageA(hTree, TVM_HITTEST, 0, (LPARAM)&ht); 2326*c2c66affSColin Finck ok((HTREEITEM)ret == hRoot, "got %p, expected %p\n", (HTREEITEM)ret, hRoot); 2327*c2c66affSColin Finck ok(ht.hItem == hRoot, "got %p, expected %p\n", ht.hItem, hRoot); 2328*c2c66affSColin Finck ok(ht.flags == TVHT_ONITEMBUTTON, "got %d, expected %d\n", ht.flags, TVHT_ONITEMBUTTON); 2329*c2c66affSColin Finck 2330*c2c66affSColin Finck ret = SendMessageA(hTree, TVM_EXPAND, TVE_EXPAND, (LPARAM)hRoot); 2331*c2c66affSColin Finck expect(TRUE, (BOOL)ret); 2332*c2c66affSColin Finck 2333*c2c66affSColin Finck *(HTREEITEM*)&rc = hChild; 2334*c2c66affSColin Finck ret = SendMessageA(hTree, TVM_GETITEMRECT, TRUE, (LPARAM)&rc); 2335*c2c66affSColin Finck expect(TRUE, (BOOL)ret); 2336*c2c66affSColin Finck 2337*c2c66affSColin Finck ht.pt.x = rc.left-1; 2338*c2c66affSColin Finck ht.pt.y = rc.top; 2339*c2c66affSColin Finck 2340*c2c66affSColin Finck ret = SendMessageA(hTree, TVM_HITTEST, 0, (LPARAM)&ht); 2341*c2c66affSColin Finck ok((HTREEITEM)ret == hChild, "got %p, expected %p\n", (HTREEITEM)ret, hChild); 2342*c2c66affSColin Finck ok(ht.hItem == hChild, "got %p, expected %p\n", ht.hItem, hChild); 2343*c2c66affSColin Finck /* Wine returns item button here, but this item has no button */ 2344*c2c66affSColin Finck todo_wine ok(ht.flags == TVHT_ONITEMINDENT, "got %d, expected %d\n", ht.flags, TVHT_ONITEMINDENT); 2345*c2c66affSColin Finck 2346*c2c66affSColin Finck DestroyWindow(hTree); 2347*c2c66affSColin Finck } 2348*c2c66affSColin Finck 2349*c2c66affSColin Finck static void test_WM_GETDLGCODE(void) 2350*c2c66affSColin Finck { 2351*c2c66affSColin Finck DWORD code; 2352*c2c66affSColin Finck HWND hTree; 2353*c2c66affSColin Finck 2354*c2c66affSColin Finck hTree = create_treeview_control(0); 2355*c2c66affSColin Finck 2356*c2c66affSColin Finck code = SendMessageA(hTree, WM_GETDLGCODE, VK_TAB, 0); 2357*c2c66affSColin Finck ok(code == (DLGC_WANTCHARS | DLGC_WANTARROWS), "0x%08x\n", code); 2358*c2c66affSColin Finck 2359*c2c66affSColin Finck DestroyWindow(hTree); 2360*c2c66affSColin Finck } 2361*c2c66affSColin Finck 2362*c2c66affSColin Finck static void test_customdraw(void) 2363*c2c66affSColin Finck { 2364*c2c66affSColin Finck LOGFONTA lf; 2365*c2c66affSColin Finck HWND hwnd; 2366*c2c66affSColin Finck 2367*c2c66affSColin Finck hwnd = create_treeview_control(0); 2368*c2c66affSColin Finck fill_tree(hwnd); 2369*c2c66affSColin Finck SendMessageA(hwnd, TVM_EXPAND, TVE_EXPAND, (WPARAM)hRoot); 2370*c2c66affSColin Finck 2371*c2c66affSColin Finck /* create additional font, custom draw handler will select it */ 2372*c2c66affSColin Finck SystemParametersInfoA(SPI_GETICONTITLELOGFONT, sizeof(lf), &lf, 0); 2373*c2c66affSColin Finck lf.lfHeight *= 2; 2374*c2c66affSColin Finck g_customdraw_font = CreateFontIndirectA(&lf); 2375*c2c66affSColin Finck flush_sequences(sequences, NUM_MSG_SEQUENCES); 2376*c2c66affSColin Finck InvalidateRect(hwnd, NULL, TRUE); 2377*c2c66affSColin Finck UpdateWindow(hwnd); 2378*c2c66affSColin Finck ok_sequence(sequences, PARENT_CD_SEQ_INDEX, parent_cd_seq, "custom draw notifications", FALSE); 2379*c2c66affSColin Finck DeleteObject(g_customdraw_font); 2380*c2c66affSColin Finck g_customdraw_font = NULL; 2381*c2c66affSColin Finck 2382*c2c66affSColin Finck DestroyWindow(hwnd); 2383*c2c66affSColin Finck } 2384*c2c66affSColin Finck 2385*c2c66affSColin Finck static void test_WM_KEYDOWN(void) 2386*c2c66affSColin Finck { 2387*c2c66affSColin Finck static const char *rootA = "root"; 2388*c2c66affSColin Finck TVINSERTSTRUCTA ins; 2389*c2c66affSColin Finck HTREEITEM hRoot; 2390*c2c66affSColin Finck HWND hwnd; 2391*c2c66affSColin Finck 2392*c2c66affSColin Finck hwnd = create_treeview_control(0); 2393*c2c66affSColin Finck 2394*c2c66affSColin Finck ins.hParent = TVI_ROOT; 2395*c2c66affSColin Finck ins.hInsertAfter = TVI_ROOT; 2396*c2c66affSColin Finck U(ins).item.mask = TVIF_TEXT; 2397*c2c66affSColin Finck U(ins).item.pszText = (char*)rootA; 2398*c2c66affSColin Finck hRoot = TreeView_InsertItemA(hwnd, &ins); 2399*c2c66affSColin Finck ok(hRoot != NULL, "got %p\n", hRoot); 2400*c2c66affSColin Finck 2401*c2c66affSColin Finck flush_sequences(sequences, NUM_MSG_SEQUENCES); 2402*c2c66affSColin Finck SendMessageA(hwnd, WM_KEYDOWN, VK_RETURN, 0); 2403*c2c66affSColin Finck ok_sequence(sequences, PARENT_SEQ_INDEX, parent_vk_return_seq, "WM_KEYDOWN/VK_RETURN parent notification", TRUE); 2404*c2c66affSColin Finck 2405*c2c66affSColin Finck DestroyWindow(hwnd); 2406*c2c66affSColin Finck } 2407*c2c66affSColin Finck 2408*c2c66affSColin Finck static void test_TVS_FULLROWSELECT(void) 2409*c2c66affSColin Finck { 2410*c2c66affSColin Finck DWORD style; 2411*c2c66affSColin Finck HWND hwnd; 2412*c2c66affSColin Finck 2413*c2c66affSColin Finck /* try to create both with TVS_HASLINES and TVS_FULLROWSELECT */ 2414*c2c66affSColin Finck hwnd = create_treeview_control(TVS_FULLROWSELECT); 2415*c2c66affSColin Finck 2416*c2c66affSColin Finck style = GetWindowLongA(hwnd, GWL_STYLE); 2417*c2c66affSColin Finck ok((style & (TVS_FULLROWSELECT | TVS_HASLINES)) == (TVS_FULLROWSELECT | TVS_HASLINES), "got style 0x%08x\n", style); 2418*c2c66affSColin Finck 2419*c2c66affSColin Finck DestroyWindow(hwnd); 2420*c2c66affSColin Finck 2421*c2c66affSColin Finck /* create just with TVS_HASLINES, try to enable TVS_FULLROWSELECT later */ 2422*c2c66affSColin Finck hwnd = create_treeview_control(0); 2423*c2c66affSColin Finck 2424*c2c66affSColin Finck style = GetWindowLongA(hwnd, GWL_STYLE); 2425*c2c66affSColin Finck SetWindowLongA(hwnd, GWL_STYLE, style | TVS_FULLROWSELECT); 2426*c2c66affSColin Finck style = GetWindowLongA(hwnd, GWL_STYLE); 2427*c2c66affSColin Finck ok(style & TVS_FULLROWSELECT, "got style 0x%08x\n", style); 2428*c2c66affSColin Finck 2429*c2c66affSColin Finck DestroyWindow(hwnd); 2430*c2c66affSColin Finck } 2431*c2c66affSColin Finck 2432*c2c66affSColin Finck static void get_item_names_string(HWND hwnd, HTREEITEM item, char *str) 2433*c2c66affSColin Finck { 2434*c2c66affSColin Finck TVITEMA tvitem = { 0 }; 2435*c2c66affSColin Finck HTREEITEM child; 2436*c2c66affSColin Finck char name[16]; 2437*c2c66affSColin Finck 2438*c2c66affSColin Finck if (!item) 2439*c2c66affSColin Finck { 2440*c2c66affSColin Finck item = (HTREEITEM)SendMessageA(hwnd, TVM_GETNEXTITEM, TVGN_ROOT, 0); 2441*c2c66affSColin Finck str[0] = 0; 2442*c2c66affSColin Finck } 2443*c2c66affSColin Finck 2444*c2c66affSColin Finck child = (HTREEITEM)SendMessageA(hwnd, TVM_GETNEXTITEM, TVGN_CHILD, (LPARAM)item); 2445*c2c66affSColin Finck 2446*c2c66affSColin Finck tvitem.mask = TVIF_TEXT; 2447*c2c66affSColin Finck tvitem.hItem = item; 2448*c2c66affSColin Finck tvitem.pszText = name; 2449*c2c66affSColin Finck tvitem.cchTextMax = sizeof(name); 2450*c2c66affSColin Finck SendMessageA(hwnd, TVM_GETITEMA, 0, (LPARAM)&tvitem); 2451*c2c66affSColin Finck strcat(str, tvitem.pszText); 2452*c2c66affSColin Finck 2453*c2c66affSColin Finck while (child != NULL) 2454*c2c66affSColin Finck { 2455*c2c66affSColin Finck get_item_names_string(hwnd, child, str); 2456*c2c66affSColin Finck child = (HTREEITEM)SendMessageA(hwnd, TVM_GETNEXTITEM, TVGN_NEXT, (LPARAM)child); 2457*c2c66affSColin Finck } 2458*c2c66affSColin Finck } 2459*c2c66affSColin Finck 2460*c2c66affSColin Finck static void fill_treeview_sort_test(HWND hwnd) 2461*c2c66affSColin Finck { 2462*c2c66affSColin Finck static const char *itemnames[] = 2463*c2c66affSColin Finck { 2464*c2c66affSColin Finck "root", "Wasp", "Caribou", "Vacuum", 2465*c2c66affSColin Finck "Ocelot", "Newspaper", "Litter bin" 2466*c2c66affSColin Finck }; 2467*c2c66affSColin Finck 2468*c2c66affSColin Finck HTREEITEM root, children[2]; 2469*c2c66affSColin Finck TVINSERTSTRUCTA ins; 2470*c2c66affSColin Finck unsigned i = 0; 2471*c2c66affSColin Finck 2472*c2c66affSColin Finck SendMessageA(hwnd, TVM_DELETEITEM, 0, 0); 2473*c2c66affSColin Finck 2474*c2c66affSColin Finck /* root, two children, with two children each */ 2475*c2c66affSColin Finck ins.hParent = TVI_ROOT; 2476*c2c66affSColin Finck ins.hInsertAfter = TVI_ROOT; 2477*c2c66affSColin Finck U(ins).item.mask = TVIF_TEXT; 2478*c2c66affSColin Finck U(ins).item.pszText = (char *)itemnames[i++]; 2479*c2c66affSColin Finck root = (HTREEITEM)SendMessageA(hwnd, TVM_INSERTITEMA, 0, (LPARAM)&ins); 2480*c2c66affSColin Finck 2481*c2c66affSColin Finck ins.hParent = root; 2482*c2c66affSColin Finck ins.hInsertAfter = TVI_LAST; 2483*c2c66affSColin Finck U(ins).item.mask = TVIF_TEXT; 2484*c2c66affSColin Finck U(ins).item.pszText = (char *)itemnames[i++]; 2485*c2c66affSColin Finck children[0] = (HTREEITEM)SendMessageA(hwnd, TVM_INSERTITEMA, 0, (LPARAM)&ins); 2486*c2c66affSColin Finck 2487*c2c66affSColin Finck U(ins).item.pszText = (char *)itemnames[i++]; 2488*c2c66affSColin Finck children[1] = (HTREEITEM)SendMessageA(hwnd, TVM_INSERTITEMA, 0, (LPARAM)&ins); 2489*c2c66affSColin Finck 2490*c2c66affSColin Finck ins.hParent = children[0]; 2491*c2c66affSColin Finck U(ins).item.pszText = (char *)itemnames[i++]; 2492*c2c66affSColin Finck SendMessageA(hwnd, TVM_INSERTITEMA, 0, (LPARAM)&ins); 2493*c2c66affSColin Finck 2494*c2c66affSColin Finck U(ins).item.pszText = (char *)itemnames[i++]; 2495*c2c66affSColin Finck SendMessageA(hwnd, TVM_INSERTITEMA, 0, (LPARAM)&ins); 2496*c2c66affSColin Finck 2497*c2c66affSColin Finck ins.hParent = children[1]; 2498*c2c66affSColin Finck U(ins).item.pszText = (char *)itemnames[i++]; 2499*c2c66affSColin Finck SendMessageA(hwnd, TVM_INSERTITEMA, 0, (LPARAM)&ins); 2500*c2c66affSColin Finck 2501*c2c66affSColin Finck U(ins).item.pszText = (char *)itemnames[i++]; 2502*c2c66affSColin Finck SendMessageA(hwnd, TVM_INSERTITEMA, 0, (LPARAM)&ins); 2503*c2c66affSColin Finck } 2504*c2c66affSColin Finck 2505*c2c66affSColin Finck static void test_TVM_SORTCHILDREN(void) 2506*c2c66affSColin Finck { 2507*c2c66affSColin Finck static const char *initial_order = "rootWaspVacuumOcelotCaribouNewspaperLitter bin"; 2508*c2c66affSColin Finck static const char *sorted_order = "rootCaribouNewspaperLitter binWaspVacuumOcelot"; 2509*c2c66affSColin Finck TVINSERTSTRUCTA ins; 2510*c2c66affSColin Finck char buff[256]; 2511*c2c66affSColin Finck HTREEITEM root; 2512*c2c66affSColin Finck HWND hwnd; 2513*c2c66affSColin Finck BOOL ret; 2514*c2c66affSColin Finck 2515*c2c66affSColin Finck hwnd = create_treeview_control(0); 2516*c2c66affSColin Finck 2517*c2c66affSColin Finck /* call on empty tree */ 2518*c2c66affSColin Finck ret = SendMessageA(hwnd, TVM_SORTCHILDREN, 0, 0); 2519*c2c66affSColin Finck ok(!ret, "Unexpected ret value %d\n", ret); 2520*c2c66affSColin Finck 2521*c2c66affSColin Finck ret = SendMessageA(hwnd, TVM_SORTCHILDREN, 0, (LPARAM)TVI_ROOT); 2522*c2c66affSColin Finck ok(!ret, "Unexpected ret value %d\n", ret); 2523*c2c66affSColin Finck 2524*c2c66affSColin Finck /* add only root, sort from it */ 2525*c2c66affSColin Finck ins.hParent = TVI_ROOT; 2526*c2c66affSColin Finck ins.hInsertAfter = TVI_ROOT; 2527*c2c66affSColin Finck U(ins).item.mask = TVIF_TEXT; 2528*c2c66affSColin Finck U(ins).item.pszText = (char *)"root"; 2529*c2c66affSColin Finck root = (HTREEITEM)SendMessageA(hwnd, TVM_INSERTITEMA, 0, (LPARAM)&ins); 2530*c2c66affSColin Finck ok(root != NULL, "Expected root node\n"); 2531*c2c66affSColin Finck 2532*c2c66affSColin Finck ret = SendMessageA(hwnd, TVM_SORTCHILDREN, 0, (LPARAM)root); 2533*c2c66affSColin Finck ok(!ret, "Unexpected ret value %d\n", ret); 2534*c2c66affSColin Finck 2535*c2c66affSColin Finck ret = SendMessageA(hwnd, TVM_SORTCHILDREN, TRUE, (LPARAM)root); 2536*c2c66affSColin Finck ok(!ret, "Unexpected ret value %d\n", ret); 2537*c2c66affSColin Finck 2538*c2c66affSColin Finck /* root, two children, with two children each */ 2539*c2c66affSColin Finck fill_treeview_sort_test(hwnd); 2540*c2c66affSColin Finck get_item_names_string(hwnd, NULL, buff); 2541*c2c66affSColin Finck ok(!strcmp(buff, initial_order), "Wrong initial order %s, expected %s\n", buff, initial_order); 2542*c2c66affSColin Finck 2543*c2c66affSColin Finck /* with NULL item nothing is sorted */ 2544*c2c66affSColin Finck fill_treeview_sort_test(hwnd); 2545*c2c66affSColin Finck ret = SendMessageA(hwnd, TVM_SORTCHILDREN, 0, 0); 2546*c2c66affSColin Finck todo_wine 2547*c2c66affSColin Finck ok(ret, "Unexpected ret value %d\n", ret); 2548*c2c66affSColin Finck get_item_names_string(hwnd, NULL, buff); 2549*c2c66affSColin Finck ok(!strcmp(buff, initial_order), "Wrong sorted order %s, expected %s\n", buff, initial_order); 2550*c2c66affSColin Finck 2551*c2c66affSColin Finck /* TVI_ROOT as item */ 2552*c2c66affSColin Finck fill_treeview_sort_test(hwnd); 2553*c2c66affSColin Finck ret = SendMessageA(hwnd, TVM_SORTCHILDREN, 0, (LPARAM)TVI_ROOT); 2554*c2c66affSColin Finck todo_wine 2555*c2c66affSColin Finck ok(ret, "Unexpected ret value %d\n", ret); 2556*c2c66affSColin Finck get_item_names_string(hwnd, NULL, buff); 2557*c2c66affSColin Finck ok(!strcmp(buff, initial_order), "Wrong sorted order %s, expected %s\n", buff, initial_order); 2558*c2c66affSColin Finck 2559*c2c66affSColin Finck /* zero WPARAM, item is specified */ 2560*c2c66affSColin Finck fill_treeview_sort_test(hwnd); 2561*c2c66affSColin Finck root = (HTREEITEM)SendMessageA(hwnd, TVM_GETNEXTITEM, TVGN_ROOT, 0); 2562*c2c66affSColin Finck ok(root != NULL, "Failed to get root item\n"); 2563*c2c66affSColin Finck ret = SendMessageA(hwnd, TVM_SORTCHILDREN, 0, (LPARAM)root); 2564*c2c66affSColin Finck ok(ret, "Unexpected ret value %d\n", ret); 2565*c2c66affSColin Finck get_item_names_string(hwnd, NULL, buff); 2566*c2c66affSColin Finck ok(!strcmp(buff, sorted_order), "Wrong sorted order %s, expected %s\n", buff, sorted_order); 2567*c2c66affSColin Finck 2568*c2c66affSColin Finck /* non-zero WPARAM, NULL item */ 2569*c2c66affSColin Finck fill_treeview_sort_test(hwnd); 2570*c2c66affSColin Finck ret = SendMessageA(hwnd, TVM_SORTCHILDREN, TRUE, 0); 2571*c2c66affSColin Finck todo_wine 2572*c2c66affSColin Finck ok(ret, "Unexpected ret value %d\n", ret); 2573*c2c66affSColin Finck get_item_names_string(hwnd, NULL, buff); 2574*c2c66affSColin Finck ok(!strcmp(buff, initial_order), "Wrong sorted order %s, expected %s\n", buff, sorted_order); 2575*c2c66affSColin Finck 2576*c2c66affSColin Finck /* TVI_ROOT as item */ 2577*c2c66affSColin Finck fill_treeview_sort_test(hwnd); 2578*c2c66affSColin Finck ret = SendMessageA(hwnd, TVM_SORTCHILDREN, TRUE, (LPARAM)TVI_ROOT); 2579*c2c66affSColin Finck todo_wine 2580*c2c66affSColin Finck ok(ret, "Unexpected ret value %d\n", ret); 2581*c2c66affSColin Finck get_item_names_string(hwnd, NULL, buff); 2582*c2c66affSColin Finck ok(!strcmp(buff, initial_order), "Wrong sorted order %s, expected %s\n", buff, sorted_order); 2583*c2c66affSColin Finck 2584*c2c66affSColin Finck /* non-zero WPARAM, item is specified */ 2585*c2c66affSColin Finck fill_treeview_sort_test(hwnd); 2586*c2c66affSColin Finck root = (HTREEITEM)SendMessageA(hwnd, TVM_GETNEXTITEM, TVGN_ROOT, 0); 2587*c2c66affSColin Finck ok(root != NULL, "Failed to get root item\n"); 2588*c2c66affSColin Finck ret = SendMessageA(hwnd, TVM_SORTCHILDREN, TRUE, (LPARAM)root); 2589*c2c66affSColin Finck ok(ret, "Unexpected ret value %d\n", ret); 2590*c2c66affSColin Finck get_item_names_string(hwnd, NULL, buff); 2591*c2c66affSColin Finck ok(!strcmp(buff, sorted_order), "Wrong sorted order %s, expected %s\n", buff, sorted_order); 2592*c2c66affSColin Finck 2593*c2c66affSColin Finck /* case insensitive comparison */ 2594*c2c66affSColin Finck SendMessageA(hwnd, TVM_DELETEITEM, 0, 0); 2595*c2c66affSColin Finck 2596*c2c66affSColin Finck ins.hParent = TVI_ROOT; 2597*c2c66affSColin Finck ins.hInsertAfter = TVI_ROOT; 2598*c2c66affSColin Finck U(ins).item.mask = TVIF_TEXT; 2599*c2c66affSColin Finck U(ins).item.pszText = (char *)"root"; 2600*c2c66affSColin Finck root = (HTREEITEM)SendMessageA(hwnd, TVM_INSERTITEMA, 0, (LPARAM)&ins); 2601*c2c66affSColin Finck ok(root != NULL, "Expected root node\n"); 2602*c2c66affSColin Finck 2603*c2c66affSColin Finck ins.hParent = root; 2604*c2c66affSColin Finck ins.hInsertAfter = TVI_LAST; 2605*c2c66affSColin Finck U(ins).item.pszText = (char *)"I1"; 2606*c2c66affSColin Finck SendMessageA(hwnd, TVM_INSERTITEMA, 0, (LPARAM)&ins); 2607*c2c66affSColin Finck 2608*c2c66affSColin Finck ins.hParent = root; 2609*c2c66affSColin Finck ins.hInsertAfter = TVI_LAST; 2610*c2c66affSColin Finck U(ins).item.pszText = (char *)"i1"; 2611*c2c66affSColin Finck SendMessageA(hwnd, TVM_INSERTITEMA, 0, (LPARAM)&ins); 2612*c2c66affSColin Finck 2613*c2c66affSColin Finck ret = SendMessageA(hwnd, TVM_SORTCHILDREN, TRUE, (LPARAM)root); 2614*c2c66affSColin Finck ok(ret, "Unexpected ret value %d\n", ret); 2615*c2c66affSColin Finck get_item_names_string(hwnd, NULL, buff); 2616*c2c66affSColin Finck ok(!strcmp(buff, "rootI1i1"), "Wrong sorted order %s\n", buff); 2617*c2c66affSColin Finck 2618*c2c66affSColin Finck DestroyWindow(hwnd); 2619*c2c66affSColin Finck } 2620*c2c66affSColin Finck 2621*c2c66affSColin Finck static void test_right_click(void) 2622*c2c66affSColin Finck { 2623*c2c66affSColin Finck HWND hTree; 2624*c2c66affSColin Finck HTREEITEM selected; 2625*c2c66affSColin Finck RECT rc; 2626*c2c66affSColin Finck LRESULT result; 2627*c2c66affSColin Finck POINT pt; 2628*c2c66affSColin Finck 2629*c2c66affSColin Finck hTree = create_treeview_control(0); 2630*c2c66affSColin Finck fill_tree(hTree); 2631*c2c66affSColin Finck 2632*c2c66affSColin Finck SendMessageA(hTree, TVM_ENSUREVISIBLE, 0, (LPARAM)hChild); 2633*c2c66affSColin Finck SendMessageA(hTree, TVM_SELECTITEM, TVGN_CARET, (LPARAM)hChild); 2634*c2c66affSColin Finck selected = (HTREEITEM)SendMessageA(hTree, TVM_GETNEXTITEM, TVGN_CARET, 0); 2635*c2c66affSColin Finck ok(selected == hChild, "child item not selected\n"); 2636*c2c66affSColin Finck 2637*c2c66affSColin Finck *(HTREEITEM *)&rc = hRoot; 2638*c2c66affSColin Finck result = SendMessageA(hTree, TVM_GETITEMRECT, TRUE, (LPARAM)&rc); 2639*c2c66affSColin Finck ok(result, "TVM_GETITEMRECT failed\n"); 2640*c2c66affSColin Finck 2641*c2c66affSColin Finck flush_events(); 2642*c2c66affSColin Finck 2643*c2c66affSColin Finck pt.x = (rc.left + rc.right) / 2; 2644*c2c66affSColin Finck pt.y = (rc.top + rc.bottom) / 2; 2645*c2c66affSColin Finck ClientToScreen(hMainWnd, &pt); 2646*c2c66affSColin Finck 2647*c2c66affSColin Finck flush_events(); 2648*c2c66affSColin Finck flush_sequences(sequences, NUM_MSG_SEQUENCES); 2649*c2c66affSColin Finck 2650*c2c66affSColin Finck PostMessageA(hTree, WM_RBUTTONDOWN, MK_RBUTTON, MAKELPARAM(pt.x, pt.y)); 2651*c2c66affSColin Finck PostMessageA(hTree, WM_RBUTTONUP, 0, MAKELPARAM(pt.x, pt.y)); 2652*c2c66affSColin Finck 2653*c2c66affSColin Finck flush_events(); 2654*c2c66affSColin Finck 2655*c2c66affSColin Finck ok_sequence(sequences, TREEVIEW_SEQ_INDEX, test_right_click_seq, "right click sequence", FALSE); 2656*c2c66affSColin Finck ok_sequence(sequences, PARENT_SEQ_INDEX, parent_right_click_seq, "parent right click sequence", FALSE); 2657*c2c66affSColin Finck 2658*c2c66affSColin Finck selected = (HTREEITEM)SendMessageA(hTree, TVM_GETNEXTITEM, TVGN_CARET, 0); 2659*c2c66affSColin Finck ok(selected == hChild, "child item should still be selected\n"); 2660*c2c66affSColin Finck 2661*c2c66affSColin Finck DestroyWindow(hTree); 2662*c2c66affSColin Finck } 2663*c2c66affSColin Finck 2664*c2c66affSColin Finck START_TEST(treeview) 2665*c2c66affSColin Finck { 2666*c2c66affSColin Finck HMODULE hComctl32; 2667*c2c66affSColin Finck BOOL (WINAPI *pInitCommonControlsEx)(const INITCOMMONCONTROLSEX*); 2668*c2c66affSColin Finck WNDCLASSA wc; 2669*c2c66affSColin Finck MSG msg; 2670*c2c66affSColin Finck 2671*c2c66affSColin Finck ULONG_PTR ctx_cookie; 2672*c2c66affSColin Finck HANDLE hCtx; 2673*c2c66affSColin Finck 2674*c2c66affSColin Finck hComctl32 = GetModuleHandleA("comctl32.dll"); 2675*c2c66affSColin Finck pInitCommonControlsEx = (void*)GetProcAddress(hComctl32, "InitCommonControlsEx"); 2676*c2c66affSColin Finck if (pInitCommonControlsEx) 2677*c2c66affSColin Finck { 2678*c2c66affSColin Finck INITCOMMONCONTROLSEX iccex; 2679*c2c66affSColin Finck iccex.dwSize = sizeof(iccex); 2680*c2c66affSColin Finck iccex.dwICC = ICC_TREEVIEW_CLASSES; 2681*c2c66affSColin Finck pInitCommonControlsEx(&iccex); 2682*c2c66affSColin Finck } 2683*c2c66affSColin Finck else 2684*c2c66affSColin Finck InitCommonControls(); 2685*c2c66affSColin Finck 2686*c2c66affSColin Finck init_msg_sequences(sequences, NUM_MSG_SEQUENCES); 2687*c2c66affSColin Finck init_msg_sequences(item_sequence, 1); 2688*c2c66affSColin Finck 2689*c2c66affSColin Finck wc.style = CS_HREDRAW | CS_VREDRAW; 2690*c2c66affSColin Finck wc.cbClsExtra = 0; 2691*c2c66affSColin Finck wc.cbWndExtra = 0; 2692*c2c66affSColin Finck wc.hInstance = GetModuleHandleA(NULL); 2693*c2c66affSColin Finck wc.hIcon = NULL; 2694*c2c66affSColin Finck wc.hCursor = LoadCursorA(NULL, (LPCSTR)IDC_IBEAM); 2695*c2c66affSColin Finck wc.hbrBackground = GetSysColorBrush(COLOR_WINDOW); 2696*c2c66affSColin Finck wc.lpszMenuName = NULL; 2697*c2c66affSColin Finck wc.lpszClassName = "MyTestWnd"; 2698*c2c66affSColin Finck wc.lpfnWndProc = parent_wnd_proc; 2699*c2c66affSColin Finck RegisterClassA(&wc); 2700*c2c66affSColin Finck 2701*c2c66affSColin Finck hMainWnd = CreateWindowExA(0, "MyTestWnd", "Blah", WS_OVERLAPPEDWINDOW, 2702*c2c66affSColin Finck CW_USEDEFAULT, CW_USEDEFAULT, 130, 105, NULL, NULL, GetModuleHandleA(NULL), 0); 2703*c2c66affSColin Finck 2704*c2c66affSColin Finck ok(hMainWnd != NULL, "Failed to create parent window. Tests aborted.\n"); 2705*c2c66affSColin Finck if (!hMainWnd) return; 2706*c2c66affSColin Finck 2707*c2c66affSColin Finck test_fillroot(); 2708*c2c66affSColin Finck test_select(); 2709*c2c66affSColin Finck test_getitemtext(); 2710*c2c66affSColin Finck test_focus(); 2711*c2c66affSColin Finck test_get_set_bkcolor(); 2712*c2c66affSColin Finck test_get_set_imagelist(); 2713*c2c66affSColin Finck test_get_set_indent(); 2714*c2c66affSColin Finck test_get_set_insertmark(); 2715*c2c66affSColin Finck test_get_set_item(); 2716*c2c66affSColin Finck test_get_set_itemheight(); 2717*c2c66affSColin Finck test_get_set_scrolltime(); 2718*c2c66affSColin Finck test_get_set_textcolor(); 2719*c2c66affSColin Finck test_get_linecolor(); 2720*c2c66affSColin Finck test_get_insertmarkcolor(); 2721*c2c66affSColin Finck test_get_set_tooltips(); 2722*c2c66affSColin Finck test_get_set_unicodeformat(); 2723*c2c66affSColin Finck test_callback(); 2724*c2c66affSColin Finck test_expandinvisible(); 2725*c2c66affSColin Finck test_itemedit(); 2726*c2c66affSColin Finck test_treeview_classinfo(); 2727*c2c66affSColin Finck test_expandnotify(); 2728*c2c66affSColin Finck test_TVS_SINGLEEXPAND(); 2729*c2c66affSColin Finck test_WM_PAINT(); 2730*c2c66affSColin Finck test_delete_items(); 2731*c2c66affSColin Finck test_cchildren(); 2732*c2c66affSColin Finck test_htreeitem_layout(); 2733*c2c66affSColin Finck test_TVS_CHECKBOXES(); 2734*c2c66affSColin Finck test_TVM_GETNEXTITEM(); 2735*c2c66affSColin Finck test_TVM_HITTEST(); 2736*c2c66affSColin Finck test_WM_GETDLGCODE(); 2737*c2c66affSColin Finck test_customdraw(); 2738*c2c66affSColin Finck test_WM_KEYDOWN(); 2739*c2c66affSColin Finck test_TVS_FULLROWSELECT(); 2740*c2c66affSColin Finck test_TVM_SORTCHILDREN(); 2741*c2c66affSColin Finck test_right_click(); 2742*c2c66affSColin Finck 2743*c2c66affSColin Finck if (!load_v6_module(&ctx_cookie, &hCtx)) 2744*c2c66affSColin Finck { 2745*c2c66affSColin Finck DestroyWindow(hMainWnd); 2746*c2c66affSColin Finck return; 2747*c2c66affSColin Finck } 2748*c2c66affSColin Finck 2749*c2c66affSColin Finck /* comctl32 version 6 tests start here */ 2750*c2c66affSColin Finck g_v6 = TRUE; 2751*c2c66affSColin Finck test_expandedimage(); 2752*c2c66affSColin Finck test_htreeitem_layout(); 2753*c2c66affSColin Finck test_WM_GETDLGCODE(); 2754*c2c66affSColin Finck 2755*c2c66affSColin Finck unload_v6_module(ctx_cookie, hCtx); 2756*c2c66affSColin Finck 2757*c2c66affSColin Finck PostMessageA(hMainWnd, WM_CLOSE, 0, 0); 2758*c2c66affSColin Finck while(GetMessageA(&msg, 0, 0, 0)) 2759*c2c66affSColin Finck { 2760*c2c66affSColin Finck TranslateMessage(&msg); 2761*c2c66affSColin Finck DispatchMessageA(&msg); 2762*c2c66affSColin Finck } 2763*c2c66affSColin Finck } 2764