1 /* Unit tests for treeview.
3 * Copyright 2005 Krzysztof Foltman
4 * Copyright 2007 Christopher James Peterson
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
32 #include "wine/test.h"
35 const char *TEST_CALLBACK_TEXT
= "callback_text";
37 #define NUM_MSG_SEQUENCES 2
38 #define TREEVIEW_SEQ_INDEX 0
39 #define PARENT_SEQ_INDEX 1
41 #define expect(expected, got) ok(got == expected, "Expected %d, got %d\n", expected, got)
43 static struct msg_sequence
*sequences
[NUM_MSG_SEQUENCES
];
45 static const struct message FillRootSeq
[] = {
46 { TVM_INSERTITEM
, sent
},
47 { TVM_INSERTITEM
, sent
},
51 static const struct message rootnone_select_seq
[] = {
52 { TVM_SELECTITEM
, sent
|wparam
, 9 },
53 { TVM_SELECTITEM
, sent
|wparam
, 9 },
54 { TVM_SELECTITEM
, sent
|wparam
, 9 },
55 { TVM_SELECTITEM
, sent
|wparam
, 9 },
56 { TVM_SELECTITEM
, sent
|wparam
, 9 },
57 { TVM_SELECTITEM
, sent
|wparam
, 9 },
61 static const struct message rootchild_select_seq
[] = {
62 { TVM_SELECTITEM
, sent
|wparam
, 9 },
63 { TVM_SELECTITEM
, sent
|wparam
, 9 },
64 { TVM_SELECTITEM
, sent
|wparam
, 9 },
65 { TVM_SELECTITEM
, sent
|wparam
, 9 },
66 { TVM_SELECTITEM
, sent
|wparam
, 9 },
67 { TVM_SELECTITEM
, sent
|wparam
, 9 },
71 static const struct message getitemtext_seq
[] = {
72 { TVM_INSERTITEM
, sent
},
73 { TVM_GETITEM
, sent
},
74 { TVM_DELETEITEM
, sent
},
78 static const struct message focus_seq
[] = {
79 { TVM_INSERTITEM
, sent
},
80 { TVM_INSERTITEM
, sent
},
81 { TVM_SELECTITEM
, sent
|wparam
, 9 },
82 /* The following end up out of order in wine */
83 { WM_WINDOWPOSCHANGING
, sent
|defwinproc
},
84 { WM_NCCALCSIZE
, sent
|wparam
|defwinproc
, TRUE
},
85 { WM_WINDOWPOSCHANGED
, sent
|defwinproc
},
86 { WM_SIZE
, sent
|defwinproc
},
87 { WM_PAINT
, sent
|defwinproc
},
88 { WM_NCPAINT
, sent
|wparam
|defwinproc
, 1 },
89 { WM_ERASEBKGND
, sent
|defwinproc
},
90 { TVM_EDITLABEL
, sent
},
91 { WM_COMMAND
, sent
|wparam
|defwinproc
, MAKEWPARAM(0, EN_UPDATE
) },
92 { WM_COMMAND
, sent
|wparam
|defwinproc
, MAKEWPARAM(0, EN_CHANGE
) },
93 { WM_PARENTNOTIFY
, sent
|wparam
|defwinproc
, MAKEWPARAM(WM_CREATE
, 0) },
94 { WM_KILLFOCUS
, sent
|defwinproc
},
95 { WM_PAINT
, sent
|defwinproc
},
96 { WM_IME_SETCONTEXT
, sent
|defwinproc
|optional
},
97 { WM_COMMAND
, sent
|wparam
|defwinproc
, MAKEWPARAM(0, EN_SETFOCUS
) },
98 { WM_ERASEBKGND
, sent
|defwinproc
|optional
},
99 { WM_CTLCOLOREDIT
, sent
|defwinproc
|optional
},
100 { WM_CTLCOLOREDIT
, sent
|defwinproc
|optional
},
104 static const struct message test_get_set_bkcolor_seq
[] = {
105 { TVM_GETBKCOLOR
, sent
|wparam
|lparam
, 0, 0 },
106 { TVM_SETBKCOLOR
, sent
|wparam
|lparam
, 0, 0 },
107 { TVM_GETBKCOLOR
, sent
|wparam
|lparam
, 0, 0 },
108 { TVM_SETBKCOLOR
, sent
|wparam
|lparam
, 0, 0x00ffffff },
109 { TVM_GETBKCOLOR
, sent
|wparam
|lparam
, 0, 0 },
110 { TVM_SETBKCOLOR
, sent
|wparam
|lparam
, 0, -1 },
114 static const struct message test_get_set_imagelist_seq
[] = {
115 { TVM_SETIMAGELIST
, sent
|wparam
|lparam
, 0, 0 },
116 { TVM_GETIMAGELIST
, sent
|wparam
|lparam
, 0, 0 },
120 static const struct message test_get_set_indent_seq
[] = {
121 { TVM_SETINDENT
, sent
|wparam
|lparam
, 0, 0 },
122 { TVM_GETINDENT
, sent
|wparam
|lparam
, 0, 0 },
123 /* The actual amount to indent is dependent on the system for this message */
124 { TVM_SETINDENT
, sent
},
125 { TVM_GETINDENT
, sent
|wparam
|lparam
, 0, 0 },
129 static const struct message test_get_set_insertmarkcolor_seq
[] = {
130 { TVM_SETINSERTMARKCOLOR
, sent
|wparam
|lparam
, 0, 0 },
131 { TVM_GETINSERTMARKCOLOR
, sent
|wparam
|lparam
, 0, 0 },
135 static const struct message test_get_set_item_seq
[] = {
136 { TVM_GETITEM
, sent
},
137 { TVM_SETITEM
, sent
},
138 { TVM_GETITEM
, sent
},
139 { TVM_SETITEM
, sent
},
143 static const struct message test_get_set_itemheight_seq
[] = {
144 { TVM_GETITEMHEIGHT
, sent
|wparam
|lparam
, 0, 0 },
145 { TVM_SETITEMHEIGHT
, sent
|wparam
|lparam
, -1, 0 },
146 { TVM_GETITEMHEIGHT
, sent
|wparam
|lparam
, 0, 0 },
147 { TVM_SETITEMHEIGHT
, sent
|lparam
, 0xcccccccc, 0 },
148 { TVM_GETITEMHEIGHT
, sent
|wparam
|lparam
|optional
, 0, 0 },
149 { TVM_SETITEMHEIGHT
, sent
|wparam
|lparam
|optional
, 9, 0 },
150 { TVM_GETITEMHEIGHT
, sent
|wparam
|lparam
, 0, 0 },
154 static const struct message test_get_set_scrolltime_seq
[] = {
155 { TVM_SETSCROLLTIME
, sent
|wparam
|lparam
, 20, 0 },
156 { TVM_GETSCROLLTIME
, sent
|wparam
|lparam
, 0, 0 },
160 static const struct message test_get_set_textcolor_seq
[] = {
161 { TVM_GETTEXTCOLOR
, sent
|wparam
|lparam
, 0, 0 },
162 { TVM_SETTEXTCOLOR
, sent
|wparam
|lparam
, 0, 0 },
163 { TVM_GETTEXTCOLOR
, sent
|wparam
|lparam
, 0, 0 },
164 { TVM_SETTEXTCOLOR
, sent
|wparam
|lparam
, 0, RGB(255, 255, 255) },
165 { TVM_GETTEXTCOLOR
, sent
|wparam
|lparam
, 0, 0 },
166 { TVM_SETTEXTCOLOR
, sent
|wparam
|lparam
, 0, CLR_NONE
},
170 static const struct message test_get_set_tooltips_seq
[] = {
171 { WM_KILLFOCUS
, sent
},
172 { WM_IME_SETCONTEXT
, sent
|optional
},
173 { WM_IME_NOTIFY
, sent
|optional
},
174 { TVM_SETTOOLTIPS
, sent
|wparam
|lparam
, 0, 0 },
175 { TVM_GETTOOLTIPS
, sent
|wparam
|lparam
, 0, 0 },
179 static const struct message test_get_set_unicodeformat_seq
[] = {
180 { TVM_SETUNICODEFORMAT
, sent
|wparam
|lparam
, TRUE
, 0 },
181 { TVM_GETUNICODEFORMAT
, sent
|wparam
|lparam
, 0, 0 },
182 { TVM_SETUNICODEFORMAT
, sent
|wparam
|lparam
, 0, 0 },
183 { TVM_GETUNICODEFORMAT
, sent
|wparam
|lparam
, 0, 0 },
184 { TVM_SETUNICODEFORMAT
, sent
|wparam
|lparam
, 0, 0 },
188 static const struct message parent_expand_seq
[] = {
189 { WM_NOTIFY
, sent
|id
, 0, 0, TVN_ITEMEXPANDING
},
190 { WM_NOTIFY
, sent
|id
, 0, 0, TVN_ITEMEXPANDED
},
194 static const struct message empty_seq
[] = {
198 static HWND hMainWnd
;
200 static HTREEITEM hRoot
, hChild
;
203 static char sequence
[256];
205 static void Clear(void)
211 static void AddItem(char ch
)
213 sequence
[pos
++] = ch
;
214 sequence
[pos
] = '\0';
217 static void IdentifyItem(HTREEITEM hItem
)
219 if (hItem
== hRoot
) {
223 if (hItem
== hChild
) {
234 /* This function hooks in and records all messages to the treeview control */
235 static LRESULT WINAPI
TreeviewWndProc(HWND hwnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
237 static LONG defwndproc_counter
= 0;
240 WNDPROC lpOldProc
= (WNDPROC
)GetWindowLongPtrA(hwnd
, GWLP_USERDATA
);
242 msg
.message
= message
;
243 msg
.flags
= sent
|wparam
|lparam
;
244 if (defwndproc_counter
) msg
.flags
|= defwinproc
;
247 add_message(sequences
, TREEVIEW_SEQ_INDEX
, &msg
);
249 defwndproc_counter
++;
250 ret
= CallWindowProcA(lpOldProc
, hwnd
, message
, wParam
, lParam
);
251 defwndproc_counter
--;
256 static HWND
create_treeview_control(void)
261 hTree
= CreateWindowExA(WS_EX_CLIENTEDGE
, WC_TREEVIEWA
, NULL
, WS_CHILD
|WS_VISIBLE
|
262 TVS_LINESATROOT
|TVS_HASLINES
|TVS_HASBUTTONS
|TVS_EDITLABELS
,
263 0, 0, 120, 100, hMainWnd
, (HMENU
)100, GetModuleHandleA(0), 0);
267 /* Record the old WNDPROC so we can call it after recording the messages */
268 pOldWndProc
= (WNDPROC
)SetWindowLongPtrA(hTree
, GWLP_WNDPROC
, (LONG_PTR
)TreeviewWndProc
);
269 SetWindowLongPtrA(hTree
, GWLP_USERDATA
, (LONG_PTR
)pOldWndProc
);
274 static void fill_tree(HWND hTree
)
277 static CHAR root
[] = "Root",
280 ins
.hParent
= TVI_ROOT
;
281 ins
.hInsertAfter
= TVI_ROOT
;
282 U(ins
).item
.mask
= TVIF_TEXT
;
283 U(ins
).item
.pszText
= root
;
284 hRoot
= TreeView_InsertItem(hTree
, &ins
);
287 ins
.hInsertAfter
= TVI_FIRST
;
288 U(ins
).item
.mask
= TVIF_TEXT
;
289 U(ins
).item
.pszText
= child
;
290 hChild
= TreeView_InsertItem(hTree
, &ins
);
293 static void test_fillroot(void)
298 hTree
= create_treeview_control();
300 flush_sequences(sequences
, NUM_MSG_SEQUENCES
);
310 ok_sequence(sequences
, TREEVIEW_SEQ_INDEX
, FillRootSeq
, "FillRoot", FALSE
);
311 ok(!strcmp(sequence
, "AB."), "Item creation\n");
313 /* UMLPad 1.15 depends on this being not -1 (I_IMAGECALLBACK) */
315 tvi
.mask
= TVIF_IMAGE
| TVIF_SELECTEDIMAGE
;
316 SendMessage( hTree
, TVM_GETITEM
, 0, (LPARAM
)&tvi
);
317 ok(tvi
.iImage
== 0, "tvi.iImage=%d\n", tvi
.iImage
);
318 ok(tvi
.iSelectedImage
== 0, "tvi.iSelectedImage=%d\n", tvi
.iSelectedImage
);
320 DestroyWindow(hTree
);
323 static void test_callback(void)
326 HTREEITEM hItem1
, hItem2
;
329 CHAR test_string
[] = "Test_string";
334 hTree
= create_treeview_control();
337 ret
= TreeView_DeleteAllItems(hTree
);
338 ok(ret
== TRUE
, "ret\n");
339 ins
.hParent
= TVI_ROOT
;
340 ins
.hInsertAfter
= TVI_ROOT
;
341 U(ins
).item
.mask
= TVIF_TEXT
;
342 U(ins
).item
.pszText
= LPSTR_TEXTCALLBACK
;
343 hRoot
= TreeView_InsertItem(hTree
, &ins
);
347 tvi
.mask
= TVIF_TEXT
;
349 tvi
.cchTextMax
= sizeof(buf
)/sizeof(buf
[0]);
350 ret
= TreeView_GetItem(hTree
, &tvi
);
351 ok(ret
== 1, "ret\n");
352 ok(strcmp(tvi
.pszText
, TEST_CALLBACK_TEXT
) == 0, "Callback item text mismatch %s vs %s\n",
353 tvi
.pszText
, TEST_CALLBACK_TEXT
);
356 ins
.hInsertAfter
= TVI_FIRST
;
357 U(ins
).item
.mask
= TVIF_TEXT
;
358 U(ins
).item
.pszText
= test_string
;
359 hItem1
= TreeView_InsertItem(hTree
, &ins
);
363 ret
= TreeView_GetItem(hTree
, &tvi
);
364 ok(ret
== TRUE
, "ret\n");
365 ok(strcmp(tvi
.pszText
, test_string
) == 0, "Item text mismatch %s vs %s\n",
366 tvi
.pszText
, test_string
);
368 /* undocumented: pszText of NULL also means LPSTR_CALLBACK: */
370 ret
= TreeView_SetItem(hTree
, &tvi
);
371 ok(ret
== 1, "Expected SetItem return 1, got %ld\n", ret
);
373 ret
= TreeView_GetItem(hTree
, &tvi
);
374 ok(ret
== TRUE
, "Expected GetItem return TRUE, got %ld\n", ret
);
375 ok(strcmp(tvi
.pszText
, TEST_CALLBACK_TEXT
) == 0, "Item text mismatch %s vs %s\n",
376 tvi
.pszText
, TEST_CALLBACK_TEXT
);
378 U(ins
).item
.pszText
= NULL
;
379 hItem2
= TreeView_InsertItem(hTree
, &ins
);
382 memset(buf
, 0, sizeof(buf
));
383 ret
= TreeView_GetItem(hTree
, &tvi
);
384 ok(ret
== TRUE
, "Expected GetItem return TRUE, got %ld\n", ret
);
385 ok(strcmp(tvi
.pszText
, TEST_CALLBACK_TEXT
) == 0, "Item text mismatch %s vs %s\n",
386 tvi
.pszText
, TEST_CALLBACK_TEXT
);
388 DestroyWindow(hTree
);
391 static void test_select(void)
396 hTree
= create_treeview_control();
399 /* root-none select tests */
400 flush_sequences(sequences
, NUM_MSG_SEQUENCES
);
401 r
= TreeView_SelectItem(hTree
, NULL
);
405 r
= TreeView_SelectItem(hTree
, hRoot
);
408 r
= TreeView_SelectItem(hTree
, hRoot
);
411 r
= TreeView_SelectItem(hTree
, NULL
);
414 r
= TreeView_SelectItem(hTree
, NULL
);
417 r
= TreeView_SelectItem(hTree
, hRoot
);
420 ok(!strcmp(sequence
, "1(nR)nR23(Rn)Rn45(nR)nR."), "root-none select test\n");
421 ok_sequence(sequences
, TREEVIEW_SEQ_INDEX
, rootnone_select_seq
,
422 "root-none select seq", FALSE
);
424 /* root-child select tests */
425 flush_sequences(sequences
, NUM_MSG_SEQUENCES
);
426 r
= TreeView_SelectItem(hTree
, NULL
);
431 r
= TreeView_SelectItem(hTree
, hRoot
);
434 r
= TreeView_SelectItem(hTree
, hRoot
);
437 r
= TreeView_SelectItem(hTree
, hChild
);
440 r
= TreeView_SelectItem(hTree
, hChild
);
443 r
= TreeView_SelectItem(hTree
, hRoot
);
446 ok(!strcmp(sequence
, "1(nR)nR23(RC)RC45(CR)CR."), "root-child select test\n");
447 ok_sequence(sequences
, TREEVIEW_SEQ_INDEX
, rootchild_select_seq
,
448 "root-child select seq", FALSE
);
450 DestroyWindow(hTree
);
453 static void test_getitemtext(void)
460 CHAR szBuffer
[80] = "Blah";
461 int nBufferSize
= sizeof(szBuffer
)/sizeof(CHAR
);
463 hTree
= create_treeview_control();
466 flush_sequences(sequences
, NUM_MSG_SEQUENCES
);
468 /* add an item without TVIF_TEXT mask and pszText == NULL */
470 ins
.hInsertAfter
= TVI_ROOT
;
471 U(ins
).item
.mask
= 0;
472 U(ins
).item
.pszText
= NULL
;
473 U(ins
).item
.cchTextMax
= 0;
474 hChild
= TreeView_InsertItem(hTree
, &ins
);
477 /* retrieve it with TVIF_TEXT mask */
479 tvi
.mask
= TVIF_TEXT
;
480 tvi
.cchTextMax
= nBufferSize
;
481 tvi
.pszText
= szBuffer
;
483 SendMessageA( hTree
, TVM_GETITEM
, 0, (LPARAM
)&tvi
);
484 ok(!strcmp(szBuffer
, ""), "szBuffer=\"%s\", expected \"\"\n", szBuffer
);
485 ok(SendMessageA(hTree
, TVM_DELETEITEM
, 0, (LPARAM
)hChild
), "DeleteItem failed\n");
486 ok_sequence(sequences
, TREEVIEW_SEQ_INDEX
, getitemtext_seq
, "get item text seq", FALSE
);
488 DestroyWindow(hTree
);
491 static void test_focus(void)
494 static CHAR child1
[] = "Edit",
495 child2
[] = "A really long string";
496 HTREEITEM hChild1
, hChild2
;
500 hTree
= create_treeview_control();
503 flush_sequences(sequences
, NUM_MSG_SEQUENCES
);
505 /* This test verifies that when a label is being edited, scrolling
506 * the treeview does not cause the label to lose focus. To test
507 * this, first some additional entries are added to generate
511 ins
.hInsertAfter
= hChild
;
512 U(ins
).item
.mask
= TVIF_TEXT
;
513 U(ins
).item
.pszText
= child1
;
514 hChild1
= TreeView_InsertItem(hTree
, &ins
);
516 ins
.hInsertAfter
= hChild1
;
517 U(ins
).item
.mask
= TVIF_TEXT
;
518 U(ins
).item
.pszText
= child2
;
519 hChild2
= TreeView_InsertItem(hTree
, &ins
);
522 ShowWindow(hMainWnd
,SW_SHOW
);
523 SendMessageA(hTree
, TVM_SELECTITEM
, TVGN_CARET
, (LPARAM
)hChild
);
524 hEdit
= TreeView_EditLabel(hTree
, hChild
);
525 ScrollWindowEx(hTree
, -10, 0, NULL
, NULL
, NULL
, NULL
, SW_SCROLLCHILDREN
);
526 ok(GetFocus() == hEdit
, "Edit control should have focus\n");
527 ok_sequence(sequences
, TREEVIEW_SEQ_INDEX
, focus_seq
, "focus test", TRUE
);
529 DestroyWindow(hTree
);
532 static void test_get_set_bkcolor(void)
534 COLORREF crColor
= RGB(0,0,0);
537 hTree
= create_treeview_control();
540 flush_sequences(sequences
, NUM_MSG_SEQUENCES
);
542 /* If the value is -1, the control is using the system color for the background color. */
543 crColor
= (COLORREF
)SendMessage( hTree
, TVM_GETBKCOLOR
, 0, 0 );
544 ok(crColor
== -1, "Default background color reported as 0x%.8x\n", crColor
);
546 /* Test for black background */
547 SendMessage( hTree
, TVM_SETBKCOLOR
, 0, RGB(0,0,0) );
548 crColor
= (COLORREF
)SendMessage( hTree
, TVM_GETBKCOLOR
, 0, 0 );
549 ok(crColor
== RGB(0,0,0), "Black background color reported as 0x%.8x\n", crColor
);
551 /* Test for white background */
552 SendMessage( hTree
, TVM_SETBKCOLOR
, 0, RGB(255,255,255) );
553 crColor
= (COLORREF
)SendMessage( hTree
, TVM_GETBKCOLOR
, 0, 0 );
554 ok(crColor
== RGB(255,255,255), "White background color reported as 0x%.8x\n", crColor
);
556 /* Reset the default background */
557 SendMessage( hTree
, TVM_SETBKCOLOR
, 0, -1 );
559 ok_sequence(sequences
, TREEVIEW_SEQ_INDEX
, test_get_set_bkcolor_seq
,
560 "test get set bkcolor", FALSE
);
562 DestroyWindow(hTree
);
565 static void test_get_set_imagelist(void)
567 HIMAGELIST hImageList
= NULL
;
570 hTree
= create_treeview_control();
573 flush_sequences(sequences
, NUM_MSG_SEQUENCES
);
575 /* Test a NULL HIMAGELIST */
576 SendMessage( hTree
, TVM_SETIMAGELIST
, TVSIL_NORMAL
, (LPARAM
)hImageList
);
577 hImageList
= (HIMAGELIST
)SendMessage( hTree
, TVM_GETIMAGELIST
, TVSIL_NORMAL
, 0 );
578 ok(hImageList
== NULL
, "NULL image list, reported as 0x%p, expected 0.\n", hImageList
);
580 /* TODO: Test an actual image list */
582 ok_sequence(sequences
, TREEVIEW_SEQ_INDEX
, test_get_set_imagelist_seq
,
583 "test get imagelist", FALSE
);
585 DestroyWindow(hTree
);
588 static void test_get_set_indent(void)
591 int ulMinIndent
= -1;
592 int ulMoreThanTwiceMin
= -1;
595 hTree
= create_treeview_control();
598 flush_sequences(sequences
, NUM_MSG_SEQUENCES
);
600 /* Finding the minimum indent */
601 SendMessage( hTree
, TVM_SETINDENT
, 0, 0 );
602 ulMinIndent
= (int)SendMessage( hTree
, TVM_GETINDENT
, 0, 0 );
604 /* Checking an indent that is more than twice the default indent */
605 ulMoreThanTwiceMin
= 2*ulMinIndent
+1;
606 SendMessage( hTree
, TVM_SETINDENT
, ulMoreThanTwiceMin
, 0 );
607 ulIndent
= (DWORD
)SendMessage( hTree
, TVM_GETINDENT
, 0, 0 );
608 ok(ulIndent
== ulMoreThanTwiceMin
, "Indent reported as %d, expected %d\n", ulIndent
, ulMoreThanTwiceMin
);
610 ok_sequence(sequences
, TREEVIEW_SEQ_INDEX
, test_get_set_indent_seq
,
611 "test get set indent", FALSE
);
613 DestroyWindow(hTree
);
616 static void test_get_set_insertmark(void)
618 COLORREF crColor
= RGB(0,0,0);
621 hTree
= create_treeview_control();
624 flush_sequences(sequences
, NUM_MSG_SEQUENCES
);
626 SendMessage( hTree
, TVM_SETINSERTMARKCOLOR
, 0, crColor
);
627 crColor
= (COLORREF
)SendMessage( hTree
, TVM_GETINSERTMARKCOLOR
, 0, 0 );
628 ok(crColor
== RGB(0,0,0), "Insert mark color reported as 0x%.8x, expected 0x00000000\n", crColor
);
630 ok_sequence(sequences
, TREEVIEW_SEQ_INDEX
, test_get_set_insertmarkcolor_seq
,
631 "test get set insertmark color", FALSE
);
633 DestroyWindow(hTree
);
636 static void test_get_set_item(void)
638 TVITEM tviRoot
= {0};
639 int nBufferSize
= 80;
640 char szBuffer
[80] = {0};
643 hTree
= create_treeview_control();
646 flush_sequences(sequences
, NUM_MSG_SEQUENCES
);
648 /* Test the root item */
649 tviRoot
.hItem
= hRoot
;
650 tviRoot
.mask
= TVIF_TEXT
;
651 tviRoot
.cchTextMax
= nBufferSize
;
652 tviRoot
.pszText
= szBuffer
;
653 SendMessage( hTree
, TVM_GETITEM
, 0, (LPARAM
)&tviRoot
);
654 ok(!strcmp("Root", szBuffer
), "GetItem: szBuffer=\"%s\", expected \"Root\"\n", szBuffer
);
656 /* Change the root text */
657 strncpy(szBuffer
, "Testing123", nBufferSize
);
658 SendMessage( hTree
, TVM_SETITEM
, 0, (LPARAM
)&tviRoot
);
659 memset(szBuffer
, 0, nBufferSize
);
660 SendMessage( hTree
, TVM_GETITEM
, 0, (LPARAM
)&tviRoot
);
661 ok(!strcmp("Testing123", szBuffer
), "GetItem: szBuffer=\"%s\", expected \"Testing123\"\n", szBuffer
);
663 /* Reset the root text */
664 memset(szBuffer
, 0, nBufferSize
);
665 strncpy(szBuffer
, "Root", nBufferSize
);
666 SendMessage( hTree
, TVM_SETITEM
, 0, (LPARAM
)&tviRoot
);
668 ok_sequence(sequences
, TREEVIEW_SEQ_INDEX
, test_get_set_item_seq
,
669 "test get set item", FALSE
);
671 DestroyWindow(hTree
);
674 static void test_get_set_itemheight(void)
680 hTree
= create_treeview_control();
683 flush_sequences(sequences
, NUM_MSG_SEQUENCES
);
685 /* Assuming default height to begin with */
686 ulOldHeight
= (int) SendMessage( hTree
, TVM_GETITEMHEIGHT
, 0, 0 );
688 /* Explicitly setting and getting the default height */
689 SendMessage( hTree
, TVM_SETITEMHEIGHT
, -1, 0 );
690 ulNewHeight
= (int) SendMessage( hTree
, TVM_GETITEMHEIGHT
, 0, 0 );
691 ok(ulNewHeight
== ulOldHeight
, "Default height not set properly, reported %d, expected %d\n", ulNewHeight
, ulOldHeight
);
693 /* Explicitly setting and getting the height of twice the normal */
694 SendMessage( hTree
, TVM_SETITEMHEIGHT
, 2*ulOldHeight
, 0 );
695 ulNewHeight
= (int) SendMessage( hTree
, TVM_GETITEMHEIGHT
, 0, 0 );
696 ok(ulNewHeight
== 2*ulOldHeight
, "New height not set properly, reported %d, expected %d\n", ulNewHeight
, 2*ulOldHeight
);
698 /* Assuming tree doesn't have TVS_NONEVENHEIGHT set, so a set of 9 will round down to 8 */
699 SendMessage( hTree
, TVM_SETITEMHEIGHT
, 9, 0 );
700 ulNewHeight
= (int) SendMessage( hTree
, TVM_GETITEMHEIGHT
, 0, 0 );
701 ok(ulNewHeight
== 8, "Uneven height not set properly, reported %d, expected %d\n", ulNewHeight
, 8);
703 ok_sequence(sequences
, TREEVIEW_SEQ_INDEX
, test_get_set_itemheight_seq
,
704 "test get set item height", FALSE
);
706 DestroyWindow(hTree
);
709 static void test_get_set_scrolltime(void)
711 int ulExpectedTime
= 20;
715 hTree
= create_treeview_control();
718 flush_sequences(sequences
, NUM_MSG_SEQUENCES
);
720 SendMessage( hTree
, TVM_SETSCROLLTIME
, ulExpectedTime
, 0 );
721 ulTime
= (int)SendMessage( hTree
, TVM_GETSCROLLTIME
, 0, 0 );
722 ok(ulTime
== ulExpectedTime
, "Scroll time reported as %d, expected %d\n", ulTime
, ulExpectedTime
);
724 ok_sequence(sequences
, TREEVIEW_SEQ_INDEX
, test_get_set_scrolltime_seq
,
725 "test get set scroll time", FALSE
);
727 DestroyWindow(hTree
);
730 static void test_get_set_textcolor(void)
732 /* If the value is -1, the control is using the system color for the text color. */
733 COLORREF crColor
= RGB(0,0,0);
736 hTree
= create_treeview_control();
739 flush_sequences(sequences
, NUM_MSG_SEQUENCES
);
741 crColor
= (COLORREF
)SendMessage( hTree
, TVM_GETTEXTCOLOR
, 0, 0 );
742 ok(crColor
== -1, "Default text color reported as 0x%.8x\n", crColor
);
744 /* Test for black text */
745 SendMessage( hTree
, TVM_SETTEXTCOLOR
, 0, RGB(0,0,0) );
746 crColor
= (COLORREF
)SendMessage( hTree
, TVM_GETTEXTCOLOR
, 0, 0 );
747 ok(crColor
== RGB(0,0,0), "Black text color reported as 0x%.8x\n", crColor
);
749 /* Test for white text */
750 SendMessage( hTree
, TVM_SETTEXTCOLOR
, 0, RGB(255,255,255) );
751 crColor
= (COLORREF
)SendMessage( hTree
, TVM_GETTEXTCOLOR
, 0, 0 );
752 ok(crColor
== RGB(255,255,255), "White text color reported as 0x%.8x\n", crColor
);
754 /* Reset the default text color */
755 SendMessage( hTree
, TVM_SETTEXTCOLOR
, 0, CLR_NONE
);
757 ok_sequence(sequences
, TREEVIEW_SEQ_INDEX
, test_get_set_textcolor_seq
,
758 "test get set text color", FALSE
);
760 DestroyWindow(hTree
);
763 static void test_get_set_tooltips(void)
765 HWND hwndLastToolTip
= NULL
;
769 hTree
= create_treeview_control();
772 flush_sequences(sequences
, NUM_MSG_SEQUENCES
);
774 /* show even WS_POPUP treeview don't send NM_TOOLTIPSCREATED */
775 hPopupTreeView
= CreateWindow(WC_TREEVIEW
, NULL
, WS_POPUP
|WS_VISIBLE
, 0, 0, 100, 100, hMainWnd
, NULL
, NULL
, NULL
);
776 DestroyWindow(hPopupTreeView
);
778 /* Testing setting a NULL ToolTip */
779 SendMessage( hTree
, TVM_SETTOOLTIPS
, 0, 0 );
780 hwndLastToolTip
= (HWND
)SendMessage( hTree
, TVM_GETTOOLTIPS
, 0, 0 );
781 ok(hwndLastToolTip
== NULL
, "NULL tool tip, reported as 0x%p, expected 0.\n", hwndLastToolTip
);
783 ok_sequence(sequences
, TREEVIEW_SEQ_INDEX
, test_get_set_tooltips_seq
,
784 "test get set tooltips", TRUE
);
786 /* TODO: Add a test of an actual tooltip */
787 DestroyWindow(hTree
);
790 static void test_get_set_unicodeformat(void)
792 BOOL bPreviousSetting
= 0;
793 BOOL bNewSetting
= 0;
796 hTree
= create_treeview_control();
799 flush_sequences(sequences
, NUM_MSG_SEQUENCES
);
802 bPreviousSetting
= (BOOL
)SendMessage( hTree
, TVM_SETUNICODEFORMAT
, 1, 0 );
803 bNewSetting
= (BOOL
)SendMessage( hTree
, TVM_GETUNICODEFORMAT
, 0, 0 );
804 ok(bNewSetting
== 1, "Unicode setting did not work.\n");
807 SendMessage( hTree
, TVM_SETUNICODEFORMAT
, 0, 0 );
808 bNewSetting
= (BOOL
)SendMessage( hTree
, TVM_GETUNICODEFORMAT
, 0, 0 );
809 ok(bNewSetting
== 0, "ANSI setting did not work.\n");
811 /* Revert to original setting */
812 SendMessage( hTree
, TVM_SETUNICODEFORMAT
, bPreviousSetting
, 0 );
814 ok_sequence(sequences
, TREEVIEW_SEQ_INDEX
, test_get_set_unicodeformat_seq
,
815 "test get set unicode format", FALSE
);
817 DestroyWindow(hTree
);
820 static TVITEMA g_item_expanding
, g_item_expanded
;
821 static BOOL g_get_from_expand
;
822 static BOOL g_get_rect_in_expand
;
824 static LRESULT CALLBACK
parent_wnd_proc(HWND hWnd
, UINT message
, WPARAM wParam
, LPARAM lParam
)
826 static LONG defwndproc_counter
= 0;
830 HTREEITEM visibleItem
;
832 msg
.message
= message
;
833 msg
.flags
= sent
|wparam
|lparam
;
834 if (defwndproc_counter
) msg
.flags
|= defwinproc
;
837 if (message
== WM_NOTIFY
&& lParam
) msg
.id
= ((NMHDR
*)lParam
)->code
;
839 /* log system messages, except for painting */
840 if (message
< WM_USER
&&
841 message
!= WM_PAINT
&&
842 message
!= WM_ERASEBKGND
&&
843 message
!= WM_NCPAINT
&&
844 message
!= WM_NCHITTEST
&&
845 message
!= WM_GETTEXT
&&
846 message
!= WM_GETICON
&&
847 message
!= WM_DEVICECHANGE
)
849 trace("parent: %p, %04x, %08lx, %08lx\n", hWnd
, message
, wParam
, lParam
);
850 add_message(sequences
, PARENT_SEQ_INDEX
, &msg
);
856 NMHDR
*pHdr
= (NMHDR
*)lParam
;
858 ok(pHdr
->code
!= NM_TOOLTIPSCREATED
, "Treeview should not send NM_TOOLTIPSCREATED\n");
859 if (pHdr
->idFrom
== 100)
861 NMTREEVIEWA
*pTreeView
= (LPNMTREEVIEWA
) lParam
;
864 case TVN_SELCHANGINGA
:
866 IdentifyItem(pTreeView
->itemOld
.hItem
);
867 IdentifyItem(pTreeView
->itemNew
.hItem
);
869 case TVN_SELCHANGEDA
:
871 IdentifyItem(pTreeView
->itemOld
.hItem
);
872 IdentifyItem(pTreeView
->itemNew
.hItem
);
874 case TVN_GETDISPINFOA
: {
875 NMTVDISPINFOA
*disp
= (NMTVDISPINFOA
*)lParam
;
876 if (disp
->item
.mask
& TVIF_TEXT
) {
877 lstrcpyn(disp
->item
.pszText
, TEST_CALLBACK_TEXT
, disp
->item
.cchTextMax
);
881 case TVN_ENDLABELEDIT
: return TRUE
;
882 case TVN_ITEMEXPANDING
:
883 ok(pTreeView
->itemNew
.mask
==
884 (TVIF_HANDLE
| TVIF_SELECTEDIMAGE
| TVIF_IMAGE
| TVIF_PARAM
| TVIF_STATE
),
885 "got wrong mask %x\n", pTreeView
->itemNew
.mask
);
886 ok((pTreeView
->itemNew
.state
& TVIS_EXPANDED
) == 0,
887 "got wrong state %x\n", pTreeView
->itemNew
.state
);
888 ok(pTreeView
->itemOld
.mask
== 0,
889 "got wrong mask %x\n", pTreeView
->itemOld
.mask
);
891 if (g_get_from_expand
)
893 g_item_expanding
.mask
= TVIF_STATE
;
894 g_item_expanding
.hItem
= hRoot
;
895 ret
= SendMessageA(pHdr
->hwndFrom
, TVM_GETITEMA
, 0, (LPARAM
)&g_item_expanding
);
896 ok(ret
== TRUE
, "got %lu\n", ret
);
899 case TVN_ITEMEXPANDED
:
900 ok(pTreeView
->itemNew
.mask
& TVIF_STATE
, "got wrong mask %x\n", pTreeView
->itemNew
.mask
);
901 ok(pTreeView
->itemNew
.state
& (TVIS_EXPANDED
|TVIS_EXPANDEDONCE
),
902 "got wrong mask %x\n", pTreeView
->itemNew
.mask
);
903 ok(pTreeView
->itemOld
.mask
== 0,
904 "got wrong mask %x\n", pTreeView
->itemOld
.mask
);
906 if (g_get_from_expand
)
908 g_item_expanded
.mask
= TVIF_STATE
;
909 g_item_expanded
.hItem
= hRoot
;
910 ret
= SendMessageA(pHdr
->hwndFrom
, TVM_GETITEMA
, 0, (LPARAM
)&g_item_expanded
);
911 ok(ret
== TRUE
, "got %lu\n", ret
);
913 if (g_get_rect_in_expand
) {
914 visibleItem
= TreeView_GetNextItem(pHdr
->hwndFrom
, NULL
, TVGN_FIRSTVISIBLE
);
915 ok(pTreeView
->itemNew
.hItem
== visibleItem
, "expanded item == first visible item\n");
916 *(HTREEITEM
*)&rect
= visibleItem
;
917 ok(SendMessage(pHdr
->hwndFrom
, TVM_GETITEMRECT
, TRUE
, (LPARAM
)&rect
), "Failed to get rect for first visible item.\n");
918 visibleItem
= TreeView_GetNextItem(pHdr
->hwndFrom
, visibleItem
, TVGN_NEXTVISIBLE
);
919 *(HTREEITEM
*)&rect
= visibleItem
;
920 ok(visibleItem
!= NULL
, "There must be a visible item after the first visisble item.\n");
922 ok(SendMessage(pHdr
->hwndFrom
, TVM_GETITEMRECT
, TRUE
, (LPARAM
)&rect
), "Failed to get rect for second visible item.\n");
934 defwndproc_counter
++;
935 ret
= DefWindowProcA(hWnd
, message
, wParam
, lParam
);
936 defwndproc_counter
--;
941 static void test_expandinvisible(void)
943 static CHAR nodeText
[][5] = {"0", "1", "2", "3", "4"};
951 hTree
= create_treeview_control();
953 /* The test builds the following tree and expands then node 1, while node 0 is collapsed.
963 ret
= TreeView_DeleteAllItems(hTree
);
964 ok(ret
== TRUE
, "ret\n");
965 ins
.hParent
= TVI_ROOT
;
966 ins
.hInsertAfter
= TVI_ROOT
;
967 U(ins
).item
.mask
= TVIF_TEXT
;
968 U(ins
).item
.pszText
= nodeText
[0];
969 node
[0] = TreeView_InsertItem(hTree
, &ins
);
972 ins
.hInsertAfter
= TVI_LAST
;
973 U(ins
).item
.mask
= TVIF_TEXT
;
974 ins
.hParent
= node
[0];
976 U(ins
).item
.pszText
= nodeText
[1];
977 node
[1] = TreeView_InsertItem(hTree
, &ins
);
979 U(ins
).item
.pszText
= nodeText
[4];
980 node
[4] = TreeView_InsertItem(hTree
, &ins
);
983 ins
.hParent
= node
[1];
985 U(ins
).item
.pszText
= nodeText
[2];
986 node
[2] = TreeView_InsertItem(hTree
, &ins
);
988 U(ins
).item
.pszText
= nodeText
[3];
989 node
[3] = TreeView_InsertItem(hTree
, &ins
);
993 nodeVisible
= TreeView_GetItemRect(hTree
, node
[1], &dummyRect
, FALSE
);
994 ok(!nodeVisible
, "Node 1 should not be visible.\n");
995 nodeVisible
= TreeView_GetItemRect(hTree
, node
[2], &dummyRect
, FALSE
);
996 ok(!nodeVisible
, "Node 2 should not be visible.\n");
997 nodeVisible
= TreeView_GetItemRect(hTree
, node
[3], &dummyRect
, FALSE
);
998 ok(!nodeVisible
, "Node 3 should not be visible.\n");
999 nodeVisible
= TreeView_GetItemRect(hTree
, node
[4], &dummyRect
, FALSE
);
1000 ok(!nodeVisible
, "Node 4 should not be visible.\n");
1002 ok(TreeView_Expand(hTree
, node
[1], TVE_EXPAND
), "Expand of node 1 failed.\n");
1004 nodeVisible
= TreeView_GetItemRect(hTree
, node
[1], &dummyRect
, FALSE
);
1005 ok(!nodeVisible
, "Node 1 should not be visible.\n");
1006 nodeVisible
= TreeView_GetItemRect(hTree
, node
[2], &dummyRect
, FALSE
);
1007 ok(!nodeVisible
, "Node 2 should not be visible.\n");
1008 nodeVisible
= TreeView_GetItemRect(hTree
, node
[3], &dummyRect
, FALSE
);
1009 ok(!nodeVisible
, "Node 3 should not be visible.\n");
1010 nodeVisible
= TreeView_GetItemRect(hTree
, node
[4], &dummyRect
, FALSE
);
1011 ok(!nodeVisible
, "Node 4 should not be visible.\n");
1013 DestroyWindow(hTree
);
1016 static void test_itemedit(void)
1024 hTree
= create_treeview_control();
1027 /* try with null item */
1028 edit
= (HWND
)SendMessage(hTree
, TVM_EDITLABEL
, 0, 0);
1029 ok(!IsWindow(edit
), "Expected valid handle\n");
1032 edit
= (HWND
)SendMessage(hTree
, TVM_EDITLABEL
, 0, (LPARAM
)hRoot
);
1033 ok(IsWindow(edit
), "Expected valid handle\n");
1034 /* item shouldn't be selected automatically after TVM_EDITLABEL */
1035 r
= SendMessage(hTree
, TVM_GETITEMSTATE
, (WPARAM
)hRoot
, TVIS_SELECTED
);
1037 /* try to cancel with wrong edit handle */
1038 r
= SendMessage(hTree
, WM_COMMAND
, MAKEWPARAM(0, EN_KILLFOCUS
), 0);
1040 ok(IsWindow(edit
), "Expected edit control to be valid\n");
1041 r
= SendMessage(hTree
, WM_COMMAND
, MAKEWPARAM(0, EN_KILLFOCUS
), (LPARAM
)edit
);
1043 ok(!IsWindow(edit
), "Expected edit control to be destroyed\n");
1044 /* try to cancel without creating edit */
1045 r
= SendMessage(hTree
, WM_COMMAND
, MAKEWPARAM(0, EN_KILLFOCUS
), 0);
1048 /* try to cancel with wrong (not null) handle */
1049 edit
= (HWND
)SendMessage(hTree
, TVM_EDITLABEL
, 0, (LPARAM
)hRoot
);
1050 ok(IsWindow(edit
), "Expected valid handle\n");
1051 r
= SendMessage(hTree
, WM_COMMAND
, MAKEWPARAM(0, EN_KILLFOCUS
), (LPARAM
)hTree
);
1053 ok(IsWindow(edit
), "Expected edit control to be valid\n");
1054 r
= SendMessage(hTree
, WM_COMMAND
, MAKEWPARAM(0, EN_KILLFOCUS
), (LPARAM
)edit
);
1057 /* remove selection after starting edit */
1058 r
= TreeView_SelectItem(hTree
, hRoot
);
1060 edit
= (HWND
)SendMessage(hTree
, TVM_EDITLABEL
, 0, (LPARAM
)hRoot
);
1061 ok(IsWindow(edit
), "Expected valid handle\n");
1062 r
= TreeView_SelectItem(hTree
, NULL
);
1065 strncpy(buff
, "x", sizeof(buff
)/sizeof(CHAR
));
1066 r
= SendMessage(edit
, WM_SETTEXT
, 0, (LPARAM
)buff
);
1068 r
= SendMessage(hTree
, WM_COMMAND
, MAKEWPARAM(0, EN_KILLFOCUS
), (LPARAM
)edit
);
1070 ok(!IsWindow(edit
), "Expected edit control to be destroyed\n");
1071 /* check that text is saved */
1072 item
.mask
= TVIF_TEXT
;
1074 item
.pszText
= buff
;
1075 item
.cchTextMax
= sizeof(buff
)/sizeof(CHAR
);
1076 r
= SendMessage(hTree
, TVM_GETITEM
, 0, (LPARAM
)&item
);
1078 ok(!strcmp("x", buff
), "Expected item text to change\n");
1080 DestroyWindow(hTree
);
1083 static void test_treeview_classinfo(void)
1087 memset(&cls
, 0, sizeof(cls
));
1088 GetClassInfo(GetModuleHandleA("comctl32.dll"), WC_TREEVIEWA
, &cls
);
1089 ok(cls
.hbrBackground
== NULL
, "Expected NULL background brush, got %p\n", cls
.hbrBackground
);
1090 ok(cls
.style
== (CS_GLOBALCLASS
| CS_DBLCLKS
), "Expected got %x\n", cls
.style
);
1091 expect(0, cls
.cbClsExtra
);
1094 static void test_get_linecolor(void)
1099 hTree
= create_treeview_control();
1101 /* newly created control has default color */
1102 clr
= (COLORREF
)SendMessage(hTree
, TVM_GETLINECOLOR
, 0, 0);
1104 win_skip("TVM_GETLINECOLOR is not supported on comctl32 < 5.80\n");
1106 expect(CLR_DEFAULT
, clr
);
1108 DestroyWindow(hTree
);
1111 static void test_get_insertmarkcolor(void)
1116 hTree
= create_treeview_control();
1118 /* newly created control has default color */
1119 clr
= (COLORREF
)SendMessage(hTree
, TVM_GETINSERTMARKCOLOR
, 0, 0);
1121 win_skip("TVM_GETINSERTMARKCOLOR is not supported on comctl32 < 5.80\n");
1123 expect(CLR_DEFAULT
, clr
);
1125 DestroyWindow(hTree
);
1128 static void test_expandnotify(void)
1134 hTree
= create_treeview_control();
1138 item
.mask
= TVIF_STATE
;
1140 item
.state
= TVIS_EXPANDED
;
1141 ret
= SendMessageA(hTree
, TVM_GETITEMA
, 0, (LPARAM
)&item
);
1142 ok(ret
== TRUE
, "got %d\n", ret
);
1143 ok((item
.state
& TVIS_EXPANDED
) == 0, "expected collapsed\n");
1145 /* preselect root node here */
1146 ret
= SendMessageA(hTree
, TVM_SELECTITEM
, TVGN_CARET
, (LPARAM
)hRoot
);
1147 ok(ret
== TRUE
, "got %d\n", ret
);
1149 g_get_from_expand
= TRUE
;
1151 flush_sequences(sequences
, NUM_MSG_SEQUENCES
);
1152 g_item_expanding
.state
= 0xdeadbeef;
1153 g_item_expanded
.state
= 0xdeadbeef;
1154 ret
= SendMessageA(hTree
, TVM_EXPAND
, TVE_EXPAND
, (LPARAM
)hRoot
);
1155 ok(ret
== TRUE
, "got %d\n", ret
);
1156 ok(g_item_expanding
.state
== TVIS_SELECTED
, "got state on TVN_ITEMEXPANDING 0x%08x\n",
1157 g_item_expanding
.state
);
1158 ok(g_item_expanded
.state
== (TVIS_SELECTED
|TVIS_EXPANDED
), "got state on TVN_ITEMEXPANDED 0x%08x\n",
1159 g_item_expanded
.state
);
1160 ok_sequence(sequences
, PARENT_SEQ_INDEX
, parent_expand_seq
, "expand notifications", FALSE
);
1161 g_get_from_expand
= FALSE
;
1163 /* check that it's expanded */
1164 item
.state
= TVIS_EXPANDED
;
1165 ret
= SendMessageA(hTree
, TVM_GETITEMA
, 0, (LPARAM
)&item
);
1166 ok(ret
== TRUE
, "got %d\n", ret
);
1167 ok((item
.state
& TVIS_EXPANDED
) == TVIS_EXPANDED
, "expected expanded\n");
1170 flush_sequences(sequences
, NUM_MSG_SEQUENCES
);
1171 ret
= SendMessageA(hTree
, TVM_EXPAND
, TVE_COLLAPSE
, (LPARAM
)hRoot
);
1172 ok(ret
== TRUE
, "got %d\n", ret
);
1173 item
.state
= TVIS_EXPANDED
;
1174 ret
= SendMessageA(hTree
, TVM_GETITEMA
, 0, (LPARAM
)&item
);
1175 ok(ret
== TRUE
, "got %d\n", ret
);
1176 ok((item
.state
& TVIS_EXPANDED
) == 0, "expected collapsed\n");
1177 /* all next collapse/expand attempts won't produce any notifications,
1178 the only way is to reset with all children removed */
1179 ok_sequence(sequences
, PARENT_SEQ_INDEX
, empty_seq
, "collapse after expand notifications", FALSE
);
1181 DestroyWindow(hTree
);
1184 static void test_rect_retrieval_after_expand_with_select(void) {
1187 hTree
= create_treeview_control();
1189 g_get_rect_in_expand
= TRUE
;
1190 ret
= TreeView_Select(hTree
, hChild
, TVGN_CARET
);
1191 g_get_rect_in_expand
= FALSE
;
1192 ok(ret
,"TreeView_Select should return true\n");
1195 START_TEST(treeview
)
1198 BOOL (WINAPI
*pInitCommonControlsEx
)(const INITCOMMONCONTROLSEX
*);
1202 hComctl32
= GetModuleHandleA("comctl32.dll");
1203 pInitCommonControlsEx
= (void*)GetProcAddress(hComctl32
, "InitCommonControlsEx");
1204 if (pInitCommonControlsEx
)
1206 INITCOMMONCONTROLSEX iccex
;
1207 iccex
.dwSize
= sizeof(iccex
);
1208 iccex
.dwICC
= ICC_TREEVIEW_CLASSES
;
1209 pInitCommonControlsEx(&iccex
);
1212 InitCommonControls();
1214 init_msg_sequences(sequences
, NUM_MSG_SEQUENCES
);
1216 wc
.style
= CS_HREDRAW
| CS_VREDRAW
;
1219 wc
.hInstance
= GetModuleHandleA(NULL
);
1221 wc
.hCursor
= LoadCursorA(NULL
, IDC_IBEAM
);
1222 wc
.hbrBackground
= GetSysColorBrush(COLOR_WINDOW
);
1223 wc
.lpszMenuName
= NULL
;
1224 wc
.lpszClassName
= "MyTestWnd";
1225 wc
.lpfnWndProc
= parent_wnd_proc
;
1226 RegisterClassA(&wc
);
1228 hMainWnd
= CreateWindowExA(0, "MyTestWnd", "Blah", WS_OVERLAPPEDWINDOW
,
1229 CW_USEDEFAULT
, CW_USEDEFAULT
, 130, 105, NULL
, NULL
, GetModuleHandleA(NULL
), 0);
1231 ok(hMainWnd
!= NULL
, "Failed to create parent window. Tests aborted.\n");
1232 if (!hMainWnd
) return;
1238 test_get_set_bkcolor();
1239 test_get_set_imagelist();
1240 test_get_set_indent();
1241 test_get_set_insertmark();
1242 test_get_set_item();
1243 test_get_set_itemheight();
1244 test_get_set_scrolltime();
1245 test_get_set_textcolor();
1246 test_get_linecolor();
1247 test_get_insertmarkcolor();
1248 test_get_set_tooltips();
1249 test_get_set_unicodeformat();
1251 test_expandinvisible();
1253 test_treeview_classinfo();
1254 test_expandnotify();
1255 test_rect_retrieval_after_expand_with_select();
1257 PostMessageA(hMainWnd
, WM_CLOSE
, 0, 0);
1258 while(GetMessageA(&msg
,0,0,0)) {
1259 TranslateMessage(&msg
);
1260 DispatchMessageA(&msg
);