ReactOS 0.4.15-dev-7958-gcd0bb1a
treeview.c
Go to the documentation of this file.
1/* Treeview control
2 *
3 * Copyright 1998 Eric Kohl <ekohl@abo.rhein-zeitung.de>
4 * Copyright 1998,1999 Alex Priem <alexp@sci.kun.nl>
5 * Copyright 1999 Sylvain St-Germain
6 * Copyright 2002 CodeWeavers, Aric Stewart
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 *
22 * NOTES
23 *
24 * Note that TREEVIEW_INFO * and HTREEITEM are the same thing.
25 *
26 * Note2: If item's text == LPSTR_TEXTCALLBACKA we allocate buffer
27 * of size TEXT_CALLBACK_SIZE in DoSetItem.
28 * We use callbackMask to keep track of fields to be updated.
29 *
30 * TODO:
31 * missing notifications: TVN_GETINFOTIP, TVN_KEYDOWN,
32 * TVN_SETDISPINFO
33 *
34 * missing styles: TVS_INFOTIP, TVS_RTLREADING,
35 *
36 * missing item styles: TVIS_EXPANDPARTIAL, TVIS_EX_FLAT,
37 * TVIS_EX_DISABLED
38 *
39 * Make the insertion mark look right.
40 * Scroll (instead of repaint) as much as possible.
41 */
42
43#include "config.h"
44#include "wine/port.h"
45
46#include <assert.h>
47#include <ctype.h>
48#include <stdarg.h>
49#include <string.h>
50#include <limits.h>
51#include <stdlib.h>
52
53#define NONAMELESSUNION
54
55#include "windef.h"
56#include "winbase.h"
57#include "wingdi.h"
58#include "winuser.h"
59#include "winnls.h"
60#include "commctrl.h"
61#include "comctl32.h"
62#include "uxtheme.h"
63#include "vssym32.h"
64#include "wine/unicode.h"
65#include "wine/debug.h"
66#include "wine/exception.h"
67#include "wine/heap.h"
68
70
71/* internal structures */
72typedef struct tagTREEVIEW_INFO
73{
75 HWND hwndNotify; /* Owner window to send notifications to */
80 UINT uNumItems; /* number of valid TREEVIEW_ITEMs */
81 INT cdmode; /* last custom draw setting */
82 UINT uScrollTime; /* max. time for scrolling in milliseconds */
83 BOOL bRedraw; /* if FALSE we validate but don't redraw in TREEVIEW_Paint() */
84
85 UINT uItemHeight; /* item height */
87
88 LONG clientWidth; /* width of control window */
89 LONG clientHeight; /* height of control window */
90
91 LONG treeWidth; /* width of visible tree items */
92 LONG treeHeight; /* height of visible tree items */
93
94 UINT uIndent; /* indentation in pixels */
95 HTREEITEM selectedItem; /* handle to selected item or 0 if none */
96 HTREEITEM hotItem; /* handle currently under cursor, 0 if none */
97 HTREEITEM focusedItem; /* item that was under the cursor when WM_LBUTTONDOWN was received */
98 HTREEITEM editItem; /* item being edited with builtin edit box */
99
100 HTREEITEM firstVisible; /* handle to item whose top edge is at y = 0 */
102 HTREEITEM dropItem; /* handle to item selected by drag cursor */
103 HTREEITEM insertMarkItem; /* item after which insertion mark is placed */
104 BOOL insertBeforeorAfter; /* flag used by TVM_SETINSERTMARK */
105 HIMAGELIST dragList; /* Bitmap of dragged item */
119
121 WNDPROC wpEditOrig; /* orig window proc for subclassing edit */
124
125 BOOL bNtfUnicode; /* TRUE if should send NOTIFY with W */
133
139
140typedef struct _TREEITEM /* HTREEITEM is a _TREEINFO *. */
141{
142 HTREEITEM parent; /* handle to parent or 0 if at root */
143 HTREEITEM nextSibling; /* handle to next item in list, 0 if last */
144 HTREEITEM firstChild; /* handle to first child or 0 if no child */
145
156 int iIntegral; /* item height multiplier (1 is normal) */
157 int iLevel; /* indentation level:0=root level */
159 HTREEITEM prevSibling; /* handle to prev item in list, 0 if first */
165 LONG textWidth; /* horizontal text extent for pszText */
166 LONG visibleOrder; /* Depth-first numbering of the items whose ancestors are all expanded,
167 corresponding to a top-to-bottom ordering in the tree view.
168 Each item takes up "item.iIntegral" spots in the visible order.
169 0 is the root's first child. */
170 const TREEVIEW_INFO *infoPtr; /* tree data this item belongs to */
172
173/******** Defines that TREEVIEW_ProcessLetterKeys uses ****************/
174#define KEY_DELAY 450
175
176/* bitflags for infoPtr->uInternalStatus */
177
178#define TV_HSCROLL 0x01 /* treeview too large to fit in window */
179#define TV_VSCROLL 0x02 /* (horizontal/vertical) */
180#define TV_LDRAG 0x04 /* Lbutton pushed to start drag */
181#define TV_LDRAGGING 0x08 /* Lbutton pushed, mouse moved. */
182#define TV_RDRAG 0x10 /* ditto Rbutton */
183#define TV_RDRAGGING 0x20
184
185/* bitflags for infoPtr->timer */
186
187#define TV_EDIT_TIMER 2
188#define TV_EDIT_TIMER_SET 2
189
190#define TEXT_CALLBACK_SIZE 260
191
192#define TREEVIEW_LEFT_MARGIN 8
193
194#define MINIMUM_INDENT 19
195
196#define CALLBACK_MASK_ALL (TVIF_TEXT|TVIF_CHILDREN|TVIF_IMAGE|TVIF_SELECTEDIMAGE)
197
198#define STATEIMAGEINDEX(x) (((x) >> 12) & 0x0f)
199#define OVERLAYIMAGEINDEX(x) (((x) >> 8) & 0x0f)
200#define ISVISIBLE(x) ((x)->visibleOrder >= 0)
201
202#define GETLINECOLOR(x) ((x) == CLR_DEFAULT ? comctl32_color.clrGrayText : (x))
203#define GETBKCOLOR(x) ((x) == CLR_NONE ? comctl32_color.clrWindow : (x))
204#define GETTXTCOLOR(x) ((x) == CLR_NONE ? comctl32_color.clrWindowText : (x))
205#define GETINSCOLOR(x) ((x) == CLR_DEFAULT ? comctl32_color.clrBtnText : (x))
206
207static const WCHAR themeClass[] = { 'T','r','e','e','v','i','e','w',0 };
208
209
211
212
213static VOID TREEVIEW_Invalidate(const TREEVIEW_INFO *, const TREEVIEW_ITEM *);
214
218static LRESULT TREEVIEW_EndEditLabelNow(TREEVIEW_INFO *infoPtr, BOOL bCancel);
221
222/* Random Utilities *****************************************************/
223static void TREEVIEW_VerifyTree(TREEVIEW_INFO *infoPtr);
224
225/* Returns the treeview private data if hwnd is a treeview.
226 * Otherwise returns an undefined value. */
227static inline TREEVIEW_INFO *
229{
231}
232
233/* Don't call this. Nothing wants an item index. */
234static inline int
236{
237 return DPA_GetPtrIndex(infoPtr->items, handle);
238}
239
240/* Checks if item has changed and needs to be redrawn */
241static inline BOOL item_changed (const TREEVIEW_ITEM *tiOld, const TREEVIEW_ITEM *tiNew,
242 const TVITEMEXW *tvChange)
243{
244 /* Number of children has changed */
245 if ((tvChange->mask & TVIF_CHILDREN) && (tiOld->cChildren != tiNew->cChildren))
246 return TRUE;
247
248 /* Image has changed and it's not a callback */
249 if ((tvChange->mask & TVIF_IMAGE) && (tiOld->iImage != tiNew->iImage) &&
250 tiNew->iImage != I_IMAGECALLBACK)
251 return TRUE;
252
253 /* Selected image has changed and it's not a callback */
254 if ((tvChange->mask & TVIF_SELECTEDIMAGE) && (tiOld->iSelectedImage != tiNew->iSelectedImage) &&
256 return TRUE;
257
258 if ((tvChange->mask & TVIF_EXPANDEDIMAGE) && (tiOld->iExpandedImage != tiNew->iExpandedImage) &&
260 return TRUE;
261
262 /* Text has changed and it's not a callback */
263 if ((tvChange->mask & TVIF_TEXT) && (tiOld->pszText != tiNew->pszText) &&
265 return TRUE;
266
267 /* Indent has changed */
268 if ((tvChange->mask & TVIF_INTEGRAL) && (tiOld->iIntegral != tiNew->iIntegral))
269 return TRUE;
270
271 /* Item state has changed */
272 if ((tvChange->mask & TVIF_STATE) && ((tiOld->state ^ tiNew->state) & tvChange->stateMask ))
273 return TRUE;
274
275 return FALSE;
276}
277
278/***************************************************************************
279 * This method checks that handle is an item for this tree.
280 */
281static BOOL
283{
284 if (TREEVIEW_GetItemIndex(infoPtr, handle) == -1)
285 {
286 TRACE("invalid item %p\n", handle);
287 return FALSE;
288 }
289 else
290 return TRUE;
291}
292
293static HFONT
295{
297
298 GetObjectW(hOrigFont, sizeof(font), &font);
299 font.lfWeight = FW_BOLD;
300 return CreateFontIndirectW(&font);
301}
302
303static HFONT
305{
307
308 GetObjectW(hOrigFont, sizeof(font), &font);
309 font.lfUnderline = TRUE;
310 return CreateFontIndirectW(&font);
311}
312
313static HFONT
315{
317
318 GetObjectW(hfont, sizeof(font), &font);
319 font.lfWeight = FW_BOLD;
320 font.lfUnderline = TRUE;
321 return CreateFontIndirectW(&font);
322}
323
324static inline HFONT
326{
327 if ((infoPtr->dwStyle & TVS_TRACKSELECT) && (item == infoPtr->hotItem))
328 return item->state & TVIS_BOLD ? infoPtr->hBoldUnderlineFont : infoPtr->hUnderlineFont;
329 if (item->state & TVIS_BOLD)
330 return infoPtr->hBoldFont;
331 return infoPtr->hFont;
332}
333
334/* for trace/debugging purposes only */
335static const char *
337{
338 if (item == NULL) return "<null item>";
339 if (item->pszText == LPSTR_TEXTCALLBACKW) return "<callback>";
340 if (item->pszText == NULL) return "<null>";
341 return debugstr_w(item->pszText);
342}
343
344/* An item is not a child of itself. */
345static BOOL
347{
348 do
349 {
350 child = child->parent;
351 if (child == parent) return TRUE;
352 } while (child != NULL);
353
354 return FALSE;
355}
356
357static BOOL
359{
360 return !(infoPtr->dwStyle & TVS_HASLINES) && (infoPtr->dwStyle & TVS_FULLROWSELECT);
361}
362
363static BOOL
365{
366 if (TREEVIEW_IsFullRowSelect(infoPtr))
368 else
369 return ht->flags & TVHT_ONITEM;
370}
371
372/* Tree Traversal *******************************************************/
373
374/***************************************************************************
375 * This method returns the last expanded sibling or child child item
376 * of a tree node
377 */
378static TREEVIEW_ITEM *
380{
381 if (!item) return NULL;
382
383 while (item->lastChild)
384 {
385 if (item->state & TVIS_EXPANDED)
386 item = item->lastChild;
387 else
388 break;
389 }
390
391 if (item == infoPtr->root)
392 return NULL;
393
394 return item;
395}
396
397/***************************************************************************
398 * This method returns the previous non-hidden item in the list not
399 * considering the tree hierarchy.
400 */
401static TREEVIEW_ITEM *
403{
404 if (tvItem->prevSibling)
405 {
406 /* This item has a prevSibling, get the last item in the sibling's tree. */
407 TREEVIEW_ITEM *upItem = tvItem->prevSibling;
408
409 if ((upItem->state & TVIS_EXPANDED) && upItem->lastChild != NULL)
410 return TREEVIEW_GetLastListItem(infoPtr, upItem->lastChild);
411 else
412 return upItem;
413 }
414 else
415 {
416 /* this item does not have a prevSibling, get the parent */
417 return (tvItem->parent != infoPtr->root) ? tvItem->parent : NULL;
418 }
419}
420
421
422/***************************************************************************
423 * This method returns the next physical item in the treeview not
424 * considering the tree hierarchy.
425 */
426static TREEVIEW_ITEM *
428{
429 /*
430 * If this item has children and is expanded, return the first child
431 */
432 if ((tvItem->state & TVIS_EXPANDED) && tvItem->firstChild != NULL)
433 {
434 return tvItem->firstChild;
435 }
436
437
438 /*
439 * try to get the sibling
440 */
441 if (tvItem->nextSibling)
442 return tvItem->nextSibling;
443
444 /*
445 * Otherwise, get the parent's sibling.
446 */
447 while (tvItem->parent)
448 {
449 tvItem = tvItem->parent;
450
451 if (tvItem->nextSibling)
452 return tvItem->nextSibling;
453 }
454
455 return NULL;
456}
457
458/***************************************************************************
459 * This method returns the nth item starting at the given item. It returns
460 * the last item (or first) we we run out of items.
461 *
462 * Will scroll backward if count is <0.
463 * forward if count is >0.
464 */
465static TREEVIEW_ITEM *
467 LONG count)
468{
469 TREEVIEW_ITEM *(*next_item)(const TREEVIEW_INFO *, const TREEVIEW_ITEM *);
470 TREEVIEW_ITEM *previousItem;
471
472 assert(item != NULL);
473
474 if (count > 0)
475 {
476 next_item = TREEVIEW_GetNextListItem;
477 }
478 else if (count < 0)
479 {
480 count = -count;
481 next_item = TREEVIEW_GetPrevListItem;
482 }
483 else
484 return item;
485
486 do
487 {
488 previousItem = item;
489 item = next_item(infoPtr, item);
490
491 } while (--count && item != NULL);
492
493
494 return item ? item : previousItem;
495}
496
497/* Notifications ************************************************************/
498
499static INT get_notifycode(const TREEVIEW_INFO *infoPtr, INT code)
500{
501 if (!infoPtr->bNtfUnicode) {
502 switch (code) {
504 case TVN_SELCHANGEDW: return TVN_SELCHANGEDA;
509 case TVN_BEGINDRAGW: return TVN_BEGINDRAGA;
510 case TVN_BEGINRDRAGW: return TVN_BEGINRDRAGA;
511 case TVN_DELETEITEMW: return TVN_DELETEITEMA;
514 case TVN_GETINFOTIPW: return TVN_GETINFOTIPA;
515 }
516 }
517 return code;
518}
519
520static inline BOOL
522{
523 TRACE("code=%d, hdr=%p\n", code, hdr);
524
525 hdr->hwndFrom = infoPtr->hwnd;
526 hdr->idFrom = GetWindowLongPtrW(infoPtr->hwnd, GWLP_ID);
527 hdr->code = get_notifycode(infoPtr, code);
528
529 return SendMessageW(infoPtr->hwndNotify, WM_NOTIFY, hdr->idFrom, (LPARAM)hdr);
530}
531
532static BOOL
534{
535 NMHDR hdr;
536 return TREEVIEW_SendRealNotify(infoPtr, code, &hdr);
537}
538
539static VOID
541{
542 tvItem->mask = mask;
543 tvItem->hItem = item;
544 tvItem->state = item->state;
545 tvItem->stateMask = 0;
546 tvItem->iImage = item->iImage;
547 tvItem->iSelectedImage = item->iSelectedImage;
548 tvItem->cChildren = item->cChildren;
549 tvItem->lParam = item->lParam;
550
551 if(mask & TVIF_TEXT)
552 {
553 if (!infoPtr->bNtfUnicode)
554 {
555 tvItem->cchTextMax = WideCharToMultiByte( CP_ACP, 0, item->pszText, -1, NULL, 0, NULL, NULL );
556 tvItem->pszText = heap_alloc (tvItem->cchTextMax);
557 WideCharToMultiByte( CP_ACP, 0, item->pszText, -1, (LPSTR)tvItem->pszText, tvItem->cchTextMax, 0, 0 );
558 }
559 else
560 {
561 tvItem->cchTextMax = item->cchTextMax;
562 tvItem->pszText = item->pszText;
563 }
564 }
565 else
566 {
567 tvItem->cchTextMax = 0;
568 tvItem->pszText = NULL;
569 }
570}
571
572static BOOL
574 UINT mask, HTREEITEM oldItem, HTREEITEM newItem)
575{
576 NMTREEVIEWW nmhdr;
577 BOOL ret;
578
579 TRACE("code:%d action:0x%x olditem:%p newitem:%p\n",
580 code, action, oldItem, newItem);
581
582 memset(&nmhdr, 0, sizeof(NMTREEVIEWW));
583 nmhdr.action = action;
584
585 if (oldItem)
586 TREEVIEW_TVItemFromItem(infoPtr, mask, &nmhdr.itemOld, oldItem);
587
588 if (newItem)
589 TREEVIEW_TVItemFromItem(infoPtr, mask, &nmhdr.itemNew, newItem);
590
591 nmhdr.ptDrag.x = 0;
592 nmhdr.ptDrag.y = 0;
593
594 ret = TREEVIEW_SendRealNotify(infoPtr, code, &nmhdr.hdr);
595 if (!infoPtr->bNtfUnicode)
596 {
599 }
600 return ret;
601}
602
603static BOOL
605 HTREEITEM dragItem, POINT pt)
606{
607 NMTREEVIEWW nmhdr;
608
609 TRACE("code:%d dragitem:%p\n", code, dragItem);
610
611 nmhdr.action = 0;
613 nmhdr.itemNew.hItem = dragItem;
614 nmhdr.itemNew.state = dragItem->state;
615 nmhdr.itemNew.lParam = dragItem->lParam;
616
617 nmhdr.ptDrag.x = pt.x;
618 nmhdr.ptDrag.y = pt.y;
619
620 return TREEVIEW_SendRealNotify(infoPtr, code, &nmhdr.hdr);
621}
622
623
624static BOOL
626 HDC hdc, RECT rc)
627{
628 NMTVCUSTOMDRAW nmcdhdr;
629 NMCUSTOMDRAW *nmcd;
630
631 TRACE("drawstage:0x%x hdc:%p\n", dwDrawStage, hdc);
632
633 nmcd = &nmcdhdr.nmcd;
634 nmcd->dwDrawStage = dwDrawStage;
635 nmcd->hdc = hdc;
636 nmcd->rc = rc;
637 nmcd->dwItemSpec = 0;
638 nmcd->uItemState = 0;
639 nmcd->lItemlParam = 0;
640 nmcdhdr.clrText = infoPtr->clrText;
641 nmcdhdr.clrTextBk = infoPtr->clrBk;
642 nmcdhdr.iLevel = 0;
643
644 return TREEVIEW_SendRealNotify(infoPtr, NM_CUSTOMDRAW, &nmcdhdr.nmcd.hdr);
645}
646
647/* FIXME: need to find out when the flags in uItemState need to be set */
648
649static BOOL
651 TREEVIEW_ITEM *item, UINT uItemDrawState,
652 NMTVCUSTOMDRAW *nmcdhdr)
653{
654 NMCUSTOMDRAW *nmcd;
655 DWORD dwDrawStage;
656 DWORD_PTR dwItemSpec;
657 UINT uItemState;
658
659 dwDrawStage = CDDS_ITEM | uItemDrawState;
660 dwItemSpec = (DWORD_PTR)item;
661 uItemState = 0;
662 if (item->state & TVIS_SELECTED)
663 uItemState |= CDIS_SELECTED;
664 if (item == infoPtr->selectedItem)
665 uItemState |= CDIS_FOCUS;
666 if (item == infoPtr->hotItem)
667 uItemState |= CDIS_HOT;
668
669 nmcd = &nmcdhdr->nmcd;
670 nmcd->dwDrawStage = dwDrawStage;
671 nmcd->hdc = hdc;
672 nmcd->rc = item->rect;
673 nmcd->dwItemSpec = dwItemSpec;
674 nmcd->uItemState = uItemState;
675 nmcd->lItemlParam = item->lParam;
676 nmcdhdr->iLevel = item->iLevel;
677
678 TRACE("drawstage:0x%x hdc:%p item:%lx, itemstate:0x%x, lItemlParam:0x%lx\n",
679 nmcd->dwDrawStage, nmcd->hdc, nmcd->dwItemSpec,
680 nmcd->uItemState, nmcd->lItemlParam);
681
682 return TREEVIEW_SendRealNotify(infoPtr, NM_CUSTOMDRAW, &nmcdhdr->nmcd.hdr);
683}
684
685static BOOL
687{
688 NMTVDISPINFOW tvdi;
689 BOOL ret;
690
692 &tvdi.item, editItem);
693
695
696 if (!infoPtr->bNtfUnicode)
697 heap_free(tvdi.item.pszText);
698
699 return ret;
700}
701
702static void
704 UINT mask)
705{
706 NMTVDISPINFOEXW callback;
707
708 TRACE("mask=0x%x, callbackmask=0x%x\n", mask, item->callbackMask);
709 mask &= item->callbackMask;
710
711 if (mask == 0) return;
712
713 /* 'state' always contains valid value, as well as 'lParam'.
714 * All other parameters are uninitialized.
715 */
716 callback.item.pszText = item->pszText;
717 callback.item.cchTextMax = item->cchTextMax;
718 callback.item.mask = mask;
719 callback.item.hItem = item;
720 callback.item.state = item->state;
721 callback.item.lParam = item->lParam;
722
723 /* If text is changed we need to recalculate textWidth */
724 if (mask & TVIF_TEXT)
725 item->textWidth = 0;
726
728 TRACE("resulting code 0x%08x\n", callback.hdr.code);
729
730 /* It may have changed due to a call to SetItem. */
731 mask &= item->callbackMask;
732
733 if ((mask & TVIF_TEXT) && callback.item.pszText != item->pszText)
734 {
735 /* Instead of copying text into our buffer user specified his own */
736 if (!infoPtr->bNtfUnicode && (callback.hdr.code == TVN_GETDISPINFOA)) {
737 LPWSTR newText;
738 int buflen;
740 (LPSTR)callback.item.pszText, -1,
741 NULL, 0);
742 buflen = max((len)*sizeof(WCHAR), TEXT_CALLBACK_SIZE);
743 newText = heap_realloc(item->pszText, buflen);
744
745 TRACE("returned str %s, len=%d, buflen=%d\n",
746 debugstr_a((LPSTR)callback.item.pszText), len, buflen);
747
748 if (newText)
749 {
750 item->pszText = newText;
752 (LPSTR)callback.item.pszText, -1,
753 item->pszText, buflen/sizeof(WCHAR));
754 item->cchTextMax = buflen/sizeof(WCHAR);
755 }
756 /* If realloc fails we have nothing to do, but keep original text */
757 }
758 else {
759 int len = max(lstrlenW(callback.item.pszText) + 1,
761 LPWSTR newText = heap_realloc(item->pszText, len);
762
763 TRACE("returned wstr %s, len=%d\n",
764 debugstr_w(callback.item.pszText), len);
765
766 if (newText)
767 {
768 item->pszText = newText;
769 strcpyW(item->pszText, callback.item.pszText);
770 item->cchTextMax = len;
771 }
772 /* If realloc fails we have nothing to do, but keep original text */
773 }
774 }
775 else if (mask & TVIF_TEXT) {
776 /* User put text into our buffer, that is ok unless A string */
777 if (!infoPtr->bNtfUnicode && (callback.hdr.code == TVN_GETDISPINFOA)) {
778 LPWSTR newText;
779 int buflen;
781 (LPSTR)callback.item.pszText, -1,
782 NULL, 0);
783 buflen = max((len)*sizeof(WCHAR), TEXT_CALLBACK_SIZE);
784 newText = heap_alloc(buflen);
785
786 TRACE("same buffer str %s, len=%d, buflen=%d\n",
787 debugstr_a((LPSTR)callback.item.pszText), len, buflen);
788
789 if (newText)
790 {
791 LPWSTR oldText = item->pszText;
792 item->pszText = newText;
794 (LPSTR)callback.item.pszText, -1,
795 item->pszText, buflen/sizeof(WCHAR));
796 item->cchTextMax = buflen/sizeof(WCHAR);
797 heap_free(oldText);
798 }
799 }
800 }
801
802 if (mask & TVIF_IMAGE)
803 item->iImage = callback.item.iImage;
804
806 item->iSelectedImage = callback.item.iSelectedImage;
807
809 item->iExpandedImage = callback.item.iExpandedImage;
810
811 if (mask & TVIF_CHILDREN)
812 item->cChildren = callback.item.cChildren;
813
814 if (callback.item.mask & TVIF_STATE)
815 {
816 item->state &= ~callback.item.stateMask;
817 item->state |= (callback.item.state & callback.item.stateMask);
818 }
819
820 /* These members are now permanently set. */
821 if (callback.item.mask & TVIF_DI_SETITEM)
822 item->callbackMask &= ~callback.item.mask;
823}
824
825/***************************************************************************
826 * This function uses cChildren field to decide whether the item has
827 * children or not.
828 * Note: if this returns TRUE, the child items may not actually exist,
829 * they could be virtual.
830 *
831 * Just use item->firstChild to check for physical children.
832 */
833static BOOL
835{
837 /* Protect for a case when callback field is not changed by a host,
838 otherwise negative values trigger normal notifications. */
839 return item->cChildren != 0 && item->cChildren != I_CHILDRENCALLBACK;
840}
841
842static INT TREEVIEW_NotifyFormat (TREEVIEW_INFO *infoPtr, HWND hwndFrom, UINT nCommand)
843{
844 INT format;
845
846 TRACE("(hwndFrom=%p, nCommand=%d)\n", hwndFrom, nCommand);
847
848 if (nCommand != NF_REQUERY) return 0;
849
850 format = SendMessageW(hwndFrom, WM_NOTIFYFORMAT, (WPARAM)infoPtr->hwnd, NF_QUERY);
851 TRACE("format=%d\n", format);
852
853 /* Invalid format returned by NF_QUERY defaults to ANSI*/
854 if (format != NFR_ANSI && format != NFR_UNICODE)
856
857 infoPtr->bNtfUnicode = (format == NFR_UNICODE);
858
859 return format;
860}
861
862/* Item Position ********************************************************/
863
864/* Compute linesOffset, stateOffset, imageOffset, textOffset of an item. */
865static VOID
867{
868 /* has TVS_LINESATROOT and (TVS_HASLINES|TVS_HASBUTTONS) */
871
872 item->linesOffset = infoPtr->uIndent * (lar ? item->iLevel : item->iLevel - 1)
873 - infoPtr->scrollX;
874 item->stateOffset = item->linesOffset + infoPtr->uIndent;
875 item->imageOffset = item->stateOffset
876 + (STATEIMAGEINDEX(item->state) ? infoPtr->stateImageWidth : 0);
877 item->textOffset = item->imageOffset + infoPtr->normalImageWidth;
878}
879
880static VOID
882{
883 HDC hdc;
884 HFONT hOldFont=0;
885 SIZE sz;
886
887 /* DRAW's OM docker creates items like this */
888 if (item->pszText == NULL)
889 {
890 item->textWidth = 0;
891 return;
892 }
893
894 if (hDC != 0)
895 {
896 hdc = hDC;
897 }
898 else
899 {
900 hdc = GetDC(infoPtr->hwnd);
901 hOldFont = SelectObject(hdc, TREEVIEW_FontForItem(infoPtr, item));
902 }
903
904 GetTextExtentPoint32W(hdc, item->pszText, strlenW(item->pszText), &sz);
905 item->textWidth = sz.cx;
906
907 if (hDC == 0)
908 {
909 SelectObject(hdc, hOldFont);
910 ReleaseDC(0, hdc);
911 }
912}
913
914static VOID
916{
917 item->rect.top = infoPtr->uItemHeight *
918 (item->visibleOrder - infoPtr->firstVisible->visibleOrder);
919
920 item->rect.bottom = item->rect.top
921 + infoPtr->uItemHeight * item->iIntegral - 1;
922
923 item->rect.left = 0;
924 item->rect.right = infoPtr->clientWidth;
925}
926
927/* We know that only items after start need their order updated. */
928static void
930{
932 int order;
933
934 if (!start)
935 {
936 start = infoPtr->root->firstChild;
937 order = 0;
938 }
939 else
941
942 for (item = start; item != NULL;
944 {
945 if (!ISVISIBLE(item) && order > 0)
947 item->visibleOrder = order;
948 order += item->iIntegral;
949 }
950
951 infoPtr->maxVisibleOrder = order;
952
953 for (item = start; item != NULL;
955 {
957 }
958}
959
960
961/* Update metrics of all items in selected subtree.
962 * root must be expanded
963 */
964static VOID
966{
967 TREEVIEW_ITEM *sibling;
968 HDC hdc;
969 HFONT hOldFont;
970
971 if (!root->firstChild || !(root->state & TVIS_EXPANDED))
972 return;
973
974 root->state &= ~TVIS_EXPANDED;
975 sibling = TREEVIEW_GetNextListItem(infoPtr, root);
976 root->state |= TVIS_EXPANDED;
977
978 hdc = GetDC(infoPtr->hwnd);
979 hOldFont = SelectObject(hdc, infoPtr->hFont);
980
981 for (; root != sibling;
983 {
985
986 if (root->callbackMask & TVIF_TEXT)
988
989 if (root->textWidth == 0)
990 {
993 }
994 }
995
996 SelectObject(hdc, hOldFont);
997 ReleaseDC(infoPtr->hwnd, hdc);
998}
999
1000/* Item Allocation **********************************************************/
1001
1002static TREEVIEW_ITEM *
1004{
1005 TREEVIEW_ITEM *newItem = heap_alloc_zero(sizeof(*newItem));
1006
1007 if (!newItem)
1008 return NULL;
1009
1010 /* I_IMAGENONE would make more sense but this is neither what is
1011 * documented (MSDN doesn't specify) nor what Windows actually does
1012 * (it sets it to zero)... and I can so imagine an application using
1013 * inc/dec to toggle the images. */
1014 newItem->iImage = 0;
1015 newItem->iSelectedImage = 0;
1016 newItem->iExpandedImage = (WORD)I_IMAGENONE;
1017 newItem->infoPtr = infoPtr;
1018
1019 if (DPA_InsertPtr(infoPtr->items, INT_MAX, newItem) == -1)
1020 {
1021 heap_free(newItem);
1022 return NULL;
1023 }
1024
1025 return newItem;
1026}
1027
1028/* Exact opposite of TREEVIEW_AllocateItem. In particular, it does not
1029 * free item->pszText. */
1030static void
1032{
1033 DPA_DeletePtr(infoPtr->items, DPA_GetPtrIndex(infoPtr->items, item));
1034 if (infoPtr->selectedItem == item)
1035 infoPtr->selectedItem = NULL;
1036 if (infoPtr->hotItem == item)
1037 infoPtr->hotItem = NULL;
1038 if (infoPtr->focusedItem == item)
1039 infoPtr->focusedItem = NULL;
1040 if (infoPtr->firstVisible == item)
1041 infoPtr->firstVisible = NULL;
1042 if (infoPtr->dropItem == item)
1043 infoPtr->dropItem = NULL;
1044 if (infoPtr->insertMarkItem == item)
1045 infoPtr->insertMarkItem = NULL;
1046 heap_free(item);
1047}
1048
1049
1050/* Item Insertion *******************************************************/
1051
1052/***************************************************************************
1053 * This method inserts newItem before sibling as a child of parent.
1054 * sibling can be NULL, but only if parent has no children.
1055 */
1056static void
1059{
1060 assert(parent != NULL);
1061
1062 if (sibling != NULL)
1063 {
1064 assert(sibling->parent == parent);
1065
1066 if (sibling->prevSibling != NULL)
1067 sibling->prevSibling->nextSibling = newItem;
1068
1069 newItem->prevSibling = sibling->prevSibling;
1070 sibling->prevSibling = newItem;
1071 }
1072 else
1073 newItem->prevSibling = NULL;
1074
1075 newItem->nextSibling = sibling;
1076
1077 if (parent->firstChild == sibling)
1078 parent->firstChild = newItem;
1079
1080 if (parent->lastChild == NULL)
1081 parent->lastChild = newItem;
1082}
1083
1084/***************************************************************************
1085 * This method inserts newItem after sibling as a child of parent.
1086 * sibling can be NULL, but only if parent has no children.
1087 */
1088static void
1091{
1092 assert(parent != NULL);
1093
1094 if (sibling != NULL)
1095 {
1096 assert(sibling->parent == parent);
1097
1098 if (sibling->nextSibling != NULL)
1099 sibling->nextSibling->prevSibling = newItem;
1100
1101 newItem->nextSibling = sibling->nextSibling;
1102 sibling->nextSibling = newItem;
1103 }
1104 else
1105 newItem->nextSibling = NULL;
1106
1107 newItem->prevSibling = sibling;
1108
1109 if (parent->lastChild == sibling)
1110 parent->lastChild = newItem;
1111
1112 if (parent->firstChild == NULL)
1113 parent->firstChild = newItem;
1114}
1115
1116static BOOL
1118 const TVITEMEXW *tvItem, BOOL isW)
1119{
1120 UINT callbackClear = 0;
1121 UINT callbackSet = 0;
1122
1123 TRACE("item %p\n", item);
1124 /* Do this first in case it fails. */
1125 if (tvItem->mask & TVIF_TEXT)
1126 {
1127 item->textWidth = 0; /* force width recalculation */
1128 if (tvItem->pszText != LPSTR_TEXTCALLBACKW && tvItem->pszText != NULL) /* covers != TEXTCALLBACKA too, and undocumented: pszText of NULL also means TEXTCALLBACK */
1129 {
1130 int len;
1131 LPWSTR newText;
1132 if (isW)
1133 len = lstrlenW(tvItem->pszText) + 1;
1134 else
1135 len = MultiByteToWideChar(CP_ACP, 0, (LPSTR)tvItem->pszText, -1, NULL, 0);
1136
1137 newText = heap_realloc(item->pszText, len * sizeof(WCHAR));
1138
1139 if (newText == NULL) return FALSE;
1140
1141 callbackClear |= TVIF_TEXT;
1142
1143 item->pszText = newText;
1144 item->cchTextMax = len;
1145 if (isW)
1146 lstrcpynW(item->pszText, tvItem->pszText, len);
1147 else
1148 MultiByteToWideChar(CP_ACP, 0, (LPSTR)tvItem->pszText, -1,
1149 item->pszText, len);
1150
1151 TRACE("setting text %s, item %p\n", debugstr_w(item->pszText), item);
1152 }
1153 else
1154 {
1155 callbackSet |= TVIF_TEXT;
1156 item->pszText = heap_realloc(item->pszText, TEXT_CALLBACK_SIZE * sizeof(WCHAR));
1157 item->cchTextMax = TEXT_CALLBACK_SIZE;
1158 TRACE("setting callback, item %p\n", item);
1159 }
1160 }
1161
1162 if (tvItem->mask & TVIF_CHILDREN)
1163 {
1164 item->cChildren = tvItem->cChildren;
1165
1166 if (item->cChildren == I_CHILDRENCALLBACK)
1167 callbackSet |= TVIF_CHILDREN;
1168 else
1169 callbackClear |= TVIF_CHILDREN;
1170 }
1171
1172 if (tvItem->mask & TVIF_IMAGE)
1173 {
1174 item->iImage = tvItem->iImage;
1175
1176 if (item->iImage == I_IMAGECALLBACK)
1177 callbackSet |= TVIF_IMAGE;
1178 else
1179 callbackClear |= TVIF_IMAGE;
1180 }
1181
1182 if (tvItem->mask & TVIF_SELECTEDIMAGE)
1183 {
1184 item->iSelectedImage = tvItem->iSelectedImage;
1185
1186 if (item->iSelectedImage == I_IMAGECALLBACK)
1187 callbackSet |= TVIF_SELECTEDIMAGE;
1188 else
1189 callbackClear |= TVIF_SELECTEDIMAGE;
1190 }
1191
1192 if (tvItem->mask & TVIF_EXPANDEDIMAGE)
1193 {
1194 item->iExpandedImage = tvItem->iExpandedImage;
1195
1196 if (item->iExpandedImage == I_IMAGECALLBACK)
1197 callbackSet |= TVIF_EXPANDEDIMAGE;
1198 else
1199 callbackClear |= TVIF_EXPANDEDIMAGE;
1200 }
1201
1202 if (tvItem->mask & TVIF_PARAM)
1203 item->lParam = tvItem->lParam;
1204
1205 /* If the application sets TVIF_INTEGRAL without
1206 * supplying a TVITEMEX structure, it's toast. */
1207 if (tvItem->mask & TVIF_INTEGRAL)
1208 item->iIntegral = tvItem->iIntegral;
1209
1210 if (tvItem->mask & TVIF_STATE)
1211 {
1212 TRACE("prevstate 0x%x, state 0x%x, mask 0x%x\n", item->state, tvItem->state,
1213 tvItem->stateMask);
1214 item->state &= ~tvItem->stateMask;
1215 item->state |= (tvItem->state & tvItem->stateMask);
1216 }
1217
1218 if (tvItem->mask & TVIF_STATEEX)
1219 {
1220 FIXME("New extended state: 0x%x\n", tvItem->uStateEx);
1221 }
1222
1223 item->callbackMask |= callbackSet;
1224 item->callbackMask &= ~callbackClear;
1225
1226 return TRUE;
1227}
1228
1229/* Note that the new item is pre-zeroed. */
1230static LRESULT
1232{
1233 const TVITEMEXW *tvItem = &ptdi->u.itemex;
1234 HTREEITEM insertAfter;
1235 TREEVIEW_ITEM *newItem, *parentItem;
1236 BOOL bTextUpdated = FALSE;
1237
1238 if (ptdi->hParent == TVI_ROOT || ptdi->hParent == 0)
1239 {
1240 parentItem = infoPtr->root;
1241 }
1242 else
1243 {
1244 parentItem = ptdi->hParent;
1245
1246 if (!TREEVIEW_ValidItem(infoPtr, parentItem))
1247 {
1248 WARN("invalid parent %p\n", parentItem);
1249 return 0;
1250 }
1251 }
1252
1253 insertAfter = ptdi->hInsertAfter;
1254
1255 /* Validate this now for convenience. */
1256 switch ((DWORD_PTR)insertAfter)
1257 {
1258 case (DWORD_PTR)TVI_FIRST:
1259 case (DWORD_PTR)TVI_LAST:
1260 case (DWORD_PTR)TVI_SORT:
1261 break;
1262
1263 default:
1264 if (!TREEVIEW_ValidItem(infoPtr, insertAfter) ||
1265 insertAfter->parent != parentItem)
1266 {
1267 WARN("invalid insert after %p\n", insertAfter);
1268 insertAfter = TVI_LAST;
1269 }
1270 }
1271
1272 TRACE("parent %p position %p: %s\n", parentItem, insertAfter,
1273 (tvItem->mask & TVIF_TEXT)
1274 ? ((tvItem->pszText == LPSTR_TEXTCALLBACKW) ? "<callback>"
1275 : (isW ? debugstr_w(tvItem->pszText) : debugstr_a((LPSTR)tvItem->pszText)))
1276 : "<no label>");
1277
1278 newItem = TREEVIEW_AllocateItem(infoPtr);
1279 if (newItem == NULL)
1280 return 0;
1281
1282 newItem->parent = parentItem;
1283 newItem->iIntegral = 1;
1284 newItem->visibleOrder = -1;
1285
1286 if (!TREEVIEW_DoSetItemT(infoPtr, newItem, tvItem, isW))
1287 return 0;
1288
1289 /* After this point, nothing can fail. (Except for TVI_SORT.) */
1290
1291 infoPtr->uNumItems++;
1292
1293 switch ((DWORD_PTR)insertAfter)
1294 {
1295 case (DWORD_PTR)TVI_FIRST:
1296 {
1297 TREEVIEW_ITEM *originalFirst = parentItem->firstChild;
1298 TREEVIEW_InsertBefore(newItem, parentItem->firstChild, parentItem);
1299 if (infoPtr->firstVisible == originalFirst)
1300 TREEVIEW_SetFirstVisible(infoPtr, newItem, TRUE);
1301 }
1302 break;
1303
1304 case (DWORD_PTR)TVI_LAST:
1305 TREEVIEW_InsertAfter(newItem, parentItem->lastChild, parentItem);
1306 break;
1307
1308 /* hInsertAfter names a specific item we want to insert after */
1309 default:
1310 TREEVIEW_InsertAfter(newItem, insertAfter, insertAfter->parent);
1311 break;
1312
1313 case (DWORD_PTR)TVI_SORT:
1314 {
1315 TREEVIEW_ITEM *aChild;
1316 TREEVIEW_ITEM *previousChild = NULL;
1317 TREEVIEW_ITEM *originalFirst = parentItem->firstChild;
1318 BOOL bItemInserted = FALSE;
1319
1320 aChild = parentItem->firstChild;
1321
1322 bTextUpdated = TRUE;
1323 TREEVIEW_UpdateDispInfo(infoPtr, newItem, TVIF_TEXT);
1324
1325 /* Iterate the parent children to see where we fit in */
1326 while (aChild != NULL)
1327 {
1328 INT comp;
1329
1330 TREEVIEW_UpdateDispInfo(infoPtr, aChild, TVIF_TEXT);
1331 comp = lstrcmpW(newItem->pszText, aChild->pszText);
1332
1333 if (comp < 0) /* we are smaller than the current one */
1334 {
1335 TREEVIEW_InsertBefore(newItem, aChild, parentItem);
1336 if (infoPtr->firstVisible == originalFirst &&
1337 aChild == originalFirst)
1338 TREEVIEW_SetFirstVisible(infoPtr, newItem, TRUE);
1339 bItemInserted = TRUE;
1340 break;
1341 }
1342 else if (comp > 0) /* we are bigger than the current one */
1343 {
1344 previousChild = aChild;
1345
1346 /* This will help us to exit if there is no more sibling */
1347 aChild = (aChild->nextSibling == 0)
1348 ? NULL
1349 : aChild->nextSibling;
1350
1351 /* Look at the next item */
1352 continue;
1353 }
1354 else if (comp == 0)
1355 {
1356 /*
1357 * An item with this name is already existing, therefore,
1358 * we add after the one we found
1359 */
1360 TREEVIEW_InsertAfter(newItem, aChild, parentItem);
1361 bItemInserted = TRUE;
1362 break;
1363 }
1364 }
1365
1366 /*
1367 * we reach the end of the child list and the item has not
1368 * yet been inserted, therefore, insert it after the last child.
1369 */
1370 if ((!bItemInserted) && (aChild == NULL))
1371 TREEVIEW_InsertAfter(newItem, previousChild, parentItem);
1372
1373 break;
1374 }
1375 }
1376
1377
1378 TRACE("new item %p; parent %p, mask 0x%x\n", newItem,
1379 newItem->parent, tvItem->mask);
1380
1381 newItem->iLevel = newItem->parent->iLevel + 1;
1382
1383 if (newItem->parent->cChildren == 0)
1384 newItem->parent->cChildren = 1;
1385
1386 if (infoPtr->dwStyle & TVS_CHECKBOXES)
1387 {
1388 if (STATEIMAGEINDEX(newItem->state) == 0)
1389 newItem->state |= INDEXTOSTATEIMAGEMASK(1);
1390 }
1391
1392 if (infoPtr->firstVisible == NULL)
1393 infoPtr->firstVisible = newItem;
1394
1395 TREEVIEW_VerifyTree(infoPtr);
1396
1397 if (!infoPtr->bRedraw) return (LRESULT)newItem;
1398
1399 if (parentItem == infoPtr->root ||
1400 (ISVISIBLE(parentItem) && parentItem->state & TVIS_EXPANDED))
1401 {
1403 TREEVIEW_ITEM *prev = TREEVIEW_GetPrevListItem(infoPtr, newItem);
1404
1405 TREEVIEW_RecalculateVisibleOrder(infoPtr, prev);
1406 TREEVIEW_ComputeItemInternalMetrics(infoPtr, newItem);
1407
1408 if (!bTextUpdated)
1409 TREEVIEW_UpdateDispInfo(infoPtr, newItem, TVIF_TEXT);
1410
1411 TREEVIEW_ComputeTextWidth(infoPtr, newItem, 0);
1413 /*
1414 * if the item was inserted in a visible part of the tree,
1415 * invalidate it, as well as those after it
1416 */
1417 for (item = newItem;
1418 item != NULL;
1420 TREEVIEW_Invalidate(infoPtr, item);
1421 }
1422 else
1423 {
1424 /* refresh treeview if newItem is the first item inserted under parentItem */
1425 if (ISVISIBLE(parentItem) && newItem->prevSibling == newItem->nextSibling)
1426 {
1427 /* parent got '+' - update it */
1428 TREEVIEW_Invalidate(infoPtr, parentItem);
1429 }
1430 }
1431
1432 return (LRESULT)newItem;
1433}
1434
1435/* Item Deletion ************************************************************/
1436static void
1438
1439static void
1441{
1442 TREEVIEW_ITEM *kill = parentItem->firstChild;
1443
1444 while (kill != NULL)
1445 {
1447
1448 TREEVIEW_RemoveItem(infoPtr, kill);
1449
1450 kill = next;
1451 }
1452
1453 assert(parentItem->cChildren <= 0); /* I_CHILDRENCALLBACK or 0 */
1454 assert(parentItem->firstChild == NULL);
1455 assert(parentItem->lastChild == NULL);
1456}
1457
1458static void
1460{
1461 TREEVIEW_ITEM *parentItem;
1462
1463 assert(item != NULL);
1464 assert(item->parent != NULL); /* i.e. it must not be the root */
1465
1466 parentItem = item->parent;
1467
1468 if (parentItem->firstChild == item)
1469 parentItem->firstChild = item->nextSibling;
1470
1471 if (parentItem->lastChild == item)
1472 parentItem->lastChild = item->prevSibling;
1473
1474 if (parentItem->firstChild == NULL && parentItem->lastChild == NULL
1475 && parentItem->cChildren > 0)
1476 parentItem->cChildren = 0;
1477
1478 if (item->prevSibling)
1479 item->prevSibling->nextSibling = item->nextSibling;
1480
1481 if (item->nextSibling)
1482 item->nextSibling->prevSibling = item->prevSibling;
1483}
1484
1485static void
1487{
1488 TRACE("%p, (%s)\n", item, TREEVIEW_ItemName(item));
1489
1490 if (item->firstChild)
1492
1495
1497
1498 infoPtr->uNumItems--;
1499
1500 if (item->pszText != LPSTR_TEXTCALLBACKW)
1501 heap_free(item->pszText);
1502
1503 TREEVIEW_FreeItem(infoPtr, item);
1504}
1505
1506
1507/* Empty out the tree. */
1508static void
1510{
1511 TREEVIEW_RemoveAllChildren(infoPtr, infoPtr->root);
1512
1513 assert(infoPtr->uNumItems == 0); /* root isn't counted in uNumItems */
1514}
1515
1516static LRESULT
1518{
1519 TREEVIEW_ITEM *newSelection = NULL;
1520 TREEVIEW_ITEM *newFirstVisible = NULL;
1521 TREEVIEW_ITEM *parent, *prev = NULL;
1522 BOOL visible = FALSE;
1523
1524 if (item == TVI_ROOT || !item)
1525 {
1526 TRACE("TVI_ROOT\n");
1527 parent = infoPtr->root;
1528 newSelection = NULL;
1529 visible = TRUE;
1530 TREEVIEW_RemoveTree(infoPtr);
1531 }
1532 else
1533 {
1534 if (!TREEVIEW_ValidItem(infoPtr, item))
1535 return FALSE;
1536
1537 TRACE("%p (%s)\n", item, TREEVIEW_ItemName(item));
1538 parent = item->parent;
1539
1540 if (ISVISIBLE(item))
1541 {
1542 prev = TREEVIEW_GetPrevListItem(infoPtr, item);
1543 visible = TRUE;
1544 }
1545
1546 if (infoPtr->selectedItem != NULL
1547 && (item == infoPtr->selectedItem
1548 || TREEVIEW_IsChildOf(item, infoPtr->selectedItem)))
1549 {
1550 if (item->nextSibling)
1551 newSelection = item->nextSibling;
1552 else if (item->parent != infoPtr->root)
1553 newSelection = item->parent;
1554 else
1555 newSelection = item->prevSibling;
1556 TRACE("newSelection = %p\n", newSelection);
1557 }
1558
1559 if (infoPtr->firstVisible == item)
1560 {
1561 visible = TRUE;
1562 if (item->nextSibling)
1563 newFirstVisible = item->nextSibling;
1564 else if (item->prevSibling)
1565 newFirstVisible = item->prevSibling;
1566 else if (item->parent != infoPtr->root)
1567 newFirstVisible = item->parent;
1569 }
1570 else
1571 newFirstVisible = infoPtr->firstVisible;
1572
1573 TREEVIEW_RemoveItem(infoPtr, item);
1574 }
1575
1576 /* Don't change if somebody else already has (infoPtr->selectedItem is cleared by FreeItem). */
1577 if (!infoPtr->selectedItem && newSelection)
1578 {
1579 if (TREEVIEW_ValidItem(infoPtr, newSelection))
1580 TREEVIEW_DoSelectItem(infoPtr, TVGN_CARET, newSelection, TVC_UNKNOWN);
1581 }
1582
1583 /* Validate insertMark dropItem.
1584 * hotItem ??? - used for comparison only.
1585 */
1586 if (!TREEVIEW_ValidItem(infoPtr, infoPtr->insertMarkItem))
1587 infoPtr->insertMarkItem = 0;
1588
1589 if (!TREEVIEW_ValidItem(infoPtr, infoPtr->dropItem))
1590 infoPtr->dropItem = 0;
1591
1592 if (!TREEVIEW_ValidItem(infoPtr, newFirstVisible))
1593 newFirstVisible = infoPtr->root->firstChild;
1594
1595 TREEVIEW_VerifyTree(infoPtr);
1596
1597 if (visible)
1598 TREEVIEW_SetFirstVisible(infoPtr, newFirstVisible, TRUE);
1599
1600 if (!infoPtr->bRedraw) return TRUE;
1601
1602 if (visible)
1603 {
1604 TREEVIEW_RecalculateVisibleOrder(infoPtr, prev);
1606 TREEVIEW_Invalidate(infoPtr, NULL);
1607 }
1608 else if (ISVISIBLE(parent) && !TREEVIEW_HasChildren(infoPtr, parent))
1609 {
1610 /* parent lost '+/-' - update it */
1611 TREEVIEW_Invalidate(infoPtr, parent);
1612 }
1613
1614 return TRUE;
1615}
1616
1617
1618/* Get/Set Messages *********************************************************/
1619static LRESULT
1621{
1622 infoPtr->bRedraw = wParam != 0;
1623
1624 if (infoPtr->bRedraw)
1625 {
1626 TREEVIEW_UpdateSubTree(infoPtr, infoPtr->root);
1629 TREEVIEW_Invalidate(infoPtr, NULL);
1630 }
1631 return 0;
1632}
1633
1634static LRESULT
1636{
1637 TRACE("\n");
1638 return infoPtr->uIndent;
1639}
1640
1641static LRESULT
1643{
1644 TRACE("\n");
1645
1646 if (newIndent < MINIMUM_INDENT)
1647 newIndent = MINIMUM_INDENT;
1648
1649 if (infoPtr->uIndent != newIndent)
1650 {
1651 infoPtr->uIndent = newIndent;
1652 TREEVIEW_UpdateSubTree(infoPtr, infoPtr->root);
1654 TREEVIEW_Invalidate(infoPtr, NULL);
1655 }
1656
1657 return 0;
1658}
1659
1660
1661static LRESULT
1663{
1664 TRACE("\n");
1665 return (LRESULT)infoPtr->hwndToolTip;
1666}
1667
1668static LRESULT
1670{
1671 HWND prevToolTip;
1672
1673 TRACE("\n");
1674 prevToolTip = infoPtr->hwndToolTip;
1675 infoPtr->hwndToolTip = hwndTT;
1676
1677 return (LRESULT)prevToolTip;
1678}
1679
1680static LRESULT
1682{
1683 BOOL rc = infoPtr->bNtfUnicode;
1684 infoPtr->bNtfUnicode = fUnicode;
1685 return rc;
1686}
1687
1688static LRESULT
1690{
1691 return infoPtr->bNtfUnicode;
1692}
1693
1694static LRESULT
1696{
1697 return infoPtr->uScrollTime;
1698}
1699
1700static LRESULT
1702{
1703 UINT uOldScrollTime = infoPtr->uScrollTime;
1704
1705 infoPtr->uScrollTime = min(uScrollTime, 100);
1706
1707 return uOldScrollTime;
1708}
1709
1710
1711static LRESULT
1713{
1714 TRACE("\n");
1715
1716 switch (wParam)
1717 {
1718 case TVSIL_NORMAL:
1719 return (LRESULT)infoPtr->himlNormal;
1720
1721 case TVSIL_STATE:
1722 return (LRESULT)infoPtr->himlState;
1723
1724 default:
1725 return 0;
1726 }
1727}
1728
1729#define TVHEIGHT_MIN 16
1730#define TVHEIGHT_FONT_ADJUST 3 /* 2 for focus border + 1 for margin some apps assume */
1731
1732/* Compute the natural height for items. */
1733static UINT
1735{
1737 HDC hdc = GetDC(0);
1738 HFONT hOldFont = SelectObject(hdc, infoPtr->hFont);
1739 UINT height;
1740
1741 /* Height is the maximum of:
1742 * 16 (a hack because our fonts are tiny), and
1743 * The text height + border & margin, and
1744 * The size of the normal image list
1745 */
1747 SelectObject(hdc, hOldFont);
1748 ReleaseDC(0, hdc);
1749
1751 if (height < tm.tmHeight + tm.tmExternalLeading + TVHEIGHT_FONT_ADJUST)
1752 height = tm.tmHeight + tm.tmExternalLeading + TVHEIGHT_FONT_ADJUST;
1753 if (height < infoPtr->normalImageHeight)
1754 height = infoPtr->normalImageHeight;
1755
1756 /* Round down, unless we support odd ("non even") heights. */
1757 if (!(infoPtr->dwStyle & TVS_NONEVENHEIGHT))
1758 height &= ~1;
1759
1760 return height;
1761}
1762
1763static LRESULT
1765{
1766 HIMAGELIST himlOld = 0;
1767 int oldWidth = infoPtr->normalImageWidth;
1768 int oldHeight = infoPtr->normalImageHeight;
1769
1770 TRACE("%u,%p\n", type, himlNew);
1771
1772 switch (type)
1773 {
1774 case TVSIL_NORMAL:
1775 himlOld = infoPtr->himlNormal;
1776 infoPtr->himlNormal = himlNew;
1777
1778 if (himlNew)
1779 ImageList_GetIconSize(himlNew, &infoPtr->normalImageWidth,
1780 &infoPtr->normalImageHeight);
1781 else
1782 {
1783 infoPtr->normalImageWidth = 0;
1784 infoPtr->normalImageHeight = 0;
1785 }
1786
1787 break;
1788
1789 case TVSIL_STATE:
1790 himlOld = infoPtr->himlState;
1791 infoPtr->himlState = himlNew;
1792
1793 if (himlNew)
1794 ImageList_GetIconSize(himlNew, &infoPtr->stateImageWidth,
1795 &infoPtr->stateImageHeight);
1796 else
1797 {
1798 infoPtr->stateImageWidth = 0;
1799 infoPtr->stateImageHeight = 0;
1800 }
1801
1802 break;
1803
1804 default:
1805 ERR("unknown imagelist type %u\n", type);
1806 }
1807
1808 if (oldWidth != infoPtr->normalImageWidth ||
1809 oldHeight != infoPtr->normalImageHeight)
1810 {
1811 BOOL bRecalcVisible = FALSE;
1812
1813 if (oldHeight != infoPtr->normalImageHeight &&
1814 !infoPtr->bHeightSet)
1815 {
1816 infoPtr->uItemHeight = TREEVIEW_NaturalHeight(infoPtr);
1817 bRecalcVisible = TRUE;
1818 }
1819
1820 if (infoPtr->normalImageWidth > MINIMUM_INDENT &&
1821 infoPtr->normalImageWidth != infoPtr->uIndent)
1822 {
1823 infoPtr->uIndent = infoPtr->normalImageWidth;
1824 bRecalcVisible = TRUE;
1825 }
1826
1827 if (bRecalcVisible)
1829
1830 TREEVIEW_UpdateSubTree(infoPtr, infoPtr->root);
1832 }
1833
1834 TREEVIEW_Invalidate(infoPtr, NULL);
1835
1836 return (LRESULT)himlOld;
1837}
1838
1839static LRESULT
1841{
1842 INT prevHeight = infoPtr->uItemHeight;
1843
1844 TRACE("new=%d, old=%d\n", newHeight, prevHeight);
1845 if (newHeight == -1)
1846 {
1847 infoPtr->uItemHeight = TREEVIEW_NaturalHeight(infoPtr);
1848 infoPtr->bHeightSet = FALSE;
1849 }
1850 else
1851 {
1852 if (newHeight == 0) newHeight = 1;
1853 infoPtr->uItemHeight = newHeight;
1854 infoPtr->bHeightSet = TRUE;
1855 }
1856
1857 /* Round down, unless we support odd ("non even") heights. */
1858 if (!(infoPtr->dwStyle & TVS_NONEVENHEIGHT) && infoPtr->uItemHeight != 1)
1859 {
1860 infoPtr->uItemHeight &= ~1;
1861 TRACE("after rounding=%d\n", infoPtr->uItemHeight);
1862 }
1863
1864 if (infoPtr->uItemHeight != prevHeight)
1865 {
1868 TREEVIEW_Invalidate(infoPtr, NULL);
1869 }
1870
1871 return prevHeight;
1872}
1873
1874static LRESULT
1876{
1877 TRACE("\n");
1878 return infoPtr->uItemHeight;
1879}
1880
1881
1882static LRESULT
1884{
1885 TRACE("%p\n", infoPtr->hFont);
1886 return (LRESULT)infoPtr->hFont;
1887}
1888
1889
1890static INT CALLBACK
1892{
1893 (void)unused;
1894
1895 ((TREEVIEW_ITEM *)pItem)->textWidth = 0;
1896
1897 return 1;
1898}
1899
1900static LRESULT
1902{
1903 UINT uHeight = infoPtr->uItemHeight;
1904
1905 TRACE("%p %i\n", hFont, bRedraw);
1906
1907 infoPtr->hFont = hFont ? hFont : infoPtr->hDefaultFont;
1908
1909 DeleteObject(infoPtr->hBoldFont);
1910 DeleteObject(infoPtr->hUnderlineFont);
1912 infoPtr->hBoldFont = TREEVIEW_CreateBoldFont(infoPtr->hFont);
1915
1916 if (!infoPtr->bHeightSet)
1917 infoPtr->uItemHeight = TREEVIEW_NaturalHeight(infoPtr);
1918
1919 if (uHeight != infoPtr->uItemHeight)
1921
1923
1924 TREEVIEW_UpdateSubTree(infoPtr, infoPtr->root);
1926
1927 if (bRedraw)
1928 TREEVIEW_Invalidate(infoPtr, NULL);
1929
1930 return 0;
1931}
1932
1933
1934static LRESULT
1936{
1937 TRACE("\n");
1938 return (LRESULT)infoPtr->clrLine;
1939}
1940
1941static LRESULT
1943{
1944 COLORREF prevColor = infoPtr->clrLine;
1945
1946 TRACE("\n");
1947 infoPtr->clrLine = color;
1948 return (LRESULT)prevColor;
1949}
1950
1951
1952static LRESULT
1954{
1955 TRACE("\n");
1956 return (LRESULT)infoPtr->clrText;
1957}
1958
1959static LRESULT
1961{
1962 COLORREF prevColor = infoPtr->clrText;
1963
1964 TRACE("\n");
1965 infoPtr->clrText = color;
1966
1967 if (infoPtr->clrText != prevColor)
1968 TREEVIEW_Invalidate(infoPtr, NULL);
1969
1970 return (LRESULT)prevColor;
1971}
1972
1973
1974static LRESULT
1976{
1977 TRACE("\n");
1978 return (LRESULT)infoPtr->clrBk;
1979}
1980
1981static LRESULT
1983{
1984 COLORREF prevColor = infoPtr->clrBk;
1985
1986 TRACE("\n");
1987 infoPtr->clrBk = newColor;
1988
1989 if (newColor != prevColor)
1990 TREEVIEW_Invalidate(infoPtr, NULL);
1991
1992 return (LRESULT)prevColor;
1993}
1994
1995
1996static LRESULT
1998{
1999 TRACE("\n");
2000 return (LRESULT)infoPtr->clrInsertMark;
2001}
2002
2003static LRESULT
2005{
2006 COLORREF prevColor = infoPtr->clrInsertMark;
2007
2008 TRACE("0x%08x\n", color);
2009 infoPtr->clrInsertMark = color;
2010
2011 return (LRESULT)prevColor;
2012}
2013
2014
2015static LRESULT
2017{
2018 TRACE("%d %p\n", wParam, item);
2019
2020 if (!TREEVIEW_ValidItem(infoPtr, item))
2021 return 0;
2022
2023 infoPtr->insertBeforeorAfter = wParam;
2024 infoPtr->insertMarkItem = item;
2025
2026 TREEVIEW_Invalidate(infoPtr, NULL);
2027
2028 return 1;
2029}
2030
2031
2032/************************************************************************
2033 * Some serious braindamage here. lParam is a pointer to both the
2034 * input HTREEITEM and the output RECT.
2035 */
2036static LRESULT
2037TREEVIEW_GetItemRect(const TREEVIEW_INFO *infoPtr, BOOL fTextRect, LPRECT lpRect)
2038{
2040 const HTREEITEM *pItem = (HTREEITEM *)lpRect;
2041
2042 TRACE("\n");
2043
2044 if (pItem == NULL)
2045 return FALSE;
2046
2047 item = *pItem;
2048 if (!TREEVIEW_ValidItem(infoPtr, item) || !ISVISIBLE(item))
2049 return FALSE;
2050
2051 /*
2052 * If wParam is TRUE return the text size otherwise return
2053 * the whole item size
2054 */
2055 if (fTextRect)
2056 {
2057 /* Windows does not send TVN_GETDISPINFO here. */
2058
2059 lpRect->top = item->rect.top;
2060 lpRect->bottom = item->rect.bottom;
2061
2062 lpRect->left = item->textOffset;
2063 if (!item->textWidth)
2064 TREEVIEW_ComputeTextWidth(infoPtr, item, 0);
2065
2066 lpRect->right = item->textOffset + item->textWidth + 4;
2067 }
2068 else
2069 {
2070 *lpRect = item->rect;
2071 }
2072
2073 TRACE("%s [%s]\n", fTextRect ? "text" : "item", wine_dbgstr_rect(lpRect));
2074
2075 return TRUE;
2076}
2077
2078static inline LRESULT
2080{
2081 /* Surprise! This does not take integral height into account. */
2082 TRACE("client=%d, item=%d\n", infoPtr->clientHeight, infoPtr->uItemHeight);
2083 return infoPtr->clientHeight / infoPtr->uItemHeight;
2084}
2085
2086
2087static LRESULT
2089{
2090 TREEVIEW_ITEM *item = tvItem->hItem;
2091
2092 if (!TREEVIEW_ValidItem(infoPtr, item))
2093 {
2094 BOOL valid_item = FALSE;
2095 if (!item) return FALSE;
2096
2097 __TRY
2098 {
2099 infoPtr = item->infoPtr;
2100 TRACE("got item from different tree %p, called from %p\n", item->infoPtr, infoPtr);
2101 valid_item = TREEVIEW_ValidItem(infoPtr, item);
2102 }
2104 {
2105 }
2106 __ENDTRY
2107 if (!valid_item) return FALSE;
2108 }
2109
2110 TREEVIEW_UpdateDispInfo(infoPtr, item, tvItem->mask);
2111
2112 if (tvItem->mask & TVIF_CHILDREN)
2113 {
2114 if (item->cChildren==I_CHILDRENCALLBACK)
2115 FIXME("I_CHILDRENCALLBACK not supported\n");
2116 tvItem->cChildren = item->cChildren;
2117 }
2118
2119 if (tvItem->mask & TVIF_HANDLE)
2120 tvItem->hItem = item;
2121
2122 if (tvItem->mask & TVIF_IMAGE)
2123 tvItem->iImage = item->iImage;
2124
2125 if (tvItem->mask & TVIF_INTEGRAL)
2126 tvItem->iIntegral = item->iIntegral;
2127
2128 /* undocumented: (mask & TVIF_PARAM) ignored and lParam is always set */
2129 tvItem->lParam = item->lParam;
2130
2131 if (tvItem->mask & TVIF_SELECTEDIMAGE)
2132 tvItem->iSelectedImage = item->iSelectedImage;
2133
2134 if (tvItem->mask & TVIF_EXPANDEDIMAGE)
2135 tvItem->iExpandedImage = item->iExpandedImage;
2136
2137 /* undocumented: stateMask and (state & TVIF_STATE) ignored, so state is always set */
2138 tvItem->state = item->state;
2139
2140 if (tvItem->mask & TVIF_TEXT)
2141 {
2142 if (item->pszText == NULL)
2143 {
2144 if (tvItem->cchTextMax > 0)
2145 tvItem->pszText[0] = '\0';
2146 }
2147 else if (isW)
2148 {
2149 if (item->pszText == LPSTR_TEXTCALLBACKW)
2150 {
2151 tvItem->pszText = LPSTR_TEXTCALLBACKW;
2152 FIXME(" GetItem called with LPSTR_TEXTCALLBACK\n");
2153 }
2154 else
2155 {
2156 lstrcpynW(tvItem->pszText, item->pszText, tvItem->cchTextMax);
2157 }
2158 }
2159 else
2160 {
2161 if (item->pszText == LPSTR_TEXTCALLBACKW)
2162 {
2164 FIXME(" GetItem called with LPSTR_TEXTCALLBACK\n");
2165 }
2166 else
2167 {
2168 WideCharToMultiByte(CP_ACP, 0, item->pszText, -1,
2169 (LPSTR)tvItem->pszText, tvItem->cchTextMax, NULL, NULL);
2170 }
2171 }
2172 }
2173
2174 if (tvItem->mask & TVIF_STATEEX)
2175 {
2176 FIXME("Extended item state not supported, returning 0.\n");
2177 tvItem->uStateEx = 0;
2178 }
2179
2180 TRACE("item <%p>, txt %p, img %d, mask 0x%x\n",
2181 item, tvItem->pszText, tvItem->iImage, tvItem->mask);
2182
2183 return TRUE;
2184}
2185
2186/* Beware MSDN Library Visual Studio 6.0. It says -1 on failure, 0 on success,
2187 * which is wrong. */
2188static LRESULT
2190{
2192 TREEVIEW_ITEM originalItem;
2193
2194 item = tvItem->hItem;
2195
2196 TRACE("item %d, mask 0x%x\n", TREEVIEW_GetItemIndex(infoPtr, item),
2197 tvItem->mask);
2198
2199 if (!TREEVIEW_ValidItem(infoPtr, item))
2200 return FALSE;
2201
2202 /* store the original item values */
2203 originalItem = *item;
2204
2205 if (!TREEVIEW_DoSetItemT(infoPtr, item, tvItem, isW))
2206 return FALSE;
2207
2208 /* If the text or TVIS_BOLD was changed, and it is visible, recalculate. */
2209 if ((tvItem->mask & TVIF_TEXT
2210 || (tvItem->mask & TVIF_STATE && tvItem->stateMask & TVIS_BOLD))
2211 && ISVISIBLE(item))
2212 {
2214 TREEVIEW_ComputeTextWidth(infoPtr, item, 0);
2215 }
2216
2217 if (tvItem->mask != 0 && ISVISIBLE(item))
2218 {
2219 /* The refresh updates everything, but we can't wait until then. */
2221
2222 /* if any of the item's values changed and it's not a callback, redraw the item */
2223 if (item_changed(&originalItem, item, tvItem))
2224 {
2225 if (tvItem->mask & TVIF_INTEGRAL)
2226 {
2229
2230 TREEVIEW_Invalidate(infoPtr, NULL);
2231 }
2232 else
2233 {
2235 TREEVIEW_Invalidate(infoPtr, item);
2236 }
2237 }
2238 }
2239
2240 return TRUE;
2241}
2242
2243static LRESULT
2245{
2246 TRACE("\n");
2247
2248 if (!item || !TREEVIEW_ValidItem(infoPtr, item))
2249 return 0;
2250
2251 return (item->state & mask);
2252}
2253
2254static LRESULT
2256{
2257 TREEVIEW_ITEM *retval;
2258
2259 retval = 0;
2260
2261 /* handle all the global data here */
2262 switch (which)
2263 {
2264 case TVGN_CHILD: /* Special case: child of 0 is root */
2265 if (item)
2266 break;
2267 /* fall through */
2268 case TVGN_ROOT:
2269 retval = infoPtr->root->firstChild;
2270 break;
2271
2272 case TVGN_CARET:
2273 retval = infoPtr->selectedItem;
2274 break;
2275
2276 case TVGN_FIRSTVISIBLE:
2277 retval = infoPtr->firstVisible;
2278 break;
2279
2280 case TVGN_DROPHILITE:
2281 retval = infoPtr->dropItem;
2282 break;
2283
2284 case TVGN_LASTVISIBLE:
2285 retval = TREEVIEW_GetLastListItem(infoPtr, infoPtr->root);
2286 break;
2287 }
2288
2289 if (retval)
2290 {
2291 TRACE("flags:0x%x, returns %p\n", which, retval);
2292 return (LRESULT)retval;
2293 }
2294
2295 if (item == TVI_ROOT) item = infoPtr->root;
2296
2297 if (!TREEVIEW_ValidItem(infoPtr, item))
2298 return FALSE;
2299
2300 switch (which)
2301 {
2302 case TVGN_NEXT:
2303 retval = item->nextSibling;
2304 break;
2305 case TVGN_PREVIOUS:
2306 retval = item->prevSibling;
2307 break;
2308 case TVGN_PARENT:
2309 retval = (item->parent != infoPtr->root) ? item->parent : NULL;
2310 break;
2311 case TVGN_CHILD:
2312 retval = item->firstChild;
2313 break;
2314 case TVGN_NEXTVISIBLE:
2315 retval = TREEVIEW_GetNextListItem(infoPtr, item);
2316 break;
2318 retval = TREEVIEW_GetPrevListItem(infoPtr, item);
2319 break;
2320 default:
2321 TRACE("Unknown msg 0x%x, item %p\n", which, item);
2322 break;
2323 }
2324
2325 TRACE("flags: 0x%x, item %p;returns %p\n", which, item, retval);
2326 return (LRESULT)retval;
2327}
2328
2329
2330static LRESULT
2332{
2333 TRACE(" %d\n", infoPtr->uNumItems);
2334 return (LRESULT)infoPtr->uNumItems;
2335}
2336
2337#ifdef __REACTOS__
2338static LRESULT
2340#endif
2341
2342#ifdef __REACTOS__
2343static VOID
2345#else
2346static VOID
2348#endif
2349{
2350 if (infoPtr->dwStyle & TVS_CHECKBOXES)
2351 {
2352 static const unsigned int state_table[] = { 0, 2, 1 };
2353
2354 unsigned int state;
2355
2356 state = STATEIMAGEINDEX(item->state);
2357 TRACE("state: 0x%x\n", state);
2358 item->state &= ~TVIS_STATEIMAGEMASK;
2359
2360 if (state < 3)
2362
2363 item->state |= INDEXTOSTATEIMAGEMASK(state);
2364
2365 TRACE("state: 0x%x\n", state);
2366#ifdef __REACTOS__
2368#endif
2369 TREEVIEW_Invalidate(infoPtr, item);
2370 }
2371}
2372
2373
2374/* Painting *************************************************************/
2375
2376/* Draw the lines and expand button for an item. Also draws one section
2377 * of the line from item's parent to item's parent's next sibling. */
2378static void
2380{
2381 LONG centerx, centery;
2382 BOOL lar = ((infoPtr->dwStyle
2384 > TVS_LINESATROOT);
2385 HBRUSH hbr, hbrOld;
2386 COLORREF clrBk = GETBKCOLOR(infoPtr->clrBk);
2387
2388 if (!lar && item->iLevel == 0)
2389 return;
2390
2391 hbr = CreateSolidBrush(clrBk);
2392 hbrOld = SelectObject(hdc, hbr);
2393
2394 centerx = (item->linesOffset + item->stateOffset) / 2;
2395 centery = (item->rect.top + item->rect.bottom) / 2;
2396
2397 if (infoPtr->dwStyle & TVS_HASLINES)
2398 {
2399 HPEN hOldPen, hNewPen;
2401 LOGBRUSH lb;
2402
2403 /* Get a dotted grey pen */
2404 lb.lbStyle = BS_SOLID;
2405 lb.lbColor = GETLINECOLOR(infoPtr->clrLine);
2406 hNewPen = ExtCreatePen(PS_COSMETIC|PS_ALTERNATE, 1, &lb, 0, NULL);
2407 hOldPen = SelectObject(hdc, hNewPen);
2408
2409 /* Make sure the center is on a dot (using +2 instead
2410 * of +1 gives us pixel-by-pixel compat with native) */
2411 centery = (centery + 2) & ~1;
2412
2413 MoveToEx(hdc, item->stateOffset, centery, NULL);
2414 LineTo(hdc, centerx - 1, centery);
2415
2416 if (item->prevSibling || item->parent != infoPtr->root)
2417 {
2418 MoveToEx(hdc, centerx, item->rect.top, NULL);
2419 LineTo(hdc, centerx, centery);
2420 }
2421
2422 if (item->nextSibling)
2423 {
2424 MoveToEx(hdc, centerx, centery, NULL);
2425 LineTo(hdc, centerx, item->rect.bottom + 1);
2426 }
2427
2428 /* Draw the line from our parent to its next sibling. */
2429 parent = item->parent;
2430 while (parent != infoPtr->root)
2431 {
2432 int pcenterx = (parent->linesOffset + parent->stateOffset) / 2;
2433
2434 if (parent->nextSibling
2435 /* skip top-levels unless TVS_LINESATROOT */
2436 && parent->stateOffset > parent->linesOffset)
2437 {
2438 MoveToEx(hdc, pcenterx, item->rect.top, NULL);
2439 LineTo(hdc, pcenterx, item->rect.bottom + 1);
2440 }
2441
2442 parent = parent->parent;
2443 }
2444
2445 SelectObject(hdc, hOldPen);
2446 DeleteObject(hNewPen);
2447 }
2448
2449 /*
2450 * Display the (+/-) signs
2451 */
2452
2453 if (infoPtr->dwStyle & TVS_HASBUTTONS)
2454 {
2455 if (item->cChildren)
2456 {
2457 HTHEME theme = GetWindowTheme(infoPtr->hwnd);
2458 if (theme)
2459 {
2460 RECT glyphRect = item->rect;
2461 glyphRect.left = item->linesOffset;
2462 glyphRect.right = item->stateOffset;
2465 &glyphRect, NULL);
2466 }
2467 else
2468 {
2469 LONG height = item->rect.bottom - item->rect.top;
2470 LONG width = item->stateOffset - item->linesOffset;
2471 LONG rectsize = min(height, width) / 4;
2472 /* plussize = ceil(rectsize * 3/4) */
2473 LONG plussize = (rectsize + 1) * 3 / 4;
2474
2475 HPEN new_pen = CreatePen(PS_SOLID, 0, GETLINECOLOR(infoPtr->clrLine));
2476 HPEN old_pen = SelectObject(hdc, new_pen);
2477
2478 Rectangle(hdc, centerx - rectsize - 1, centery - rectsize - 1,
2479 centerx + rectsize + 2, centery + rectsize + 2);
2480
2481 SelectObject(hdc, old_pen);
2482 DeleteObject(new_pen);
2483
2484 /* draw +/- signs with current text color */
2485 new_pen = CreatePen(PS_SOLID, 0, GETTXTCOLOR(infoPtr->clrText));
2486 old_pen = SelectObject(hdc, new_pen);
2487
2488 if (height < 18 || width < 18)
2489 {
2490 MoveToEx(hdc, centerx - plussize + 1, centery, NULL);
2491 LineTo(hdc, centerx + plussize, centery);
2492
2493 if (!(item->state & TVIS_EXPANDED) ||
2494 (item->state & TVIS_EXPANDPARTIAL))
2495 {
2496 MoveToEx(hdc, centerx, centery - plussize + 1, NULL);
2497 LineTo(hdc, centerx, centery + plussize);
2498 }
2499 }
2500 else
2501 {
2502 Rectangle(hdc, centerx - plussize + 1, centery - 1,
2503 centerx + plussize, centery + 2);
2504
2505 if (!(item->state & TVIS_EXPANDED) ||
2506 (item->state & TVIS_EXPANDPARTIAL))
2507 {
2508 Rectangle(hdc, centerx - 1, centery - plussize + 1,
2509 centerx + 2, centery + plussize);
2510 SetPixel(hdc, centerx - 1, centery, clrBk);
2511 SetPixel(hdc, centerx + 1, centery, clrBk);
2512 }
2513 }
2514
2515 SelectObject(hdc, old_pen);
2516 DeleteObject(new_pen);
2517 }
2518 }
2519 }
2520 SelectObject(hdc, hbrOld);
2521 DeleteObject(hbr);
2522}
2523
2524static void
2526{
2527 INT cditem;
2528 HFONT hOldFont;
2529 COLORREF oldTextColor, oldTextBkColor;
2530 int centery;
2531 BOOL inFocus = (GetFocus() == infoPtr->hwnd);
2532 NMTVCUSTOMDRAW nmcdhdr;
2533
2535
2536 /* - If item is drop target or it is selected and window is in focus -
2537 * use blue background (COLOR_HIGHLIGHT).
2538 * - If item is selected, window is not in focus, but it has style
2539 * TVS_SHOWSELALWAYS - use grey background (COLOR_BTNFACE)
2540 * - Otherwise - use background color
2541 */
2542 if ((item->state & TVIS_DROPHILITED) || ((item == infoPtr->focusedItem) && !(item->state & TVIS_SELECTED)) ||
2543 ((item->state & TVIS_SELECTED) && (!infoPtr->focusedItem || item == infoPtr->focusedItem) &&
2544 (inFocus || (infoPtr->dwStyle & TVS_SHOWSELALWAYS))))
2545 {
2546 if ((item->state & TVIS_DROPHILITED) || inFocus)
2547 {
2550 }
2551 else
2552 {
2554 nmcdhdr.clrText = GETTXTCOLOR(infoPtr->clrText);
2555 }
2556 }
2557 else
2558 {
2559 nmcdhdr.clrTextBk = GETBKCOLOR(infoPtr->clrBk);
2560 if ((infoPtr->dwStyle & TVS_TRACKSELECT) && (item == infoPtr->hotItem))
2562 else
2563 nmcdhdr.clrText = GETTXTCOLOR(infoPtr->clrText);
2564 }
2565
2566 hOldFont = SelectObject(hdc, TREEVIEW_FontForItem(infoPtr, item));
2567 oldTextColor = SetTextColor(hdc, nmcdhdr.clrText);
2568 oldTextBkColor = SetBkColor(hdc, nmcdhdr.clrTextBk);
2569
2570 /* The custom draw handler can query the text rectangle,
2571 * so get ready. */
2572 /* should already be known, set to 0 when changed */
2573 if (!item->textWidth)
2575
2576 cditem = 0;
2577
2578 if (infoPtr->cdmode & CDRF_NOTIFYITEMDRAW)
2579 {
2581 (infoPtr, hdc, item, CDDS_ITEMPREPAINT, &nmcdhdr);
2582 TRACE("prepaint:cditem-app returns 0x%x\n", cditem);
2583
2584 if (cditem & CDRF_SKIPDEFAULT)
2585 {
2586 SelectObject(hdc, hOldFont);
2587 return;
2588 }
2589 }
2590
2591 if (cditem & CDRF_NEWFONT)
2593
2594 if (TREEVIEW_IsFullRowSelect(infoPtr))
2595 {
2596 HBRUSH brush = CreateSolidBrush(nmcdhdr.clrTextBk);
2597 FillRect(hdc, &item->rect, brush);
2598 DeleteObject(brush);
2599 }
2600
2601 TREEVIEW_DrawItemLines(infoPtr, hdc, item);
2602
2603 /* reset colors. Custom draw handler can change them */
2604 SetTextColor(hdc, nmcdhdr.clrText);
2605 SetBkColor(hdc, nmcdhdr.clrTextBk);
2606
2607 centery = (item->rect.top + item->rect.bottom) / 2;
2608
2609 /*
2610 * Display the images associated with this item
2611 */
2612 {
2613 INT imageIndex;
2614
2615 /* State images are displayed to the left of the Normal image
2616 * image number is in state; zero should be `display no image'.
2617 */
2618 imageIndex = STATEIMAGEINDEX(item->state);
2619
2620 if (infoPtr->himlState && imageIndex)
2621 {
2622 ImageList_Draw(infoPtr->himlState, imageIndex, hdc,
2623 item->stateOffset,
2624 centery - infoPtr->stateImageHeight / 2,
2625 ILD_NORMAL);
2626 }
2627
2628 /* Now, draw the normal image; can be either selected,
2629 * non-selected or expanded image.
2630 */
2631
2632 if ((item->state & TVIS_SELECTED) && (item->iSelectedImage >= 0))
2633 {
2634 /* The item is currently selected */
2635 imageIndex = item->iSelectedImage;
2636 }
2637 else if ((item->state & TVIS_EXPANDED) && (item->iExpandedImage != (WORD)I_IMAGENONE))
2638 {
2639 /* The item is currently not selected but expanded */
2640 imageIndex = item->iExpandedImage;
2641 }
2642 else
2643 {
2644 /* The item is not selected and not expanded */
2645 imageIndex = item->iImage;
2646 }
2647
2648 if (infoPtr->himlNormal)
2649 {
2651
2652 style |= item->state & TVIS_OVERLAYMASK;
2653
2654 ImageList_DrawEx(infoPtr->himlNormal, imageIndex, hdc,
2655 item->imageOffset, centery - infoPtr->normalImageHeight / 2,
2656 0, 0, infoPtr->clrBk, item->state & TVIS_CUT ? GETBKCOLOR(infoPtr->clrBk) : CLR_DEFAULT,
2657 style);
2658 }
2659 }
2660
2661
2662 /*
2663 * Display the text associated with this item
2664 */
2665
2666 /* Don't paint item's text if it's being edited */
2667 if (!infoPtr->hwndEdit || (infoPtr->selectedItem != item))
2668 {
2669 if (item->pszText)
2670 {
2671 RECT rcText;
2672 UINT align;
2673 SIZE sz;
2674
2675 rcText.top = item->rect.top;
2676 rcText.bottom = item->rect.bottom;
2677 rcText.left = item->textOffset;
2678 rcText.right = rcText.left + item->textWidth + 4;
2679
2680 TRACE("drawing text %s at (%s)\n",
2681 debugstr_w(item->pszText), wine_dbgstr_rect(&rcText));
2682
2683 /* Draw it */
2684 GetTextExtentPoint32W(hdc, item->pszText, strlenW(item->pszText), &sz);
2685
2687 ExtTextOutW(hdc, rcText.left + 2, (rcText.top + rcText.bottom - sz.cy) / 2,
2689 &rcText,
2690 item->pszText,
2691 lstrlenW(item->pszText),
2692 NULL);
2694
2695 /* Draw focus box around the selected item */
2696 if ((item == infoPtr->selectedItem) && inFocus)
2697 {
2698 DrawFocusRect(hdc,&rcText);
2699 }
2700 }
2701 }
2702
2703 /* Draw insertion mark if necessary */
2704
2705 if (infoPtr->insertMarkItem)
2706 TRACE("item:%d,mark:%p\n",
2707 TREEVIEW_GetItemIndex(infoPtr, item),
2708 infoPtr->insertMarkItem);
2709
2710 if (item == infoPtr->insertMarkItem)
2711 {
2712 HPEN hNewPen, hOldPen;
2713 int offset;
2714 int left, right;
2715
2716 hNewPen = CreatePen(PS_SOLID, 2, GETINSCOLOR(infoPtr->clrInsertMark));
2717 hOldPen = SelectObject(hdc, hNewPen);
2718
2719 if (infoPtr->insertBeforeorAfter)
2720 offset = item->rect.bottom - 1;
2721 else
2722 offset = item->rect.top + 1;
2723
2724 left = item->textOffset - 2;
2725 right = item->textOffset + item->textWidth + 2;
2726
2727 MoveToEx(hdc, left, offset - 3, NULL);
2728 LineTo(hdc, left, offset + 4);
2729
2731 LineTo(hdc, right + 1, offset);
2732
2733 MoveToEx(hdc, right, offset + 3, NULL);
2734 LineTo(hdc, right, offset - 4);
2735
2736 SelectObject(hdc, hOldPen);
2737 DeleteObject(hNewPen);
2738 }
2739
2740 /* Restore the hdc state */
2741 SetTextColor(hdc, oldTextColor);
2742 SetBkColor(hdc, oldTextBkColor);
2743 SelectObject(hdc, hOldFont);
2744
2745 if (cditem & CDRF_NOTIFYPOSTPAINT)
2746 {
2748 (infoPtr, hdc, item, CDDS_ITEMPOSTPAINT, &nmcdhdr);
2749 TRACE("postpaint:cditem-app returns 0x%x\n", cditem);
2750 }
2751}
2752
2753/* Computes treeHeight and treeWidth and updates the scroll bars.
2754 */
2755static void
2757{
2759 HWND hwnd = infoPtr->hwnd;
2760 BOOL vert = FALSE;
2761 BOOL horz = FALSE;
2762 SCROLLINFO si;
2763 LONG scrollX = infoPtr->scrollX;
2764
2765 infoPtr->treeWidth = 0;
2766 infoPtr->treeHeight = 0;
2767
2768 /* We iterate through all visible items in order to get the tree height
2769 * and width */
2770 item = infoPtr->root->firstChild;
2771
2772 while (item != NULL)
2773 {
2774 if (ISVISIBLE(item))
2775 {
2776 /* actually we draw text at textOffset + 2 */
2777 if (2+item->textOffset+item->textWidth > infoPtr->treeWidth)
2778 infoPtr->treeWidth = item->textOffset+item->textWidth+2;
2779
2780 /* This is scroll-adjusted, but we fix this below. */
2781 infoPtr->treeHeight = item->rect.bottom;
2782 }
2783
2785 }
2786
2787 /* Fix the scroll adjusted treeHeight and treeWidth. */
2788 if (infoPtr->root->firstChild)
2789 infoPtr->treeHeight -= infoPtr->root->firstChild->rect.top;
2790
2791 infoPtr->treeWidth += infoPtr->scrollX;
2792
2793 if (infoPtr->dwStyle & TVS_NOSCROLL) return;
2794
2795 /* Adding one scroll bar may take up enough space that it forces us
2796 * to add the other as well. */
2797 if (infoPtr->treeHeight > infoPtr->clientHeight)
2798 {
2799 vert = TRUE;
2800
2801 if (infoPtr->treeWidth
2803 horz = TRUE;
2804 }
2805 else if (infoPtr->treeWidth > infoPtr->clientWidth || infoPtr->scrollX > 0)
2806 horz = TRUE;
2807
2808 if (!vert && horz && infoPtr->treeHeight
2810 vert = TRUE;
2811
2812 if (horz && (infoPtr->dwStyle & TVS_NOHSCROLL)) horz = FALSE;
2813
2814 si.cbSize = sizeof(SCROLLINFO);
2816 si.nMin = 0;
2817
2818 if (vert)
2819 {
2820 si.nPage = TREEVIEW_GetVisibleCount(infoPtr);
2821 if ( si.nPage && NULL != infoPtr->firstVisible)
2822 {
2823 si.nPos = infoPtr->firstVisible->visibleOrder;
2824 si.nMax = infoPtr->maxVisibleOrder - 1;
2825
2827
2828 if (!(infoPtr->uInternalStatus & TV_VSCROLL))
2830 infoPtr->uInternalStatus |= TV_VSCROLL;
2831 }
2832 else
2833 {
2834 if (infoPtr->uInternalStatus & TV_VSCROLL)
2836 infoPtr->uInternalStatus &= ~TV_VSCROLL;
2837 }
2838 }
2839 else
2840 {
2841 if (infoPtr->uInternalStatus & TV_VSCROLL)
2843 infoPtr->uInternalStatus &= ~TV_VSCROLL;
2844 }
2845
2846 if (horz)
2847 {
2848 si.nPage = infoPtr->clientWidth;
2849 si.nPos = infoPtr->scrollX;
2850 si.nMax = infoPtr->treeWidth - 1;
2851
2852 if (si.nPos > si.nMax - max( si.nPage-1, 0 ))
2853 {
2854 si.nPos = si.nMax - max( si.nPage-1, 0 );
2855 scrollX = si.nPos;
2856 }
2857
2858 if (!(infoPtr->uInternalStatus & TV_HSCROLL))
2860 infoPtr->uInternalStatus |= TV_HSCROLL;
2861
2863 TREEVIEW_HScroll(infoPtr,
2864 MAKEWPARAM(SB_THUMBPOSITION, scrollX));
2865 }
2866 else
2867 {
2868 if (infoPtr->uInternalStatus & TV_HSCROLL)
2870 infoPtr->uInternalStatus &= ~TV_HSCROLL;
2871
2872 scrollX = 0;
2873 if (infoPtr->scrollX != 0)
2874 {
2875 TREEVIEW_HScroll(infoPtr,
2876 MAKEWPARAM(SB_THUMBPOSITION, scrollX));
2877 }
2878 }
2879
2880 if (!horz)
2881 infoPtr->uInternalStatus &= ~TV_HSCROLL;
2882}
2883
2884static void
2885TREEVIEW_FillBkgnd(const TREEVIEW_INFO *infoPtr, HDC hdc, const RECT *rc)
2886{
2887 HBRUSH hBrush;
2888 COLORREF clrBk = GETBKCOLOR(infoPtr->clrBk);
2889
2890 hBrush = CreateSolidBrush(clrBk);
2891 FillRect(hdc, rc, hBrush);
2892 DeleteObject(hBrush);
2893}
2894
2895/* CtrlSpy doesn't mention this, but CorelDRAW's object manager needs it. */
2896static LRESULT
2898{
2899 RECT rect;
2900
2901 TRACE("%p\n", infoPtr);
2902
2903 GetClientRect(infoPtr->hwnd, &rect);
2904 TREEVIEW_FillBkgnd(infoPtr, hdc, &rect);
2905
2906 return 1;
2907}
2908
2909static void
2911{
2912 HWND hwnd = infoPtr->hwnd;
2913 RECT rect = *rc;
2915
2916 if (infoPtr->clientHeight == 0 || infoPtr->clientWidth == 0)
2917 {
2918 TRACE("empty window\n");
2919 return;
2920 }
2921
2923 hdc, rect);
2924
2925 if (infoPtr->cdmode == CDRF_SKIPDEFAULT)
2926 {
2927 ReleaseDC(hwnd, hdc);
2928 return;
2929 }
2930
2931 for (item = infoPtr->root->firstChild;
2932 item != NULL;
2934 {
2935 if (ISVISIBLE(item))
2936 {
2937 /* Avoid unneeded calculations */
2938 if (item->rect.top > rect.bottom)
2939 break;
2940 if (item->rect.bottom < rect.top)
2941 continue;
2942
2943 TREEVIEW_DrawItem(infoPtr, hdc, item);
2944 }
2945 }
2946
2947 //
2948 // FIXME: This is correct, but is causes and infinite loop of WM_PAINT
2949 // messages, resulting in continuous painting of the scroll bar in reactos.
2950 // Comment out until the real bug is found. CORE-4912
2951 //
2952#ifndef __REACTOS__
2954#endif
2955
2956 if (infoPtr->cdmode & CDRF_NOTIFYPOSTPAINT)
2957 infoPtr->cdmode =
2959}
2960
2961static inline void
2963{
2964 if (item) InvalidateRect(infoPtr->hwnd, &item->rect, TRUE);
2965}
2966
2967static void
2969{
2970 if (item)
2971 InvalidateRect(infoPtr->hwnd, &item->rect, TRUE);
2972 else
2973 InvalidateRect(infoPtr->hwnd, NULL, TRUE);
2974}
2975
2976static void
2978{
2979 RECT rc;
2980 HBITMAP hbm, hbmOld;
2981 HDC hdc, hdcScreen;
2982 int nIndex;
2983
2984 infoPtr->himlState = ImageList_Create(16, 16, ILC_COLOR | ILC_MASK, 3, 0);
2985
2986 hdcScreen = GetDC(0);
2987
2988 hdc = CreateCompatibleDC(hdcScreen);
2989 hbm = CreateCompatibleBitmap(hdcScreen, 48, 16);
2990 hbmOld = SelectObject(hdc, hbm);
2991
2992 SetRect(&rc, 0, 0, 48, 16);
2993 FillRect(hdc, &rc, (HBRUSH)(COLOR_WINDOW+1));
2994
2995 SetRect(&rc, 18, 2, 30, 14);
2998
2999 SetRect(&rc, 34, 2, 46, 14);
3002
3003 SelectObject(hdc, hbmOld);
3004 nIndex = ImageList_AddMasked(infoPtr->himlState, hbm,
3006 TRACE("checkbox index %d\n", nIndex);
3007
3009 DeleteDC(hdc);
3010 ReleaseDC(0, hdcScreen);
3011
3012 infoPtr->stateImageWidth = 16;
3013 infoPtr->stateImageHeight = 16;
3014}
3015
3016static void
3018{
3019 TREEVIEW_ITEM *child = item->firstChild;
3020
3021 item->state &= ~TVIS_STATEIMAGEMASK;
3022 item->state |= INDEXTOSTATEIMAGEMASK(1);
3023
3024 while (child)
3025 {
3026 TREEVIEW_ITEM *next = child->nextSibling;
3028 child = next;
3029 }
3030}
3031
3032static LRESULT
3034{
3035 HDC hdc;
3036 PAINTSTRUCT ps;
3037 RECT rc;
3038
3039 TRACE("(%p %p)\n", infoPtr, hdc_ref);
3040
3041 if ((infoPtr->dwStyle & TVS_CHECKBOXES) && !infoPtr->himlState)
3042 {
3043 TREEVIEW_InitCheckboxes(infoPtr);
3044 TREEVIEW_ResetImageStateIndex(infoPtr, infoPtr->root);
3045
3047 TREEVIEW_UpdateSubTree(infoPtr, infoPtr->root);
3049 TREEVIEW_Invalidate(infoPtr, NULL);
3050 }
3051
3052 if (hdc_ref)
3053 {
3054 hdc = hdc_ref;
3055 GetClientRect(infoPtr->hwnd, &rc);
3056 TREEVIEW_FillBkgnd(infoPtr, hdc, &rc);
3057 }
3058 else
3059 {
3060 hdc = BeginPaint(infoPtr->hwnd, &ps);
3061 rc = ps.rcPaint;
3062 if(ps.fErase)
3063 TREEVIEW_FillBkgnd(infoPtr, hdc, &rc);
3064 }
3065
3066 if(infoPtr->bRedraw) /* WM_SETREDRAW sets bRedraw */
3067 TREEVIEW_Refresh(infoPtr, hdc, &rc);
3068
3069 if (!hdc_ref)
3070 EndPaint(infoPtr->hwnd, &ps);
3071
3072 return 0;
3073}
3074
3075static LRESULT
3077{
3078 FIXME("Partial Stub: (hdc=%p options=0x%08x)\n", hdc, options);
3079
3080 if ((options & PRF_CHECKVISIBLE) && !IsWindowVisible(infoPtr->hwnd))
3081 return 0;
3082
3083 if (options & PRF_ERASEBKGND)
3084 TREEVIEW_EraseBackground(infoPtr, hdc);
3085
3086 if (options & PRF_CLIENT)
3087 {
3088 RECT rc;
3089 GetClientRect(infoPtr->hwnd, &rc);
3090 TREEVIEW_Refresh(infoPtr, hdc, &rc);
3091 }
3092
3093 return 0;
3094}
3095
3096/* Sorting **************************************************************/
3097
3098/***************************************************************************
3099 * Forward the DPA local callback to the treeview owner callback
3100 */
3101static INT WINAPI
3103 const TVSORTCB *pCallBackSort)
3104{
3105 /* Forward the call to the client-defined callback */
3106 return pCallBackSort->lpfnCompare(first->lParam,
3107 second->lParam,
3108 pCallBackSort->lParam);
3109}
3110
3111/***************************************************************************
3112 * Treeview native sort routine: sort on item text.
3113 */
3114static INT WINAPI
3116 const TREEVIEW_INFO *infoPtr)
3117{
3119 TREEVIEW_UpdateDispInfo(infoPtr, second, TVIF_TEXT);
3120
3121 if(first->pszText && second->pszText)
3122 return lstrcmpiW(first->pszText, second->pszText);
3123 else if(first->pszText)
3124 return -1;
3125 else if(second->pszText)
3126 return 1;
3127 else
3128 return 0;
3129}
3130
3131/* Returns the number of physical children belonging to item. */
3132static INT
3134{
3135 INT cChildren = 0;
3136 HTREEITEM hti;
3137
3138 for (hti = item->firstChild; hti != NULL; hti = hti->nextSibling)
3139 cChildren++;
3140
3141 return cChildren;
3142}
3143
3144/* Returns a DPA containing a pointer to each physical child of item in
3145 * sibling order. If item has no children, an empty DPA is returned. */
3146static HDPA
3148{
3150
3151 HDPA list = DPA_Create(8);
3152 if (list == 0) return NULL;
3153
3154 for (child = item->firstChild; child != NULL; child = child->nextSibling)
3155 {
3156 if (DPA_InsertPtr(list, INT_MAX, child) == -1)
3157 {
3159 return NULL;
3160 }
3161 }
3162
3163 return list;
3164}
3165
3166/***************************************************************************
3167 * Setup the treeview structure with regards of the sort method
3168 * and sort the children of the TV item specified in lParam
3169 * fRecurse: currently unused. Should be zero.
3170 * parent: if pSort!=NULL, should equal pSort->hParent.
3171 * otherwise, item which child items are to be sorted.
3172 * pSort: sort method info. if NULL, sort on item text.
3173 * if non-NULL, sort on item's lParam content, and let the
3174 * application decide what that means. See also TVM_SORTCHILDRENCB.
3175 */
3176
3177static LRESULT
3179 LPTVSORTCB pSort)
3180{
3181 INT cChildren;
3182 PFNDPACOMPARE pfnCompare;
3183 LPARAM lpCompare;
3184
3185 /* undocumented feature: TVI_ROOT or NULL means `sort the whole tree' */
3186 if (parent == TVI_ROOT || parent == NULL)
3187 parent = infoPtr->root;
3188
3189 /* Check for a valid handle to the parent item */
3190 if (!TREEVIEW_ValidItem(infoPtr, parent))
3191 {
3192 ERR("invalid item hParent=%p\n", parent);
3193 return FALSE;
3194 }
3195
3196 if (pSort)
3197 {
3199 lpCompare = (LPARAM)pSort;
3200 }
3201 else
3202 {
3203 pfnCompare = (PFNDPACOMPARE)TREEVIEW_SortOnName;
3204 lpCompare = (LPARAM)infoPtr;
3205 }
3206
3207 cChildren = TREEVIEW_CountChildren(parent);
3208
3209 /* Make sure there is something to sort */
3210 if (cChildren > 1)
3211 {
3212 /* TREEVIEW_ITEM rechaining */
3213 INT count = 0;
3214 HTREEITEM item = 0;
3215 HTREEITEM nextItem = 0;
3216 HTREEITEM prevItem = 0;
3217
3219
3220 if (sortList == NULL)
3221 return FALSE;
3222
3223 /* let DPA sort the list */
3224 DPA_Sort(sortList, pfnCompare, lpCompare);
3225
3226 /* The order of DPA entries has been changed, so fixup the
3227 * nextSibling and prevSibling pointers. */
3228
3229 item = DPA_GetPtr(sortList, count++);
3230 while ((nextItem = DPA_GetPtr(sortList, count++)) != NULL)
3231 {
3232 /* link the two current item together */
3233 item->nextSibling = nextItem;
3234 nextItem->prevSibling = item;
3235
3236 if (prevItem == NULL)
3237 {
3238 /* this is the first item, update the parent */
3239 parent->firstChild = item;
3240 item->prevSibling = NULL;
3241 }
3242 else
3243 {
3244 /* fix the back chaining */
3245 item->prevSibling = prevItem;
3246 }
3247
3248 /* get ready for the next one */
3249 prevItem = item;
3250 item = nextItem;
3251 }
3252
3253 /* the last item is pointed to by item and never has a sibling */
3254 item->nextSibling = NULL;
3255 parent->lastChild = item;
3256
3257 DPA_Destroy(sortList);
3258
3259 TREEVIEW_VerifyTree(infoPtr);
3260
3261 if (parent->state & TVIS_EXPANDED)
3262 {
3263 int visOrder = infoPtr->firstVisible->visibleOrder;
3264
3265 if (parent == infoPtr->root)
3267 else
3269
3270 if (TREEVIEW_IsChildOf(parent, infoPtr->firstVisible))
3271 {
3273
3274 for (item = infoPtr->root->firstChild; item != NULL;
3276 {
3277 if (item->visibleOrder == visOrder)
3278 break;
3279 }
3280
3281 if (!item) item = parent->firstChild;
3283 }
3284
3285 TREEVIEW_Invalidate(infoPtr, NULL);
3286 }
3287
3288 return TRUE;
3289 }
3290 return FALSE;
3291}
3292
3293
3294/***************************************************************************
3295 * Setup the treeview structure with regards of the sort method
3296 * and sort the children of the TV item specified in lParam
3297 */
3298static LRESULT
3300{
3301 return TREEVIEW_Sort(infoPtr, pSort->hParent, pSort);
3302}
3303
3304
3305/***************************************************************************
3306 * Sort the children of the TV item specified in lParam.
3307 */
3308static LRESULT
3310{
3311 return TREEVIEW_Sort(infoPtr, (HTREEITEM)lParam, NULL);
3312}
3313
3314
3315/* Expansion/Collapse ***************************************************/
3316
3317static BOOL
3319 UINT action)
3320{
3324 0, item);
3325}
3326
3327static VOID
3329 UINT action)
3330{
3334 0, item);
3335}
3336
3337
3338/* This corresponds to TVM_EXPAND with TVE_COLLAPSE.
3339 * bRemoveChildren corresponds to TVE_COLLAPSERESET. */
3340static BOOL
3342 BOOL bRemoveChildren, BOOL bUser)
3343{
3344 UINT action = TVE_COLLAPSE | (bRemoveChildren ? TVE_COLLAPSERESET : 0);
3345 BOOL bSetSelection, bSetFirstVisible;
3346 RECT scrollRect;
3347 LONG scrollDist = 0;
3348 TREEVIEW_ITEM *nextItem = NULL, *tmpItem;
3349 BOOL wasExpanded;
3350
3351 TRACE("TVE_COLLAPSE %p %s\n", item, TREEVIEW_ItemName(item));
3352
3353 if (!TREEVIEW_HasChildren(infoPtr, item))
3354 return FALSE;
3355
3356 if (bUser)
3358
3359 if (item->firstChild == NULL)
3360 return FALSE;
3361
3362 wasExpanded = (item->state & TVIS_EXPANDED) != 0;
3363 item->state &= ~TVIS_EXPANDED;
3364
3365 if (wasExpanded && bUser)
3367
3368 bSetSelection = (infoPtr->selectedItem != NULL
3369 && TREEVIEW_IsChildOf(item, infoPtr->selectedItem));
3370
3371 bSetFirstVisible = (infoPtr->firstVisible != NULL
3372 && TREEVIEW_IsChildOf(item, infoPtr->firstVisible));
3373
3374 tmpItem = item;
3375 while (tmpItem)
3376 {
3377 if (tmpItem->nextSibling)
3378 {
3379 nextItem = tmpItem->nextSibling;
3380 break;
3381 }
3382 tmpItem = tmpItem->parent;
3383 }
3384
3385 if (nextItem)
3386 scrollDist = nextItem->rect.top;
3387
3388 if (bRemoveChildren)
3389 {
3390 INT old_cChildren = item->cChildren;
3391 TRACE("TVE_COLLAPSERESET\n");
3392 item->state &= ~TVIS_EXPANDEDONCE;
3394 item->cChildren = old_cChildren;
3395 }
3396 if (!wasExpanded)
3397 return FALSE;
3398
3399 if (item->firstChild)
3400 {
3401 TREEVIEW_ITEM *i, *sibling;
3402
3403 sibling = TREEVIEW_GetNextListItem(infoPtr, item);
3404
3405 for (i = item->firstChild; i != sibling;
3406 i = TREEVIEW_GetNextListItem(infoPtr, i))
3407 {
3408 i->visibleOrder = -1;
3409 }
3410 }
3411
3413
3414 if (nextItem)
3415 scrollDist = -(scrollDist - nextItem->rect.top);
3416
3417 if (bSetSelection)
3418 {
3419 /* Don't call DoSelectItem, it sends notifications. */
3420 if (TREEVIEW_ValidItem(infoPtr, infoPtr->selectedItem))
3421 infoPtr->selectedItem->state &= ~TVIS_SELECTED;
3422 item->state |= TVIS_SELECTED;
3423 infoPtr->selectedItem = item;
3424 }
3425
3427
3428 scrollRect.left = 0;
3429 scrollRect.right = infoPtr->clientWidth;
3430 scrollRect.bottom = infoPtr->clientHeight;
3431
3432 if (nextItem)
3433 {
3434 scrollRect.top = nextItem->rect.top;
3435
3436 ScrollWindowEx (infoPtr->hwnd, 0, scrollDist, &scrollRect, &scrollRect,
3438 TREEVIEW_Invalidate(infoPtr, item);
3439 } else {
3440 scrollRect.top = item->rect.top;
3441 InvalidateRect(infoPtr->hwnd, &scrollRect, TRUE);
3442 }
3443
3445 bSetFirstVisible ? item : infoPtr->firstVisible,
3446 TRUE);
3447
3448 return wasExpanded;
3449}
3450
3451static BOOL
3453 BOOL partial, BOOL user)
3454{
3455 LONG scrollDist;
3456 LONG orgNextTop = 0;
3457 RECT scrollRect;
3458 TREEVIEW_ITEM *nextItem, *tmpItem;
3459 BOOL sendsNotifications;
3460
3461 TRACE("(%p, %p, partial=%d, %d)\n", infoPtr, item, partial, user);
3462
3463 if (!TREEVIEW_HasChildren(infoPtr, item))
3464 return FALSE;
3465
3466 tmpItem = item; nextItem = NULL;
3467 while (tmpItem)
3468 {
3469 if (tmpItem->nextSibling)
3470 {
3471 nextItem = tmpItem->nextSibling;
3472 break;
3473 }
3474 tmpItem = tmpItem->parent;
3475 }
3476
3477 if (nextItem)
3478 orgNextTop = nextItem->rect.top;
3479
3480 TRACE("TVE_EXPAND %p %s\n", item, TREEVIEW_ItemName(item));
3481
3482 sendsNotifications = user || ((item->cChildren != 0) &&
3483 !(item->state & TVIS_EXPANDEDONCE));
3484 if (sendsNotifications)
3485 {
3486 if (!TREEVIEW_SendExpanding(infoPtr, item, TVE_EXPAND))
3487 {
3488 TRACE(" TVN_ITEMEXPANDING returned TRUE, exiting...\n");
3489 return FALSE;
3490 }
3491 }
3492 if (!item->firstChild)
3493 return FALSE;
3494
3495 item->state |= TVIS_EXPANDED;
3496
3497 if (partial)
3498 FIXME("TVE_EXPANDPARTIAL not implemented\n");
3499
3500 if (ISVISIBLE(item))
3501 {
3503 TREEVIEW_UpdateSubTree(infoPtr, item);
3505
3506 scrollRect.left = 0;
3507 scrollRect.bottom = infoPtr->treeHeight;
3508 scrollRect.right = infoPtr->clientWidth;
3509 if (nextItem)
3510 {
3511 scrollDist = nextItem->rect.top - orgNextTop;
3512 scrollRect.top = orgNextTop;
3513
3514 ScrollWindowEx (infoPtr->hwnd, 0, scrollDist, &scrollRect, NULL,
3516 TREEVIEW_Invalidate (infoPtr, item);
3517 } else {
3518 scrollRect.top = item->rect.top;
3519 InvalidateRect(infoPtr->hwnd, &scrollRect, FALSE);
3520 }
3521
3522 /* Scroll up so that as many children as possible are visible.
3523 * This fails when expanding causes an HScroll bar to appear, but we
3524 * don't know that yet, so the last item is obscured. */
3525 if (item->firstChild != NULL)
3526 {
3527 int nChildren = item->lastChild->visibleOrder
3528 - item->firstChild->visibleOrder + 1;
3529
3530 int visible_pos = item->visibleOrder
3531 - infoPtr->firstVisible->visibleOrder;
3532
3533 int rows_below = TREEVIEW_GetVisibleCount(infoPtr) - visible_pos - 1;
3534
3535 if (visible_pos > 0 && nChildren > rows_below)
3536 {
3537 int scroll = nChildren - rows_below;
3538
3539 if (scroll > visible_pos)
3540 scroll = visible_pos;
3541
3542 if (scroll > 0)
3543 {
3544 TREEVIEW_ITEM *newFirstVisible
3545 = TREEVIEW_GetListItem(infoPtr, infoPtr->firstVisible,
3546 scroll);
3547
3548
3549 TREEVIEW_SetFirstVisible(infoPtr, newFirstVisible, TRUE);
3550 }
3551 }
3552 }
3553 }
3554
3555 if (sendsNotifications) {
3557 item->state |= TVIS_EXPANDEDONCE;
3558 }
3559
3560 return TRUE;
3561}
3562
3563/* Handler for TVS_SINGLEEXPAND behaviour. Used on response
3564 to mouse messages and TVM_SELECTITEM.
3565
3566 selection - previously selected item, used to collapse a part of a tree
3567 item - new selected item
3568*/
3571{
3572 TREEVIEW_ITEM *prev, *curr;
3573
3574 if ((infoPtr->dwStyle & TVS_SINGLEEXPAND) == 0 || infoPtr->hwndEdit || !item) return;
3575
3577
3578 /*
3579 * Close the previous item and its ancestors as long as they are not
3580 * ancestors of the current item
3581 */
3582 for (prev = selection; prev && TREEVIEW_ValidItem(infoPtr, prev); prev = prev->parent)
3583 {
3584 for (curr = item; curr && TREEVIEW_ValidItem(infoPtr, curr); curr = curr->parent)
3585 {
3586 if (curr == prev)
3587 goto finish;
3588 }
3589 TREEVIEW_Collapse(infoPtr, prev, FALSE, TRUE);
3590 }
3591
3592finish:
3593 /*
3594 * Expand the current item
3595 */
3596 TREEVIEW_Expand(infoPtr, item, FALSE, TRUE);
3597}
3598
3599static BOOL
3601{
3602 TRACE("item=%p, user=%d\n", item, user);
3603
3604 if (item->state & TVIS_EXPANDED)
3605 return TREEVIEW_Collapse(infoPtr, item, FALSE, user);
3606 else
3607 return TREEVIEW_Expand(infoPtr, item, FALSE, user);
3608}
3609
3610static VOID
3612{
3613 TREEVIEW_Expand(infoPtr, item, FALSE, TRUE);
3614
3615 for (item = item->firstChild; item != NULL; item = item->nextSibling)
3616 {
3617 if (TREEVIEW_HasChildren(infoPtr, item))
3618 TREEVIEW_ExpandAll(infoPtr, item);
3619 }
3620}
3621
3622/* Note:If the specified item is the child of a collapsed parent item,
3623 the parent's list of child items is (recursively) expanded to reveal the
3624 specified item. This is mentioned for TREEVIEW_SelectItem; don't
3625 know if it also applies here.
3626*/
3627
3628static LRESULT
3630{
3631 if (!TREEVIEW_ValidItem(infoPtr, item))
3632 return 0;
3633
3634 TRACE("For (%s) item:%d, flags 0x%x, state:%d\n",
3636 flag, item->state);
3637
3638 switch (flag & TVE_TOGGLE)
3639 {
3640 case TVE_COLLAPSE:
3641 return TREEVIEW_Collapse(infoPtr, item, flag & TVE_COLLAPSERESET,
3642 FALSE);
3643
3644 case TVE_EXPAND:
3645 return TREEVIEW_Expand(infoPtr, item, flag & TVE_EXPANDPARTIAL,
3646 FALSE);
3647
3648 case TVE_TOGGLE:
3649 return TREEVIEW_Toggle(infoPtr, item, FALSE);
3650
3651 default:
3652 return 0;
3653 }
3654}
3655
3656/* Hit-Testing **********************************************************/
3657
3658static TREEVIEW_ITEM *
3660{
3662 LONG row;
3663
3664 if (!infoPtr->firstVisible)
3665 return NULL;
3666
3667 row = pt.y / infoPtr->uItemHeight + infoPtr->firstVisible->visibleOrder;
3668
3669 for (item = infoPtr->firstVisible; item != NULL;
3671 {
3672 if (row >= item->visibleOrder
3673 && row < item->visibleOrder + item->iIntegral)
3674 break;
3675 }
3676
3677 return item;
3678}
3679
3680static TREEVIEW_ITEM *
3682{
3684 RECT rect;
3685 UINT status;
3686 LONG x, y;
3687
3688 lpht->hItem = 0;
3689 GetClientRect(infoPtr->hwnd, &rect);
3690 status = 0;
3691 x = lpht->pt.x;
3692 y = lpht->pt.y;
3693
3694 if (x < rect.left)
3695 {
3697 }
3698 else if (x > rect.right)
3699 {
3701 }
3702
3703 if (y < rect.top)
3704 {
3705 status |= TVHT_ABOVE;
3706 }
3707 else if (y > rect.bottom)
3708 {
3709 status |= TVHT_BELOW;
3710 }
3711
3712 if (status)
3713 {
3714 lpht->flags = status;
3715 return NULL;
3716 }
3717
3718 item = TREEVIEW_HitTestPoint(infoPtr, lpht->pt);
3719 if (!item)
3720 {
3721 lpht->flags = TVHT_NOWHERE;
3722 return NULL;
3723 }
3724
3725 if (!item->textWidth)
3726 TREEVIEW_ComputeTextWidth(infoPtr, item, 0);
3727
3728 if (x >= item->textOffset + item->textWidth)
3729 {
3730 lpht->flags = TVHT_ONITEMRIGHT;
3731 }
3732 else if (x >= item->textOffset)
3733 {
3734 lpht->flags = TVHT_ONITEMLABEL;
3735 }
3736 else if (x >= item->imageOffset)
3737 {
3738 lpht->flags = TVHT_ONITEMICON;
3739 }
3740 else if (x >= item->stateOffset)
3741 {
3743 }
3744 else if (x >= item->linesOffset && infoPtr->dwStyle & TVS_HASBUTTONS)
3745 {
3746 lpht->flags = TVHT_ONITEMBUTTON;
3747 }
3748 else
3749 {
3750 lpht->flags = TVHT_ONITEMINDENT;
3751 }
3752
3753 lpht->hItem = item;
3754 TRACE("(%d,%d):result 0x%x\n", lpht->pt.x, lpht->pt.y, lpht->flags);
3755
3756 return item;
3757}
3758
3759/* Item Label Editing ***************************************************/
3760
3761static LRESULT
3763{
3764 return (LRESULT)infoPtr->hwndEdit;
3765}
3766
3767static LRESULT CALLBACK
3769{
3771 BOOL bCancel = FALSE;
3772 LRESULT rc;
3773
3774 switch (uMsg)
3775 {
3776 case WM_PAINT:
3777 TRACE("WM_PAINT start\n");
3778 rc = CallWindowProcW(infoPtr->wpEditOrig, hwnd, uMsg, wParam,
3779 lParam);
3780 TRACE("WM_PAINT done\n");
3781 return rc;
3782
3783 case WM_KILLFOCUS:
3784 if (infoPtr->bIgnoreEditKillFocus)
3785 return TRUE;
3786 break;
3787
3788 case WM_DESTROY:
3789 {
3790 WNDPROC editProc = infoPtr->wpEditOrig;
3791 infoPtr->wpEditOrig = 0;
3793 return CallWindowProcW(editProc, hwnd, uMsg, wParam, lParam);
3794 }
3795
3796 case WM_GETDLGCODE:
3798
3799 case WM_KEYDOWN:
3800 if (wParam == VK_ESCAPE)
3801 {
3802 bCancel = TRUE;
3803 break;
3804 }
3805 else if (wParam == VK_RETURN)
3806 {
3807 break;
3808 }
3809
3810 /* fall through */
3811 default:
3812 return CallWindowProcW(infoPtr->wpEditOrig, hwnd, uMsg, wParam, lParam);
3813 }
3814
3815 /* Processing TVN_ENDLABELEDIT message could kill the focus */
3816 /* eg. Using a messagebox */
3817
3818 infoPtr->bIgnoreEditKillFocus = TRUE;
3819 TREEVIEW_EndEditLabelNow(infoPtr, bCancel || !infoPtr->bLabelChanged);
3820 infoPtr->bIgnoreEditKillFocus = FALSE;
3821
3822 return 0;
3823}
3824
3825
3826/* should handle edit control messages here */
3827
3828static LRESULT
3830{
3831 TRACE("code=0x%x, id=0x%x, handle=0x%lx\n", HIWORD(wParam), LOWORD(wParam), lParam);
3832
3833 switch (HIWORD(wParam))
3834 {
3835 case EN_UPDATE:
3836 {
3837 /*
3838 * Adjust the edit window size
3839 */
3840 WCHAR buffer[1024];
3841 TREEVIEW_ITEM *editItem = infoPtr->editItem;
3842 HDC hdc = GetDC(infoPtr->hwndEdit);
3843 SIZE sz;
3844 HFONT hFont, hOldFont = 0;
3845
3846 TRACE("edit=%p\n", infoPtr->hwndEdit);
3847
3848 if (!IsWindow(infoPtr->hwndEdit) || !hdc) return FALSE;
3849
3850 infoPtr->bLabelChanged = TRUE;
3851
3853
3854 /* Select font to get the right dimension of the string */
3855 hFont = (HFONT)SendMessageW(infoPtr->hwndEdit, WM_GETFONT, 0, 0);
3856
3857 if (hFont != 0)
3858 {
3859 hOldFont = SelectObject(hdc, hFont);
3860 }
3861
3863 {
3864 TEXTMETRICW textMetric;
3865
3866 /* Add Extra spacing for the next character */
3867 GetTextMetricsW(hdc, &textMetric);
3868 sz.cx += (textMetric.tmMaxCharWidth * 2);
3869
3870 sz.cx = max(sz.cx, textMetric.tmMaxCharWidth * 3);
3871 sz.cx = min(sz.cx,
3872 infoPtr->clientWidth - editItem->textOffset + 2);
3873
3874 SetWindowPos(infoPtr->hwndEdit,
3875 HWND_TOP,
3876 0,
3877 0,
3878 sz.cx,
3879 editItem->rect.bottom - editItem->rect.top + 3,
3881 }
3882
3883 if (hFont != 0)
3884 {
3885 SelectObject(hdc, hOldFont);
3886 }
3887
3888 ReleaseDC(infoPtr->hwnd, hdc);
3889 break;
3890 }
3891 case EN_KILLFOCUS:
3892 /* apparently we should respect passed handle value */
3893 if (infoPtr->hwndEdit != (HWND)lParam) return FALSE;
3894
3896 break;
3897
3898 default:
3899 return SendMessageW(infoPtr->hwndNotify, WM_COMMAND, wParam, lParam);
3900 }
3901
3902 return 0;
3903}
3904
3905static HWND
3907{
3908 HWND hwnd = infoPtr->hwnd;
3909 HWND hwndEdit;
3910 SIZE sz;
3912 HDC hdc;
3913 HFONT hOldFont=0;
3914 TEXTMETRICW textMetric;
3915
3916 TRACE("%p %p\n", hwnd, hItem);
3917 if (!(infoPtr->dwStyle & TVS_EDITLABELS))
3918 return NULL;
3919
3920 if (!TREEVIEW_ValidItem(infoPtr, hItem))
3921 return NULL;
3922
3923 if (infoPtr->hwndEdit)
3924 return infoPtr->hwndEdit;
3925
3926 infoPtr->bLabelChanged = FALSE;
3927
3928 /* make edit item visible */
3930
3932
3933 hdc = GetDC(hwnd);
3934 /* Select the font to get appropriate metric dimensions */
3935 if (infoPtr->hFont != 0)
3936 {
3937 hOldFont = SelectObject(hdc, infoPtr->hFont);
3938 }
3939
3940 /* Get string length in pixels */
3941 if (hItem->pszText)
3943 &sz);
3944 else
3945 GetTextExtentPoint32A(hdc, "", 0, &sz);
3946
3947 /* Add Extra spacing for the next character */
3948 GetTextMetricsW(hdc, &textMetric);
3949 sz.cx += (textMetric.tmMaxCharWidth * 2);
3950
3951 sz.cx = max(sz.cx, textMetric.tmMaxCharWidth * 3);
3952 sz.cx = min(sz.cx, infoPtr->clientWidth - hItem->textOffset + 2);
3953
3954 if (infoPtr->hFont != 0)
3955 {
3956 SelectObject(hdc, hOldFont);
3957 }
3958
3959 ReleaseDC(hwnd, hdc);
3960
3961 infoPtr->editItem = hItem;
3962
3964 WC_EDITW,
3965 0,
3968 ES_LEFT, hItem->textOffset - 2,
3969 hItem->rect.top - 1, sz.cx + 3,
3970 hItem->rect.bottom -
3971 hItem->rect.top + 3, hwnd, 0, hinst, 0);
3972/* FIXME: (HMENU)IDTVEDIT,pcs->hInstance,0); */
3973
3974 infoPtr->hwndEdit = hwndEdit;
3975
3976 /* Get a 2D border. */
3981
3984
3986 (DWORD_PTR)
3988 if (hItem->pszText)
3990
3992 {
3994 infoPtr->hwndEdit = 0;
3995 infoPtr->editItem = NULL;
3996 return NULL;
3997 }
3998
4002
4003 return hwndEdit;
4004}
4005
4006
4007static LRESULT
4009{
4010 TREEVIEW_ITEM *editedItem = infoPtr->editItem;
4011 NMTVDISPINFOW tvdi;
4012 BOOL bCommit;
4013 WCHAR tmpText[1024] = { '\0' };
4014 WCHAR *newText = tmpText;
4015 int iLength = 0;
4016
4017 if (!IsWindow(infoPtr->hwndEdit)) return FALSE;
4018
4019 tvdi.item.mask = 0;
4020 tvdi.item.hItem = editedItem;
4021 tvdi.item.state = editedItem->state;
4022 tvdi.item.lParam = editedItem->lParam;
4023
4024 if (!bCancel)
4025 {
4026 if (!infoPtr->bNtfUnicode)
4027 iLength = GetWindowTextA(infoPtr->hwndEdit, (LPSTR)tmpText, 1023);
4028 else
4029 iLength = GetWindowTextW(infoPtr->hwndEdit, tmpText, 1023);
4030
4031 if (iLength >= 1023)
4032 {
4033 ERR("Insufficient space to retrieve new item label\n");
4034 }
4035
4036 tvdi.item.mask = TVIF_TEXT;
4037 tvdi.item.pszText = tmpText;
4038 tvdi.item.cchTextMax = iLength + 1;
4039 }
4040 else
4041 {
4042 tvdi.item.pszText = NULL;
4043 tvdi.item.cchTextMax = 0;
4044 }
4045
4046 bCommit = TREEVIEW_SendRealNotify(infoPtr, TVN_ENDLABELEDITW, &tvdi.hdr);
4047
4048 if (!bCancel && bCommit) /* Apply the changes */
4049 {
4050 if (!infoPtr->bNtfUnicode)
4051 {
4052 DWORD len = MultiByteToWideChar( CP_ACP, 0, (LPSTR)tmpText, -1, NULL, 0 );
4053 newText = heap_alloc(len * sizeof(WCHAR));
4054 MultiByteToWideChar( CP_ACP, 0, (LPSTR)tmpText, -1, newText, len );
4055 iLength = len - 1;
4056 }
4057
4058 if (strcmpW(newText, editedItem->pszText) != 0)
4059 {
4060 WCHAR *ptr = heap_realloc(editedItem->pszText, sizeof(WCHAR)*(iLength + 1));
4061 if (ptr == NULL)
4062 {
4063 ERR("OutOfMemory, cannot allocate space for label\n");
4064 if (newText != tmpText) heap_free(newText);
4065 DestroyWindow(infoPtr->hwndEdit);
4066 infoPtr->hwndEdit = 0;
4067 infoPtr->editItem = NULL;
4068 return FALSE;
4069 }
4070 else
4071 {
4072 editedItem->pszText = ptr;
4073 editedItem->cchTextMax = iLength + 1;
4074 strcpyW(editedItem->pszText, newText);
4075 TREEVIEW_ComputeTextWidth(infoPtr, editedItem, 0);
4076 }
4077 }
4078 if (newText != tmpText) heap_free(newText);
4079 }
4080
4081 ShowWindow(infoPtr->hwndEdit, SW_HIDE);
4082 DestroyWindow(infoPtr->hwndEdit);
4083 infoPtr->hwndEdit = 0;
4084 infoPtr->editItem = NULL;
4085 return TRUE;
4086}
4087
4088static LRESULT
4090{
4091 if (wParam != TV_EDIT_TIMER)
4092 {
4093 ERR("got unknown timer\n");
4094 return 1;
4095 }
4096
4097 KillTimer(infoPtr->hwnd, TV_EDIT_TIMER);
4098 infoPtr->Timer &= ~TV_EDIT_TIMER_SET;
4099
4100 TREEVIEW_EditLabel(infoPtr, infoPtr->selectedItem);
4101
4102 return 0;
4103}
4104
4105
4106/* Mouse Tracking/Drag **************************************************/
4107
4108/***************************************************************************
4109 * This is quite unusual piece of code, but that's how it's implemented in
4110 * Windows.
4111 */
4112static LRESULT
4114{
4115 INT cxDrag = GetSystemMetrics(SM_CXDRAG);
4116 INT cyDrag = GetSystemMetrics(SM_CYDRAG);
4117 RECT r;
4118 MSG msg;
4119
4120 r.top = pt.y - cyDrag;
4121 r.left = pt.x - cxDrag;
4122 r.bottom = pt.y + cyDrag;
4123 r.right = pt.x + cxDrag;
4124
4125 SetCapture(infoPtr->hwnd);
4126
4127 while (1)
4128 {
4129 if (PeekMessageW(&msg, 0, 0, 0, PM_REMOVE | PM_NOYIELD))
4130 {
4131 if (msg.message == WM_MOUSEMOVE)
4132 {
4133 pt.x = (short)LOWORD(msg.lParam);
4134 pt.y = (short)HIWORD(msg.lParam);
4135 if (PtInRect(&r, pt))
4136 continue;
4137 else
4138 {
4140 return 1;
4141 }
4142 }
4143 else if (msg.message >= WM_LBUTTONDOWN &&
4144 msg.message <= WM_RBUTTONDBLCLK)
4145 {
4146 break;
4147 }
4148
4150 }
4151
4152 if (GetCapture() != infoPtr->hwnd)
4153 return 0;
4154 }
4155
4157 return 0;
4158}
4159
4160
4161static LRESULT
4163{
4165 TVHITTESTINFO hit;
4166
4167 TRACE("\n");
4168 SetFocus(infoPtr->hwnd);
4169
4170 if (infoPtr->Timer & TV_EDIT_TIMER_SET)
4171 {
4172 /* If there is pending 'edit label' event - kill it now */
4173 KillTimer(infoPtr->hwnd, TV_EDIT_TIMER);
4174 }
4175
4176 hit.pt.x = (short)LOWORD(lParam);
4177 hit.pt.y = (short)HIWORD(lParam);
4178
4179 item = TREEVIEW_HitTest(infoPtr, &hit);
4180 if (!item)
4181 return 0;
4182 TRACE("item %d\n", TREEVIEW_GetItemIndex(infoPtr, item));
4183
4184 if (TREEVIEW_SendSimpleNotify(infoPtr, NM_DBLCLK) == FALSE)
4185 { /* FIXME! */
4186 switch (hit.flags)
4187 {
4188 case TVHT_ONITEMRIGHT:
4189 /* FIXME: we should not have sent NM_DBLCLK in this case. */
4190 break;
4191
4192 case TVHT_ONITEMINDENT:
4193 if (!(infoPtr->dwStyle & TVS_HASLINES))
4194 {
4195 break;
4196 }
4197 else
4198 {
4199 int level = hit.pt.x / infoPtr->uIndent;
4200 if (!(infoPtr->dwStyle & TVS_LINESATROOT)) level++;
4201
4202 while (item->iLevel > level)
4203 {
4204 item = item->parent;
4205 }
4206
4207 /* fall through */
4208 }
4209
4210 case TVHT_ONITEMLABEL:
4211 case TVHT_ONITEMICON:
4212 case TVHT_ONITEMBUTTON:
4213 TREEVIEW_Toggle(infoPtr, item, TRUE);
4214 break;
4215
4217 if (infoPtr->dwStyle & TVS_CHECKBOXES)
4219 else
4220 TREEVIEW_Toggle(infoPtr, item, TRUE);
4221 break;
4222 }
4223 }
4224 return TRUE;
4225}
4226
4227
4228static LRESULT
4230{
4231 BOOL do_track, do_select, bDoLabelEdit;
4232 HWND hwnd = infoPtr->hwnd;
4234
4235 /* If Edit control is active - kill it and return.
4236 * The best way to do it is to set focus to itself.
4237 * Edit control subclassed procedure will automatically call
4238 * EndEditLabelNow.
4239 */
4240 if (infoPtr->hwndEdit)
4241 {
4242 SetFocus(hwnd);
4243 return 0;
4244 }
4245
4246 ht.pt.x = (short)LOWORD(lParam);
4247 ht.pt.y = (short)HIWORD(lParam);
4248
4249 TREEVIEW_HitTest(infoPtr, &ht);
4250 TRACE("item %d\n", TREEVIEW_GetItemIndex(infoPtr, ht.hItem));
4251
4252 /* update focusedItem and redraw both items */
4253 if (ht.hItem)
4254 {
4255 BOOL do_focus;
4256
4257 if (TREEVIEW_IsFullRowSelect(infoPtr))
4258 do_focus = ht.flags & (TVHT_ONITEMINDENT | TVHT_ONITEM | TVHT_ONITEMRIGHT);
4259 else
4260 do_focus = ht.flags & TVHT_ONITEM;
4261
4262 if (do_focus)
4263 {
4264 infoPtr->focusedItem = ht.hItem;
4265 TREEVIEW_InvalidateItem(infoPtr, infoPtr->focusedItem);
4266 TREEVIEW_InvalidateItem(infoPtr, infoPtr->selectedItem);
4267 }
4268 }
4269
4270 if (!(infoPtr->dwStyle & TVS_DISABLEDRAGDROP))
4271 {
4272 if (TREEVIEW_IsFullRowSelect(infoPtr))
4273 do_track = ht.flags & (TVHT_ONITEMINDENT | TVHT_ONITEM | TVHT_ONITEMRIGHT);
4274 else
4275 do_track = ht.flags & TVHT_ONITEM;
4276 }
4277 else
4278 do_track = FALSE;
4279
4280 /*
4281 * If the style allows editing and the node is already selected
4282 * and the click occurred on the item label...
4283 */
4284 bDoLabelEdit = (infoPtr->dwStyle & TVS_EDITLABELS) &&
4285 (ht.flags & TVHT_ONITEMLABEL) && (infoPtr->selectedItem == ht.hItem);
4286
4287 /* Send NM_CLICK right away */
4288 if (!do_track && TREEVIEW_SendSimpleNotify(infoPtr, NM_CLICK))
4289 goto setfocus;
4290
4291 if (ht.flags & TVHT_ONITEMBUTTON)
4292 {
4293 TREEVIEW_Toggle(infoPtr, ht.hItem, TRUE);
4294 goto setfocus;
4295 }
4296 else if (do_track)
4297 { /* if TREEVIEW_TrackMouse == 1 dragging occurred and the cursor left the dragged item's rectangle */
4298 if (TREEVIEW_TrackMouse(infoPtr, ht.pt))
4299 {
4301 infoPtr->dropItem = ht.hItem;
4302
4303 /* clean up focusedItem as we dragged and won't select this item */
4304 if(infoPtr->focusedItem)
4305 {
4306 /* refresh the item that was focused */
4307 TREEVIEW_InvalidateItem(infoPtr, infoPtr->focusedItem);
4308 infoPtr->focusedItem = NULL;
4309
4310 /* refresh the selected item to return the filled background */
4311 TREEVIEW_InvalidateItem(infoPtr, infoPtr->selectedItem);
4312 }
4313
4314 return 0;
4315 }
4316 }
4317
4318 if (do_track && TREEVIEW_SendSimpleNotify(infoPtr, NM_CLICK))
4319 goto setfocus;
4320
4321 if (TREEVIEW_IsFullRowSelect(infoPtr))
4323 else
4325
4326 if (bDoLabelEdit)
4327 {
4328 if (infoPtr->Timer & TV_EDIT_TIMER_SET)
4330
4332 infoPtr->Timer |= TV_EDIT_TIMER_SET;
4333 }
4334 else if (do_select)
4335 {
4337
4338 /* Select the current item */
4340 TREEVIEW_SingleExpand(infoPtr, selection, ht.hItem);
4341 }
4342 else if (ht.flags & TVHT_ONITEMSTATEICON)
4343 {
4344 /* TVS_CHECKBOXES requires us to toggle the current state */
4345 if (infoPtr->dwStyle & TVS_CHECKBOXES)
4346 TREEVIEW_ToggleItemState(infoPtr, ht.hItem);
4347 }
4348
4349 setfocus:
4350 SetFocus(hwnd);
4351 return 0;
4352}
4353
4354
4355static LRESULT
4357{
4359
4360 if (infoPtr->hwndEdit)
4361 {
4362 SetFocus(infoPtr->hwnd);
4363 return 0;
4364 }
4365
4366 ht.pt.x = (short)LOWORD(lParam);
4367 ht.pt.y = (short)HIWORD(lParam);
4368
4369 if (TREEVIEW_HitTest(infoPtr, &ht))
4370 {
4371 infoPtr->focusedItem = ht.hItem;
4372 TREEVIEW_InvalidateItem(infoPtr, infoPtr->focusedItem);
4373 TREEVIEW_InvalidateItem(infoPtr, infoPtr->selectedItem);
4374 }
4375
4376 if (TREEVIEW_TrackMouse(infoPtr, ht.pt))
4377 {
4378 if (ht.hItem)
4379 {
4381 infoPtr->dropItem = ht.hItem;
4382 }
4383 }
4384 else
4385 {
4386 SetFocus(infoPtr->hwnd);
4388 {
4389 /* Send a WM_CONTEXTMENU message in response to the RBUTTONUP */
4391 (WPARAM)infoPtr->hwnd, (LPARAM)GetMessagePos());
4392 }
4393 }
4394
4395 if (ht.hItem)
4396 {
4397 TREEVIEW_InvalidateItem(infoPtr, infoPtr->focusedItem);
4398 infoPtr->focusedItem = infoPtr->selectedItem;
4399 TREEVIEW_InvalidateItem(infoPtr, infoPtr->focusedItem);
4400 }
4401
4402 return 0;
4403}
4404
4405static LRESULT
4407{
4408 TREEVIEW_ITEM *dragItem = (HTREEITEM)lParam;
4409 INT cx, cy;
4410 HDC hdc, htopdc;
4411 HWND hwtop;
4412 HBITMAP hbmp, hOldbmp;
4413 SIZE size;
4414 RECT rc;
4415 HFONT hOldFont;
4416
4417 TRACE("\n");
4418
4419 if (!(infoPtr->himlNormal))
4420 return 0;
4421
4422 if (!dragItem || !TREEVIEW_ValidItem(infoPtr, dragItem))
4423 return 0;
4424
4425 TREEVIEW_UpdateDispInfo(infoPtr, dragItem, TVIF_TEXT);
4426
4427 hwtop = GetDesktopWindow();
4428 htopdc = GetDC(hwtop);
4429 hdc = CreateCompatibleDC(htopdc);
4430
4431 hOldFont = SelectObject(hdc, infoPtr->hFont);
4432
4433 if (dragItem->pszText)
4434 GetTextExtentPoint32W(hdc, dragItem->pszText, strlenW(dragItem->pszText),
4435 &size);
4436 else
4437 GetTextExtentPoint32A(hdc, "", 0, &size);
4438
4439 TRACE("%d %d %s\n", size.cx, size.cy, debugstr_w(dragItem->pszText));
4440 hbmp = CreateCompatibleBitmap(htopdc, size.cx, size.cy);
4441 hOldbmp = SelectObject(hdc, hbmp);
4442
4443 ImageList_GetIconSize(infoPtr->himlNormal, &cx, &cy);
4444 size.cx += cx;
4445 if (cy > size.cy)
4446 size.cy = cy;
4447
4448 infoPtr->dragList = ImageList_Create(size.cx, size.cy, ILC_COLOR, 10, 10);
4449 ImageList_Draw(infoPtr->himlNormal, dragItem->iImage, hdc, 0, 0,
4450 ILD_NORMAL);
4451
4452/*
4453 ImageList_GetImageInfo (infoPtr->himlNormal, dragItem->hItem, &iminfo);
4454 ImageList_AddMasked (infoPtr->dragList, iminfo.hbmImage, CLR_DEFAULT);
4455*/
4456
4457/* draw item text */
4458
4459 SetRect(&rc, cx, 0, size.cx, size.cy);
4460
4461 if (dragItem->pszText)
4462 DrawTextW(hdc, dragItem->pszText, strlenW(dragItem->pszText), &rc,
4463 DT_LEFT);
4464
4465 SelectObject(hdc, hOldFont);
4466 SelectObject(hdc, hOldbmp);
4467
4468 ImageList_Add(infoPtr->dragList, hbmp, 0);
4469
4470 DeleteDC(hdc);
4472 ReleaseDC(hwtop, htopdc);
4473
4474 return (LRESULT)infoPtr->dragList;
4475}
4476
4477/* Selection ************************************************************/
4478
4479static LRESULT
4481 INT cause)
4482{
4483 TREEVIEW_ITEM *prevSelect;
4484
4485 assert(newSelect == NULL || TREEVIEW_ValidItem(infoPtr, newSelect));
4486
4487 TRACE("Entering item %p (%s), flag 0x%x, cause 0x%x, state 0x%x\n",
4488 newSelect, TREEVIEW_ItemName(newSelect), action, cause,
4489 newSelect ? newSelect->state : 0);
4490
4491 /* reset and redraw focusedItem if focusedItem was set so we don't */
4492 /* have to worry about the previously focused item when we set a new one */
4493 TREEVIEW_InvalidateItem(infoPtr, infoPtr->focusedItem);
4494 infoPtr->focusedItem = NULL;
4495
4496 switch (action)
4497 {
4499 FIXME("TVSI_NOSINGLEEXPAND specified.\n");
4500 /* Fall through */
4501 case TVGN_CARET:
4502 prevSelect = infoPtr->selectedItem;
4503
4504 if (prevSelect == newSelect) {
4505 TREEVIEW_EnsureVisible(infoPtr, infoPtr->selectedItem, FALSE);
4506 break;
4507 }
4508
4509 if (TREEVIEW_SendTreeviewNotify(infoPtr,
4511 cause,
4513 prevSelect,
4514 newSelect))
4515 return FALSE;
4516
4517 if (prevSelect)
4518 prevSelect->state &= ~TVIS_SELECTED;
4519 if (newSelect)
4520 newSelect->state |= TVIS_SELECTED;
4521
4522 infoPtr->selectedItem = newSelect;
4523
4524 TREEVIEW_EnsureVisible(infoPtr, infoPtr->selectedItem, FALSE);
4525
4526 TREEVIEW_InvalidateItem(infoPtr, prevSelect);
4527 TREEVIEW_InvalidateItem(infoPtr, newSelect);
4528
4531 cause,
4533 prevSelect,
4534 newSelect);
4535 break;
4536
4537 case TVGN_DROPHILITE:
4538 prevSelect = infoPtr->dropItem;
4539
4540 if (prevSelect)
4541 prevSelect->state &= ~TVIS_DROPHILITED;
4542
4543 infoPtr->dropItem = newSelect;
4544
4545 if (newSelect)
4546 newSelect->state |= TVIS_DROPHILITED;
4547
4548 TREEVIEW_Invalidate(infoPtr, prevSelect);
4549 TREEVIEW_Invalidate(infoPtr, newSelect);
4550 break;
4551
4552 case TVGN_FIRSTVISIBLE:
4553 if (newSelect != NULL)
4554 {
4555 TREEVIEW_EnsureVisible(infoPtr, newSelect, FALSE);
4556 TREEVIEW_SetFirstVisible(infoPtr, newSelect, TRUE);
4557 TREEVIEW_Invalidate(infoPtr, NULL);
4558 }
4559 break;
4560 }
4561
4562 TRACE("Leaving state 0x%x\n", newSelect ? newSelect->state : 0);
4563 return TRUE;
4564}
4565
4566/* FIXME: handle NM_KILLFOCUS etc */
4567static LRESULT
4569{
4571
4572 if (item && !TREEVIEW_ValidItem(infoPtr, item))
4573 return FALSE;
4574
4575 if (item == infoPtr->selectedItem)
4576 return TRUE;
4577
4578 TRACE("%p (%s) %d\n", item, TREEVIEW_ItemName(item), wParam);
4579
4581 return FALSE;
4582
4584
4585 return TRUE;
4586}
4587
4588/*************************************************************************
4589 * TREEVIEW_ProcessLetterKeys
4590 *
4591 * Processes keyboard messages generated by pressing the letter keys
4592 * on the keyboard.
4593 * What this does is perform a case insensitive search from the
4594 * current position with the following quirks:
4595 * - If two chars or more are pressed in quick succession we search
4596 * for the corresponding string (e.g. 'abc').
4597 * - If there is a delay we wipe away the current search string and
4598 * restart with just that char.
4599 * - If the user keeps pressing the same character, whether slowly or
4600 * fast, so that the search string is entirely composed of this
4601 * character ('aaaaa' for instance), then we search for first item
4602 * that starting with that character.
4603 * - If the user types the above character in quick succession, then
4604 * we must also search for the corresponding string ('aaaaa'), and
4605 * go to that string if there is a match.
4606 *
4607 * RETURNS
4608 *
4609 * Zero.
4610 *
4611 * BUGS
4612 *
4613 * - The current implementation has a list of characters it will
4614 * accept and it ignores everything else. In particular it will
4615 * ignore accentuated characters which seems to match what
4616 * Windows does. But I'm not sure it makes sense to follow
4617 * Windows there.
4618 * - We don't sound a beep when the search fails.
4619 * - The search should start from the focused item, not from the selected
4620 * item. One reason for this is to allow for multiple selections in trees.
4621 * But currently infoPtr->focusedItem does not seem very usable.
4622 *
4623 * SEE ALSO
4624 *
4625 * TREEVIEW_ProcessLetterKeys
4626 */
4627static INT TREEVIEW_ProcessLetterKeys(TREEVIEW_INFO *infoPtr, WPARAM charCode, LPARAM keyData)
4628{
4629 HTREEITEM nItem;
4630 HTREEITEM endidx,idx;
4633 DWORD timestamp,elapsed;
4634
4635 /* simple parameter checking */
4636 if (!charCode || !keyData) return 0;
4637
4638 /* only allow the valid WM_CHARs through */
4639 if (!isalnum(charCode) &&
4640 charCode != '.' && charCode != '`' && charCode != '!' &&
4641 charCode != '@' && charCode != '#' && charCode != '$' &&
4642 charCode != '%' && charCode != '^' && charCode != '&' &&
4643 charCode != '*' && charCode != '(' && charCode != ')' &&
4644 charCode != '-' && charCode != '_' && charCode != '+' &&
4645 charCode != '=' && charCode != '\\'&& charCode != ']' &&
4646 charCode != '}' && charCode != '[' && charCode != '{' &&
4647 charCode != '/' && charCode != '?' && charCode != '>' &&
4648 charCode != '<' && charCode != ',' && charCode != '~')
4649 return 0;
4650
4651 /* compute how much time elapsed since last keypress */
4653 if (timestamp > infoPtr->lastKeyPressTimestamp) {
4654 elapsed=timestamp-infoPtr->lastKeyPressTimestamp;
4655 } else {
4656 elapsed=infoPtr->lastKeyPressTimestamp-timestamp;
4657 }
4658
4659 /* update the search parameters */
4661 if (elapsed < KEY_DELAY) {
4662 if (infoPtr->nSearchParamLength < ARRAY_SIZE(infoPtr->szSearchParam)) {
4663 infoPtr->szSearchParam[infoPtr->nSearchParamLength++]=charCode;
4664 }
4665 if (infoPtr->charCode != charCode) {
4666 infoPtr->charCode=charCode=0;
4667 }
4668 } else {
4669 infoPtr->charCode=charCode;
4670 infoPtr->szSearchParam[0]=charCode;
4671 infoPtr->nSearchParamLength=1;
4672 /* Redundant with the 1 char string */
4673 charCode=0;
4674 }
4675
4676 /* and search from the current position */
4677 nItem=NULL;
4678 if (infoPtr->selectedItem != NULL) {
4679 endidx=infoPtr->selectedItem;
4680 /* if looking for single character match,
4681 * then we must always move forward
4682 */
4683 if (infoPtr->nSearchParamLength == 1)
4684 idx=TREEVIEW_GetNextListItem(infoPtr,endidx);
4685 else
4686 idx=endidx;
4687 } else {
4688 endidx=NULL;
4689 idx=infoPtr->root->firstChild;
4690 }
4691 do {
4692 /* At the end point, sort out wrapping */
4693 if (idx == NULL) {
4694
4695 /* If endidx is null, stop at the last item (ie top to bottom) */
4696 if (endidx == NULL)
4697 break;
4698
4699 /* Otherwise, start again at the very beginning */
4700 idx=infoPtr->root->firstChild;
4701
4702 /* But if we are stopping on the first child, end now! */
4703 if (idx == endidx) break;
4704 }
4705
4706 /* get item */
4707 ZeroMemory(&item, sizeof(item));
4708 item.mask = TVIF_TEXT;
4709 item.hItem = idx;
4710 item.pszText = buffer;
4711 item.cchTextMax = sizeof(buffer);
4712 TREEVIEW_GetItemT( infoPtr, &item, TRUE );
4713
4714 /* check for a match */
4715 if (strncmpiW(item.pszText,infoPtr->szSearchParam,infoPtr->nSearchParamLength) == 0) {
4716 nItem=idx;
4717 break;
4718 } else if ( (charCode != 0) && (nItem == NULL) &&
4719 (nItem != infoPtr->selectedItem) &&
4720 (strncmpiW(item.pszText,infoPtr->szSearchParam,1) == 0) ) {
4721 /* This would work but we must keep looking for a longer match */
4722 nItem=idx;
4723 }
4725 } while (idx != endidx);
4726
4727 if (nItem != NULL) {
4728 if (TREEVIEW_DoSelectItem(infoPtr, TVGN_CARET, nItem, TVC_BYKEYBOARD)) {
4729 TREEVIEW_EnsureVisible(infoPtr, nItem, FALSE);
4730 }
4731 }
4732
4733 return 0;
4734}
4735
4736/* Scrolling ************************************************************/
4737
4738static LRESULT
4740{
4741 int viscount;
4742 BOOL hasFirstVisible = infoPtr->firstVisible != NULL;
4743 HTREEITEM newFirstVisible = NULL;
4744 int visible_pos = -1;
4745
4746 if (!TREEVIEW_ValidItem(infoPtr, item))
4747 return FALSE;
4748
4749 if (!ISVISIBLE(item))
4750 {
4751 /* Expand parents as necessary. */
4753
4754 /* see if we are trying to ensure that root is visible */
4755 if((item != infoPtr->root) && TREEVIEW_ValidItem(infoPtr, item))
4756 parent = item->parent;
4757 else
4758 parent = item; /* this item is the topmost item */
4759
4760 while (parent != infoPtr->root)
4761 {
4762 if (!(parent->state & TVIS_EXPANDED))
4763 TREEVIEW_Expand(infoPtr, parent, FALSE, TRUE);
4764
4765 parent = parent->parent;
4766 }
4767 }
4768
4769 viscount = TREEVIEW_GetVisibleCount(infoPtr);
4770
4771 TRACE("%p (%s) %d - %d viscount(%d)\n", item, TREEVIEW_ItemName(item), item->visibleOrder,
4772 hasFirstVisible ? infoPtr->firstVisible->visibleOrder : -1, viscount);
4773
4774 if (hasFirstVisible)
4775 visible_pos = item->visibleOrder - infoPtr->firstVisible->visibleOrder;
4776
4777 if (visible_pos < 0)
4778 {
4779 /* item is before the start of the list: put it at the top. */
4780 newFirstVisible = item;
4781 }
4782 else if (visible_pos >= viscount
4783 /* Sometimes, before we are displayed, GVC is 0, causing us to
4784 * spuriously scroll up. */
4785 && visible_pos > 0 && !(infoPtr->dwStyle & TVS_NOSCROLL) )
4786 {
4787 /* item is past the end of the list. */
4788 int scroll = visible_pos - viscount;
4789
4790 newFirstVisible = TREEVIEW_GetListItem(infoPtr, infoPtr->firstVisible,
4791 scroll + 1);
4792 }
4793
4794 if (bHScroll)
4795 {
4796 /* Scroll window so item's text is visible as much as possible */
4797 /* Calculation of amount of extra space is taken from EditLabel code */
4798 INT pos, x;
4799 TEXTMETRICW textMetric;
4800 HDC hdc = GetWindowDC(infoPtr->hwnd);
4801
4802 x = item->textWidth;
4803
4804 GetTextMetricsW(hdc, &textMetric);
4805 ReleaseDC(infoPtr->hwnd, hdc);
4806
4807 x += (textMetric.tmMaxCharWidth * 2);
4808 x = max(x, textMetric.tmMaxCharWidth * 3);
4809
4810 if (item->textOffset < 0)
4811 pos = item->textOffset;
4812 else if (item->textOffset + x > infoPtr->clientWidth)
4813 {
4814 if (x > infoPtr->clientWidth)
4815 pos = item->textOffset;
4816 else
4817 pos = item->textOffset + x - infoPtr->clientWidth;
4818 }
4819 else
4820 pos = 0;
4821
4823 }
4824
4825 if (newFirstVisible != NULL && newFirstVisible != infoPtr->firstVisible)
4826 {
4827 TREEVIEW_SetFirstVisible(infoPtr, newFirstVisible, TRUE);
4828
4829 return TRUE;
4830 }
4831
4832 return FALSE;
4833}
4834
4835static VOID
4837 TREEVIEW_ITEM *newFirstVisible,
4838 BOOL bUpdateScrollPos)
4839{
4840 int gap_size;
4841
4842 TRACE("%p: %s\n", newFirstVisible, TREEVIEW_ItemName(newFirstVisible));
4843
4844 if (newFirstVisible != NULL)
4845 {
4846 /* Prevent an empty gap from appearing at the bottom... */
4847 gap_size = TREEVIEW_GetVisibleCount(infoPtr)
4848 - infoPtr->maxVisibleOrder + newFirstVisible->visibleOrder;
4849
4850 if (gap_size > 0)
4851 {
4852 newFirstVisible = TREEVIEW_GetListItem(infoPtr, newFirstVisible,
4853 -gap_size);
4854
4855 /* ... unless we just don't have enough items. */
4856 if (newFirstVisible == NULL)
4857 newFirstVisible = infoPtr->root->firstChild;
4858 }
4859 }
4860
4861 if (infoPtr->firstVisible != newFirstVisible)
4862 {
4863 if (infoPtr->firstVisible == NULL || newFirstVisible == NULL)
4864 {
4865 infoPtr->firstVisible = newFirstVisible;
4866 TREEVIEW_Invalidate(infoPtr, NULL);
4867 }
4868 else
4869 {
4871 int scroll = infoPtr->uItemHeight *
4872 (infoPtr->firstVisible->visibleOrder
4873 - newFirstVisible->visibleOrder);
4874
4875 infoPtr->firstVisible = newFirstVisible;
4876
4877 for (item = infoPtr->root->firstChild; item != NULL;
4879 {
4880 item->rect.top += scroll;
4881 item->rect.bottom += scroll;
4882 }
4883
4884 if (bUpdateScrollPos)
4885 SetScrollPos(infoPtr->hwnd, SB_VERT,
4886 newFirstVisible->visibleOrder, TRUE);
4887
4888 ScrollWindowEx(infoPtr->hwnd, 0, scroll, NULL, NULL, NULL, NULL, SW_ERASE | SW_INVALIDATE);
4889 }
4890 }
4891}
4892
4893/************************************************************************
4894 * VScroll is always in units of visible items. i.e. we always have a
4895 * visible item aligned to the top of the control. (Unless we have no
4896 * items at all.)
4897 */
4898static LRESULT
4900{
4901 TREEVIEW_ITEM *oldFirstVisible = infoPtr->firstVisible;
4902 TREEVIEW_ITEM *newFirstVisible = NULL;
4903
4904 int nScrollCode = LOWORD(wParam);
4905
4906 TRACE("wp %lx\n", wParam);
4907
4908 if (!(infoPtr->uInternalStatus & TV_VSCROLL))
4909 return 0;
4910
4911 if (!oldFirstVisible)
4912 {
4913 assert(infoPtr->root->firstChild == NULL);
4914 return 0;
4915 }
4916
4917 switch (nScrollCode)
4918 {
4919 case SB_TOP:
4920 newFirstVisible = infoPtr->root->firstChild;
4921 break;
4922
4923 case SB_BOTTOM:
4924 newFirstVisible = TREEVIEW_GetLastListItem(infoPtr, infoPtr->root);
4925 break;
4926
4927 case SB_LINEUP:
4928 newFirstVisible = TREEVIEW_GetPrevListItem(infoPtr, oldFirstVisible);
4929 break;
4930
4931 case SB_LINEDOWN:
4932 newFirstVisible = TREEVIEW_GetNextListItem(infoPtr, oldFirstVisible);
4933 break;
4934
4935 case SB_PAGEUP:
4936 newFirstVisible = TREEVIEW_GetListItem(infoPtr, oldFirstVisible,
4937 -max(1, TREEVIEW_GetVisibleCount(infoPtr)));
4938 break;
4939
4940 case SB_PAGEDOWN:
4941 newFirstVisible = TREEVIEW_GetListItem(infoPtr, oldFirstVisible,
4942 max(1, TREEVIEW_GetVisibleCount(infoPtr)));
4943 break;
4944
4945 case SB_THUMBTRACK:
4946 case SB_THUMBPOSITION:
4947 newFirstVisible = TREEVIEW_GetListItem(infoPtr,
4948 infoPtr->root->firstChild,
4949 (LONG)(SHORT)HIWORD(wParam));
4950 break;
4951
4952 case SB_ENDSCROLL:
4953 return 0;
4954 }
4955
4956 if (newFirstVisible != NULL)
4957 {
4958 if (newFirstVisible != oldFirstVisible)
4959 TREEVIEW_SetFirstVisible(infoPtr, newFirstVisible,
4960 nScrollCode != SB_THUMBTRACK);
4961 else if (nScrollCode == SB_THUMBPOSITION)
4962 SetScrollPos(infoPtr->hwnd, SB_VERT,
4963 newFirstVisible->visibleOrder, TRUE);
4964 }
4965
4966 return 0;
4967}
4968
4969static LRESULT
4971{
4972 int maxWidth;
4973 int scrollX = infoPtr->scrollX;
4974 int nScrollCode = LOWORD(wParam);
4975
4976 TRACE("wp %lx\n", wParam);
4977
4978 if (!(infoPtr->uInternalStatus & TV_HSCROLL))
4979 return FALSE;
4980
4981 maxWidth = infoPtr->treeWidth - infoPtr->clientWidth;
4982 /* shall never occur */
4983 if (maxWidth <= 0)
4984 {
4985 scrollX = 0;
4986 goto scroll;
4987 }
4988
4989 switch (nScrollCode)
4990 {
4991 case SB_LINELEFT:
4992 scrollX -= infoPtr->uItemHeight;
4993 break;
4994 case SB_LINERIGHT:
4995 scrollX += infoPtr->uItemHeight;
4996 break;
4997 case SB_PAGELEFT:
4998 scrollX -= infoPtr->clientWidth;
4999 break;
5000 case SB_PAGERIGHT:
5001 scrollX += infoPtr->clientWidth;
5002 break;
5003
5004 case SB_THUMBTRACK:
5005 case SB_THUMBPOSITION:
5006 scrollX = (int)(SHORT)HIWORD(wParam);
5007 break;
5008
5009 case SB_ENDSCROLL:
5010 return 0;
5011 }
5012
5013 if (scrollX > maxWidth)
5014 scrollX = maxWidth;
5015 else if (scrollX < 0)
5016 scrollX = 0;
5017
5018scroll:
5019 if (scrollX != infoPtr->scrollX)
5020 {
5022 LONG scroll_pixels = infoPtr->scrollX - scrollX;
5023
5024 for (item = infoPtr->root->firstChild; item != NULL;
5026 {
5027 item->linesOffset += scroll_pixels;
5028 item->stateOffset += scroll_pixels;
5029 item->imageOffset += scroll_pixels;
5030 item->textOffset += scroll_pixels;
5031 }
5032
5033 ScrollWindow(infoPtr->hwnd, scroll_pixels, 0, NULL, NULL);
5034 infoPtr->scrollX = scrollX;
5035 UpdateWindow(infoPtr->hwnd);
5036 }
5037
5038 if (nScrollCode != SB_THUMBTRACK)
5039 SetScrollPos(infoPtr->hwnd, SB_HORZ, scrollX, TRUE);
5040
5041 return 0;
5042}
5043
5044static LRESULT
5046{
5047 short wheelDelta;
5048 UINT pulScrollLines = 3;
5049
5050 if (wParam & (MK_SHIFT | MK_CONTROL))
5051 return DefWindowProcW(infoPtr->hwnd, WM_MOUSEWHEEL, wParam, lParam);
5052
5053 if (infoPtr->firstVisible == NULL)
5054 return TRUE;
5055
5056 SystemParametersInfoW(SPI_GETWHEELSCROLLLINES, 0, &pulScrollLines, 0);
5057
5058 wheelDelta = GET_WHEEL_DELTA_WPARAM(wParam);
5059 /* if scrolling changes direction, ignore left overs */
5060 if ((wheelDelta < 0 && infoPtr->wheelRemainder < 0) ||
5061 (wheelDelta > 0 && infoPtr->wheelRemainder > 0))
5062 infoPtr->wheelRemainder += wheelDelta;
5063 else
5064 infoPtr->wheelRemainder = wheelDelta;
5065
5066 if (infoPtr->wheelRemainder && pulScrollLines)
5067 {
5068 int newDy;
5069 int maxDy;
5070 int lineScroll;
5071
5072 lineScroll = pulScrollLines * (float)infoPtr->wheelRemainder / WHEEL_DELTA;
5073 infoPtr->wheelRemainder -= WHEEL_DELTA * lineScroll / (int)pulScrollLines;
5074
5075 newDy = infoPtr->firstVisible->visibleOrder - lineScroll;
5076 maxDy = infoPtr->maxVisibleOrder;
5077
5078 if (newDy > maxDy)
5079 newDy = maxDy;
5080
5081 if (newDy < 0)
5082 newDy = 0;
5083
5085 }
5086 return TRUE;
5087}
5088
5089/* Create/Destroy *******************************************************/
5090
5091static LRESULT
5093{
5094 RECT rcClient;
5095 TREEVIEW_INFO *infoPtr;
5096 LOGFONTW lf;
5097
5098 TRACE("wnd %p, style 0x%x\n", hwnd, GetWindowLongW(hwnd, GWL_STYLE));
5099
5100 infoPtr = heap_alloc_zero(sizeof(TREEVIEW_INFO));
5101
5102 if (infoPtr == NULL)
5103 {
5104 ERR("could not allocate info memory!\n");
5105 return 0;
5106 }
5107
5108 SetWindowLongPtrW(hwnd, 0, (DWORD_PTR)infoPtr);
5109
5110 infoPtr->hwnd = hwnd;
5111 infoPtr->dwStyle = GetWindowLongW(hwnd, GWL_STYLE);
5112 infoPtr->Timer = 0;
5113 infoPtr->uNumItems = 0;
5114 infoPtr->cdmode = 0;
5115 infoPtr->uScrollTime = 300; /* milliseconds */
5116 infoPtr->bRedraw = TRUE;
5117
5118 GetClientRect(hwnd, &rcClient);
5119
5120 /* No scroll bars yet. */
5121 infoPtr->clientWidth = rcClient.right;
5122 infoPtr->clientHeight = rcClient.bottom;
5123 infoPtr->uInternalStatus = 0;
5124
5125 infoPtr->treeWidth = 0;
5126 infoPtr->treeHeight = 0;
5127
5128 infoPtr->uIndent = MINIMUM_INDENT;
5129 infoPtr->selectedItem = NULL;
5130 infoPtr->focusedItem = NULL;
5131 infoPtr->hotItem = NULL;
5132 infoPtr->editItem = NULL;
5133 infoPtr->firstVisible = NULL;
5134 infoPtr->maxVisibleOrder = 0;
5135 infoPtr->dropItem = NULL;
5136 infoPtr->insertMarkItem = NULL;
5137 infoPtr->insertBeforeorAfter = 0;
5138 /* dragList */
5139
5140 infoPtr->scrollX = 0;
5141 infoPtr->wheelRemainder = 0;
5142
5143 infoPtr->clrBk = CLR_NONE; /* use system color */
5144 infoPtr->clrText = CLR_NONE; /* use system color */
5145 infoPtr->clrLine = CLR_DEFAULT;
5146 infoPtr->clrInsertMark = CLR_DEFAULT;
5147
5148 /* hwndToolTip */
5149
5150 infoPtr->hwndEdit = NULL;
5151 infoPtr->wpEditOrig = NULL;
5152 infoPtr->bIgnoreEditKillFocus = FALSE;
5153 infoPtr->bLabelChanged = FALSE;
5154
5155 infoPtr->himlNormal = NULL;
5156 infoPtr->himlState = NULL;
5157 infoPtr->normalImageWidth = 0;
5158 infoPtr->normalImageHeight = 0;
5159 infoPtr->stateImageWidth = 0;
5160 infoPtr->stateImageHeight = 0;
5161
5162 infoPtr->items = DPA_Create(16);
5163
5165 infoPtr->hFont = infoPtr->hDefaultFont = CreateFontIndirectW(&lf);
5166 infoPtr->hBoldFont = TREEVIEW_CreateBoldFont(infoPtr->hFont);
5169 infoPtr->hcurHand = LoadCursorW(NULL, (LPWSTR)IDC_HAND);
5170
5171 infoPtr->uItemHeight = TREEVIEW_NaturalHeight(infoPtr);
5172
5173 infoPtr->root = TREEVIEW_AllocateItem(infoPtr);
5174 infoPtr->root->state = TVIS_EXPANDED;
5175 infoPtr->root->iLevel = -1;
5176 infoPtr->root->visibleOrder = -1;
5177
5178 infoPtr->hwndNotify = lpcs->hwndParent;
5179 infoPtr->hwndToolTip = 0;
5180
5181 /* Determine what type of notify should be issued (sets infoPtr->bNtfUnicode) */
5182 TREEVIEW_NotifyFormat(infoPtr, infoPtr->hwndNotify, NF_REQUERY);
5183
5184 if (!(infoPtr->dwStyle & TVS_NOTOOLTIPS))
5187 hwnd, 0, 0, 0);
5188
5189 /* Make sure actual scrollbar state is consistent with uInternalStatus */
5192
5194
5195 return 0;
5196}
5197
5198
5199static LRESULT
5201{
5202 TRACE("\n");
5203
5204 /* free item data */
5205 TREEVIEW_RemoveTree(infoPtr);
5206 /* root isn't freed with other items */
5207 TREEVIEW_FreeItem(infoPtr, infoPtr->root);
5208 DPA_Destroy(infoPtr->items);
5209
5210 /* Restore original wndproc */
5211 if (infoPtr->hwndEdit)
5213 (DWORD_PTR)infoPtr->wpEditOrig);
5214
5215 CloseThemeData (GetWindowTheme (infoPtr->hwnd));
5216
5217 /* Deassociate treeview from the window before doing anything drastic. */
5218 SetWindowLongPtrW(infoPtr->hwnd, 0, 0);
5219
5220 DeleteObject(infoPtr->hDefaultFont);
5221 DeleteObject(infoPtr->hBoldFont);
5222 DeleteObject(infoPtr->hUnderlineFont);
5224 DestroyWindow(infoPtr->hwndToolTip);
5225 heap_free(infoPtr);
5226
5227 return 0;
5228}
5229
5230/* Miscellaneous Messages ***********************************************/
5231
5232static LRESULT
5234{
5235 static const struct
5236 {
5237 unsigned char code;
5238 }
5239 scroll[] =
5240 {
5241#define SCROLL_ENTRY(dir, code) { ((dir) << 7) | (code) }
5242 SCROLL_ENTRY(SB_VERT, SB_PAGEUP), /* VK_PRIOR */
5243 SCROLL_ENTRY(SB_VERT, SB_PAGEDOWN), /* VK_NEXT */
5244 SCROLL_ENTRY(SB_VERT, SB_BOTTOM), /* VK_END */
5245 SCROLL_ENTRY(SB_VERT, SB_TOP), /* VK_HOME */
5246 SCROLL_ENTRY(SB_HORZ, SB_LINEUP), /* VK_LEFT */
5247 SCROLL_ENTRY(SB_VERT, SB_LINEUP), /* VK_UP */
5248 SCROLL_ENTRY(SB_HORZ, SB_LINEDOWN), /* VK_RIGHT */
5249 SCROLL_ENTRY(SB_VERT, SB_LINEDOWN) /* VK_DOWN */
5250#undef SCROLL_ENTRY
5251 };
5252
5253 if (key >= VK_PRIOR && key <= VK_DOWN)
5254 {
5255 unsigned char code = scroll[key - VK_PRIOR].code;
5256
5257 (((code & (1 << 7)) == (SB_HORZ << 7))
5259 : TREEVIEW_VScroll)(infoPtr, code & 0x7F);
5260 }
5261
5262 return 0;
5263}
5264
5265/************************************************************************
5266 * TREEVIEW_KeyDown
5267 *
5268 * VK_UP Move selection to the previous non-hidden item.
5269 * VK_DOWN Move selection to the next non-hidden item.
5270 * VK_HOME Move selection to the first item.
5271 * VK_END Move selection to the last item.
5272 * VK_LEFT If expanded then collapse, otherwise move to parent.
5273 * VK_RIGHT If collapsed then expand, otherwise move to first child.
5274 * VK_ADD Expand.
5275 * VK_SUBTRACT Collapse.
5276 * VK_MULTIPLY Expand all.
5277 * VK_PRIOR Move up GetVisibleCount items.
5278 * VK_NEXT Move down GetVisibleCount items.
5279 * VK_BACK Move to parent.
5280 * CTRL-Left,Right,Up,Down,PgUp,PgDown,Home,End: Scroll without changing selection
5281 */
5282static LRESULT
5284{
5285 /* If it is non-NULL and different, it will be selected and visible. */
5286 TREEVIEW_ITEM *newSelection = NULL;
5287 TREEVIEW_ITEM *prevItem = infoPtr->selectedItem;
5288 NMTVKEYDOWN nmkeydown;
5289
5290 TRACE("%lx\n", wParam);
5291
5292 nmkeydown.wVKey = wParam;
5293 nmkeydown.flags = 0;
5294 TREEVIEW_SendRealNotify(infoPtr, TVN_KEYDOWN, &nmkeydown.hdr);
5295
5296 if (prevItem == NULL)
5297 return FALSE;
5298
5299 if (GetAsyncKeyState(VK_CONTROL) & 0x8000)
5300 return TREEVIEW_ScrollKeyDown(infoPtr, wParam);
5301
5302 switch (wParam)
5303 {
5304 case VK_UP:
5305 newSelection = TREEVIEW_GetPrevListItem(infoPtr, prevItem);
5306 if (!newSelection)
5307 newSelection = infoPtr->root->firstChild;
5308 break;
5309
5310 case VK_DOWN:
5311 newSelection = TREEVIEW_GetNextListItem(infoPtr, prevItem);
5312 break;
5313
5314 case VK_RETURN:
5316 break;
5317
5318 case VK_HOME:
5319 newSelection = infoPtr->root->firstChild;
5320 break;
5321
5322 case VK_END:
5323 newSelection = TREEVIEW_GetLastListItem(infoPtr, infoPtr->root);
5324 break;
5325
5326 case VK_LEFT:
5327 if (prevItem->state & TVIS_EXPANDED)
5328 {
5329 TREEVIEW_Collapse(infoPtr, prevItem, FALSE, TRUE);
5330 }
5331 else if (prevItem->parent != infoPtr->root)
5332 {
5333 newSelection = prevItem->parent;
5334 }
5335 break;
5336
5337 case VK_RIGHT:
5338 if (TREEVIEW_HasChildren(infoPtr, prevItem))
5339 {
5340 if (!(prevItem->state & TVIS_EXPANDED))
5341 TREEVIEW_Expand(infoPtr, prevItem, FALSE, TRUE);
5342 else
5343 {
5344 newSelection = prevItem->firstChild;
5345 }
5346 }
5347
5348 break;
5349
5350 case VK_MULTIPLY:
5351 TREEVIEW_ExpandAll(infoPtr, prevItem);
5352 break;
5353
5354 case VK_ADD:
5355 TREEVIEW_Expand(infoPtr, prevItem, FALSE, TRUE);
5356 break;
5357
5358 case VK_SUBTRACT:
5359 TREEVIEW_Collapse(infoPtr, prevItem, FALSE, TRUE);
5360 break;
5361
5362 case VK_PRIOR:
5363 newSelection
5364 = TREEVIEW_GetListItem(infoPtr, prevItem,
5365 -TREEVIEW_GetVisibleCount(infoPtr));
5366 break;
5367
5368 case VK_NEXT:
5369 newSelection
5370 = TREEVIEW_GetListItem(infoPtr, prevItem,
5371 TREEVIEW_GetVisibleCount(infoPtr));
5372 break;
5373
5374 case VK_BACK:
5375 newSelection = prevItem->parent;
5376 if (newSelection == infoPtr->root)
5377 newSelection = NULL;
5378 break;
5379
5380 case VK_SPACE:
5381 if (infoPtr->dwStyle & TVS_CHECKBOXES)
5382 TREEVIEW_ToggleItemState(infoPtr, prevItem);
5383 break;
5384 }
5385
5386 if (newSelection && newSelection != prevItem)
5387 {
5388 if (TREEVIEW_DoSelectItem(infoPtr, TVGN_CARET, newSelection,
5390 {
5391 TREEVIEW_EnsureVisible(infoPtr, newSelection, FALSE);
5392 }
5393 }
5394
5395 return FALSE;
5396}
5397
5398static LRESULT
5400{
5401 /* remove hot effect from item */
5402 TREEVIEW_InvalidateItem(infoPtr, infoPtr->hotItem);
5403 infoPtr->hotItem = NULL;
5404
5405 return 0;
5406}
5407
5408static LRESULT
5410{
5411 TRACKMOUSEEVENT trackinfo;
5414 BOOL item_hit;
5415
5416 if (!(infoPtr->dwStyle & TVS_TRACKSELECT)) return 0;
5417
5418 /* fill in the TRACKMOUSEEVENT struct */
5419 trackinfo.cbSize = sizeof(TRACKMOUSEEVENT);
5420 trackinfo.dwFlags = TME_QUERY;
5421 trackinfo.hwndTrack = infoPtr->hwnd;
5422
5423 /* call _TrackMouseEvent to see if we are currently tracking for this hwnd */
5424 _TrackMouseEvent(&trackinfo);
5425
5426 /* Make sure tracking is enabled so we receive a WM_MOUSELEAVE message */
5427 if(!(trackinfo.dwFlags & TME_LEAVE))
5428 {
5429 trackinfo.dwFlags = TME_LEAVE; /* notify upon leaving */
5430 trackinfo.hwndTrack = infoPtr->hwnd;
5431 /* do it as fast as possible, minimal systimer latency will be used */
5432 trackinfo.dwHoverTime = 1;
5433
5434 /* call TRACKMOUSEEVENT so we receive a WM_MOUSELEAVE message */
5435 /* and can properly deactivate the hot item */
5436 _TrackMouseEvent(&trackinfo);
5437 }
5438
5439 ht.pt.x = (short)LOWORD(lParam);
5440 ht.pt.y = (short)HIWORD(lParam);
5441
5442 item = TREEVIEW_HitTest(infoPtr, &ht);
5443 item_hit = TREEVIEW_IsItemHit(infoPtr, &ht);
5444 if ((item != infoPtr->hotItem) || !item_hit)
5445 {
5446 /* redraw old hot item */
5447 TREEVIEW_InvalidateItem(infoPtr, infoPtr->hotItem);
5448 infoPtr->hotItem = NULL;
5449 if (item && item_hit)
5450 {
5451 infoPtr->hotItem = item;
5452 /* redraw new hot item */
5453 TREEVIEW_InvalidateItem(infoPtr, infoPtr->hotItem);
5454 }
5455 }
5456
5457 return 0;
5458}
5459
5460/* Draw themed border */
5461static BOOL TREEVIEW_NCPaint (const TREEVIEW_INFO *infoPtr, HRGN region, LPARAM lParam)
5462{
5463 HTHEME theme = GetWindowTheme (infoPtr->hwnd);
5464 HDC dc;
5465 RECT r;
5466 HRGN cliprgn;
5467 int cxEdge = GetSystemMetrics (SM_CXEDGE),
5468 cyEdge = GetSystemMetrics (SM_CYEDGE);
5469
5470 if (!theme)
5471 return DefWindowProcW (infoPtr->hwnd, WM_NCPAINT, (WPARAM)region, lParam);
5472
5473 GetWindowRect(infoPtr->hwnd, &r);
5474
5475 cliprgn = CreateRectRgn (r.left + cxEdge, r.top + cyEdge,
5476 r.right - cxEdge, r.bottom - cyEdge);
5477 if (region != (HRGN)1)
5478 CombineRgn (cliprgn, cliprgn, region, RGN_AND);
5479 OffsetRect(&r, -r.left, -r.top);
5480
5481#ifdef __REACTOS__ /* r73789 */
5482 dc = GetWindowDC(infoPtr->hwnd);
5483 /* Exclude client part */
5484 ExcludeClipRect(dc, r.left + cxEdge, r.top + cyEdge,
5485 r.right - cxEdge, r.bottom -cyEdge);
5486#else
5487 dc = GetDCEx(infoPtr->hwnd, region, DCX_WINDOW|DCX_INTERSECTRGN);
5488 OffsetRect(&r, -r.left, -r.top);
5489#endif
5490
5491 if (IsThemeBackgroundPartiallyTransparent (theme, 0, 0))
5492 DrawThemeParentBackground(infoPtr->hwnd, dc, &r);
5493 DrawThemeBackground (theme, dc, 0, 0, &r, 0);
5494 ReleaseDC(infoPtr->hwnd, dc);
5495
5496 /* Call default proc to get the scrollbars etc. painted */
5497 DefWindowProcW (infoPtr->hwnd, WM_NCPAINT, (WPARAM)cliprgn, 0);
5498 DeleteObject(cliprgn);
5499
5500 return TRUE;
5501}
5502
5503static LRESULT
5505{
5506 LPNMHDR lpnmh = (LPNMHDR)lParam;
5507
5508 if (lpnmh->code == PGN_CALCSIZE) {
5510
5511 if (lppgc->dwFlag == PGF_CALCWIDTH) {
5512 lppgc->iWidth = infoPtr->treeWidth;
5513 TRACE("got PGN_CALCSIZE, returning horz size = %d, client=%d\n",
5514 infoPtr->treeWidth, infoPtr->clientWidth);
5515 }
5516 else {
5517 lppgc->iHeight = infoPtr->treeHeight;
5518 TRACE("got PGN_CALCSIZE, returning vert size = %d, client=%d\n",
5519 infoPtr->treeHeight, infoPtr->clientHeight);
5520 }
5521 return 0;
5522 }
5523 return DefWindowProcW(infoPtr->hwnd, WM_NOTIFY, wParam, lParam);
5524}
5525
5526static LRESULT
5528{
5529 if (wParam == SIZE_RESTORED)
5530 {
5531 infoPtr->clientWidth = (short)LOWORD(lParam);
5532 infoPtr->clientHeight = (short)HIWORD(lParam);
5533
5535 TREEVIEW_SetFirstVisible(infoPtr, infoPtr->firstVisible, TRUE);
5537 }
5538 else
5539 {
5540 FIXME("WM_SIZE flag %lx %lx not handled\n", wParam, lParam);
5541 }
5542
5543 TREEVIEW_Invalidate(infoPtr, NULL);
5544 return 0;
5545}
5546
5547static LRESULT
5549{
5550 TRACE("(%lx %lx)\n", wParam, lParam);
5551
5552 if (wParam == GWL_STYLE)
5553 {
5554 DWORD dwNewStyle = ((LPSTYLESTRUCT)lParam)->styleNew;
5555
5556 if ((infoPtr->dwStyle ^ dwNewStyle) & TVS_CHECKBOXES)
5557 {
5558 if (dwNewStyle & TVS_CHECKBOXES)
5559 {
5560 TREEVIEW_InitCheckboxes(infoPtr);
5561 TRACE("checkboxes enabled\n");
5562
5563 /* set all items to state image index 1 */
5564 TREEVIEW_ResetImageStateIndex(infoPtr, infoPtr->root);
5565 }
5566 else
5567 {
5568 FIXME("tried to disable checkboxes\n");
5569 }
5570 }
5571
5572 if ((infoPtr->dwStyle ^ dwNewStyle) & TVS_NOTOOLTIPS)
5573 {
5574 if (infoPtr->dwStyle & TVS_NOTOOLTIPS)
5575 {
5576 infoPtr->hwndToolTip = COMCTL32_CreateToolTip(infoPtr->hwnd);
5577 TRACE("tooltips enabled\n");
5578 }
5579 else
5580 {
5581 DestroyWindow(infoPtr->hwndToolTip);
5582 infoPtr->hwndToolTip = 0;
5583 TRACE("tooltips disabled\n");
5584 }
5585 }
5586
5587 infoPtr->dwStyle = dwNewStyle;
5588 }
5589
5591 TREEVIEW_UpdateSubTree(infoPtr, infoPtr->root);
5593 TREEVIEW_Invalidate(infoPtr, NULL);
5594
5595 return 0;
5596}
5597
5598static LRESULT
5600{
5603 NMMOUSE nmmouse;
5604
5605 GetCursorPos(&ht.pt);
5606 ScreenToClient(infoPtr->hwnd, &ht.pt);
5607
5608 item = TREEVIEW_HitTest(infoPtr, &ht);
5609
5610 memset(&nmmouse, 0, sizeof(nmmouse));
5611 if (item)
5612 {
5613 nmmouse.dwItemSpec = (DWORD_PTR)item;
5614 nmmouse.dwItemData = item->lParam;
5615 }
5616 nmmouse.pt.x = 0;
5617 nmmouse.pt.y = 0;
5618 nmmouse.dwHitInfo = lParam;
5619 if (TREEVIEW_SendRealNotify(infoPtr, NM_SETCURSOR, &nmmouse.hdr))
5620 return 0;
5621
5622 if (item && (infoPtr->dwStyle & TVS_TRACKSELECT) && TREEVIEW_IsItemHit(infoPtr, &ht))
5623 {
5624 SetCursor(infoPtr->hcurHand);
5625 return 0;
5626 }
5627 else
5628 return DefWindowProcW(infoPtr->hwnd, WM_SETCURSOR, wParam, lParam);
5629}
5630
5631static LRESULT
5633{
5634 TRACE("\n");
5635
5636 if (!infoPtr->selectedItem)
5637 {
5639 TVC_UNKNOWN);
5640 }
5641
5642 TREEVIEW_Invalidate(infoPtr, infoPtr->selectedItem);
5644 return 0;
5645}
5646
5647static LRESULT
5649{
5650 TRACE("\n");
5651
5652 TREEVIEW_Invalidate(infoPtr, infoPtr->selectedItem);
5653 UpdateWindow(infoPtr->hwnd);
5655 return 0;
5656}
5657
5658/* update theme after a WM_THEMECHANGED message */
5660{
5661 HTHEME theme = GetWindowTheme (infoPtr->hwnd);
5662 CloseThemeData (theme);
5663 OpenThemeData (infoPtr->hwnd, themeClass);
5664 return 0;
5665}
5666
5667
5668static LRESULT WINAPI
5670{
5672
5673 TRACE("hwnd %p msg %04x wp=%08lx lp=%08lx\n", hwnd, uMsg, wParam, lParam);
5674
5675 if (infoPtr) TREEVIEW_VerifyTree(infoPtr);
5676 else
5677 {
5678 if (uMsg == WM_CREATE)
5680 else
5681 goto def;
5682 }
5683
5684 switch (uMsg)
5685 {
5687 return TREEVIEW_CreateDragImage(infoPtr, lParam);
5688
5689 case TVM_DELETEITEM:
5690 return TREEVIEW_DeleteItem(infoPtr, (HTREEITEM)lParam);
5691
5692 case TVM_EDITLABELA:
5693 case TVM_EDITLABELW:
5694 return (LRESULT)TREEVIEW_EditLabel(infoPtr, (HTREEITEM)lParam);
5695
5697 return TREEVIEW_EndEditLabelNow(infoPtr, (BOOL)wParam);
5698
5699 case TVM_ENSUREVISIBLE:
5700 return TREEVIEW_EnsureVisible(infoPtr, (HTREEITEM)lParam, TRUE);
5701
5702 case TVM_EXPAND:
5703 return TREEVIEW_ExpandMsg(infoPtr, (UINT)wParam, (HTREEITEM)lParam);
5704
5705 case TVM_GETBKCOLOR:
5706 return TREEVIEW_GetBkColor(infoPtr);
5707
5708 case TVM_GETCOUNT:
5709 return TREEVIEW_GetCount(infoPtr);
5710
5711 case TVM_GETEDITCONTROL:
5712 return TREEVIEW_GetEditControl(infoPtr);
5713
5714 case TVM_GETIMAGELIST:
5715 return TREEVIEW_GetImageList(infoPtr, wParam);
5716
5717 case TVM_GETINDENT:
5718 return TREEVIEW_GetIndent(infoPtr);
5719
5721 return TREEVIEW_GetInsertMarkColor(infoPtr);
5722
5724 FIXME("Unimplemented msg TVM_GETISEARCHSTRINGA\n");
5725 return 0;
5726
5728 FIXME("Unimplemented msg TVM_GETISEARCHSTRINGW\n");
5729 return 0;
5730
5731 case TVM_GETITEMA:
5732 case TVM_GETITEMW:
5733 return TREEVIEW_GetItemT(infoPtr, (LPTVITEMEXW)lParam,
5734 uMsg == TVM_GETITEMW);
5735 case TVM_GETITEMHEIGHT:
5736 return TREEVIEW_GetItemHeight(infoPtr);
5737
5738 case TVM_GETITEMRECT:
5739 return TREEVIEW_GetItemRect(infoPtr, (BOOL)wParam, (LPRECT)lParam);
5740
5741 case TVM_GETITEMSTATE:
5742 return TREEVIEW_GetItemState(infoPtr, (HTREEITEM)wParam, (UINT)lParam);
5743
5744 case TVM_GETLINECOLOR:
5745 return TREEVIEW_GetLineColor(infoPtr);
5746
5747 case TVM_GETNEXTITEM:
5748 return TREEVIEW_GetNextItem(infoPtr, (UINT)wParam, (HTREEITEM)lParam);
5749
5750 case TVM_GETSCROLLTIME:
5751 return TREEVIEW_GetScrollTime(infoPtr);
5752
5753 case TVM_GETTEXTCOLOR:
5754 return TREEVIEW_GetTextColor(infoPtr);
5755
5756 case TVM_GETTOOLTIPS:
5757 return TREEVIEW_GetToolTips(infoPtr);
5758
5760 return TREEVIEW_GetUnicodeFormat(infoPtr);
5761
5763 return TREEVIEW_GetVisibleCount(infoPtr);
5764
5765 case TVM_HITTEST:
5766 return (LRESULT)TREEVIEW_HitTest(infoPtr, (TVHITTESTINFO*)lParam);
5767
5768 case TVM_INSERTITEMA:
5769 case TVM_INSERTITEMW:
5771 uMsg == TVM_INSERTITEMW);
5772 case TVM_SELECTITEM:
5773 return TREEVIEW_SelectItem(infoPtr, (INT)wParam, (HTREEITEM)lParam);
5774
5775 case TVM_SETBKCOLOR:
5776 return TREEVIEW_SetBkColor(infoPtr, (COLORREF)lParam);
5777
5778 case TVM_SETIMAGELIST:
5779 return TREEVIEW_SetImageList(infoPtr, wParam, (HIMAGELIST)lParam);
5780
5781 case TVM_SETINDENT:
5782 return TREEVIEW_SetIndent(infoPtr, (UINT)wParam);
5783
5784 case TVM_SETINSERTMARK:
5786
5789
5790 case TVM_SETITEMA:
5791 case TVM_SETITEMW:
5792 return TREEVIEW_SetItemT(infoPtr, (LPTVITEMEXW)lParam,
5793 uMsg == TVM_SETITEMW);
5794 case TVM_SETLINECOLOR:
5795 return TREEVIEW_SetLineColor(infoPtr, (COLORREF)lParam);
5796
5797 case TVM_SETITEMHEIGHT:
5798 return TREEVIEW_SetItemHeight(infoPtr, (INT)(SHORT)wParam);
5799
5800 case TVM_SETSCROLLTIME:
5801 return TREEVIEW_SetScrollTime(infoPtr, (UINT)wParam);
5802
5803 case TVM_SETTEXTCOLOR:
5804 return TREEVIEW_SetTextColor(infoPtr, (COLORREF)lParam);
5805
5806 case TVM_SETTOOLTIPS:
5807 return TREEVIEW_SetToolTips(infoPtr, (HWND)wParam);
5808
5810 return TREEVIEW_SetUnicodeFormat(infoPtr, (BOOL)wParam);
5811
5812 case TVM_SORTCHILDREN:
5813 return TREEVIEW_SortChildren(infoPtr, lParam);
5814
5815 case TVM_SORTCHILDRENCB:
5816 return TREEVIEW_SortChildrenCB(infoPtr, (LPTVSORTCB)lParam);
5817
5818 case WM_CHAR:
5819 return TREEVIEW_ProcessLetterKeys(infoPtr, wParam, lParam);
5820
5821 case WM_COMMAND:
5822 return TREEVIEW_Command(infoPtr, wParam, lParam);
5823
5824 case WM_DESTROY:
5825 return TREEVIEW_Destroy(infoPtr);
5826
5827 /* WM_ENABLE */
5828
5829 case WM_ERASEBKGND:
5830 return TREEVIEW_EraseBackground(infoPtr, (HDC)wParam);
5831
5832 case WM_GETDLGCODE:
5834
5835 case WM_GETFONT:
5836 return TREEVIEW_GetFont(infoPtr);
5837
5838 case WM_HSCROLL:
5839 return TREEVIEW_HScroll(infoPtr, wParam);
5840
5841 case WM_KEYDOWN:
5842#ifndef __REACTOS__
5843 case WM_SYSKEYDOWN:
5844#endif
5845 return TREEVIEW_KeyDown(infoPtr, wParam);
5846
5847 case WM_KILLFOCUS:
5848 return TREEVIEW_KillFocus(infoPtr);
5849
5850 case WM_LBUTTONDBLCLK:
5851 return TREEVIEW_LButtonDoubleClick(infoPtr, lParam);
5852
5853 case WM_LBUTTONDOWN:
5854 return TREEVIEW_LButtonDown(infoPtr, lParam);
5855
5856 /* WM_MBUTTONDOWN */
5857
5858 case WM_MOUSELEAVE:
5859 return TREEVIEW_MouseLeave(infoPtr);
5860
5861 case WM_MOUSEMOVE:
5862 return TREEVIEW_MouseMove(infoPtr, lParam);
5863
5864 case WM_NCLBUTTONDOWN:
5865 if (infoPtr->hwndEdit)
5866 SetFocus(infoPtr->hwnd);
5867 goto def;
5868
5869 case WM_NCPAINT:
5870 return TREEVIEW_NCPaint (infoPtr, (HRGN)wParam, lParam);
5871
5872 case WM_NOTIFY:
5873 return TREEVIEW_Notify(infoPtr, wParam, lParam);
5874
5875 case WM_NOTIFYFORMAT:
5876 return TREEVIEW_NotifyFormat(infoPtr, (HWND)wParam, (UINT)lParam);
5877
5878 case WM_PRINTCLIENT:
5879 return TREEVIEW_PrintClient(infoPtr, (HDC)wParam, lParam);
5880
5881 case WM_PAINT:
5882 return TREEVIEW_Paint(infoPtr, (HDC)wParam);
5883
5884 case WM_RBUTTONDOWN:
5885 return TREEVIEW_RButtonDown(infoPtr, lParam);
5886
5887 case WM_SETCURSOR:
5888 return TREEVIEW_SetCursor(infoPtr, wParam, lParam);
5889
5890 case WM_SETFOCUS:
5891 return TREEVIEW_SetFocus(infoPtr);
5892
5893 case WM_SETFONT:
5894 return TREEVIEW_SetFont(infoPtr, (HFONT)wParam, (BOOL)lParam);
5895
5896 case WM_SETREDRAW:
5897 return TREEVIEW_SetRedraw(infoPtr, wParam);
5898
5899 case WM_SIZE:
5900 return TREEVIEW_Size(infoPtr, wParam, lParam);
5901
5902 case WM_STYLECHANGED:
5903 return TREEVIEW_StyleChanged(infoPtr, wParam, lParam);
5904
5905 case WM_SYSCOLORCHANGE:
5907 return 0;
5908
5909 case WM_TIMER:
5910 return TREEVIEW_HandleTimer(infoPtr, wParam);
5911
5912 case WM_THEMECHANGED:
5913 return TREEVIEW_ThemeChanged (infoPtr);
5914
5915 case WM_VSCROLL:
5916 return TREEVIEW_VScroll(infoPtr, wParam);
5917
5918 /* WM_WININICHANGE */
5919
5920 case WM_MOUSEWHEEL:
5921 return TREEVIEW_MouseWheel(infoPtr, wParam, lParam);
5922
5923 case WM_DRAWITEM:
5924 TRACE("drawItem\n");
5925 goto def;
5926
5927 default:
5928 /* This mostly catches MFC and Delphi messages. :( */
5929 if ((uMsg >= WM_USER) && (uMsg < WM_APP) && !COMCTL32_IsReflectedMessage(uMsg))
5930 TRACE("Unknown msg %04x wp=%08lx lp=%08lx\n", uMsg, wParam, lParam);
5931def:
5932 return DefWindowProcW(hwnd, uMsg, wParam, lParam);
5933 }
5934}
5935
5936
5937/* Class Registration ***************************************************/
5938
5939VOID
5941{
5942 WNDCLASSW wndClass;
5943
5944 TRACE("\n");
5945
5946 ZeroMemory(&wndClass, sizeof(WNDCLASSW));
5947 wndClass.style = CS_GLOBALCLASS | CS_DBLCLKS;
5949 wndClass.cbClsExtra = 0;
5950 wndClass.cbWndExtra = sizeof(TREEVIEW_INFO *);
5951
5952 wndClass.hCursor = LoadCursorW(0, (LPWSTR)IDC_ARROW);
5953 wndClass.hbrBackground = 0;
5954 wndClass.lpszClassName = WC_TREEVIEWW;
5955
5956 RegisterClassW(&wndClass);
5957}
5958
5959
5960VOID
5962{
5964}
5965
5966
5967/* Tree Verification ****************************************************/
5968
5969static inline void
5971
5972static inline void TREEVIEW_VerifyItemCommon(TREEVIEW_INFO *infoPtr,
5973 const TREEVIEW_ITEM *item)
5974{
5975 assert(infoPtr != NULL);
5976 assert(item != NULL);
5977
5978 /* both NULL, or both non-null */
5979 assert((item->firstChild == NULL) == (item->lastChild == NULL));
5980
5981 assert(item->firstChild != item);
5982 assert(item->lastChild != item);
5983
5984 if (item->firstChild)
5985 {
5986 assert(item->firstChild->parent == item);
5987 assert(item->firstChild->prevSibling == NULL);
5988 }
5989
5990 if (item->lastChild)
5991 {
5992 assert(item->lastChild->parent == item);
5993 assert(item->lastChild->nextSibling == NULL);
5994 }
5995
5996 assert(item->nextSibling != item);
5997 if (item->nextSibling)
5998 {
5999 assert(item->nextSibling->parent == item->parent);
6000 assert(item->nextSibling->prevSibling == item);
6001 }
6002
6003 assert(item->prevSibling != item);
6004 if (item->prevSibling)
6005 {
6006 assert(item->prevSibling->parent == item->parent);
6007 assert(item->prevSibling->nextSibling == item);
6008 }
6009}
6010
6011static inline void
6013{
6014 assert(item != NULL);
6015
6016 assert(item->parent != NULL);
6017 assert(item->parent != item);
6018 assert(item->iLevel == item->parent->iLevel + 1);
6019
6020 assert(DPA_GetPtrIndex(infoPtr->items, item) != -1);
6021
6023
6024 TREEVIEW_VerifyChildren(infoPtr, item);
6025}
6026
6027static inline void
6029{
6030 const TREEVIEW_ITEM *child;
6031 assert(item != NULL);
6032
6033 for (child = item->firstChild; child != NULL; child = child->nextSibling)
6034 TREEVIEW_VerifyItem(infoPtr, child);
6035}
6036
6037static inline void
6039{
6040 TREEVIEW_ITEM *root = infoPtr->root;
6041
6042 assert(root != NULL);
6043 assert(root->iLevel == -1);
6044 assert(root->parent == NULL);
6045 assert(root->prevSibling == NULL);
6046
6048
6049 TREEVIEW_VerifyChildren(infoPtr, root);
6050}
6051
6052static void
6054{
6055 if (!TRACE_ON(treeview)) return;
6056
6057 assert(infoPtr != NULL);
6058 TREEVIEW_VerifyRoot(infoPtr);
6059}
static HDC hDC
Definition: 3dtext.c:33
static HFONT hfont
#define VOID
Definition: acefi.h:82
Arabic default style
Definition: afstyles.h:94
static int state
Definition: maze.c:121
static void * heap_alloc(size_t len)
Definition: appwiz.h:66
static BOOL heap_free(void *mem)
Definition: appwiz.h:76
static void * heap_realloc(void *mem, size_t len)
Definition: appwiz.h:71
FORCEINLINE VOID SetPixel(_In_ ULONG Left, _In_ ULONG Top, _In_ UCHAR Color)
Definition: arm.h:55
static const char * wine_dbgstr_rect(const RECT *prc)
Definition: atltest.h:160
#define msg(x)
Definition: auth_time.c:54
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
void user(int argc, const char *argv[])
Definition: cmds.c:1350
HFONT hFont
Definition: main.c:53
#define ARRAY_SIZE(A)
Definition: main.h:33
#define FIXME(fmt,...)
Definition: debug.h:111
#define WARN(fmt,...)
Definition: debug.h:112
#define ERR(fmt,...)
Definition: debug.h:110
HBITMAP hbmp
Definition: list.h:37
WPARAM wParam
Definition: combotst.c:138
HWND hwndEdit
Definition: combotst.c:65
LPARAM lParam
Definition: combotst.c:139
BOOL COMCTL32_IsReflectedMessage(UINT uMsg) DECLSPEC_HIDDEN
Definition: commctrl.c:1748
HWND COMCTL32_CreateToolTip(HWND) DECLSPEC_HIDDEN
Definition: commctrl.c:1544
VOID COMCTL32_RefreshSysColors(void) DECLSPEC_HIDDEN
Definition: commctrl.c:1586
COMCTL32_SysColor comctl32_color
Definition: commctrl.c:82
BOOL WINAPI _TrackMouseEvent(TRACKMOUSEEVENT *ptme)
Definition: commctrl.c:1207
int selection
Definition: ctm.c:92
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
static const struct @249 state_table[]
unsigned int idx
Definition: utils.c:41
BOOL WINAPI DPA_Sort(HDPA hdpa, PFNDPACOMPARE pfnCompare, LPARAM lParam)
Definition: dpa.c:813
VOID WINAPI DPA_EnumCallback(HDPA hdpa, PFNDPAENUMCALLBACK enumProc, LPVOID lParam)
Definition: dpa.c:969
INT WINAPI DPA_GetPtrIndex(HDPA hdpa, LPCVOID p)
Definition: dpa.c:561
LPVOID WINAPI DPA_DeletePtr(HDPA hdpa, INT i)
Definition: dpa.c:677
BOOL WINAPI DPA_Destroy(HDPA hdpa)
Definition: dpa.c:396
HDPA WINAPI DPA_Create(INT nGrow)
Definition: dpa.c:950
INT WINAPI DPA_InsertPtr(HDPA hdpa, INT i, LPVOID p)
Definition: dpa.c:591
BOOL WINAPI ImageList_Draw(HIMAGELIST himl, INT i, HDC hdc, INT x, INT y, UINT fStyle)
Definition: imagelist.c:1228
INT WINAPI ImageList_Add(HIMAGELIST himl, HBITMAP hbmImage, HBITMAP hbmMask)
Definition: imagelist.c:448
BOOL WINAPI ImageList_DrawEx(HIMAGELIST himl, INT i, HDC hdc, INT x, INT y, INT dx, INT dy, COLORREF rgbBk, COLORREF rgbFg, UINT fStyle)
Definition: imagelist.c:1264
INT WINAPI ImageList_AddMasked(HIMAGELIST himl, HBITMAP hBitmap, COLORREF clrMask)
Definition: imagelist.c:563
HIMAGELIST WINAPI ImageList_Create(INT cx, INT cy, UINT flags, INT cInitial, INT cGrow)
Definition: imagelist.c:804
BOOL WINAPI ImageList_GetIconSize(HIMAGELIST himl, INT *cx, INT *cy)
Definition: imagelist.c:2037
static LRESULT TREEVIEW_GetLineColor(const TREEVIEW_INFO *infoPtr)
Definition: treeview.c:1935
static UINT TREEVIEW_NaturalHeight(const TREEVIEW_INFO *infoPtr)
Definition: treeview.c:1734
static LRESULT TREEVIEW_SetScrollTime(TREEVIEW_INFO *infoPtr, UINT uScrollTime)
Definition: treeview.c:1701
static LRESULT TREEVIEW_GetTextColor(const TREEVIEW_INFO *infoPtr)
Definition: treeview.c:1953
static LRESULT TREEVIEW_SetIndent(TREEVIEW_INFO *infoPtr, UINT newIndent)
Definition: treeview.c:1642
static LRESULT TREEVIEW_KillFocus(const TREEVIEW_INFO *infoPtr)
Definition: treeview.c:5648
static LRESULT TREEVIEW_VScroll(TREEVIEW_INFO *infoPtr, WPARAM wParam)
Definition: treeview.c:4899
#define TV_HSCROLL
Definition: treeview.c:178
static LRESULT TREEVIEW_SetInsertMarkColor(TREEVIEW_INFO *infoPtr, COLORREF color)
Definition: treeview.c:2004
static LRESULT TREEVIEW_Size(TREEVIEW_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
Definition: treeview.c:5527
#define MINIMUM_INDENT
Definition: treeview.c:194
static LRESULT TREEVIEW_GetImageList(const TREEVIEW_INFO *infoPtr, WPARAM wParam)
Definition: treeview.c:1712
static LRESULT TREEVIEW_HScroll(TREEVIEW_INFO *, WPARAM)
Definition: treeview.c:4970
static BOOL TREEVIEW_Toggle(TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *item, BOOL user)
Definition: treeview.c:3600
static LRESULT TREEVIEW_Paint(TREEVIEW_INFO *infoPtr, HDC hdc_ref)
Definition: treeview.c:3033
static void TREEVIEW_UnlinkItem(const TREEVIEW_ITEM *item)
Definition: treeview.c:1459
static VOID TREEVIEW_Invalidate(const TREEVIEW_INFO *, const TREEVIEW_ITEM *)
Definition: treeview.c:2968
#define TEXT_CALLBACK_SIZE
Definition: treeview.c:190
static BOOL TREEVIEW_Expand(TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *item, BOOL partial, BOOL user)
Definition: treeview.c:3452
static TREEVIEW_ITEM * TREEVIEW_GetListItem(const TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *item, LONG count)
Definition: treeview.c:466
static INT TREEVIEW_CountChildren(const TREEVIEW_ITEM *item)
Definition: treeview.c:3133
static LRESULT TREEVIEW_SetTextColor(TREEVIEW_INFO *infoPtr, COLORREF color)
Definition: treeview.c:1960
static LRESULT TREEVIEW_SetInsertMark(TREEVIEW_INFO *infoPtr, BOOL wParam, HTREEITEM item)
Definition: treeview.c:2016
static LRESULT TREEVIEW_SelectItem(TREEVIEW_INFO *infoPtr, INT wParam, HTREEITEM item)
Definition: treeview.c:4568
#define TV_EDIT_TIMER
Definition: treeview.c:187
static INT get_notifycode(const TREEVIEW_INFO *infoPtr, INT code)
Definition: treeview.c:499
#define ISVISIBLE(x)
Definition: treeview.c:200
static LRESULT TREEVIEW_GetItemT(const TREEVIEW_INFO *infoPtr, LPTVITEMEXW tvItem, BOOL isW)
Definition: treeview.c:2088
static void TREEVIEW_RecalculateVisibleOrder(TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *start)
Definition: treeview.c:929
static TREEVIEW_ITEM * TREEVIEW_HitTest(const TREEVIEW_INFO *infoPtr, LPTVHITTESTINFO lpht)
Definition: treeview.c:3681
static BOOL TREEVIEW_IsItemHit(const TREEVIEW_INFO *infoPtr, const TVHITTESTINFO *ht)
Definition: treeview.c:364
static LRESULT TREEVIEW_GetFont(const TREEVIEW_INFO *infoPtr)
Definition: treeview.c:1883
static LRESULT TREEVIEW_ExpandMsg(TREEVIEW_INFO *infoPtr, UINT flag, HTREEITEM item)
Definition: treeview.c:3629
static LRESULT TREEVIEW_SetUnicodeFormat(TREEVIEW_INFO *infoPtr, BOOL fUnicode)
Definition: treeview.c:1681
static LRESULT TREEVIEW_GetUnicodeFormat(const TREEVIEW_INFO *infoPtr)
Definition: treeview.c:1689
static LRESULT TREEVIEW_DeleteItem(TREEVIEW_INFO *infoPtr, HTREEITEM item)
Definition: treeview.c:1517
static void TREEVIEW_InsertAfter(TREEVIEW_ITEM *newItem, TREEVIEW_ITEM *sibling, TREEVIEW_ITEM *parent)
Definition: treeview.c:1089
static LRESULT TREEVIEW_InsertItemT(TREEVIEW_INFO *infoPtr, const TVINSERTSTRUCTW *ptdi, BOOL isW)
Definition: treeview.c:1231
static void TREEVIEW_VerifyItem(TREEVIEW_INFO *infoPtr, const TREEVIEW_ITEM *item)
Definition: treeview.c:6012
static LRESULT TREEVIEW_SetImageList(TREEVIEW_INFO *infoPtr, UINT type, HIMAGELIST himlNew)
Definition: treeview.c:1764
static void TREEVIEW_Refresh(TREEVIEW_INFO *infoPtr, HDC hdc, const RECT *rc)
Definition: treeview.c:2910
static VOID TREEVIEW_UpdateScrollBars(TREEVIEW_INFO *infoPtr)
Definition: treeview.c:2756
static void TREEVIEW_RemoveTree(TREEVIEW_INFO *infoPtr)
Definition: treeview.c:1509
static BOOL TREEVIEW_SendCustomDrawItemNotify(const TREEVIEW_INFO *infoPtr, HDC hdc, TREEVIEW_ITEM *item, UINT uItemDrawState, NMTVCUSTOMDRAW *nmcdhdr)
Definition: treeview.c:650
#define CALLBACK_MASK_ALL
Definition: treeview.c:196
#define KEY_DELAY
Definition: treeview.c:174
static LRESULT TREEVIEW_SetRedraw(TREEVIEW_INFO *infoPtr, WPARAM wParam)
Definition: treeview.c:1620
static LRESULT TREEVIEW_EraseBackground(const TREEVIEW_INFO *infoPtr, HDC hdc)
Definition: treeview.c:2897
static BOOL TREEVIEW_NCPaint(const TREEVIEW_INFO *infoPtr, HRGN region, LPARAM lParam)
Definition: treeview.c:5461
static INT CALLBACK TREEVIEW_ResetTextWidth(LPVOID pItem, LPVOID unused)
Definition: treeview.c:1891
VOID(* TREEVIEW_ItemEnumFunc)(TREEVIEW_INFO *, TREEVIEW_ITEM *, LPVOID)
Definition: treeview.c:210
static INT TREEVIEW_ProcessLetterKeys(TREEVIEW_INFO *infoPtr, WPARAM charCode, LPARAM keyData)
Definition: treeview.c:4627
static LRESULT TREEVIEW_SetItemT(TREEVIEW_INFO *infoPtr, const TVITEMEXW *tvItem, BOOL isW)
Definition: treeview.c:2189
static INT WINAPI TREEVIEW_SortOnName(TREEVIEW_ITEM *first, TREEVIEW_ITEM *second, const TREEVIEW_INFO *infoPtr)
Definition: treeview.c:3115
static LRESULT TREEVIEW_GetScrollTime(const TREEVIEW_INFO *infoPtr)
Definition: treeview.c:1695
static void TREEVIEW_RemoveAllChildren(TREEVIEW_INFO *infoPtr, const TREEVIEW_ITEM *parentItem)
Definition: treeview.c:1440
static void TREEVIEW_VerifyRoot(TREEVIEW_INFO *infoPtr)
Definition: treeview.c:6038
static LRESULT TREEVIEW_TrackMouse(const TREEVIEW_INFO *infoPtr, POINT pt)
Definition: treeview.c:4113
static LRESULT TREEVIEW_GetEditControl(const TREEVIEW_INFO *infoPtr)
Definition: treeview.c:3762
static LRESULT TREEVIEW_GetIndent(const TREEVIEW_INFO *infoPtr)
Definition: treeview.c:1635
static HWND TREEVIEW_EditLabel(TREEVIEW_INFO *infoPtr, HTREEITEM hItem)
Definition: treeview.c:3906
static LRESULT TREEVIEW_Sort(TREEVIEW_INFO *infoPtr, HTREEITEM parent, LPTVSORTCB pSort)
Definition: treeview.c:3178
static LRESULT TREEVIEW_Notify(const TREEVIEW_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
Definition: treeview.c:5504
static LRESULT TREEVIEW_LButtonDoubleClick(TREEVIEW_INFO *infoPtr, LPARAM lParam)
Definition: treeview.c:4162
static HFONT TREEVIEW_CreateUnderlineFont(HFONT hOrigFont)
Definition: treeview.c:304
static LRESULT CALLBACK TREEVIEW_Edit_SubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
Definition: treeview.c:3768
static void TREEVIEW_FillBkgnd(const TREEVIEW_INFO *infoPtr, HDC hdc, const RECT *rc)
Definition: treeview.c:2885
static int TREEVIEW_GetItemIndex(const TREEVIEW_INFO *infoPtr, HTREEITEM handle)
Definition: treeview.c:235
static LRESULT TREEVIEW_GetInsertMarkColor(const TREEVIEW_INFO *infoPtr)
Definition: treeview.c:1997
static LRESULT TREEVIEW_SortChildrenCB(TREEVIEW_INFO *infoPtr, LPTVSORTCB pSort)
Definition: treeview.c:3299
static LRESULT TREEVIEW_MouseLeave(TREEVIEW_INFO *infoPtr)
Definition: treeview.c:5399
static LRESULT TREEVIEW_SetBkColor(TREEVIEW_INFO *infoPtr, COLORREF newColor)
Definition: treeview.c:1982
static LRESULT TREEVIEW_GetItemRect(const TREEVIEW_INFO *infoPtr, BOOL fTextRect, LPRECT lpRect)
Definition: treeview.c:2037
#define TVHEIGHT_MIN
Definition: treeview.c:1729
VOID TREEVIEW_Register(void)
Definition: treeview.c:5940
static LRESULT TREEVIEW_DoSelectItem(TREEVIEW_INFO *, INT, HTREEITEM, INT)
Definition: treeview.c:4480
static VOID TREEVIEW_SendExpanded(const TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *item, UINT action)
Definition: treeview.c:3328
static LRESULT TREEVIEW_KeyDown(TREEVIEW_INFO *infoPtr, WPARAM wParam)
Definition: treeview.c:5283
static void TREEVIEW_ResetImageStateIndex(TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *item)
Definition: treeview.c:3017
static TREEVIEW_ITEM * TREEVIEW_GetPrevListItem(const TREEVIEW_INFO *infoPtr, const TREEVIEW_ITEM *tvItem)
Definition: treeview.c:402
static LRESULT TREEVIEW_EnsureVisible(TREEVIEW_INFO *, HTREEITEM, BOOL)
Definition: treeview.c:4739
static LRESULT TREEVIEW_CreateDragImage(TREEVIEW_INFO *infoPtr, LPARAM lParam)
Definition: treeview.c:4406
struct tagTREEVIEW_INFO TREEVIEW_INFO
static LRESULT TREEVIEW_PrintClient(TREEVIEW_INFO *infoPtr, HDC hdc, DWORD options)
Definition: treeview.c:3076
static HFONT TREEVIEW_FontForItem(const TREEVIEW_INFO *infoPtr, const TREEVIEW_ITEM *item)
Definition: treeview.c:325
static BOOL item_changed(const TREEVIEW_ITEM *tiOld, const TREEVIEW_ITEM *tiNew, const TVITEMEXW *tvChange)
Definition: treeview.c:241
static void TREEVIEW_SingleExpand(TREEVIEW_INFO *infoPtr, HTREEITEM selection, HTREEITEM item)
Definition: treeview.c:3569
static LRESULT TREEVIEW_SetToolTips(TREEVIEW_INFO *infoPtr, HWND hwndTT)
Definition: treeview.c:1669
static LRESULT TREEVIEW_ScrollKeyDown(TREEVIEW_INFO *infoPtr, WPARAM key)
Definition: treeview.c:5233
static LRESULT TREEVIEW_SetCursor(const TREEVIEW_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
Definition: treeview.c:5599
static LRESULT TREEVIEW_Destroy(TREEVIEW_INFO *infoPtr)
Definition: treeview.c:5200
static LRESULT TREEVIEW_GetNextItem(const TREEVIEW_INFO *infoPtr, UINT which, HTREEITEM item)
Definition: treeview.c:2255
#define GETINSCOLOR(x)
Definition: treeview.c:205
static LRESULT TREEVIEW_RButtonDown(TREEVIEW_INFO *infoPtr, LPARAM lParam)
Definition: treeview.c:4356
static HDPA TREEVIEW_BuildChildDPA(const TREEVIEW_ITEM *item)
Definition: treeview.c:3147
static LRESULT TREEVIEW_SetFont(TREEVIEW_INFO *infoPtr, HFONT hFont, BOOL bRedraw)
Definition: treeview.c:1901
static VOID TREEVIEW_UpdateSubTree(const TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *root)
Definition: treeview.c:965
static TREEVIEW_ITEM * TREEVIEW_GetNextListItem(const TREEVIEW_INFO *infoPtr, const TREEVIEW_ITEM *tvItem)
Definition: treeview.c:427
static void TREEVIEW_InsertBefore(TREEVIEW_ITEM *newItem, TREEVIEW_ITEM *sibling, TREEVIEW_ITEM *parent)
Definition: treeview.c:1057
static INT TREEVIEW_NotifyFormat(TREEVIEW_INFO *infoPtr, HWND hwndFrom, UINT nCommand)
Definition: treeview.c:842
static BOOL TREEVIEW_IsFullRowSelect(const TREEVIEW_INFO *infoPtr)
Definition: treeview.c:358
static const WCHAR themeClass[]
Definition: treeview.c:207
static TREEVIEW_INFO * TREEVIEW_GetInfoPtr(HWND hwnd)
Definition: treeview.c:228
static LRESULT TREEVIEW_SortChildren(TREEVIEW_INFO *infoPtr, LPARAM lParam)
Definition: treeview.c:3309
static LRESULT TREEVIEW_HandleTimer(TREEVIEW_INFO *infoPtr, WPARAM wParam)
Definition: treeview.c:4089
static VOID TREEVIEW_TVItemFromItem(const TREEVIEW_INFO *infoPtr, UINT mask, TVITEMW *tvItem, TREEVIEW_ITEM *item)
Definition: treeview.c:540
static LRESULT TREEVIEW_Create(HWND hwnd, const CREATESTRUCTW *lpcs)
Definition: treeview.c:5092
static VOID TREEVIEW_ComputeItemRect(const TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *item)
Definition: treeview.c:915
static LRESULT TREEVIEW_GetCount(const TREEVIEW_INFO *infoPtr)
Definition: treeview.c:2331
static INT WINAPI TREEVIEW_CallBackCompare(const TREEVIEW_ITEM *first, const TREEVIEW_ITEM *second, const TVSORTCB *pCallBackSort)
Definition: treeview.c:3102
static BOOL TREEVIEW_Collapse(TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *item, BOOL bRemoveChildren, BOOL bUser)
Definition: treeview.c:3341
#define TV_VSCROLL
Definition: treeview.c:179
static const char * TREEVIEW_ItemName(const TREEVIEW_ITEM *item)
Definition: treeview.c:336
static BOOL TREEVIEW_DoSetItemT(const TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *item, const TVITEMEXW *tvItem, BOOL isW)
Definition: treeview.c:1117
static TREEVIEW_ITEM * TREEVIEW_AllocateItem(const TREEVIEW_INFO *infoPtr)
Definition: treeview.c:1003
struct _TREEITEM TREEVIEW_ITEM
static LRESULT TREEVIEW_ThemeChanged(const TREEVIEW_INFO *infoPtr)
Definition: treeview.c:5659
static BOOL TREEVIEW_BeginLabelEditNotify(const TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *editItem)
Definition: treeview.c:686
static void TREEVIEW_DrawItemLines(const TREEVIEW_INFO *infoPtr, HDC hdc, const TREEVIEW_ITEM *item)
Definition: treeview.c:2379
static LRESULT TREEVIEW_GetToolTips(const TREEVIEW_INFO *infoPtr)
Definition: treeview.c:1662
#define SCROLL_ENTRY(dir, code)
static BOOL TREEVIEW_ValidItem(const TREEVIEW_INFO *infoPtr, HTREEITEM handle)
Definition: treeview.c:282
static void TREEVIEW_FreeItem(TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *item)
Definition: treeview.c:1031
static VOID TREEVIEW_SetFirstVisible(TREEVIEW_INFO *, TREEVIEW_ITEM *, BOOL)
Definition: treeview.c:4836
static void TREEVIEW_UpdateDispInfo(const TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *item, UINT mask)
Definition: treeview.c:703
static BOOL TREEVIEW_HasChildren(const TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *item)
Definition: treeview.c:834
static void TREEVIEW_VerifyItemCommon(TREEVIEW_INFO *infoPtr, const TREEVIEW_ITEM *item)
Definition: treeview.c:5972
static BOOL TREEVIEW_SendRealNotify(const TREEVIEW_INFO *infoPtr, UINT code, NMHDR *hdr)
Definition: treeview.c:521
static VOID TREEVIEW_ComputeTextWidth(const TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *item, HDC hDC)
Definition: treeview.c:881
static LRESULT TREEVIEW_GetItemHeight(const TREEVIEW_INFO *infoPtr)
Definition: treeview.c:1875
static BOOL TREEVIEW_SendExpanding(const TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *item, UINT action)
Definition: treeview.c:3318
static void TREEVIEW_DrawItem(const TREEVIEW_INFO *infoPtr, HDC hdc, TREEVIEW_ITEM *item)
Definition: treeview.c:2525
static LRESULT TREEVIEW_Command(TREEVIEW_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
Definition: treeview.c:3829
#define TVHEIGHT_FONT_ADJUST
Definition: treeview.c:1730
static void TREEVIEW_RemoveItem(TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *item)
Definition: treeview.c:1486
static LRESULT TREEVIEW_SetItemHeight(TREEVIEW_INFO *infoPtr, INT newHeight)
Definition: treeview.c:1840
static void TREEVIEW_VerifyChildren(TREEVIEW_INFO *infoPtr, const TREEVIEW_ITEM *item)
Definition: treeview.c:6028
static LRESULT TREEVIEW_GetVisibleCount(const TREEVIEW_INFO *infoPtr)
Definition: treeview.c:2079
static HFONT TREEVIEW_CreateBoldFont(HFONT hOrigFont)
Definition: treeview.c:294
static BOOL TREEVIEW_SendTreeviewDnDNotify(const TREEVIEW_INFO *infoPtr, UINT code, HTREEITEM dragItem, POINT pt)
Definition: treeview.c:604
#define GETLINECOLOR(x)
Definition: treeview.c:202
static LRESULT TREEVIEW_MouseMove(TREEVIEW_INFO *infoPtr, LPARAM lParam)
Definition: treeview.c:5409
static LRESULT TREEVIEW_GetItemState(const TREEVIEW_INFO *infoPtr, HTREEITEM item, UINT mask)
Definition: treeview.c:2244
static HFONT TREEVIEW_CreateBoldUnderlineFont(HFONT hfont)
Definition: treeview.c:314
static void TREEVIEW_InvalidateItem(const TREEVIEW_INFO *infoPtr, const TREEVIEW_ITEM *item)
Definition: treeview.c:2962
static VOID TREEVIEW_ComputeItemInternalMetrics(const TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *item)
Definition: treeview.c:866
#define TV_EDIT_TIMER_SET
Definition: treeview.c:188
static VOID TREEVIEW_ExpandAll(TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *item)
Definition: treeview.c:3611
static LRESULT TREEVIEW_MouseWheel(TREEVIEW_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
Definition: treeview.c:5045
static TREEVIEW_ITEM * TREEVIEW_GetLastListItem(const TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *item)
Definition: treeview.c:379
static BOOL TREEVIEW_SendSimpleNotify(const TREEVIEW_INFO *infoPtr, UINT code)
Definition: treeview.c:533
static void TREEVIEW_InitCheckboxes(TREEVIEW_INFO *infoPtr)
Definition: treeview.c:2977
static LRESULT TREEVIEW_GetBkColor(const TREEVIEW_INFO *infoPtr)
Definition: treeview.c:1975
#define GETBKCOLOR(x)
Definition: treeview.c:203
static LRESULT WINAPI TREEVIEW_WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
Definition: treeview.c:5669
#define GETTXTCOLOR(x)
Definition: treeview.c:204
static LRESULT TREEVIEW_EndEditLabelNow(TREEVIEW_INFO *infoPtr, BOOL bCancel)
Definition: treeview.c:4008
static BOOL TREEVIEW_SendTreeviewNotify(const TREEVIEW_INFO *infoPtr, UINT code, UINT action, UINT mask, HTREEITEM oldItem, HTREEITEM newItem)
Definition: treeview.c:573
static TREEVIEW_ITEM * TREEVIEW_HitTestPoint(const TREEVIEW_INFO *infoPtr, POINT pt)
Definition: treeview.c:3659
static BOOL TREEVIEW_IsChildOf(const TREEVIEW_ITEM *parent, const TREEVIEW_ITEM *child)
Definition: treeview.c:346
static void TREEVIEW_VerifyTree(TREEVIEW_INFO *infoPtr)
Definition: treeview.c:6053
#define STATEIMAGEINDEX(x)
Definition: treeview.c:198
static LRESULT TREEVIEW_SetLineColor(TREEVIEW_INFO *infoPtr, COLORREF color)
Definition: treeview.c:1942
static BOOL TREEVIEW_SendCustomDrawNotify(const TREEVIEW_INFO *infoPtr, DWORD dwDrawStage, HDC hdc, RECT rc)
Definition: treeview.c:625
static LRESULT TREEVIEW_LButtonDown(TREEVIEW_INFO *infoPtr, LPARAM lParam)
Definition: treeview.c:4229
VOID TREEVIEW_Unregister(void)
Definition: treeview.c:5961
static VOID TREEVIEW_ToggleItemState(const TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *item)
Definition: treeview.c:2347
static LRESULT TREEVIEW_SetFocus(TREEVIEW_INFO *infoPtr)
Definition: treeview.c:5632
static LRESULT TREEVIEW_StyleChanged(TREEVIEW_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
Definition: treeview.c:5548
#define CP_ACP
Definition: compat.h:109
#define __TRY
Definition: compat.h:80
#define TRACE_ON(x)
Definition: compat.h:75
#define MAX_PATH
Definition: compat.h:34
#define __ENDTRY
Definition: compat.h:82
#define CALLBACK
Definition: compat.h:35
#define WideCharToMultiByte
Definition: compat.h:111
#define MultiByteToWideChar
Definition: compat.h:110
#define __EXCEPT_PAGE_FAULT
Definition: compat.h:81
#define lstrcpynW
Definition: compat.h:738
#define lstrlenW
Definition: compat.h:750
DWORD WINAPI GetTickCount(VOID)
Definition: time.c:455
const WCHAR * action
Definition: action.c:7479
HRESULT WINAPI DrawThemeBackground(HTHEME hTheme, HDC hdc, int iPartId, int iStateId, const RECT *pRect, const RECT *pClipRect)
Definition: draw.c:128
BOOL WINAPI IsThemeBackgroundPartiallyTransparent(HTHEME hTheme, int iPartId, int iStateId)
Definition: draw.c:1883
HRESULT WINAPI DrawThemeParentBackground(HWND hwnd, HDC hdc, RECT *prc)
Definition: draw.c:72
HTHEME WINAPI OpenThemeData(HWND hwnd, LPCWSTR classlist)
Definition: system.c:835
HTHEME WINAPI GetWindowTheme(HWND hwnd)
Definition: system.c:851
HRESULT WINAPI CloseThemeData(HTHEME hTheme)
Definition: system.c:950
struct png_info_def *typedef unsigned char **typedef struct png_info_def *typedef struct png_info_def *typedef struct png_info_def *typedef unsigned char ** row
Definition: typeof.h:78
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
unsigned short(__cdecl typeof(TIFFCurrentDirectory))(struct tiff *)
Definition: typeof.h:94
#define assert(x)
Definition: debug.h:53
#define pt(x, y)
Definition: drawing.c:79
r parent
Definition: btrfs.c:3010
int do_select(int n, fd_set_bits *fds, long *timeout)
int align(int length, int align)
Definition: dsound8.c:36
#define WM_APP
Definition: eventvwr.h:73
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned short WORD
Definition: ntddk_ex.h:93
pKey DeleteObject()
GLuint start
Definition: gl.h:1545
GLint level
Definition: gl.h:1546
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
GLint GLint GLsizei GLsizei height
Definition: gl.h:1546
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLint GLint GLsizei width
Definition: gl.h:1546
GLsizeiptr size
Definition: glext.h:5919
GLuint buffer
Definition: glext.h:5915
GLuint color
Definition: glext.h:6243
GLenum GLint GLuint mask
Definition: glext.h:6028
GLdouble GLdouble right
Definition: glext.h:10859
GLint left
Definition: glext.h:7726
const GLint * first
Definition: glext.h:5794
GLuint GLdouble GLdouble GLint GLint order
Definition: glext.h:11194
GLenum GLsizei len
Definition: glext.h:6722
GLintptr offset
Definition: glext.h:5920
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean flag
Definition: glfuncs.h:52
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
static const struct newhuff ht[]
Definition: huffman.h:296
_Check_return_ _CRTIMP int __cdecl isalnum(_In_ int _C)
#define INT_MAX
Definition: limits.h:40
char hdr[14]
Definition: iptest.cpp:33
#define debugstr_a
Definition: kernel32.h:31
#define debugstr_w
Definition: kernel32.h:32
int WINAPI lstrcmpiW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:194
int WINAPI lstrcmpW(LPCWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:170
static const WCHAR dc[]
static PVOID ptr
Definition: dispmode.c:27
HDC hdc
Definition: main.c:9
static HBITMAP
Definition: button.c:44
static HINSTANCE hinst
Definition: edit.c:551
static HDC
Definition: imagelist.c:92
static IPrintDialogCallback callback
Definition: printdlg.c:326
static DWORD *static HFONT(WINAPI *pCreateFontIndirectExA)(const ENUMLOGFONTEXDVA *)
static float(__cdecl *square_half_float)(float x
static HWND child
Definition: cursoricon.c:298
static ATOM item
Definition: dde.c:856
static HTHEME(WINAPI *pOpenThemeDataEx)(HWND
WORD unused[29]
Definition: crypt.c:1155
#define min(a, b)
Definition: monoChain.cc:55
Definition: mk_font.cpp:20
unsigned int UINT
Definition: ndis.h:50
#define LPVOID
Definition: nt_native.h:45
_In_ HBITMAP hbm
Definition: ntgdi.h:2776
INT WINAPI DrawTextW(HDC hdc, LPCWSTR str, INT count, LPRECT rect, UINT flags)
Definition: defwnd.c:16
#define LOWORD(l)
Definition: pedump.c:82
#define WS_CHILD
Definition: pedump.c:617
#define ES_WANTRETURN
Definition: pedump.c:676
#define WS_BORDER
Definition: pedump.c:625
#define WS_POPUP
Definition: pedump.c:616
#define ES_AUTOHSCROLL
Definition: pedump.c:672
short SHORT
Definition: pedump.c:59
long LONG
Definition: pedump.c:60
#define ES_LEFT
Definition: pedump.c:664
#define WS_CLIPSIBLINGS
Definition: pedump.c:618
#define CDDS_ITEMPOSTPAINT
Definition: commctrl.h:286
#define TVN_ENDLABELEDITA
Definition: commctrl.h:3711
#define TVSIL_STATE
Definition: commctrl.h:3444
#define TVM_GETCOUNT
Definition: commctrl.h:3431
#define TVN_SELCHANGINGW
Definition: commctrl.h:3646
#define I_IMAGECALLBACK
Definition: commctrl.h:2385
#define TVM_CREATEDRAGIMAGE
Definition: commctrl.h:3538
#define TVIF_INTEGRAL
Definition: commctrl.h:3274
#define TVHT_TORIGHT
Definition: commctrl.h:3535
#define TVN_ITEMEXPANDEDW
Definition: commctrl.h:3702
_Out_opt_ int _Out_opt_ int * cy
Definition: commctrl.h:586
#define TVHT_NOWHERE
Definition: commctrl.h:3524
#define TVE_COLLAPSERESET
Definition: commctrl.h:3426
#define TVHT_BELOW
Definition: commctrl.h:3534
#define TVS_TRACKSELECT
Definition: commctrl.h:3256
#define TVN_KEYDOWN
Definition: commctrl.h:3713
#define CDDS_ITEM
Definition: commctrl.h:284
#define TVGN_PARENT
Definition: commctrl.h:3455
#define ILD_NORMAL
Definition: commctrl.h:417
#define TVM_GETTOOLTIPS
Definition: commctrl.h:3560
#define TVS_LINESATROOT
Definition: commctrl.h:3249
#define TVN_BEGINRDRAGW
Definition: commctrl.h:3706
#define TVI_LAST
Definition: commctrl.h:3370
#define TVHT_ABOVE
Definition: commctrl.h:3533
#define TME_LEAVE
Definition: commctrl.h:4981
#define TVN_SETDISPINFOW
Definition: commctrl.h:3657
#define TVM_SORTCHILDRENCB
Definition: commctrl.h:3547
#define TVIF_TEXT
Definition: commctrl.h:3266
#define TVM_SETITEMW
Definition: commctrl.h:3493
#define TVHT_ONITEM
Definition: commctrl.h:3527
#define CDDS_ITEMPREPAINT
Definition: commctrl.h:285
#define TVGN_FIRSTVISIBLE
Definition: commctrl.h:3457
#define NM_DBLCLK
Definition: commctrl.h:131
#define TVN_ITEMEXPANDINGA
Definition: commctrl.h:3699
#define NM_SETCURSOR
Definition: commctrl.h:142
#define LPSTR_TEXTCALLBACKW
Definition: commctrl.h:2380
#define TVM_ENDEDITLABELNOW
Definition: commctrl.h:3550
#define TVN_BEGINLABELEDITA
Definition: commctrl.h:3709
#define TVGN_PREVIOUSVISIBLE
Definition: commctrl.h:3459
#define WC_EDITW
Definition: commctrl.h:4687
#define TVM_GETITEMW
Definition: commctrl.h:3486
#define TVIF_IMAGE
Definition: commctrl.h:3267
#define CLR_NONE
Definition: commctrl.h:319
#define TVE_EXPANDPARTIAL
Definition: commctrl.h:3425
#define TVM_GETITEMRECT
Definition: commctrl.h:3428
#define TVIS_EXPANDEDONCE
Definition: commctrl.h:3285
#define CDRF_NOTIFYITEMDRAW
Definition: commctrl.h:275
#define LPSTR_TEXTCALLBACKA
Definition: commctrl.h:2381
#define TVIF_EXPANDEDIMAGE
Definition: commctrl.h:3279
#define TVGN_LASTVISIBLE
Definition: commctrl.h:3462
#define TVM_SETTEXTCOLOR
Definition: commctrl.h:3577
#define TVHT_ONITEMINDENT
Definition: commctrl.h:3528
#define TVSIL_NORMAL
Definition: commctrl.h:3443
#define TVM_GETUNICODEFORMAT
Definition: commctrl.h:3568
#define TVN_GETINFOTIPW
Definition: commctrl.h:3715
#define TVIS_BOLD
Definition: commctrl.h:3283
#define TVM_GETISEARCHSTRINGW
Definition: commctrl.h:3554
#define TVN_SELCHANGEDW
Definition: commctrl.h:3648
#define TOOLTIPS_CLASSW
Definition: commctrl.h:1707
#define TVM_GETITEMHEIGHT
Definition: commctrl.h:3573
#define TVM_SETSCROLLTIME
Definition: commctrl.h:3583
#define TVN_BEGINRDRAGA
Definition: commctrl.h:3705
#define TVC_BYMOUSE
Definition: commctrl.h:3651
#define TVHT_ONITEMBUTTON
Definition: commctrl.h:3529
_Out_opt_ int * cx
Definition: commctrl.h:585
#define TVI_FIRST
Definition: commctrl.h:3369
#define TVS_SHOWSELALWAYS
Definition: commctrl.h:3252
#define CDIS_SELECTED
Definition: commctrl.h:291
#define TVIS_SELECTED
Definition: commctrl.h:3280
#define TVS_FULLROWSELECT
Definition: commctrl.h:3259
#define CDRF_NOTIFYPOSTPAINT
Definition: commctrl.h:274
#define TVSI_NOSINGLEEXPAND
Definition: commctrl.h:3464
struct _TREEITEM * HTREEITEM
Definition: commctrl.h:3264
#define TVHT_ONITEMLABEL
Definition: commctrl.h:3526
#define NM_CLICK
Definition: commctrl.h:130
#define NM_KILLFOCUS
Definition: commctrl.h:136
#define TVS_HASLINES
Definition: commctrl.h:3248
#define PGN_CALCSIZE
Definition: commctrl.h:4580
#define TVN_ITEMEXPANDEDA
Definition: commctrl.h:3701
#define TVE_EXPAND
Definition: commctrl.h:3423
#define TVGN_PREVIOUS
Definition: commctrl.h:3454
#define TVM_EDITLABELA
Definition: commctrl.h:3499
#define TVM_SETINSERTMARKCOLOR
Definition: commctrl.h:3587
#define TVI_ROOT
Definition: commctrl.h:3368
#define TVIS_CUT
Definition: commctrl.h:3281
#define NM_CUSTOMDRAW
Definition: commctrl.h:137
#define TVHT_ONITEMSTATEICON
Definition: commctrl.h:3531
#define TVS_NONEVENHEIGHT
Definition: commctrl.h:3261
#define TVN_GETDISPINFOW
Definition: commctrl.h:3655
#define TVM_GETEDITCONTROL
Definition: commctrl.h:3506
#define TVS_CHECKBOXES
Definition: commctrl.h:3255
#define TVE_TOGGLE
Definition: commctrl.h:3424
#define TVS_NOSCROLL
Definition: commctrl.h:3260
#define TVM_GETTEXTCOLOR
Definition: commctrl.h:3581
#define TVM_DELETEITEM
Definition: commctrl.h:3414
#define TVHT_ONITEMRIGHT
Definition: commctrl.h:3530
#define TVN_SELCHANGINGA
Definition: commctrl.h:3645
#define TVM_SORTCHILDREN
Definition: commctrl.h:3541
#define TVGN_DROPHILITE
Definition: commctrl.h:3460
#define TVM_SETBKCOLOR
Definition: commctrl.h:3575
#define TVM_SETINSERTMARK
Definition: commctrl.h:3564
#define TVIS_DROPHILITED
Definition: commctrl.h:3282
#define I_CHILDRENCALLBACK
Definition: commctrl.h:3293
#define TVC_UNKNOWN
Definition: commctrl.h:3650
#define CDIS_FOCUS
Definition: commctrl.h:295
#define TVN_BEGINDRAGW
Definition: commctrl.h:3704
#define NM_RETURN
Definition: commctrl.h:132
#define TVM_GETVISIBLECOUNT
Definition: commctrl.h:3509
#define TVM_SELECTITEM
Definition: commctrl.h:3478
#define WC_TREEVIEWW
Definition: commctrl.h:3243
#define TVN_DELETEITEMA
Definition: commctrl.h:3707
#define TVM_INSERTITEMW
Definition: commctrl.h:3408
int(CALLBACK * PFNDPACOMPARE)(void *p1, void *p2, LPARAM lParam)
Definition: commctrl.h:4852
#define CDRF_NEWFONT
Definition: commctrl.h:269
#define TVIF_HANDLE
Definition: commctrl.h:3270
#define WM_MOUSELEAVE
Definition: commctrl.h:4975
#define TVGN_ROOT
Definition: commctrl.h:3452
#define TVM_GETITEMA
Definition: commctrl.h:3485
#define CLR_DEFAULT
Definition: commctrl.h:320
#define TVE_COLLAPSE
Definition: commctrl.h:3422
#define TVGN_NEXTVISIBLE
Definition: commctrl.h:3458
#define TVGN_CHILD
Definition: commctrl.h:3456
#define TVM_SETUNICODEFORMAT
Definition: commctrl.h:3566
#define TVIS_EXPANDED
Definition: commctrl.h:3284
#define TVIS_EXPANDPARTIAL
Definition: commctrl.h:3286
#define CDDS_PREPAINT
Definition: commctrl.h:280
#define TVM_SETITEMA
Definition: commctrl.h:3492
#define TVC_BYKEYBOARD
Definition: commctrl.h:3652
#define TVM_ENSUREVISIBLE
Definition: commctrl.h:3544
#define TVM_SETIMAGELIST
Definition: commctrl.h:3446
struct tagTRACKMOUSEEVENT TRACKMOUSEEVENT
#define TVN_BEGINDRAGA
Definition: commctrl.h:3703
#define TVM_SETINDENT
Definition: commctrl.h:3437
#define TVS_NOHSCROLL
Definition: commctrl.h:3262
#define TVN_GETDISPINFOA
Definition: commctrl.h:3654
#define NM_RCLICK
Definition: commctrl.h:133
#define NM_SETFOCUS
Definition: commctrl.h:135
#define TVIS_OVERLAYMASK
Definition: commctrl.h:3287
#define TVN_ITEMEXPANDINGW
Definition: commctrl.h:3700
#define TVGN_CARET
Definition: commctrl.h:3461
#define TVS_HASBUTTONS
Definition: commctrl.h:3247
#define ILC_MASK
Definition: commctrl.h:351
#define TVM_HITTEST
Definition: commctrl.h:3512
#define TVS_NOTOOLTIPS
Definition: commctrl.h:3254
#define INDEXTOSTATEIMAGEMASK(i)
Definition: commctrl.h:2328
#define TVM_INSERTITEMA
Definition: commctrl.h:3407
#define TVM_GETIMAGELIST
Definition: commctrl.h:3440
#define TVS_DISABLEDRAGDROP
Definition: commctrl.h:3251
#define TVM_GETINSERTMARKCOLOR
Definition: commctrl.h:3589
#define CDDS_POSTPAINT
Definition: commctrl.h:281
#define TVN_BEGINLABELEDITW
Definition: commctrl.h:3710
#define TVM_GETBKCOLOR
Definition: commctrl.h:3579
#define PGF_CALCWIDTH
Definition: commctrl.h:4582
#define TVM_EDITLABELW
Definition: commctrl.h:3500
#define TVI_SORT
Definition: commctrl.h:3371
#define TVHT_ONITEMICON
Definition: commctrl.h:3525
#define TVS_SINGLEEXPAND
Definition: commctrl.h:3257
#define TME_QUERY
Definition: commctrl.h:4983
#define CDRF_SKIPDEFAULT
Definition: commctrl.h:270
#define TVIF_PARAM
Definition: commctrl.h:3268
#define TVS_EDITLABELS
Definition: commctrl.h:3250
#define CDIS_HOT
Definition: commctrl.h:297
#define TVN_SELCHANGEDA
Definition: commctrl.h:3647
#define TVN_SETDISPINFOA
Definition: commctrl.h:3656
#define TVIF_CHILDREN
Definition: commctrl.h:3272
#define TVM_GETINDENT
Definition: commctrl.h:3434
#define I_IMAGENONE
Definition: commctrl.h:2386
#define TVM_GETSCROLLTIME
Definition: commctrl.h:3585
#define TVIF_SELECTEDIMAGE
Definition: commctrl.h:3271
#define TVN_ENDLABELEDITW
Definition: commctrl.h:3712
#define TVHT_TOLEFT
Definition: commctrl.h:3536
#define TVM_EXPAND
Definition: commctrl.h:3419
#define TVN_DELETEITEMW
Definition: commctrl.h:3708
#define TVIF_STATE
Definition: commctrl.h:3269
#define ILC_COLOR
Definition: commctrl.h:352
#define TVM_SETTOOLTIPS
Definition: commctrl.h:3558
struct NMPGCALCSIZE * LPNMPGCALCSIZE
#define TVIF_DI_SETITEM
Definition: commctrl.h:3659
#define ILD_SELECTED
Definition: commctrl.h:430
#define TVN_SINGLEEXPAND
Definition: commctrl.h:3716
#define TVGN_NEXT
Definition: commctrl.h:3453
#define TVN_GETINFOTIPA
Definition: commctrl.h:3714
#define TVM_GETNEXTITEM
Definition: commctrl.h:3449
#define TVM_SETITEMHEIGHT
Definition: commctrl.h:3571
#define TVM_GETISEARCHSTRINGA
Definition: commctrl.h:3553
static unsigned __int64 next
Definition: rand_nt.c:6
#define DPA_GetPtr
Definition: commctrl.h:5
#define strncmpiW(s1, s2, n)
Definition: unicode.h:40
#define strcmpW(s1, s2)
Definition: unicode.h:38
#define strlenW(s)
Definition: unicode.h:28
#define strcpyW(d, s)
Definition: unicode.h:29
#define WM_CONTEXTMENU
Definition: richedit.h:64
#define WM_PRINTCLIENT
Definition: richedit.h:70
#define WM_NOTIFY
Definition: richedit.h:61
#define list
Definition: rosglue.h:35
#define memset(x, y, z)
Definition: compat.h:39
#define finish()
Definition: seh0024.c:15
#define TRACE(s)
Definition: solgame.cpp:4
& rect
Definition: startmenu.cpp:1413
COLORREF clrHighlightText
Definition: comctl32.h:170
COLORREF clrBtnFace
Definition: comctl32.h:168
COLORREF clrWindow
Definition: comctl32.h:176
COLORREF clrHighlight
Definition: comctl32.h:169
DWORD dwFlag
Definition: commctrl.h:4587
Definition: dpa.c:49
LONG cx
Definition: kdterminal.h:27
LONG cy
Definition: kdterminal.h:28
int cChildren
Definition: treeview.c:154
LPARAM lParam
Definition: treeview.c:155
UINT callbackMask
Definition: treeview.c:146
LONG linesOffset
Definition: treeview.c:161
LONG imageOffset
Definition: treeview.c:163
RECT rect
Definition: treeview.c:160
LPWSTR pszText
Definition: treeview.c:149
LONG stateOffset
Definition: treeview.c:162
LONG textOffset
Definition: treeview.c:164
HTREEITEM prevSibling
Definition: treeview.c:159
HTREEITEM lastChild
Definition: treeview.c:158
UINT stateMask
Definition: treeview.c:148
UINT state
Definition: treeview.c:147
const TREEVIEW_INFO * infoPtr
Definition: treeview.c:170
HTREEITEM firstChild
Definition: treeview.c:144
HTREEITEM parent
Definition: treeview.c:142
int iIntegral
Definition: treeview.c:156
int iImage
Definition: treeview.c:151
LONG visibleOrder
Definition: treeview.c:166
HTREEITEM nextSibling
Definition: treeview.c:143
int cchTextMax
Definition: treeview.c:150
int iSelectedImage
Definition: treeview.c:152
int iLevel
Definition: treeview.c:157
int iExpandedImage
Definition: treeview.c:153
LONG textWidth
Definition: treeview.c:165
LPCWSTR lpszClassName
Definition: winuser.h:3185
HBRUSH hbrBackground
Definition: winuser.h:3183
int cbClsExtra
Definition: winuser.h:3178
UINT style
Definition: winuser.h:3176
WNDPROC lpfnWndProc
Definition: winuser.h:3177
int cbWndExtra
Definition: winuser.h:3179
HCURSOR hCursor
Definition: winuser.h:3182
uint64_t parent
Definition: btrfs_drv.h:459
Definition: inflate.c:139
Definition: copy.c:22
Definition: ps.c:97
UINT lbStyle
Definition: wingdi.h:1747
COLORREF lbColor
Definition: wingdi.h:1748
DWORD_PTR dwItemSpec
Definition: commctrl.h:307
UINT code
Definition: winuser.h:3159
POINT pt
Definition: commctrl.h:166
DWORD_PTR dwItemData
Definition: commctrl.h:165
DWORD_PTR dwItemSpec
Definition: commctrl.h:164
NMHDR hdr
Definition: commctrl.h:163
LPARAM dwHitInfo
Definition: commctrl.h:167
TVITEMW itemNew
Definition: commctrl.h:3638
TVITEMW itemOld
Definition: commctrl.h:3637
COLORREF clrText
Definition: commctrl.h:3750
NMCUSTOMDRAW nmcd
Definition: commctrl.h:3749
COLORREF clrTextBk
Definition: commctrl.h:3751
long y
Definition: polytest.cpp:48
long x
Definition: polytest.cpp:48
LONG right
Definition: windef.h:308
LONG bottom
Definition: windef.h:309
LONG top
Definition: windef.h:307
LONG left
Definition: windef.h:306
LONG tmMaxCharWidth
Definition: wingdi.h:2389
LONG maxVisibleOrder
Definition: treeview.c:101
BOOL bIgnoreEditKillFocus
Definition: treeview.c:122
HIMAGELIST dragList
Definition: treeview.c:105
INT nSearchParamLength
Definition: treeview.c:136
HTREEITEM focusedItem
Definition: treeview.c:97
HIMAGELIST himlState
Definition: treeview.c:129
HTREEITEM selectedItem
Definition: treeview.c:95
HCURSOR hcurHand
Definition: treeview.c:117
LONG clientHeight
Definition: treeview.c:89
UINT uScrollTime
Definition: treeview.c:82
WPARAM charCode
Definition: treeview.c:135
HTREEITEM hotItem
Definition: treeview.c:96
HTREEITEM editItem
Definition: treeview.c:98
COLORREF clrInsertMark
Definition: treeview.c:111
COLORREF clrText
Definition: treeview.c:109
BOOL insertBeforeorAfter
Definition: treeview.c:104
COLORREF clrBk
Definition: treeview.c:108
HFONT hBoldUnderlineFont
Definition: treeview.c:116
HTREEITEM root
Definition: treeview.c:77
HFONT hUnderlineFont
Definition: treeview.c:115
HTREEITEM firstVisible
Definition: treeview.c:100
HIMAGELIST himlNormal
Definition: treeview.c:126
int stateImageHeight
Definition: treeview.c:130
UINT uItemHeight
Definition: treeview.c:85
DWORD lastKeyPressTimestamp
Definition: treeview.c:134
WNDPROC wpEditOrig
Definition: treeview.c:121
LONG clientWidth
Definition: treeview.c:88
HFONT hDefaultFont
Definition: treeview.c:113
UINT uInternalStatus
Definition: treeview.c:78
COLORREF clrLine
Definition: treeview.c:110
int normalImageWidth
Definition: treeview.c:128
BOOL bLabelChanged
Definition: treeview.c:123
HTREEITEM dropItem
Definition: treeview.c:102
int normalImageHeight
Definition: treeview.c:127
HTREEITEM insertMarkItem
Definition: treeview.c:103
WCHAR szSearchParam[MAX_PATH]
Definition: treeview.c:137
TVITEMW item
Definition: commctrl.h:3672
HTREEITEM hItem
Definition: commctrl.h:3521
TVITEMEXW itemex
Definition: commctrl.h:3396
HTREEITEM hParent
Definition: commctrl.h:3393
HTREEITEM hInsertAfter
Definition: commctrl.h:3394
LPARAM lParam
Definition: commctrl.h:3355
int iExpandedImage
Definition: commctrl.h:3359
int iSelectedImage
Definition: commctrl.h:3353
LPWSTR pszText
Definition: commctrl.h:3350
UINT stateMask
Definition: commctrl.h:3349
UINT uStateEx
Definition: commctrl.h:3357
int cchTextMax
Definition: commctrl.h:3351
HTREEITEM hItem
Definition: commctrl.h:3347
HTREEITEM hItem
Definition: commctrl.h:3317
LPARAM lParam
Definition: commctrl.h:3325
UINT mask
Definition: commctrl.h:3316
LPWSTR pszText
Definition: commctrl.h:3320
int cchTextMax
Definition: commctrl.h:3321
int iImage
Definition: commctrl.h:3322
int cChildren
Definition: commctrl.h:3324
UINT state
Definition: commctrl.h:3318
int iSelectedImage
Definition: commctrl.h:3323
UINT stateMask
Definition: commctrl.h:3319
LPARAM lParam
Definition: commctrl.h:3616
HTREEITEM hParent
Definition: commctrl.h:3614
PFNTVCOMPARE lpfnCompare
Definition: commctrl.h:3615
Definition: time.h:68
#define max(a, b)
Definition: svc.c:63
#define WHEEL_DELTA
Definition: treelist.c:99
#define GWLP_WNDPROC
Definition: treelist.c:66
#define WM_MOUSEWHEEL
Definition: treelist.c:96
#define DWORD_PTR
Definition: treelist.c:76
#define GLPS_OPENED
Definition: treelist.c:142
#define TVP_GLYPH
Definition: treelist.c:136
#define GLPS_CLOSED
Definition: treelist.c:139
#define TVM_GETLINECOLOR
Definition: treelist.h:345
HTREEITEM hItem
Definition: treelist.h:37
#define TVM_SETLINECOLOR
Definition: treelist.h:348
#define TVM_GETITEMSTATE
Definition: treelist.h:336
TW_UINT32 TW_UINT16 TW_UINT16 MSG
Definition: twain.h:1829
HANDLE HINSTANCE
Definition: typedefs.h:77
uint32_t DWORD_PTR
Definition: typedefs.h:65
int32_t INT
Definition: typedefs.h:58
#define HIWORD(l)
Definition: typedefs.h:247
static const WCHAR isW[]
Definition: lex.c:62
int ret
static GLenum which
Definition: wgl_font.c:159
int WINAPI GetWindowTextA(HWND hWnd, LPSTR lpString, int nMaxCount)
Definition: window.c:1330
int WINAPI GetWindowTextW(HWND hWnd, LPWSTR lpString, int nMaxCount)
Definition: window.c:1412
#define ZeroMemory
Definition: winbase.h:1712
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023
LONG_PTR LPARAM
Definition: windef.h:208
LONG_PTR LRESULT
Definition: windef.h:209
UINT_PTR WPARAM
Definition: windef.h:207
DWORD COLORREF
Definition: windef.h:300
HICON HCURSOR
Definition: windef.h:299
#define WINAPI
Definition: msvc.h:6
BOOL WINAPI GetTextMetricsW(_In_ HDC, _Out_ LPTEXTMETRICW)
Definition: text.c:221
int WINAPI GetObjectW(_In_ HANDLE h, _In_ int c, _Out_writes_bytes_opt_(c) LPVOID pv)
#define PS_ALTERNATE
Definition: wingdi.h:585
COLORREF WINAPI SetBkColor(_In_ HDC, _In_ COLORREF)
Definition: dc.c:999
HRGN WINAPI CreateRectRgn(_In_ int, _In_ int, _In_ int, _In_ int)
HPEN WINAPI ExtCreatePen(_In_ DWORD iPenStyle, _In_ DWORD cWidth, _In_ const LOGBRUSH *plbrush, _In_ DWORD cStyle, _In_reads_opt_(cStyle) const DWORD *pstyle)
#define FW_BOLD
Definition: wingdi.h:378
UINT WINAPI SetTextAlign(_In_ HDC, _In_ UINT)
Definition: text.c:883
int WINAPI ExcludeClipRect(_In_ HDC, _In_ int, _In_ int, _In_ int, _In_ int)
#define PS_COSMETIC
Definition: wingdi.h:584
HGDIOBJ WINAPI SelectObject(_In_ HDC, _In_ HGDIOBJ)
Definition: dc.c:1539
BOOL WINAPI MoveToEx(_In_ HDC, _In_ int, _In_ int, _Out_opt_ LPPOINT)
#define TA_LEFT
Definition: wingdi.h:932
HDC WINAPI CreateCompatibleDC(_In_opt_ HDC hdc)
int WINAPI CombineRgn(_In_opt_ HRGN hrgnDest, _In_opt_ HRGN hrgnSrc1, _In_opt_ HRGN hrgnSrc2, _In_ int fnCombineMode)
#define RGN_AND
Definition: wingdi.h:356
#define ETO_CLIPPED
Definition: wingdi.h:648
BOOL WINAPI ExtTextOutW(_In_ HDC hdc, _In_ int x, _In_ int y, _In_ UINT options, _In_opt_ const RECT *lprect, _In_reads_opt_(c) LPCWSTR lpString, _In_ UINT c, _In_reads_opt_(c) const INT *lpDx)
#define ETO_OPAQUE
Definition: wingdi.h:647
HBITMAP WINAPI CreateCompatibleBitmap(_In_ HDC hdc, _In_ INT cx, _In_ INT cy)
#define TA_TOP
Definition: wingdi.h:930
int WINAPI FillRect(HDC, LPCRECT, HBRUSH)
BOOL WINAPI Rectangle(_In_ HDC, _In_ int, _In_ int, _In_ int, _In_ int)
HFONT WINAPI CreateFontIndirectW(_In_ const LOGFONTW *)
COLORREF WINAPI SetTextColor(_In_ HDC, _In_ COLORREF)
Definition: text.c:918
HBRUSH WINAPI CreateSolidBrush(_In_ COLORREF)
BOOL WINAPI DeleteDC(_In_ HDC)
HPEN WINAPI CreatePen(_In_ int, _In_ int, _In_ COLORREF)
BOOL WINAPI LineTo(_In_ HDC, _In_ int, _In_ int)
BOOL WINAPI GetTextExtentPoint32A(_In_ HDC hdc, _In_reads_(c) LPCSTR lpString, _In_ int c, _Out_ LPSIZE psizl)
#define BS_SOLID
Definition: wingdi.h:1086
#define PS_SOLID
Definition: wingdi.h:586
BOOL WINAPI GetTextExtentPoint32W(_In_ HDC hdc, _In_reads_(c) LPCWSTR lpString, _In_ int c, _Out_ LPSIZE psizl)
#define WM_PAINT
Definition: winuser.h:1620
HWND WINAPI GetFocus(void)
Definition: window.c:1893
HWND WINAPI SetCapture(_In_ HWND hWnd)
int WINAPI ReleaseDC(_In_opt_ HWND, _In_ HDC)
#define WM_ERASEBKGND
Definition: winuser.h:1625
#define MAKEWPARAM(l, h)
Definition: winuser.h:4009
BOOL WINAPI IsWindow(_In_opt_ HWND)
#define MK_SHIFT
Definition: winuser.h:2369
#define SW_HIDE
Definition: winuser.h:768
#define SB_THUMBTRACK
Definition: winuser.h:573
#define GetWindowLongPtrW
Definition: winuser.h:4829
HDC WINAPI GetWindowDC(_In_opt_ HWND)
#define SM_CYEDGE
Definition: winuser.h:1009
#define SM_CXDRAG
Definition: winuser.h:1028
#define SB_LINEUP
Definition: winuser.h:564
#define WM_HSCROLL
Definition: winuser.h:1743
#define EN_KILLFOCUS
Definition: winuser.h:2025
#define COLOR_WINDOW
Definition: winuser.h:918
BOOL WINAPI ShowWindow(_In_ HWND, _In_ int)
BOOL WINAPI ReleaseCapture(void)
Definition: message.c:2890
DWORD WINAPI GetMessagePos(void)
Definition: message.c:1351
#define DCX_WINDOW
Definition: winuser.h:2113
LRESULT WINAPI DefWindowProcW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define VK_MULTIPLY
Definition: winuser.h:2249
#define SM_CXEDGE
Definition: winuser.h:1008
#define SM_CYVSCROLL
Definition: winuser.h:981
struct tagSCROLLINFO SCROLLINFO
#define WM_VSCROLL
Definition: winuser.h:1744
BOOL WINAPI GetWindowRect(_In_ HWND, _Out_ LPRECT)
#define SIF_RANGE
Definition: winuser.h:1235
#define WM_CREATE
Definition: winuser.h:1608
#define DLGC_WANTCHARS
Definition: winuser.h:2618
BOOL WINAPI DrawFrameControl(_In_ HDC, _Inout_ LPRECT, _In_ UINT, _In_ UINT)
BOOL WINAPI SetWindowPos(_In_ HWND, _In_opt_ HWND, _In_ int, _In_ int, _In_ int, _In_ int, _In_ UINT)
#define EN_UPDATE
Definition: winuser.h:2028
#define SB_PAGERIGHT
Definition: winuser.h:571
#define SM_CXVSCROLL
Definition: winuser.h:961
#define DFCS_FLAT
Definition: winuser.h:510
#define SWP_DRAWFRAME
Definition: winuser.h:1239
#define VK_SPACE
Definition: winuser.h:2219
#define WM_SIZE
Definition: winuser.h:1611
#define PRF_ERASEBKGND
Definition: winuser.h:2526
#define SB_VERT
Definition: winuser.h:553
LONG WINAPI SetWindowLongW(_In_ HWND, _In_ int, _In_ LONG)
LONG WINAPI GetWindowLongW(_In_ HWND, _In_ int)
#define SB_BOTTOM
Definition: winuser.h:577
#define DLGC_WANTALLKEYS
Definition: winuser.h:2612
#define WM_LBUTTONDBLCLK
Definition: winuser.h:1778
#define SWP_NOMOVE
Definition: winuser.h:1244
#define WM_COMMAND
Definition: winuser.h:1740
#define DFCS_BUTTONCHECK
Definition: winuser.h:496
#define SW_INVALIDATE
Definition: winuser.h:2579
ATOM WINAPI RegisterClassW(_In_ CONST WNDCLASSW *)
#define IDC_ARROW
Definition: winuser.h:687
#define VK_CONTROL
Definition: winuser.h:2203
BOOL WINAPI GetCursorPos(_Out_ LPPOINT)
Definition: cursoricon.c:2670
#define DFC_BUTTON
Definition: winuser.h:476
#define VK_UP
Definition: winuser.h:2225
#define WM_RBUTTONDBLCLK
Definition: winuser.h:1781
#define WM_SETFOCUS
Definition: winuser.h:1613
HCURSOR WINAPI SetCursor(_In_opt_ HCURSOR)
#define SIF_PAGE
Definition: winuser.h:1233
#define WM_MOUSEMOVE
Definition: winuser.h:1775
HDC WINAPI GetDCEx(_In_opt_ HWND, _In_opt_ HRGN, _In_ DWORD)
HWND WINAPI GetCapture(void)
Definition: message.c:2881
#define SB_LINERIGHT
Definition: winuser.h:567
#define CS_DBLCLKS
Definition: winuser.h:651
#define SPI_GETICONTITLELOGFONT
Definition: winuser.h:1380
#define WM_LBUTTONDOWN
Definition: winuser.h:1776
#define NF_REQUERY
Definition: winuser.h:2461
#define WM_SYSCOLORCHANGE
Definition: winuser.h:1626
HCURSOR WINAPI LoadCursorW(_In_opt_ HINSTANCE, _In_ LPCWSTR)
Definition: cursoricon.c:2105
#define WM_GETFONT
Definition: winuser.h:1651
int WINAPI SetScrollPos(_In_ HWND, _In_ int, _In_ int, _In_ BOOL)
#define GWLP_HINSTANCE
Definition: winuser.h:856
UINT WINAPI GetDoubleClickTime(void)
Definition: ntwrapper.h:314
#define WM_DRAWITEM
Definition: winuser.h:1645
UINT_PTR WINAPI SetTimer(_In_opt_ HWND, _In_ UINT_PTR, _In_ UINT, _In_opt_ TIMERPROC)
#define VK_NEXT
Definition: winuser.h:2221
HWND WINAPI GetDesktopWindow(void)
Definition: window.c:656
#define WM_RBUTTONDOWN
Definition: winuser.h:1779
BOOL WINAPI SetWindowTextW(_In_ HWND, _In_opt_ LPCWSTR)
struct tagSTYLESTRUCT * LPSTYLESTRUCT
BOOL WINAPI PtInRect(_In_ LPCRECT, _In_ POINT)
#define DT_LEFT
Definition: winuser.h:534
BOOL WINAPI GetClientRect(_In_ HWND, _Out_ LPRECT)
#define DCX_INTERSECTRGN
Definition: winuser.h:2122
#define VK_RETURN
Definition: winuser.h:2201
#define HWND_TOP
Definition: winuser.h:1207
#define SB_LINELEFT
Definition: winuser.h:566
HWND WINAPI SetFocus(_In_opt_ HWND)
#define MK_CONTROL
Definition: winuser.h:2370
#define PM_NOYIELD
Definition: winuser.h:1197
BOOL WINAPI PeekMessageW(_Out_ LPMSG, _In_opt_ HWND, _In_ UINT, _In_ UINT, _In_ UINT)
#define WM_SETFONT
Definition: winuser.h:1650
#define WM_TIMER
Definition: winuser.h:1742
#define VK_END
Definition: winuser.h:2222
HWND WINAPI CreateWindowExW(_In_ DWORD dwExStyle, _In_opt_ LPCWSTR lpClassName, _In_opt_ LPCWSTR lpWindowName, _In_ DWORD dwStyle, _In_ int X, _In_ int Y, _In_ int nWidth, _In_ int nHeight, _In_opt_ HWND hWndParent, _In_opt_ HMENU hMenu, _In_opt_ HINSTANCE hInstance, _In_opt_ LPVOID lpParam)
#define VK_HOME
Definition: winuser.h:2223
BOOL WINAPI EndPaint(_In_ HWND, _In_ const PAINTSTRUCT *)
#define DLGC_WANTARROWS
Definition: winuser.h:2610
#define VK_ADD
Definition: winuser.h:2250
#define PM_REMOVE
Definition: winuser.h:1196
BOOL WINAPI UpdateWindow(_In_ HWND)
#define SB_PAGEDOWN
Definition: winuser.h:569
struct tagNMHDR * LPNMHDR
#define VK_BACK
Definition: winuser.h:2198
HDC WINAPI GetDC(_In_opt_ HWND)
#define SB_LINEDOWN
Definition: winuser.h:565
#define EM_SETSEL
Definition: winuser.h:2018
#define PRF_CLIENT
Definition: winuser.h:2525
BOOL WINAPI SystemParametersInfoW(_In_ UINT uiAction, _In_ UINT uiParam, _Inout_opt_ PVOID pvParam, _In_ UINT fWinIni)
#define WM_CHAR
Definition: winuser.h:1717
#define CW_USEDEFAULT
Definition: winuser.h:225
HWND WINAPI GetParent(_In_ HWND)
#define CS_GLOBALCLASS
Definition: winuser.h:652
#define VK_LEFT
Definition: winuser.h:2224
#define NFR_ANSI
Definition: winuser.h:2458
#define VK_RIGHT
Definition: winuser.h:2226
#define SIZE_RESTORED
Definition: winuser.h:2505
LRESULT WINAPI DispatchMessageW(_In_ const MSG *)
#define SB_TOP
Definition: winuser.h:578
#define SIF_POS
Definition: winuser.h:1234
#define VK_DOWN
Definition: winuser.h:2227
#define GWLP_ID
Definition: winuser.h:860
#define PRF_CHECKVISIBLE
Definition: winuser.h:2523
#define WM_SETCURSOR
Definition: winuser.h:1636
#define SW_ERASE
Definition: winuser.h:2580
#define WM_USER
Definition: winuser.h:1895
#define SB_ENDSCROLL
Definition: winuser.h:574
BOOL WINAPI OffsetRect(_Inout_ LPRECT, _In_ int, _In_ int)
#define IDC_HAND
Definition: winuser.h:698
#define SW_SHOW
Definition: winuser.h:775
#define VK_PRIOR
Definition: winuser.h:2220
int WINAPI SetScrollInfo(_In_ HWND, _In_ int, _In_ LPCSCROLLINFO, _In_ BOOL)
#define WM_DESTROY
Definition: winuser.h:1609
BOOL WINAPI UnregisterClassW(_In_ LPCWSTR, HINSTANCE)
#define WS_EX_CLIENTEDGE
Definition: winuser.h:384
#define DFCS_CHECKED
Definition: winuser.h:504
SHORT WINAPI GetAsyncKeyState(_In_ int)
BOOL WINAPI ShowScrollBar(_In_ HWND, _In_ int, _In_ BOOL)
#define WM_KEYDOWN
Definition: winuser.h:1715
BOOL WINAPI DrawFocusRect(_In_ HDC, _In_ LPCRECT)
BOOL WINAPI InvalidateRect(_In_opt_ HWND, _In_opt_ LPCRECT, _In_ BOOL)
LRESULT(CALLBACK * WNDPROC)(HWND, UINT, WPARAM, LPARAM)
Definition: winuser.h:2906
HDC WINAPI BeginPaint(_In_ HWND, _Out_ LPPAINTSTRUCT)
BOOL WINAPI KillTimer(_In_opt_ HWND, _In_ UINT_PTR)
#define SetWindowLongPtrW
Definition: winuser.h:5346
#define SM_CYDRAG
Definition: winuser.h:1029
LRESULT WINAPI CallWindowProcW(_In_ WNDPROC, _In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define NFR_UNICODE
Definition: winuser.h:2459
#define GWL_STYLE
Definition: winuser.h:852
#define VK_ESCAPE
Definition: winuser.h:2214
BOOL WINAPI IsWindowVisible(_In_ HWND)
BOOL WINAPI DestroyWindow(_In_ HWND)
int WINAPI ScrollWindowEx(_In_ HWND, _In_ int, _In_ int, _In_opt_ LPCRECT, _In_opt_ LPCRECT, _In_opt_ HRGN, _Out_opt_ LPRECT, _In_ UINT)
BOOL WINAPI ScrollWindow(_In_ HWND, _In_ int, _In_ int, _In_opt_ LPCRECT, _In_opt_ LPCRECT)
#define WM_KILLFOCUS
Definition: winuser.h:1614
#define WS_EX_LEFT
Definition: winuser.h:391
int WINAPI GetSystemMetrics(_In_ int)
#define SB_PAGEUP
Definition: winuser.h:568
#define WM_SYSKEYDOWN
Definition: winuser.h:1719
#define WM_NCLBUTTONDOWN
Definition: winuser.h:1692
#define WM_GETDLGCODE
Definition: winuser.h:1689
#define NF_QUERY
Definition: winuser.h:2460
LRESULT WINAPI SendMessageW(_In_ HWND, _In_ UINT, _In_ WPARAM, _In_ LPARAM)
#define SB_HORZ
Definition: winuser.h:552
#define VK_SUBTRACT
Definition: winuser.h:2252
#define WM_NCPAINT
Definition: winuser.h:1687
BOOL WINAPI SetRect(_Out_ LPRECT, _In_ int, _In_ int, _In_ int, _In_ int)
#define SB_PAGELEFT
Definition: winuser.h:570
#define GWL_EXSTYLE
Definition: winuser.h:851
#define WM_SETREDRAW
Definition: winuser.h:1616
#define SB_THUMBPOSITION
Definition: winuser.h:572
BOOL WINAPI ScreenToClient(_In_ HWND, _Inout_ LPPOINT)
char * LPSTR
Definition: xmlstorage.h:182
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184