Mercurial > projects > dwt-win
comparison dwt/widgets/Tree.d @ 213:36f5cb12e1a2
Update to SWT 3.4M7
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Sat, 17 May 2008 17:34:28 +0200 |
parents | ab60f3309436 |
children | a8fed3e56433 |
comparison
equal
deleted
inserted
replaced
212:ab60f3309436 | 213:36f5cb12e1a2 |
---|---|
35 import dwt.widgets.Display; | 35 import dwt.widgets.Display; |
36 import dwt.widgets.Shell; | 36 import dwt.widgets.Shell; |
37 import dwt.widgets.Control; | 37 import dwt.widgets.Control; |
38 import dwt.widgets.Listener; | 38 import dwt.widgets.Listener; |
39 import dwt.widgets.Widget; | 39 import dwt.widgets.Widget; |
40 import dwt.widgets.Table; | |
40 | 41 |
41 import dwt.dwthelper.utils; | 42 import dwt.dwthelper.utils; |
42 | 43 |
43 | 44 |
44 /** | 45 /** |
75 * } | 76 * } |
76 * }); | 77 * }); |
77 * </pre></code> | 78 * </pre></code> |
78 * </p><p> | 79 * </p><p> |
79 * Note that although this class is a subclass of <code>Composite</code>, | 80 * Note that although this class is a subclass of <code>Composite</code>, |
80 * it does not make sense to add <code>Control</code> children to it, | 81 * it does not normally make sense to add <code>Control</code> children to |
81 * or set a layout on it. | 82 * it, or set a layout on it, unless implementing something like a cell |
83 * editor. | |
82 * </p><p> | 84 * </p><p> |
83 * <dl> | 85 * <dl> |
84 * <dt><b>Styles:</b></dt> | 86 * <dt><b>Styles:</b></dt> |
85 * <dd>SINGLE, MULTI, CHECK, FULL_SELECTION, VIRTUAL</dd> | 87 * <dd>SINGLE, MULTI, CHECK, FULL_SELECTION, VIRTUAL, NO_SCROLL</dd> |
86 * <dt><b>Events:</b></dt> | 88 * <dt><b>Events:</b></dt> |
87 * <dd>Selection, DefaultSelection, Collapse, Expand, SetData, MeasureItem, EraseItem, PaintItem</dd> | 89 * <dd>Selection, DefaultSelection, Collapse, Expand, SetData, MeasureItem, EraseItem, PaintItem</dd> |
88 * </dl> | 90 * </dl> |
89 * </p><p> | 91 * </p><p> |
90 * Note: Only one of the styles SINGLE and MULTI may be specified. | 92 * Note: Only one of the styles SINGLE and MULTI may be specified. |
100 alias Composite.setCursor setCursor; | 102 alias Composite.setCursor setCursor; |
101 alias Composite.sort sort; | 103 alias Composite.sort sort; |
102 | 104 |
103 TreeItem [] items; | 105 TreeItem [] items; |
104 TreeColumn [] columns; | 106 TreeColumn [] columns; |
107 int columnCount; | |
105 ImageList imageList, headerImageList; | 108 ImageList imageList, headerImageList; |
106 TreeItem currentItem; | 109 TreeItem currentItem; |
107 TreeColumn sortColumn; | 110 TreeColumn sortColumn; |
111 RECT* focusRect; | |
108 HWND hwndParent, hwndHeader; | 112 HWND hwndParent, hwndHeader; |
109 HANDLE hAnchor, hInsert, hSelect; | 113 HANDLE hAnchor, hInsert, hSelect; |
110 int lastID; | 114 int lastID; |
111 HANDLE hFirstIndexOf, hLastIndexOf; | 115 HANDLE hFirstIndexOf, hLastIndexOf; |
112 int lastIndexOf, itemCount, sortDirection; | 116 int lastIndexOf, itemCount, sortDirection; |
175 * </ul> | 179 * </ul> |
176 * | 180 * |
177 * @see DWT#SINGLE | 181 * @see DWT#SINGLE |
178 * @see DWT#MULTI | 182 * @see DWT#MULTI |
179 * @see DWT#CHECK | 183 * @see DWT#CHECK |
184 * @see DWT#FULL_SELECTION | |
185 * @see DWT#VIRTUAL | |
186 * @see DWT#NO_SCROLL | |
180 * @see Widget#checkSubclass | 187 * @see Widget#checkSubclass |
181 * @see Widget#getStyle | 188 * @see Widget#getStyle |
182 */ | 189 */ |
183 public this (Composite parent, int style) { | 190 public this (Composite parent, int style) { |
184 static_this(); | 191 static_this(); |
185 super (parent, checkStyle (style)); | 192 super (parent, checkStyle (style)); |
186 } | 193 } |
187 | 194 |
188 static int checkStyle (int style) { | 195 static int checkStyle (int style) { |
189 /* | 196 /* |
190 * Feature in Windows. It is not possible to create | 197 * Feature in Windows. Even when WS_HSCROLL or |
191 * a tree that scrolls and does not have scroll bars. | 198 * WS_VSCROLL is not specified, Windows creates |
192 * The TVS_NOSCROLL style will remove the scroll bars | 199 * trees and tables with scroll bars. The fix |
193 * but the tree will never scroll. Therefore, no matter | 200 * is to set H_SCROLL and V_SCROLL. |
194 * what style bits are specified, set the H_SCROLL and | 201 * |
195 * V_SCROLL bits so that the DWT style will match the | 202 * NOTE: This code appears on all platforms so that |
196 * widget that Windows creates. | 203 * applications have consistent scroll bar behavior. |
197 */ | 204 */ |
198 style |= DWT.H_SCROLL | DWT.V_SCROLL; | 205 if ((style & DWT.NO_SCROLL) is 0) { |
206 style |= DWT.H_SCROLL | DWT.V_SCROLL; | |
207 } | |
208 /* | |
209 * Note: Windows only supports TVS_NOSCROLL and TVS_NOHSCROLL. | |
210 */ | |
211 if ((style & DWT.H_SCROLL) !is 0 && (style & DWT.V_SCROLL) is 0) { | |
212 style |= DWT.V_SCROLL; | |
213 } | |
199 return checkBits (style, DWT.SINGLE, DWT.MULTI, 0, 0, 0, 0); | 214 return checkBits (style, DWT.SINGLE, DWT.MULTI, 0, 0, 0, 0); |
200 } | 215 } |
201 | 216 |
202 override void _addListener (int eventType, Listener listener) { | 217 override void _addListener (int eventType, Listener listener) { |
203 super._addListener (eventType, listener); | 218 super._addListener (eventType, listener); |
213 case DWT.MeasureItem: | 228 case DWT.MeasureItem: |
214 case DWT.EraseItem: | 229 case DWT.EraseItem: |
215 case DWT.PaintItem: { | 230 case DWT.PaintItem: { |
216 customDraw = true; | 231 customDraw = true; |
217 style |= DWT.DOUBLE_BUFFERED; | 232 style |= DWT.DOUBLE_BUFFERED; |
233 if (isCustomToolTip ()) createItemToolTips (); | |
218 OS.SendMessage (handle, OS.TVM_SETSCROLLTIME, 0, 0); | 234 OS.SendMessage (handle, OS.TVM_SETSCROLLTIME, 0, 0); |
219 int bits = OS.GetWindowLong (handle, OS.GWL_STYLE); | 235 int bits = OS.GetWindowLong (handle, OS.GWL_STYLE); |
220 bits |= OS.TVS_NOTOOLTIPS; | 236 if (eventType is DWT.MeasureItem) { |
221 if (eventType is DWT.MeasureItem) bits |= OS.TVS_NOHSCROLL; | 237 if (explorerTheme) { |
238 int bits1 = OS.SendMessage (handle, OS.TVM_GETEXTENDEDSTYLE, 0, 0); | |
239 bits1 &= ~OS.TVS_EX_AUTOHSCROLL; | |
240 OS.SendMessage (handle, OS.TVM_SETEXTENDEDSTYLE, 0, bits1); | |
241 } | |
242 bits |= OS.TVS_NOHSCROLL; | |
243 } | |
222 /* | 244 /* |
223 * Feature in Windows. When the tree has the style | 245 * Feature in Windows. When the tree has the style |
224 * TVS_FULLROWSELECT, the background color for the | 246 * TVS_FULLROWSELECT, the background color for the |
225 * entire row is filled when an item is painted, | 247 * entire row is filled when an item is painted, |
226 * drawing on top of any custom drawing. The fix | 248 * drawing on top of any custom drawing. The fix |
417 OS.SetTextColor (hDC, getForegroundPixel ()); | 439 OS.SetTextColor (hDC, getForegroundPixel ()); |
418 } | 440 } |
419 } | 441 } |
420 } | 442 } |
421 } | 443 } |
422 int count = 0; | |
423 int [] order = null; | 444 int [] order = null; |
424 RECT clientRect; | 445 RECT clientRect; |
425 OS.GetClientRect (scrolledHandle (), &clientRect); | 446 OS.GetClientRect (scrolledHandle (), &clientRect); |
426 if (hwndHeader !is null) { | 447 if (hwndHeader !is null) { |
427 OS.MapWindowPoints (hwndParent, handle, cast(POINT*) &clientRect, 2); | 448 OS.MapWindowPoints (hwndParent, handle, cast(POINT*) &clientRect, 2); |
428 count = OS.SendMessage (hwndHeader, OS.HDM_GETITEMCOUNT, 0, 0); | 449 if (columnCount !is 0) { |
429 if (count !is 0) { | 450 order = new int [columnCount]; |
430 order = new int [count]; | 451 OS.SendMessage (hwndHeader, OS.HDM_GETORDERARRAY, columnCount, cast(int) order.ptr); |
431 OS.SendMessage (hwndHeader, OS.HDM_GETORDERARRAY, count, cast(int) order.ptr); | |
432 } | 452 } |
433 } | 453 } |
434 int sortIndex = -1, clrSortBk = -1; | 454 int sortIndex = -1, clrSortBk = -1; |
435 if (OS.COMCTL32_MAJOR >= 6 && OS.IsAppThemed ()) { | 455 if (OS.COMCTL32_MAJOR >= 6 && OS.IsAppThemed ()) { |
436 if (sortColumn !is null && sortDirection !is DWT.NONE) { | 456 if (sortColumn !is null && sortDirection !is DWT.NONE) { |
440 } | 460 } |
441 } | 461 } |
442 } | 462 } |
443 int x = 0; | 463 int x = 0; |
444 Point size = null; | 464 Point size = null; |
445 for (int i=0; i<Math.max (1, count); i++) { | 465 for (int i=0; i<Math.max (1, columnCount); i++) { |
446 int index = order is null ? i : order [i], width = nmcd.nmcd.rc.right - nmcd.nmcd.rc.left; | 466 int index = order is null ? i : order [i], width = nmcd.nmcd.rc.right - nmcd.nmcd.rc.left; |
447 if (count > 0 && hwndHeader !is null) { | 467 if (columnCount > 0 && hwndHeader !is null) { |
448 HDITEM hdItem; | 468 HDITEM hdItem; |
449 hdItem.mask = OS.HDI_WIDTH; | 469 hdItem.mask = OS.HDI_WIDTH; |
450 OS.SendMessage (hwndHeader, OS.HDM_GETITEM, index, &hdItem); | 470 OS.SendMessage (hwndHeader, OS.HDM_GETITEM, index, &hdItem); |
451 width = hdItem.cxy; | 471 width = hdItem.cxy; |
452 } | 472 } |
462 RECT itemRect = item.getBounds (index, true, true, false, false, true, hDC); | 482 RECT itemRect = item.getBounds (index, true, true, false, false, true, hDC); |
463 itemRect.left -= EXPLORER_EXTRA; | 483 itemRect.left -= EXPLORER_EXTRA; |
464 itemRect.right += EXPLORER_EXTRA + 1; | 484 itemRect.right += EXPLORER_EXTRA + 1; |
465 pClipRect.left = itemRect.left; | 485 pClipRect.left = itemRect.left; |
466 pClipRect.right = itemRect.right; | 486 pClipRect.right = itemRect.right; |
467 if (count > 0 && hwndHeader !is null) { | 487 if (columnCount > 0 && hwndHeader !is null) { |
468 HDITEM hdItem; | 488 HDITEM hdItem; |
469 hdItem.mask = OS.HDI_WIDTH; | 489 hdItem.mask = OS.HDI_WIDTH; |
470 OS.SendMessage (hwndHeader, OS.HDM_GETITEM, index, &hdItem); | 490 OS.SendMessage (hwndHeader, OS.HDM_GETITEM, index, &hdItem); |
471 pClipRect.right = Math.min (pClipRect.right, nmcd.nmcd.rc.left + hdItem.cxy); | 491 pClipRect.right = Math.min (pClipRect.right, nmcd.nmcd.rc.left + hdItem.cxy); |
472 } | 492 } |
473 } | 493 } |
474 RECT pRect; | 494 RECT pRect; |
475 OS.SetRect (&pRect, nmcd.nmcd.rc.left, nmcd.nmcd.rc.top, nmcd.nmcd.rc.right, nmcd.nmcd.rc.bottom); | 495 OS.SetRect (&pRect, nmcd.nmcd.rc.left, nmcd.nmcd.rc.top, nmcd.nmcd.rc.right, nmcd.nmcd.rc.bottom); |
476 if (count > 0 && hwndHeader !is null) { | 496 if (columnCount > 0 && hwndHeader !is null) { |
477 int totalWidth = 0; | 497 int totalWidth = 0; |
478 HDITEM hdItem; | 498 HDITEM hdItem; |
479 hdItem.mask = OS.HDI_WIDTH; | 499 hdItem.mask = OS.HDI_WIDTH; |
480 for (int j=0; j<count; j++) { | 500 for (int j=0; j<columnCount; j++) { |
481 OS.SendMessage (hwndHeader, OS.HDM_GETITEM, j, &hdItem); | 501 OS.SendMessage (hwndHeader, OS.HDM_GETITEM, j, &hdItem); |
482 totalWidth += hdItem.cxy; | 502 totalWidth += hdItem.cxy; |
483 } | 503 } |
484 if (totalWidth > clientRect.right - clientRect.left) { | 504 if (totalWidth > clientRect.right - clientRect.left) { |
485 pRect.left = 0; | 505 pRect.left = 0; |
495 if (OS.GetFocus () !is handle && selected && !hot) iStateId = OS.TREIS_SELECTEDNOTFOCUS; | 515 if (OS.GetFocus () !is handle && selected && !hot) iStateId = OS.TREIS_SELECTEDNOTFOCUS; |
496 OS.DrawThemeBackground (hTheme, hDC, OS.TVP_TREEITEM, iStateId, &pRect, &pClipRect); | 516 OS.DrawThemeBackground (hTheme, hDC, OS.TVP_TREEITEM, iStateId, &pRect, &pClipRect); |
497 OS.CloseThemeData (hTheme); | 517 OS.CloseThemeData (hTheme); |
498 } | 518 } |
499 if (draw) fillBackground (hDC, OS.GetBkColor (hDC), &pClipRect); | 519 if (draw) fillBackground (hDC, OS.GetBkColor (hDC), &pClipRect); |
500 } | |
501 } else { | |
502 if (explorerTheme && hooks (DWT.EraseItem)) { | |
503 if ((selected && !ignoreDrawSelection) || (hot && !ignoreDrawHot)) { | |
504 RECT pRect = item.getBounds (index, true, true, false, false, false, hDC); | |
505 RECT pClipRect = item.getBounds (index, true, true, false, false, true, hDC); | |
506 pRect.left -= EXPLORER_EXTRA; | |
507 pRect.right += EXPLORER_EXTRA; | |
508 pClipRect.left -= EXPLORER_EXTRA; | |
509 pClipRect.right += EXPLORER_EXTRA; | |
510 auto hTheme = OS.OpenThemeData (handle, cast(TCHAR*) Display.TREEVIEW); | |
511 int iStateId = selected ? OS.TREIS_SELECTED : OS.TREIS_HOT; | |
512 if (OS.GetFocus () !is handle && selected && !hot) iStateId = OS.TREIS_SELECTEDNOTFOCUS; | |
513 OS.DrawThemeBackground (hTheme, hDC, OS.TVP_TREEITEM, iStateId, &pRect, &pClipRect); | |
514 OS.CloseThemeData (hTheme); | |
515 } | |
516 } | 520 } |
517 } | 521 } |
518 } | 522 } |
519 if (x + width > clientRect.left) { | 523 if (x + width > clientRect.left) { |
520 RECT rect; | 524 RECT rect; |
577 ignoreDrawForeground = ignoreDrawBackground = ignoreDrawSelection = ignoreDrawFocus = ignoreDrawHot = false; | 581 ignoreDrawForeground = ignoreDrawBackground = ignoreDrawSelection = ignoreDrawFocus = ignoreDrawHot = false; |
578 OS.SetRect (&rect, x, nmcd.nmcd.rc.top, x + width, nmcd.nmcd.rc.bottom); | 582 OS.SetRect (&rect, x, nmcd.nmcd.rc.top, x + width, nmcd.nmcd.rc.bottom); |
579 backgroundRect = ▭ | 583 backgroundRect = ▭ |
580 } | 584 } |
581 int clrText = -1, clrTextBk = -1; | 585 int clrText = -1, clrTextBk = -1; |
582 HFONT hFont = item.cellFont !is null ? item.cellFont [index] : cast(HFONT)-1; | 586 auto hFont = item.fontHandle (index); |
583 if (hFont is cast(HFONT)-1) hFont = item.font; | |
584 if (selectionForeground !is -1) clrText = selectionForeground; | 587 if (selectionForeground !is -1) clrText = selectionForeground; |
585 if (OS.IsWindowEnabled (handle)) { | 588 if (OS.IsWindowEnabled (handle)) { |
586 bool drawForeground = false; | 589 bool drawForeground = false; |
587 if (selected) { | 590 if (selected) { |
588 if (i !is 0 && (style & DWT.FULL_SELECTION) is 0) { | 591 if (i !is 0 && (style & DWT.FULL_SELECTION) is 0) { |
621 } | 624 } |
622 } | 625 } |
623 if (drawItem) { | 626 if (drawItem) { |
624 if (i !is 0) { | 627 if (i !is 0) { |
625 if (hooks (DWT.MeasureItem)) { | 628 if (hooks (DWT.MeasureItem)) { |
626 RECT itemRect = item.getBounds (index, true, true, false, false, false, hDC); | 629 sendMeasureItemEvent (item, index, hDC); |
627 int nSavedDC = OS.SaveDC (hDC); | |
628 GCData data = new GCData (); | |
629 data.device = display; | |
630 data.hFont = hFont; | |
631 GC gc = GC.win32_new (hDC, data); | |
632 Event event = new Event (); | |
633 event.item = item; | |
634 event.index = index; | |
635 event.gc = gc; | |
636 event.x = itemRect.left; | |
637 event.y = itemRect.top; | |
638 event.width = itemRect.right - itemRect.left; | |
639 event.height = itemRect.bottom - itemRect.top; | |
640 sendEvent (DWT.MeasureItem, event); | |
641 event.gc = null; | |
642 gc.dispose (); | |
643 OS.RestoreDC (hDC, nSavedDC); | |
644 if (isDisposed () || item.isDisposed ()) break; | 630 if (isDisposed () || item.isDisposed ()) break; |
645 if (event.height > getItemHeight ()) setItemHeight (event.height); | |
646 } | 631 } |
647 if (hooks (DWT.EraseItem)) { | 632 if (hooks (DWT.EraseItem)) { |
648 RECT cellRect = item.getBounds (index, true, true, true, true, true, hDC); | 633 RECT cellRect = item.getBounds (index, true, true, true, true, true, hDC); |
649 int nSavedDC = OS.SaveDC (hDC); | 634 int nSavedDC = OS.SaveDC (hDC); |
650 GCData data = new GCData (); | 635 GCData data = new GCData (); |
653 data.background = OS.GetBkColor (hDC); | 638 data.background = OS.GetBkColor (hDC); |
654 if (!selected || (style & DWT.FULL_SELECTION) is 0) { | 639 if (!selected || (style & DWT.FULL_SELECTION) is 0) { |
655 if (clrText !is -1) data.foreground = clrText; | 640 if (clrText !is -1) data.foreground = clrText; |
656 if (clrTextBk !is -1) data.background = clrTextBk; | 641 if (clrTextBk !is -1) data.background = clrTextBk; |
657 } | 642 } |
658 data.hFont = hFont; | 643 data.font = item.getFont (index); |
659 data.uiState = OS.SendMessage (handle, OS.WM_QUERYUISTATE, 0, 0); | 644 data.uiState = OS.SendMessage (handle, OS.WM_QUERYUISTATE, 0, 0); |
660 GC gc = GC.win32_new (hDC, data); | 645 GC gc = GC.win32_new (hDC, data); |
661 Event event = new Event (); | 646 Event event = new Event (); |
662 event.item = item; | 647 event.item = item; |
663 event.index = index; | 648 event.index = index; |
707 selectionForeground = OS.GetSysColor (OS.COLOR_HIGHLIGHTTEXT); | 692 selectionForeground = OS.GetSysColor (OS.COLOR_HIGHLIGHTTEXT); |
708 } else { | 693 } else { |
709 if (!explorerTheme) { | 694 if (!explorerTheme) { |
710 drawBackground = true; | 695 drawBackground = true; |
711 ignoreDrawBackground = false; | 696 ignoreDrawBackground = false; |
712 if (handle is OS.GetFocus () && OS.IsWindowEnabled (handle)) { | 697 if ((handle is OS.GetFocus () || display.getHighContrast ()) && OS.IsWindowEnabled (handle)) { |
713 clrTextBk = OS.GetSysColor (OS.COLOR_HIGHLIGHT); | 698 clrTextBk = OS.GetSysColor (OS.COLOR_HIGHLIGHT); |
714 } else { | 699 } else { |
715 clrTextBk = OS.GetSysColor (OS.COLOR_3DFACE); | 700 clrTextBk = OS.GetSysColor (OS.COLOR_3DFACE); |
716 } | 701 } |
717 if (!ignoreFullSelection && index is count - 1) { | 702 if (!ignoreFullSelection && index is columnCount - 1) { |
718 RECT* selectionRect = new RECT (); | 703 RECT* selectionRect = new RECT (); |
719 OS.SetRect (selectionRect, backgroundRect.left, backgroundRect.top, nmcd.nmcd.rc.right, backgroundRect.bottom); | 704 OS.SetRect (selectionRect, backgroundRect.left, backgroundRect.top, nmcd.nmcd.rc.right, backgroundRect.bottom); |
720 backgroundRect = selectionRect; | 705 backgroundRect = selectionRect; |
721 } | 706 } |
722 } else { | 707 } else { |
723 RECT pRect; | 708 RECT pRect; |
724 OS.SetRect (&pRect, nmcd.nmcd.rc.left, nmcd.nmcd.rc.top, nmcd.nmcd.rc.right, nmcd.nmcd.rc.bottom); | 709 OS.SetRect (&pRect, nmcd.nmcd.rc.left, nmcd.nmcd.rc.top, nmcd.nmcd.rc.right, nmcd.nmcd.rc.bottom); |
725 if (count > 0 && hwndHeader !is null) { | 710 if (columnCount > 0 && hwndHeader !is null) { |
726 int totalWidth = 0; | 711 int totalWidth = 0; |
727 HDITEM hdItem; | 712 HDITEM hdItem; |
728 hdItem.mask = OS.HDI_WIDTH; | 713 hdItem.mask = OS.HDI_WIDTH; |
729 for (int j=0; j<count; j++) { | 714 for (int j=0; j<columnCount; j++) { |
730 OS.SendMessage (hwndHeader, OS.HDM_GETITEM, j, &hdItem); | 715 OS.SendMessage (hwndHeader, OS.HDM_GETITEM, j, &hdItem); |
731 totalWidth += hdItem.cxy; | 716 totalWidth += hdItem.cxy; |
732 } | 717 } |
733 if (totalWidth > clientRect.right - clientRect.left) { | 718 if (totalWidth > clientRect.right - clientRect.left) { |
734 pRect.left = 0; | 719 pRect.left = 0; |
735 pRect.right = totalWidth; | 720 pRect.right = totalWidth; |
736 } else { | 721 } else { |
737 pRect.left = clientRect.left; | 722 pRect.left = clientRect.left; |
738 pRect.right = clientRect.right; | 723 pRect.right = clientRect.right; |
739 } | 724 } |
740 if (index is count - 1) { | 725 if (index is columnCount - 1) { |
741 RECT* selectionRect = new RECT (); | 726 RECT* selectionRect = new RECT (); |
742 OS.SetRect (selectionRect, backgroundRect.left, backgroundRect.top, pRect.right, backgroundRect.bottom); | 727 OS.SetRect (selectionRect, backgroundRect.left, backgroundRect.top, pRect.right, backgroundRect.bottom); |
743 backgroundRect = selectionRect; | 728 backgroundRect = selectionRect; |
744 } | 729 } |
745 } | 730 } |
794 int inset = i !is 0 ? INSET : 0; | 779 int inset = i !is 0 ? INSET : 0; |
795 int offset = i !is 0 ? INSET : INSET + 2; | 780 int offset = i !is 0 ? INSET : INSET + 2; |
796 if (image !is null) { | 781 if (image !is null) { |
797 Rectangle bounds = image.getBounds (); | 782 Rectangle bounds = image.getBounds (); |
798 if (size is null) size = getImageSize (); | 783 if (size is null) size = getImageSize (); |
799 //int y = rect.top + (index is 0 ? (getItemHeight () - size.y) / 2 : 0); | |
800 int y = rect.top; | |
801 if (!ignoreDrawForeground) { | 784 if (!ignoreDrawForeground) { |
802 //TODO - share GC, clip the drawing for index is 0 | 785 //int y1 = rect.top + (index is 0 ? (getItemHeight () - size.y) / 2 : 0); |
786 int y1 = rect.top; | |
787 int x1 = Math.max (rect.left, rect.left - inset + 1); | |
803 GCData data = new GCData(); | 788 GCData data = new GCData(); |
804 data.device = display; | 789 data.device = display; |
805 GC gc = GC.win32_new (hDC, data); | 790 GC gc = GC.win32_new (hDC, data); |
806 //if (index is 0) { //must clear | 791 gc.setClipping (x1, rect.top, rect.right - x1, rect.bottom - rect.top); |
807 //gc.setClipping (rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top); | 792 gc.drawImage (image, 0, 0, bounds.width, bounds.height, x1, y1, size.x, size.y); |
808 //} | 793 OS.SelectClipRgn (hDC, null); |
809 gc.drawImage (image, 0, 0, bounds.width, bounds.height, rect.left - inset + 1, y, size.x, size.y); | |
810 gc.dispose (); | 794 gc.dispose (); |
811 } | 795 } |
812 OS.SetRect (&rect, rect.left + size.x + offset, rect.top, rect.right - inset, rect.bottom); | 796 OS.SetRect (&rect, rect.left + size.x + offset, rect.top, rect.right - inset, rect.bottom); |
813 } else { | 797 } else { |
814 if (i is 0) { | 798 if (i is 0) { |
835 } else { | 819 } else { |
836 String [] strings = item.strings; | 820 String [] strings = item.strings; |
837 if (strings !is null) string = strings [index]; | 821 if (strings !is null) string = strings [index]; |
838 } | 822 } |
839 if (string !is null) { | 823 if (string !is null) { |
840 if (hFont !is cast(HFONT)-1) hFont = OS.SelectObject (hDC, hFont); | 824 if (hFont !is cast(HFONT)-1) hFont = cast(HFONT)OS.SelectObject (hDC, hFont); |
841 if (clrText !is -1) clrText = OS.SetTextColor (hDC, clrText); | 825 if (clrText !is -1) clrText = OS.SetTextColor (hDC, clrText); |
842 if (clrTextBk !is -1) clrTextBk = OS.SetBkColor (hDC, clrTextBk); | 826 if (clrTextBk !is -1) clrTextBk = OS.SetBkColor (hDC, clrTextBk); |
843 int flags = OS.DT_NOPREFIX | OS.DT_SINGLELINE | OS.DT_VCENTER; | 827 int flags = OS.DT_NOPREFIX | OS.DT_SINGLELINE | OS.DT_VCENTER; |
844 if (i !is 0) flags |= OS.DT_ENDELLIPSIS; | 828 if (i !is 0) flags |= OS.DT_ENDELLIPSIS; |
845 TreeColumn column = columns !is null ? columns [index] : null; | 829 TreeColumn column = columns !is null ? columns [index] : null; |
848 if ((column.style & DWT.RIGHT) !is 0) flags |= OS.DT_RIGHT; | 832 if ((column.style & DWT.RIGHT) !is 0) flags |= OS.DT_RIGHT; |
849 } | 833 } |
850 TCHAR[] buffer = StrToTCHARs (getCodePage (), string, false); | 834 TCHAR[] buffer = StrToTCHARs (getCodePage (), string, false); |
851 if (!ignoreDrawForeground) OS.DrawText (hDC, buffer.ptr, buffer.length, &rect, flags); | 835 if (!ignoreDrawForeground) OS.DrawText (hDC, buffer.ptr, buffer.length, &rect, flags); |
852 OS.DrawText (hDC, buffer.ptr, buffer.length, &rect, flags | OS.DT_CALCRECT); | 836 OS.DrawText (hDC, buffer.ptr, buffer.length, &rect, flags | OS.DT_CALCRECT); |
853 if (hFont !is cast(HFONT)-1) hFont = OS.SelectObject (hDC, hFont); | 837 if (hFont !is cast(HFONT)-1) hFont = cast(HFONT)OS.SelectObject (hDC, hFont); |
854 if (clrText !is -1) clrText = OS.SetTextColor (hDC, clrText); | 838 if (clrText !is -1) clrText = OS.SetTextColor (hDC, clrText); |
855 if (clrTextBk !is -1) clrTextBk = OS.SetBkColor (hDC, clrTextBk); | 839 if (clrTextBk !is -1) clrTextBk = OS.SetBkColor (hDC, clrTextBk); |
856 } | 840 } |
857 } | 841 } |
858 } | 842 } |
861 if (hooks (DWT.PaintItem)) { | 845 if (hooks (DWT.PaintItem)) { |
862 RECT itemRect = item.getBounds (index, true, true, false, false, false, hDC); | 846 RECT itemRect = item.getBounds (index, true, true, false, false, false, hDC); |
863 int nSavedDC = OS.SaveDC (hDC); | 847 int nSavedDC = OS.SaveDC (hDC); |
864 GCData data = new GCData (); | 848 GCData data = new GCData (); |
865 data.device = display; | 849 data.device = display; |
866 data.hFont = hFont; | 850 data.font = item.getFont (index); |
867 data.foreground = OS.GetTextColor (hDC); | 851 data.foreground = OS.GetTextColor (hDC); |
868 data.background = OS.GetBkColor (hDC); | 852 data.background = OS.GetBkColor (hDC); |
869 if (selected && (style & DWT.FULL_SELECTION) !is 0) { | 853 if (selected && (style & DWT.FULL_SELECTION) !is 0) { |
870 if (selectionForeground !is -1) data.foreground = selectionForeground; | 854 if (selectionForeground !is -1) data.foreground = selectionForeground; |
871 } else { | 855 } else { |
902 RECT cellRect = item.getBounds (index, true, true, true, true, true, hDC); | 886 RECT cellRect = item.getBounds (index, true, true, true, true, true, hDC); |
903 int cellWidth = cellRect.right - cellRect.left; | 887 int cellWidth = cellRect.right - cellRect.left; |
904 int cellHeight = cellRect.bottom - cellRect.top; | 888 int cellHeight = cellRect.bottom - cellRect.top; |
905 gc.setClipping (cellRect.left, cellRect.top, cellWidth, cellHeight); | 889 gc.setClipping (cellRect.left, cellRect.top, cellWidth, cellHeight); |
906 sendEvent (DWT.PaintItem, event); | 890 sendEvent (DWT.PaintItem, event); |
891 if (data.focusDrawn) focusRect = null; | |
907 event.gc = null; | 892 event.gc = null; |
908 gc.dispose (); | 893 gc.dispose (); |
909 OS.RestoreDC (hDC, nSavedDC); | 894 OS.RestoreDC (hDC, nSavedDC); |
910 if (isDisposed () || item.isDisposed ()) break; | 895 if (isDisposed () || item.isDisposed ()) break; |
911 } | 896 } |
913 x += width; | 898 x += width; |
914 if (x > clientRect.right) break; | 899 if (x > clientRect.right) break; |
915 } | 900 } |
916 if (linesVisible) { | 901 if (linesVisible) { |
917 if ((style & DWT.FULL_SELECTION) !is 0) { | 902 if ((style & DWT.FULL_SELECTION) !is 0) { |
918 if (hwndHeader !is null) { | 903 if (columnCount !is 0) { |
919 if (OS.SendMessage (hwndHeader, OS.HDM_GETITEMCOUNT, 0, 0) !is 0) { | 904 HDITEM hdItem; |
920 HDITEM hdItem; | 905 hdItem.mask = OS.HDI_WIDTH; |
921 hdItem.mask = OS.HDI_WIDTH; | 906 OS.SendMessage (hwndHeader, OS.HDM_GETITEM, 0, &hdItem); |
922 OS.SendMessage (hwndHeader, OS.HDM_GETITEM, 0, &hdItem); | 907 RECT rect; |
923 RECT rect; | 908 OS.SetRect (&rect, nmcd.nmcd.rc.left + hdItem.cxy, nmcd.nmcd.rc.top, nmcd.nmcd.rc.right, nmcd.nmcd.rc.bottom); |
924 OS.SetRect (&rect, nmcd.nmcd.rc.left + hdItem.cxy, nmcd.nmcd.rc.top, nmcd.nmcd.rc.right, nmcd.nmcd.rc.bottom); | 909 OS.DrawEdge (hDC, &rect, OS.BDR_SUNKENINNER, OS.BF_BOTTOM); |
925 OS.DrawEdge (hDC, &rect, OS.BDR_SUNKENINNER, OS.BF_BOTTOM); | |
926 } | |
927 } | 910 } |
928 } | 911 } |
929 RECT rect; | 912 RECT rect; |
930 OS.SetRect (&rect, nmcd.nmcd.rc.left, nmcd.nmcd.rc.top, nmcd.nmcd.rc.right, nmcd.nmcd.rc.bottom); | 913 OS.SetRect (&rect, nmcd.nmcd.rc.left, nmcd.nmcd.rc.top, nmcd.nmcd.rc.right, nmcd.nmcd.rc.bottom); |
931 OS.DrawEdge (hDC, &rect, OS.BDR_SUNKENINNER, OS.BF_BOTTOM); | 914 OS.DrawEdge (hDC, &rect, OS.BDR_SUNKENINNER, OS.BF_BOTTOM); |
932 } | 915 } |
933 if (!explorerTheme) { | 916 if (!ignoreDrawFocus && focusRect !is null) { |
934 if (handle is OS.GetFocus ()) { | 917 OS.DrawFocusRect (hDC, focusRect); |
935 int uiState = OS.SendMessage (handle, OS.WM_QUERYUISTATE, 0, 0); | 918 focusRect = null; |
936 if ((uiState & OS.UISF_HIDEFOCUS) is 0) { | 919 } else { |
937 auto hItem = cast(HANDLE) OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_CARET, 0); | 920 if (!explorerTheme) { |
938 if (hItem is item.handle) { | 921 if (handle is OS.GetFocus ()) { |
939 if (!ignoreDrawFocus && findImageControl () !is null) { | 922 int uiState = OS.SendMessage (handle, OS.WM_QUERYUISTATE, 0, 0); |
940 if ((style & DWT.FULL_SELECTION) !is 0) { | 923 if ((uiState & OS.UISF_HIDEFOCUS) is 0) { |
941 RECT focusRect; | 924 auto hItem = cast(HANDLE) OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_CARET, 0); |
942 OS.SetRect (&focusRect, nmcd.nmcd.rc.left, nmcd.nmcd.rc.top, nmcd.nmcd.rc.right, nmcd.nmcd.rc.bottom); | 925 if (hItem is item.handle) { |
943 if (count > 0 && hwndHeader !is null) { | 926 if (!ignoreDrawFocus && findImageControl () !is null) { |
944 int width = 0; | 927 if ((style & DWT.FULL_SELECTION) !is 0) { |
945 HDITEM hdItem; | 928 RECT focusRect; |
946 hdItem.mask = OS.HDI_WIDTH; | 929 OS.SetRect (&focusRect, 0, nmcd.nmcd.rc.top, clientRect.right + 1, nmcd.nmcd.rc.bottom); |
947 for (int j=0; j<count; j++) { | 930 OS.DrawFocusRect (hDC, &focusRect); |
948 OS.SendMessage (hwndHeader, OS.HDM_GETITEM, j, &hdItem); | 931 } else { |
949 width += hdItem.cxy; | 932 int index = OS.SendMessage (hwndHeader, OS.HDM_ORDERTOINDEX, 0, 0); |
950 } | 933 RECT focusRect = item.getBounds (index, true, false, false, false, false, hDC); |
951 focusRect.left = 0; | 934 RECT clipRect = item.getBounds (index, true, false, false, false, true, hDC); |
952 RECT rect; | 935 OS.IntersectClipRect (hDC, clipRect.left, clipRect.top, clipRect.right, clipRect.bottom); |
953 OS.GetClientRect (handle, &rect); | 936 OS.DrawFocusRect (hDC, &focusRect); |
954 focusRect.right = Math.max (width, rect.right - OS.GetSystemMetrics (OS.SM_CXVSCROLL)); | 937 OS.SelectClipRgn (hDC, null); |
955 } | 938 } |
956 OS.DrawFocusRect (hDC, &focusRect); | |
957 } else { | |
958 int index = OS.SendMessage (hwndHeader, OS.HDM_ORDERTOINDEX, 0, 0); | |
959 RECT focusRect = item.getBounds (index, true, false, false, false, false, hDC); | |
960 RECT clipRect = item.getBounds (index, true, false, false, false, true, hDC); | |
961 OS.IntersectClipRect (hDC, clipRect.left, clipRect.top, clipRect.right, clipRect.bottom); | |
962 OS.DrawFocusRect (hDC, &focusRect); | |
963 OS.SelectClipRgn (hDC, null); | |
964 } | 939 } |
965 } | 940 } |
966 } | 941 } |
967 } | 942 } |
968 } | 943 } |
988 * COMCTL32.DLL, | 963 * COMCTL32.DLL, |
989 */ | 964 */ |
990 if (item is null) return null; | 965 if (item is null) return null; |
991 auto hDC = nmcd.nmcd.hdc; | 966 auto hDC = nmcd.nmcd.hdc; |
992 int index = hwndHeader !is null ? OS.SendMessage (hwndHeader, OS.HDM_ORDERTOINDEX, 0, 0) : 0; | 967 int index = hwndHeader !is null ? OS.SendMessage (hwndHeader, OS.HDM_ORDERTOINDEX, 0, 0) : 0; |
993 HFONT hFont = item.cellFont !is null ? item.cellFont [index] : cast(HFONT)-1; | 968 auto hFont = item.fontHandle (index); |
994 if (hFont is cast(HFONT)-1) hFont = item.font; | |
995 if (hFont !is cast(HFONT)-1) OS.SelectObject (hDC, hFont); | 969 if (hFont !is cast(HFONT)-1) OS.SelectObject (hDC, hFont); |
996 if (ignoreCustomDraw || nmcd.nmcd.rc.left is nmcd.nmcd.rc.right) { | 970 if (ignoreCustomDraw || nmcd.nmcd.rc.left is nmcd.nmcd.rc.right) { |
997 return new LRESULT (hFont is cast(HFONT)-1 ? OS.CDRF_DODEFAULT : OS.CDRF_NEWFONT); | 971 return new LRESULT (hFont is cast(HFONT)-1 ? OS.CDRF_DODEFAULT : OS.CDRF_NEWFONT); |
998 } | 972 } |
999 int count = 0; | |
1000 RECT* clipRect = null; | 973 RECT* clipRect = null; |
1001 if (hwndHeader !is null) { | 974 if (columnCount !is 0) { |
1002 count = OS.SendMessage (hwndHeader, OS.HDM_GETITEMCOUNT, 0, 0); | 975 bool clip = !printClient; |
1003 if (count !is 0) { | 976 if (!OS.IsWinCE && OS.WIN32_VERSION >= OS.VERSION (6, 0)) { |
1004 bool clip = !printClient; | 977 clip = true; |
1005 if (!OS.IsWinCE && OS.WIN32_VERSION >= OS.VERSION (6, 0)) { | 978 } |
1006 clip = true; | 979 if (clip) { |
1007 } | 980 clipRect = new RECT (); |
1008 if (clip) { | 981 HDITEM hdItem; |
1009 clipRect = new RECT (); | 982 hdItem.mask = OS.HDI_WIDTH; |
1010 HDITEM hdItem; | 983 OS.SendMessage (hwndHeader, OS.HDM_GETITEM, index, &hdItem); |
1011 hdItem.mask = OS.HDI_WIDTH; | 984 OS.SetRect (clipRect, nmcd.nmcd.rc.left, nmcd.nmcd.rc.top, nmcd.nmcd.rc.left + hdItem.cxy, nmcd.nmcd.rc.bottom); |
1012 OS.SendMessage (hwndHeader, OS.HDM_GETITEM, index, &hdItem); | |
1013 OS.SetRect (clipRect, nmcd.nmcd.rc.left, nmcd.nmcd.rc.top, nmcd.nmcd.rc.left + hdItem.cxy, nmcd.nmcd.rc.bottom); | |
1014 } | |
1015 } | 985 } |
1016 } | 986 } |
1017 int clrText = -1, clrTextBk = -1; | 987 int clrText = -1, clrTextBk = -1; |
1018 if (OS.IsWindowEnabled (handle)) { | 988 if (OS.IsWindowEnabled (handle)) { |
1019 clrText = item.cellForeground !is null ? item.cellForeground [index] : -1; | 989 clrText = item.cellForeground !is null ? item.cellForeground [index] : -1; |
1032 } | 1002 } |
1033 } | 1003 } |
1034 } | 1004 } |
1035 bool selected = isItemSelected (nmcd); | 1005 bool selected = isItemSelected (nmcd); |
1036 bool hot = explorerTheme && (nmcd.nmcd.uItemState & OS.CDIS_HOT) !is 0; | 1006 bool hot = explorerTheme && (nmcd.nmcd.uItemState & OS.CDIS_HOT) !is 0; |
1007 bool focused = explorerTheme && (nmcd.nmcd.uItemState & OS.CDIS_FOCUS) !is 0; | |
1037 if (OS.IsWindowVisible (handle) && nmcd.nmcd.rc.left < nmcd.nmcd.rc.right && nmcd.nmcd.rc.top < nmcd.nmcd.rc.bottom) { | 1008 if (OS.IsWindowVisible (handle) && nmcd.nmcd.rc.left < nmcd.nmcd.rc.right && nmcd.nmcd.rc.top < nmcd.nmcd.rc.bottom) { |
1038 if (hFont !is cast(HFONT)-1) OS.SelectObject (hDC, hFont); | 1009 if (hFont !is cast(HFONT)-1) OS.SelectObject (hDC, hFont); |
1039 if (linesVisible) { | 1010 if (linesVisible) { |
1040 RECT rect; | 1011 RECT rect; |
1041 OS.SetRect (&rect, nmcd.nmcd.rc.left, nmcd.nmcd.rc.top, nmcd.nmcd.rc.right, nmcd.nmcd.rc.bottom); | 1012 OS.SetRect (&rect, nmcd.nmcd.rc.left, nmcd.nmcd.rc.top, nmcd.nmcd.rc.right, nmcd.nmcd.rc.bottom); |
1042 OS.DrawEdge (hDC, &rect, OS.BDR_SUNKENINNER, OS.BF_BOTTOM); | 1013 OS.DrawEdge (hDC, &rect, OS.BDR_SUNKENINNER, OS.BF_BOTTOM); |
1043 } | 1014 } |
1044 //TODO - BUG - measure and erase sent when first column is clipped | 1015 //TODO - BUG - measure and erase sent when first column is clipped |
1016 Event measureEvent = null; | |
1045 if (hooks (DWT.MeasureItem)) { | 1017 if (hooks (DWT.MeasureItem)) { |
1046 RECT itemRect = item.getBounds (index, true, true, false, false, false, hDC); | 1018 measureEvent = sendMeasureItemEvent (item, index, hDC); |
1047 int nSavedDC = OS.SaveDC (hDC); | |
1048 GCData data = new GCData (); | |
1049 data.device = display; | |
1050 data.hFont = hFont; | |
1051 GC gc = GC.win32_new (hDC, data); | |
1052 Event event = new Event (); | |
1053 event.item = item; | |
1054 event.gc = gc; | |
1055 event.index = index; | |
1056 event.x = itemRect.left; | |
1057 event.y = itemRect.top; | |
1058 event.width = itemRect.right - itemRect.left; | |
1059 event.height = itemRect.bottom - itemRect.top; | |
1060 sendEvent (DWT.MeasureItem, event); | |
1061 event.gc = null; | |
1062 gc.dispose (); | |
1063 OS.RestoreDC (hDC, nSavedDC); | |
1064 if (isDisposed () || item.isDisposed ()) return null; | 1019 if (isDisposed () || item.isDisposed ()) return null; |
1065 if (hwndHeader !is null) { | |
1066 if (count is 0) { | |
1067 if (event.x + event.width > scrollWidth) { | |
1068 setScrollWidth (scrollWidth = event.x + event.width); | |
1069 } | |
1070 } | |
1071 } | |
1072 if (event.height > getItemHeight ()) setItemHeight (event.height); | |
1073 } | 1020 } |
1074 selectionForeground = -1; | 1021 selectionForeground = -1; |
1075 ignoreDrawForeground = ignoreDrawBackground = ignoreDrawSelection = ignoreDrawFocus = ignoreDrawHot = ignoreFullSelection = false; | 1022 ignoreDrawForeground = ignoreDrawBackground = ignoreDrawSelection = ignoreDrawFocus = ignoreDrawHot = ignoreFullSelection = false; |
1076 if (hooks (DWT.EraseItem)) { | 1023 if (hooks (DWT.EraseItem)) { |
1077 RECT rect; | 1024 RECT rect; |
1078 OS.SetRect (&rect, nmcd.nmcd.rc.left, nmcd.nmcd.rc.top, nmcd.nmcd.rc.right, nmcd.nmcd.rc.bottom); | 1025 OS.SetRect (&rect, nmcd.nmcd.rc.left, nmcd.nmcd.rc.top, nmcd.nmcd.rc.right, nmcd.nmcd.rc.bottom); |
1079 if (OS.IsWindowEnabled (handle) || findImageControl () !is null) { | |
1080 drawBackground (hDC, &rect); | |
1081 } else { | |
1082 fillBackground (hDC, OS.GetBkColor (hDC), &rect); | |
1083 } | |
1084 RECT cellRect = item.getBounds (index, true, true, true, true, true, hDC); | 1026 RECT cellRect = item.getBounds (index, true, true, true, true, true, hDC); |
1085 if (clrSortBk !is -1) { | 1027 if (clrSortBk !is -1) { |
1086 RECT fullRect = item.getBounds (index, true, true, true, true, true, hDC); | 1028 drawBackground (hDC, &cellRect, clrSortBk); |
1087 drawBackground (hDC, &fullRect, clrSortBk); | 1029 } else { |
1030 if (OS.IsWindowEnabled (handle) || findImageControl () !is null) { | |
1031 drawBackground (hDC, &rect); | |
1032 } else { | |
1033 fillBackground (hDC, OS.GetBkColor (hDC), &rect); | |
1034 } | |
1088 } | 1035 } |
1089 int nSavedDC = OS.SaveDC (hDC); | 1036 int nSavedDC = OS.SaveDC (hDC); |
1090 GCData data = new GCData (); | 1037 GCData data = new GCData (); |
1091 data.device = display; | 1038 data.device = display; |
1092 if (selected && explorerTheme) { | 1039 if (selected && explorerTheme) { |
1098 if (!selected) { | 1045 if (!selected) { |
1099 if (clrText !is -1) data.foreground = clrText; | 1046 if (clrText !is -1) data.foreground = clrText; |
1100 if (clrTextBk !is -1) data.background = clrTextBk; | 1047 if (clrTextBk !is -1) data.background = clrTextBk; |
1101 } | 1048 } |
1102 data.uiState = OS.SendMessage (handle, OS.WM_QUERYUISTATE, 0, 0); | 1049 data.uiState = OS.SendMessage (handle, OS.WM_QUERYUISTATE, 0, 0); |
1103 if (hFont !is cast(HFONT)-1) data.hFont = hFont; | 1050 data.font = item.getFont (index); |
1104 GC gc = GC.win32_new (hDC, data); | 1051 GC gc = GC.win32_new (hDC, data); |
1105 Event event = new Event (); | 1052 Event event = new Event (); |
1106 event.index = index; | 1053 event.index = index; |
1107 event.item = item; | 1054 event.item = item; |
1108 event.gc = gc; | 1055 event.gc = gc; |
1113 if (!explorerTheme) { | 1060 if (!explorerTheme) { |
1114 //if ((nmcd.uItemState & OS.CDIS_FOCUS) !is 0) { | 1061 //if ((nmcd.uItemState & OS.CDIS_FOCUS) !is 0) { |
1115 if (OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_CARET, 0) is nmcd.nmcd.dwItemSpec) { | 1062 if (OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_CARET, 0) is nmcd.nmcd.dwItemSpec) { |
1116 if (handle is OS.GetFocus ()) { | 1063 if (handle is OS.GetFocus ()) { |
1117 int uiState = OS.SendMessage (handle, OS.WM_QUERYUISTATE, 0, 0); | 1064 int uiState = OS.SendMessage (handle, OS.WM_QUERYUISTATE, 0, 0); |
1118 if ((uiState & OS.UISF_HIDEFOCUS) is 0) event.detail |= DWT.FOCUSED; | 1065 if ((uiState & OS.UISF_HIDEFOCUS) is 0) { |
1066 focused = true; | |
1067 event.detail |= DWT.FOCUSED; | |
1068 } | |
1119 } | 1069 } |
1120 } | 1070 } |
1121 } | 1071 } |
1122 event.x = cellRect.left; | 1072 event.x = cellRect.left; |
1123 event.y = cellRect.top; | 1073 event.y = cellRect.top; |
1142 if (selected && ignoreDrawSelection) ignoreDrawHot = true; | 1092 if (selected && ignoreDrawSelection) ignoreDrawHot = true; |
1143 if (!ignoreDrawBackground && clrTextBk !is -1) { | 1093 if (!ignoreDrawBackground && clrTextBk !is -1) { |
1144 bool draw = !selected && !hot; | 1094 bool draw = !selected && !hot; |
1145 if (!explorerTheme && selected) draw = !ignoreDrawSelection; | 1095 if (!explorerTheme && selected) draw = !ignoreDrawSelection; |
1146 if (draw) { | 1096 if (draw) { |
1147 if (count is 0) { | 1097 if (columnCount is 0) { |
1148 if ((style & DWT.FULL_SELECTION) !is 0) { | 1098 if ((style & DWT.FULL_SELECTION) !is 0) { |
1149 fillBackground (hDC, clrTextBk, &rect); | 1099 fillBackground (hDC, clrTextBk, &rect); |
1150 } else { | 1100 } else { |
1151 RECT textRect = item.getBounds (index, true, false, true, false, true, hDC); | 1101 RECT textRect = item.getBounds (index, true, false, false, false, true, hDC); |
1102 if (measureEvent !is null) { | |
1103 textRect.right = Math.min (cellRect.right, measureEvent.x + measureEvent.width); | |
1104 } | |
1152 fillBackground (hDC, clrTextBk, &textRect); | 1105 fillBackground (hDC, clrTextBk, &textRect); |
1153 } | 1106 } |
1154 } else { | 1107 } else { |
1155 fillBackground (hDC, clrTextBk, &cellRect); | 1108 fillBackground (hDC, clrTextBk, &cellRect); |
1156 } | 1109 } |
1159 if (ignoreDrawSelection) ignoreFullSelection = true; | 1112 if (ignoreDrawSelection) ignoreFullSelection = true; |
1160 if (!ignoreDrawSelection || !ignoreDrawHot) { | 1113 if (!ignoreDrawSelection || !ignoreDrawHot) { |
1161 if (!selected && !hot) { | 1114 if (!selected && !hot) { |
1162 selectionForeground = clrText = OS.GetSysColor (OS.COLOR_HIGHLIGHTTEXT); | 1115 selectionForeground = clrText = OS.GetSysColor (OS.COLOR_HIGHLIGHTTEXT); |
1163 } | 1116 } |
1164 if (!explorerTheme) { | 1117 if (explorerTheme) { |
1118 if ((style & DWT.FULL_SELECTION) is 0) { | |
1119 RECT pRect = item.getBounds (index, true, true, false, false, false, hDC); | |
1120 RECT pClipRect = item.getBounds (index, true, true, true, false, true, hDC); | |
1121 if (measureEvent !is null) { | |
1122 pRect.right = Math.min (pClipRect.right, measureEvent.x + measureEvent.width); | |
1123 } else { | |
1124 pRect.right += EXPLORER_EXTRA; | |
1125 pClipRect.right += EXPLORER_EXTRA; | |
1126 } | |
1127 pRect.left -= EXPLORER_EXTRA; | |
1128 pClipRect.left -= EXPLORER_EXTRA; | |
1129 auto hTheme = OS.OpenThemeData (handle, Display.TREEVIEW.ptr); | |
1130 int iStateId = selected ? OS.TREIS_SELECTED : OS.TREIS_HOT; | |
1131 if (OS.GetFocus () !is handle && selected && !hot) iStateId = OS.TREIS_SELECTEDNOTFOCUS; | |
1132 OS.DrawThemeBackground (hTheme, hDC, OS.TVP_TREEITEM, iStateId, &pRect, &pClipRect); | |
1133 OS.CloseThemeData (hTheme); | |
1134 } | |
1135 } else { | |
1165 /* | 1136 /* |
1166 * Feature in Windows. When the tree has the style | 1137 * Feature in Windows. When the tree has the style |
1167 * TVS_FULLROWSELECT, the background color for the | 1138 * TVS_FULLROWSELECT, the background color for the |
1168 * entire row is filled when an item is painted, | 1139 * entire row is filled when an item is painted, |
1169 * drawing on top of any custom drawing. The fix | 1140 * drawing on top of any custom drawing. The fix |
1170 * is to emulate TVS_FULLROWSELECT. | 1141 * is to emulate TVS_FULLROWSELECT. |
1171 */ | 1142 */ |
1172 if ((style & DWT.FULL_SELECTION) !is 0) { | 1143 if ((style & DWT.FULL_SELECTION) !is 0) { |
1173 if ((style & DWT.FULL_SELECTION) !is 0 && count is 0) { | 1144 if ((style & DWT.FULL_SELECTION) !is 0 && columnCount is 0) { |
1174 fillBackground (hDC, OS.GetBkColor (hDC), &rect); | 1145 fillBackground (hDC, OS.GetBkColor (hDC), &rect); |
1175 } else { | 1146 } else { |
1176 fillBackground (hDC, OS.GetBkColor (hDC), &cellRect); | 1147 fillBackground (hDC, OS.GetBkColor (hDC), &cellRect); |
1177 } | 1148 } |
1178 } else { | 1149 } else { |
1179 RECT textRect = item.getBounds (index, true, false, false, false, true, hDC); | 1150 RECT textRect = item.getBounds (index, true, false, false, false, true, hDC); |
1151 if (measureEvent !is null) { | |
1152 textRect.right = Math.min (cellRect.right, measureEvent.x + measureEvent.width); | |
1153 } | |
1180 fillBackground (hDC, OS.GetBkColor (hDC), &textRect); | 1154 fillBackground (hDC, OS.GetBkColor (hDC), &textRect); |
1181 } | 1155 } |
1182 } | 1156 } |
1183 } else { | 1157 } else { |
1184 if (selected || hot) { | 1158 if (selected || hot) { |
1201 nmcd.clrText = newColor; | 1175 nmcd.clrText = newColor; |
1202 } | 1176 } |
1203 OS.MoveMemory (lParam, nmcd, NMTVCUSTOMDRAW.sizeof); | 1177 OS.MoveMemory (lParam, nmcd, NMTVCUSTOMDRAW.sizeof); |
1204 } | 1178 } |
1205 } | 1179 } |
1180 if (focused && !ignoreDrawFocus && (style & DWT.FULL_SELECTION) is 0) { | |
1181 RECT textRect = item.getBounds (index, true, explorerTheme, false, false, true, hDC); | |
1182 if (measureEvent !is null) { | |
1183 textRect.right = Math.min (cellRect.right, measureEvent.x + measureEvent.width); | |
1184 } | |
1185 nmcd.nmcd.uItemState &= ~OS.CDIS_FOCUS; | |
1186 OS.MoveMemory (lParam, nmcd, NMTVCUSTOMDRAW.sizeof); | |
1187 if( focusRect is null ) focusRect = new RECT; | |
1188 *focusRect = textRect; | |
1189 } | |
1206 if (explorerTheme) { | 1190 if (explorerTheme) { |
1207 if (selected || (hot && ignoreDrawHot)) nmcd.nmcd.uItemState &= ~OS.CDIS_HOT; | 1191 if (selected || (hot && ignoreDrawHot)) nmcd.nmcd.uItemState &= ~OS.CDIS_HOT; |
1208 OS.MoveMemory (cast(void*)lParam, nmcd, NMTVCUSTOMDRAW.sizeof); | 1192 OS.MoveMemory (cast(void*)lParam, nmcd, NMTVCUSTOMDRAW.sizeof); |
1209 } | 1193 } |
1210 RECT itemRect = item.getBounds (index, true, true, false, false, false, hDC); | 1194 RECT itemRect = item.getBounds (index, true, true, false, false, false, hDC); |
1258 * The fix is to fill the cell with the background color. | 1242 * The fix is to fill the cell with the background color. |
1259 */ | 1243 */ |
1260 if (clrTextBk !is -1) { | 1244 if (clrTextBk !is -1) { |
1261 int bits = OS.GetWindowLong (handle, OS.GWL_STYLE); | 1245 int bits = OS.GetWindowLong (handle, OS.GWL_STYLE); |
1262 if ((bits & OS.TVS_FULLROWSELECT) is 0) { | 1246 if ((bits & OS.TVS_FULLROWSELECT) is 0) { |
1263 if (count !is 0 && hwndHeader !is null) { | 1247 if (columnCount !is 0 && hwndHeader !is null) { |
1264 RECT rect; | 1248 RECT rect; |
1265 HDITEM hdItem; | 1249 HDITEM hdItem; |
1266 hdItem.mask = OS.HDI_WIDTH; | 1250 hdItem.mask = OS.HDI_WIDTH; |
1267 OS.SendMessage (hwndHeader, OS.HDM_GETITEM, index, &hdItem); | 1251 OS.SendMessage (hwndHeader, OS.HDM_GETITEM, index, &hdItem); |
1268 OS.SetRect (&rect, nmcd.nmcd.rc.left, nmcd.nmcd.rc.top, nmcd.nmcd.rc.left + hdItem.cxy, nmcd.nmcd.rc.bottom); | 1252 OS.SetRect (&rect, nmcd.nmcd.rc.left, nmcd.nmcd.rc.top, nmcd.nmcd.rc.left + hdItem.cxy, nmcd.nmcd.rc.bottom); |
1269 if (OS.COMCTL32_MAJOR < 6 || !OS.IsAppThemed ()) { | 1253 if (OS.COMCTL32_MAJOR < 6 || !OS.IsAppThemed ()) { |
1270 RECT itemRect; | 1254 RECT itemRect; |
1271 itemRect.left = cast(int) item.handle; | 1255 if (OS.TreeView_GetItemRect (handle, item.handle, &itemRect, true)) { |
1272 if (OS.SendMessage (handle, OS.TVM_GETITEMRECT, 1, &itemRect) !is 0) { | |
1273 rect.left = Math.min (itemRect.left, rect.right); | 1256 rect.left = Math.min (itemRect.left, rect.right); |
1274 } | 1257 } |
1275 } | 1258 } |
1276 if ((style & DWT.FULL_SELECTION) !is 0) { | 1259 if ((style & DWT.FULL_SELECTION) !is 0) { |
1277 if (!selected) fillBackground (hDC, clrTextBk, &rect); | 1260 if (!selected) fillBackground (hDC, clrTextBk, &rect); |
1327 } | 1310 } |
1328 OS.MoveMemory (lParam, nmcd, NMTVCUSTOMDRAW.sizeof); | 1311 OS.MoveMemory (lParam, nmcd, NMTVCUSTOMDRAW.sizeof); |
1329 if (clrTextBk !is -1) { | 1312 if (clrTextBk !is -1) { |
1330 if ((style & DWT.FULL_SELECTION) !is 0) { | 1313 if ((style & DWT.FULL_SELECTION) !is 0) { |
1331 RECT rect; | 1314 RECT rect; |
1332 if (count !is 0) { | 1315 if (columnCount !is 0) { |
1333 HDITEM hdItem; | 1316 HDITEM hdItem; |
1334 hdItem.mask = OS.HDI_WIDTH; | 1317 hdItem.mask = OS.HDI_WIDTH; |
1335 OS.SendMessage (hwndHeader, OS.HDM_GETITEM, index, &hdItem); | 1318 OS.SendMessage (hwndHeader, OS.HDM_GETITEM, index, &hdItem); |
1336 OS.SetRect (&rect, nmcd.nmcd.rc.left, nmcd.nmcd.rc.top, nmcd.nmcd.rc.left + hdItem.cxy, nmcd.nmcd.rc.bottom); | 1319 OS.SetRect (&rect, nmcd.nmcd.rc.left, nmcd.nmcd.rc.top, nmcd.nmcd.rc.left + hdItem.cxy, nmcd.nmcd.rc.bottom); |
1337 } else { | 1320 } else { |
1404 } else { | 1387 } else { |
1405 hItem = cast(HANDLE) OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_LASTVISIBLE, 0); | 1388 hItem = cast(HANDLE) OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_LASTVISIBLE, 0); |
1406 } | 1389 } |
1407 if (hItem !is null) { | 1390 if (hItem !is null) { |
1408 RECT rect; | 1391 RECT rect; |
1409 rect.left = cast(int) hItem; | 1392 if (OS.TreeView_GetItemRect (handle, hItem, &rect, false)) { |
1410 if (OS.SendMessage (handle, OS.TVM_GETITEMRECT, 0, &rect) !is 0) { | |
1411 top = rect.bottom; | 1393 top = rect.bottom; |
1412 } | 1394 } |
1413 } | 1395 } |
1414 RECT rect; | 1396 RECT rect; |
1415 OS.SetRect (&rect, nmcd.nmcd.rc.left, top, nmcd.nmcd.rc.right, nmcd.nmcd.rc.bottom); | 1397 OS.SetRect (&rect, nmcd.nmcd.rc.left, top, nmcd.nmcd.rc.right, nmcd.nmcd.rc.bottom); |
1427 if (hwndHeader !is null) { | 1409 if (hwndHeader !is null) { |
1428 int x = 0; | 1410 int x = 0; |
1429 RECT rect; | 1411 RECT rect; |
1430 HDITEM hdItem; | 1412 HDITEM hdItem; |
1431 hdItem.mask = OS.HDI_WIDTH; | 1413 hdItem.mask = OS.HDI_WIDTH; |
1432 int count = OS.SendMessage (hwndHeader, OS.HDM_GETITEMCOUNT, 0, 0); | 1414 for (int i=0; i<columnCount; i++) { |
1433 for (int i=0; i<count; i++) { | |
1434 int index = OS.SendMessage (hwndHeader, OS.HDM_ORDERTOINDEX, i, 0); | 1415 int index = OS.SendMessage (hwndHeader, OS.HDM_ORDERTOINDEX, i, 0); |
1435 OS.SendMessage (hwndHeader, OS.HDM_GETITEM, index, &hdItem); | 1416 OS.SendMessage (hwndHeader, OS.HDM_GETITEM, index, &hdItem); |
1436 OS.SetRect (&rect, x, nmcd.nmcd.rc.top, x + hdItem.cxy, nmcd.nmcd.rc.bottom); | 1417 OS.SetRect (&rect, x, nmcd.nmcd.rc.top, x + hdItem.cxy, nmcd.nmcd.rc.bottom); |
1437 OS.DrawEdge (hDC, &rect, OS.BDR_SUNKENINNER, OS.BF_RIGHT); | 1418 OS.DrawEdge (hDC, &rect, OS.BDR_SUNKENINNER, OS.BF_RIGHT); |
1438 x += hdItem.cxy; | 1419 x += hdItem.cxy; |
1461 hItem = getBottomItem (); | 1442 hItem = getBottomItem (); |
1462 } else { | 1443 } else { |
1463 hItem = cast(HANDLE) OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_LASTVISIBLE, 0); | 1444 hItem = cast(HANDLE) OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_LASTVISIBLE, 0); |
1464 } | 1445 } |
1465 if (hItem !is null) { | 1446 if (hItem !is null) { |
1466 rect.left = cast(int) hItem; | 1447 if (OS.TreeView_GetItemRect (handle, hItem, &rect, false)) { |
1467 if (OS.SendMessage (handle, OS.TVM_GETITEMRECT, 0, &rect) !is 0) { | |
1468 height = rect.bottom - rect.top; | 1448 height = rect.bottom - rect.top; |
1469 } | 1449 } |
1470 } | 1450 } |
1471 if (height is 0) { | 1451 if (height is 0) { |
1472 height = OS.SendMessage (handle, OS.TVM_GETITEMHEIGHT, 0, 0); | 1452 height = OS.SendMessage (handle, OS.TVM_GETITEMHEIGHT, 0, 0); |
1589 } | 1569 } |
1590 break; | 1570 break; |
1591 } | 1571 } |
1592 default: | 1572 default: |
1593 } | 1573 } |
1594 int code = OS.CallWindowProc (TreeProc, hwnd, msg, wParam, lParam); | 1574 int /*long*/ code = OS.CallWindowProc (TreeProc, hwnd, msg, wParam, lParam); |
1595 switch (msg) { | 1575 switch (msg) { |
1596 /* Keyboard messages */ | 1576 /* Keyboard messages */ |
1597 case OS.WM_KEYDOWN: | 1577 case OS.WM_KEYDOWN: |
1598 if (wParam is OS.VK_CONTROL || wParam is OS.VK_SHIFT) break; | 1578 if (wParam is OS.VK_CONTROL || wParam is OS.VK_SHIFT) break; |
1599 //FALL THROUGH | 1579 //FALL THROUGH |
1663 if ((style & DWT.VIRTUAL) !is 0) { | 1643 if ((style & DWT.VIRTUAL) !is 0) { |
1664 style |= DWT.DOUBLE_BUFFERED; | 1644 style |= DWT.DOUBLE_BUFFERED; |
1665 OS.SendMessage (handle, OS.TVM_SETSCROLLTIME, 0, 0); | 1645 OS.SendMessage (handle, OS.TVM_SETSCROLLTIME, 0, 0); |
1666 } | 1646 } |
1667 if (EXPLORER_THEME) { | 1647 if (EXPLORER_THEME) { |
1668 if (!OS.IsWinCE && OS.WIN32_VERSION >= OS.VERSION (6, 0)) { | 1648 if (!OS.IsWinCE && OS.WIN32_VERSION >= OS.VERSION (6, 0) && OS.IsAppThemed ()) { |
1669 int exStyle = OS.SendMessage (handle, OS.TVM_GETEXTENDEDSTYLE, 0, 0); | 1649 int exStyle = OS.SendMessage (handle, OS.TVM_GETEXTENDEDSTYLE, 0, 0); |
1670 if ((exStyle & OS.TVS_EX_DOUBLEBUFFER) !is 0) style |= DWT.DOUBLE_BUFFERED; | 1650 if ((exStyle & OS.TVS_EX_DOUBLEBUFFER) !is 0) style |= DWT.DOUBLE_BUFFERED; |
1671 } | 1651 } |
1672 } | 1652 } |
1673 } | 1653 } |
1674 | 1654 |
1675 bool checkData (TreeItem item, bool redraw) { | 1655 bool checkData (TreeItem item, bool redraw) { |
1676 if ((style & DWT.VIRTUAL) is 0) return true; | 1656 if ((style & DWT.VIRTUAL) is 0) return true; |
1677 TreeItem parentItem = item.getParentItem (); | 1657 if (!item.cached) { |
1678 return checkData (item, parentItem is null ? indexOf (item) : parentItem.indexOf (item), redraw); | 1658 TreeItem parentItem = item.getParentItem (); |
1659 return checkData (item, parentItem is null ? indexOf (item) : parentItem.indexOf (item), redraw); | |
1660 } | |
1661 return true; | |
1679 } | 1662 } |
1680 | 1663 |
1681 bool checkData (TreeItem item, int index, bool redraw) { | 1664 bool checkData (TreeItem item, int index, bool redraw) { |
1682 if ((style & DWT.VIRTUAL) is 0) return true; | 1665 if ((style & DWT.VIRTUAL) is 0) return true; |
1683 if (!item.cached) { | 1666 if (!item.cached) { |
1711 * | 1694 * |
1712 * NOTE: The code that actually works around the problem is in the | 1695 * NOTE: The code that actually works around the problem is in the |
1713 * callers of this method. | 1696 * callers of this method. |
1714 */ | 1697 */ |
1715 if (drawCount is 0) return false; | 1698 if (drawCount is 0) return false; |
1716 int hRoot = OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_ROOT, 0); | 1699 int /*long*/ hRoot = OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_ROOT, 0); |
1717 int hParent = OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_PARENT, hItem); | 1700 int /*long*/ hParent = OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_PARENT, hItem); |
1718 while (hParent !is hRoot && hParent !is 0) { | 1701 while (hParent !is hRoot && hParent !is 0) { |
1719 hParent = OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_PARENT, hParent); | 1702 hParent = OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_PARENT, hParent); |
1720 } | 1703 } |
1721 return hParent is 0; | 1704 return hParent is 0; |
1722 } | 1705 } |
1768 TreeItem item = null; | 1751 TreeItem item = null; |
1769 if (OS.SendMessage (handle, OS.TVM_GETITEM, 0, tvItem) !is 0) { | 1752 if (OS.SendMessage (handle, OS.TVM_GETITEM, 0, tvItem) !is 0) { |
1770 item = tvItem.lParam !is -1 ? items [tvItem.lParam] : null; | 1753 item = tvItem.lParam !is -1 ? items [tvItem.lParam] : null; |
1771 } | 1754 } |
1772 if (item !is null) { | 1755 if (item !is null) { |
1756 if ((style & DWT.VIRTUAL) !is 0 && !item.cached) return; | |
1773 item.clear (); | 1757 item.clear (); |
1774 item.redraw (); | 1758 item.redraw (); |
1775 } | 1759 } |
1776 } | 1760 } |
1777 | 1761 |
1796 */ | 1780 */ |
1797 public void clearAll (bool all) { | 1781 public void clearAll (bool all) { |
1798 checkWidget (); | 1782 checkWidget (); |
1799 HANDLE hItem = cast(HANDLE) OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_ROOT, 0); | 1783 HANDLE hItem = cast(HANDLE) OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_ROOT, 0); |
1800 if (hItem is null) return; | 1784 if (hItem is null) return; |
1801 TVITEM tvItem; | 1785 if (all) { |
1802 tvItem.mask = OS.TVIF_HANDLE | OS.TVIF_PARAM; | 1786 bool redraw = false; |
1803 clearAll (hItem, &tvItem, all); | 1787 for (int i=0; i<items.length; i++) { |
1788 TreeItem item = items [i]; | |
1789 if (item !is null && item !is currentItem) { | |
1790 item.clear (); | |
1791 redraw = true; | |
1792 } | |
1793 } | |
1794 if (redraw) OS.InvalidateRect (handle, null, true); | |
1795 } else { | |
1796 TVITEM tvItem; | |
1797 tvItem.mask = OS.TVIF_HANDLE | OS.TVIF_PARAM; | |
1798 clearAll (hItem, &tvItem, all); | |
1799 } | |
1804 } | 1800 } |
1805 | 1801 |
1806 void clearAll (HANDLE hItem, TVITEM* tvItem, bool all) { | 1802 void clearAll (HANDLE hItem, TVITEM* tvItem, bool all) { |
1807 while (hItem !is null) { | 1803 while (hItem !is null) { |
1808 clear (hItem, tvItem); | 1804 clear (hItem, tvItem); |
1809 auto hFirstItem = cast(HANDLE) OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_CHILD, hItem); | 1805 if (all) { |
1810 if (all) clearAll (hFirstItem, tvItem, all); | 1806 auto hFirstItem = cast(HANDLE)OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_CHILD, hItem); |
1807 clearAll (hFirstItem, tvItem, all); | |
1808 } | |
1811 hItem = cast(HANDLE) OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_NEXT, hItem); | 1809 hItem = cast(HANDLE) OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_NEXT, hItem); |
1812 } | 1810 } |
1813 } | 1811 } |
1814 | 1812 |
1815 private static extern(Windows) int CompareFunc (int lParam1, int lParam2, int lParamSort) { | 1813 private static extern(Windows) int CompareFunc (int lParam1, int lParam2, int lParamSort) { |
1825 checkWidget (); | 1823 checkWidget (); |
1826 int width = 0, height = 0; | 1824 int width = 0, height = 0; |
1827 if (hwndHeader !is null) { | 1825 if (hwndHeader !is null) { |
1828 HDITEM hdItem; | 1826 HDITEM hdItem; |
1829 hdItem.mask = OS.HDI_WIDTH; | 1827 hdItem.mask = OS.HDI_WIDTH; |
1830 int count = OS.SendMessage (hwndHeader, OS.HDM_GETITEMCOUNT, 0, 0); | 1828 for (int i=0; i<columnCount; i++) { |
1831 for (int i=0; i<count; i++) { | |
1832 OS.SendMessage (hwndHeader, OS.HDM_GETITEM, i, &hdItem); | 1829 OS.SendMessage (hwndHeader, OS.HDM_GETITEM, i, &hdItem); |
1833 width += hdItem.cxy; | 1830 width += hdItem.cxy; |
1834 } | 1831 } |
1835 RECT rect; | 1832 RECT rect; |
1836 OS.GetWindowRect (hwndHeader, &rect); | 1833 OS.GetWindowRect (hwndHeader, &rect); |
1846 tvItem.pszText = OS.LPSTR_TEXTCALLBACK; | 1843 tvItem.pszText = OS.LPSTR_TEXTCALLBACK; |
1847 ignoreCustomDraw = true; | 1844 ignoreCustomDraw = true; |
1848 OS.SendMessage (handle, OS.TVM_SETITEM, 0, &tvItem); | 1845 OS.SendMessage (handle, OS.TVM_SETITEM, 0, &tvItem); |
1849 ignoreCustomDraw = false; | 1846 ignoreCustomDraw = false; |
1850 } | 1847 } |
1851 rect.left = cast(int) hItem; | 1848 if (OS.TreeView_GetItemRect (handle, hItem, &rect, true)) { |
1852 if (OS.SendMessage (handle, OS.TVM_GETITEMRECT, 1, &rect) !is 0) { | |
1853 width = Math.max (width, rect.right); | 1849 width = Math.max (width, rect.right); |
1854 height += rect.bottom - rect.top; | 1850 height += rect.bottom - rect.top; |
1855 } | 1851 } |
1856 hItem = cast(HANDLE) OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_NEXT, hItem); | 1852 hItem = cast(HANDLE) OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_NEXTVISIBLE, hItem); |
1857 } | 1853 } |
1858 if (width is 0) width = DEFAULT_WIDTH; | 1854 if (width is 0) width = DEFAULT_WIDTH; |
1859 if (height is 0) height = DEFAULT_HEIGHT; | 1855 if (height is 0) height = DEFAULT_HEIGHT; |
1860 if (wHint !is DWT.DEFAULT) width = wHint; | 1856 if (wHint !is DWT.DEFAULT) width = wHint; |
1861 if (hHint !is DWT.DEFAULT) height = hHint; | 1857 if (hHint !is DWT.DEFAULT) height = hHint; |
1875 super.createHandle (); | 1871 super.createHandle (); |
1876 state &= ~(CANVAS | THEME_BACKGROUND); | 1872 state &= ~(CANVAS | THEME_BACKGROUND); |
1877 | 1873 |
1878 /* Use the Explorer theme */ | 1874 /* Use the Explorer theme */ |
1879 if (EXPLORER_THEME) { | 1875 if (EXPLORER_THEME) { |
1880 if (!OS.IsWinCE && OS.WIN32_VERSION >= OS.VERSION (6, 0)) { | 1876 if (!OS.IsWinCE && OS.WIN32_VERSION >= OS.VERSION (6, 0) && OS.IsAppThemed ()) { |
1881 explorerTheme = true; | 1877 explorerTheme = true; |
1882 OS.SetWindowTheme (handle, cast(TCHAR*) Display.EXPLORER, null); | 1878 OS.SetWindowTheme (handle, cast(TCHAR*) Display.EXPLORER, null); |
1883 int bits = OS.TVS_EX_DOUBLEBUFFER | OS.TVS_EX_FADEINOUTEXPANDOS | OS.TVS_EX_RICHTOOLTIP; | 1879 int bits = OS.TVS_EX_DOUBLEBUFFER | OS.TVS_EX_FADEINOUTEXPANDOS | OS.TVS_EX_RICHTOOLTIP; |
1884 if ((style & DWT.FULL_SELECTION) is 0) bits |= OS.TVS_EX_AUTOHSCROLL; | 1880 if ((style & DWT.FULL_SELECTION) is 0) bits |= OS.TVS_EX_AUTOHSCROLL; |
1885 OS.SendMessage (handle, OS.TVM_SETEXTENDEDSTYLE, 0, bits); | 1881 OS.SendMessage (handle, OS.TVM_SETEXTENDEDSTYLE, 0, bits); |
1929 } | 1925 } |
1930 | 1926 |
1931 void createHeaderToolTips () { | 1927 void createHeaderToolTips () { |
1932 static if (OS.IsWinCE) return; | 1928 static if (OS.IsWinCE) return; |
1933 if (headerToolTipHandle !is null) return; | 1929 if (headerToolTipHandle !is null) return; |
1930 int bits = 0; | |
1931 if (OS.WIN32_VERSION >= OS.VERSION (4, 10)) { | |
1932 if ((style & DWT.RIGHT_TO_LEFT) !is 0) bits |= OS.WS_EX_LAYOUTRTL; | |
1933 } | |
1934 headerToolTipHandle = OS.CreateWindowEx ( | 1934 headerToolTipHandle = OS.CreateWindowEx ( |
1935 0, | 1935 bits, |
1936 OS.TOOLTIPS_CLASS.ptr, | 1936 OS.TOOLTIPS_CLASS.ptr, |
1937 null, | 1937 null, |
1938 0, | 1938 OS.TTS_NOPREFIX, |
1939 OS.CW_USEDEFAULT, 0, OS.CW_USEDEFAULT, 0, | 1939 OS.CW_USEDEFAULT, 0, OS.CW_USEDEFAULT, 0, |
1940 handle, | 1940 handle, |
1941 null, | 1941 null, |
1942 OS.GetModuleHandle (null), | 1942 OS.GetModuleHandle (null), |
1943 null); | 1943 null); |
1952 OS.SendMessage (headerToolTipHandle, OS.TTM_SETMAXTIPWIDTH, 0, 0x7FFF); | 1952 OS.SendMessage (headerToolTipHandle, OS.TTM_SETMAXTIPWIDTH, 0, 0x7FFF); |
1953 } | 1953 } |
1954 | 1954 |
1955 void createItem (TreeColumn column, int index) { | 1955 void createItem (TreeColumn column, int index) { |
1956 if (hwndHeader is null) createParent (); | 1956 if (hwndHeader is null) createParent (); |
1957 int columnCount = OS.SendMessage (hwndHeader, OS.HDM_GETITEMCOUNT, 0, 0); | |
1958 if (!(0 <= index && index <= columnCount)) error (DWT.ERROR_INVALID_RANGE); | 1957 if (!(0 <= index && index <= columnCount)) error (DWT.ERROR_INVALID_RANGE); |
1959 if (columnCount is columns.length) { | 1958 if (columnCount is columns.length) { |
1960 TreeColumn [] newColumns = new TreeColumn [columns.length + 4]; | 1959 TreeColumn [] newColumns = new TreeColumn [columns.length + 4]; |
1961 System.arraycopy (columns, 0, newColumns, 0, columns.length); | 1960 System.arraycopy (columns, 0, newColumns, 0, columns.length); |
1962 columns = newColumns; | 1961 columns = newColumns; |
2007 System.arraycopy (cellForeground, index, temp, index + 1, columnCount - index); | 2006 System.arraycopy (cellForeground, index, temp, index + 1, columnCount - index); |
2008 temp [index] = -1; | 2007 temp [index] = -1; |
2009 item.cellForeground = temp; | 2008 item.cellForeground = temp; |
2010 } | 2009 } |
2011 if (item.cellFont !is null) { | 2010 if (item.cellFont !is null) { |
2012 HFONT [] cellFont = item.cellFont; | 2011 Font [] cellFont = item.cellFont; |
2013 HFONT [] temp = new HFONT [columnCount + 1]; | 2012 Font [] temp = new Font [columnCount + 1]; |
2014 System.arraycopy (cellFont, 0, temp, 0, index); | 2013 System.arraycopy (cellFont, 0, temp, 0, index); |
2015 System.arraycopy (cellFont, index, temp, index + 1, columnCount- index); | 2014 System.arraycopy (cellFont, index, temp, index + 1, columnCount- index); |
2016 temp [index] = cast(HFONT)-1; | |
2017 item.cellFont = temp; | 2015 item.cellFont = temp; |
2018 } | 2016 } |
2019 } | 2017 } |
2020 } | 2018 } |
2021 System.arraycopy (columns, index, columns, index + 1, columnCount - index); | 2019 System.arraycopy (columns, index, columns, index + 1, columnCount++ - index); |
2022 columns [index] = column; | 2020 columns [index] = column; |
2023 | 2021 |
2024 /* | 2022 /* |
2025 * Bug in Windows. For some reason, when HDM_INSERTITEM | 2023 * Bug in Windows. For some reason, when HDM_INSERTITEM |
2026 * is used to insert an item into a header without text, | 2024 * is used to insert an item into a header without text, |
2037 if ((column.style & DWT.RIGHT) is DWT.RIGHT) hdItem.fmt = OS.HDF_RIGHT; | 2035 if ((column.style & DWT.RIGHT) is DWT.RIGHT) hdItem.fmt = OS.HDF_RIGHT; |
2038 OS.SendMessage (hwndHeader, OS.HDM_INSERTITEM, index, &hdItem); | 2036 OS.SendMessage (hwndHeader, OS.HDM_INSERTITEM, index, &hdItem); |
2039 if (pszText !is null) OS.HeapFree (hHeap, 0, pszText); | 2037 if (pszText !is null) OS.HeapFree (hHeap, 0, pszText); |
2040 | 2038 |
2041 /* When the first column is created, hide the horizontal scroll bar */ | 2039 /* When the first column is created, hide the horizontal scroll bar */ |
2042 if (columnCount is 0) { | 2040 if (columnCount is 1) { |
2043 scrollWidth = 0; | 2041 scrollWidth = 0; |
2044 int bits = OS.GetWindowLong (handle, OS.GWL_STYLE); | 2042 if ((style & DWT.H_SCROLL) !is 0) { |
2045 bits |= OS.TVS_NOHSCROLL; | 2043 int bits = OS.GetWindowLong (handle, OS.GWL_STYLE); |
2046 OS.SetWindowLong (handle, OS.GWL_STYLE, bits); | 2044 bits |= OS.TVS_NOHSCROLL; |
2045 OS.SetWindowLong (handle, OS.GWL_STYLE, bits); | |
2046 } | |
2047 /* | 2047 /* |
2048 * Bug in Windows. When TVS_NOHSCROLL is set after items | 2048 * Bug in Windows. When TVS_NOHSCROLL is set after items |
2049 * have been inserted into the tree, Windows shows the | 2049 * have been inserted into the tree, Windows shows the |
2050 * scroll bar. The fix is to check for this case and | 2050 * scroll bar. The fix is to check for this case and |
2051 * explicitly hide the scroll bar explicitly. | 2051 * explicitly hide the scroll bar explicitly. |
2052 */ | 2052 */ |
2053 int count = OS.SendMessage (handle, OS.TVM_GETCOUNT, 0, 0); | 2053 int count = OS.SendMessage (handle, OS.TVM_GETCOUNT, 0, 0); |
2054 if (count !is 0) { | 2054 if (count !is 0) { |
2055 static if (!OS.IsWinCE) OS.ShowScrollBar (handle, OS.SB_HORZ, false); | 2055 static if (!OS.IsWinCE) OS.ShowScrollBar (handle, OS.SB_HORZ, false); |
2056 } | 2056 } |
2057 createItemToolTips (); | |
2058 if (itemToolTipHandle !is null) { | |
2059 OS.SendMessage (itemToolTipHandle, OS.TTM_SETDELAYTIME, OS.TTDT_AUTOMATIC, -1); | |
2060 } | |
2057 } | 2061 } |
2058 setScrollWidth (); | 2062 setScrollWidth (); |
2059 updateImageList (); | 2063 updateImageList (); |
2060 updateScrollBar (); | 2064 updateScrollBar (); |
2061 | 2065 |
2062 /* Redraw to hide the items when the first column is created */ | 2066 /* Redraw to hide the items when the first column is created */ |
2063 if (columnCount is 0 && OS.SendMessage (handle, OS.TVM_GETCOUNT, 0, 0) !is 0) { | 2067 if (columnCount is 1 && OS.SendMessage (handle, OS.TVM_GETCOUNT, 0, 0) !is 0) { |
2064 OS.InvalidateRect (handle, null, true); | 2068 OS.InvalidateRect (handle, null, true); |
2065 } | 2069 } |
2066 | 2070 |
2067 /* Add the tool tip item for the header */ | 2071 /* Add the tool tip item for the header */ |
2068 if (headerToolTipHandle !is null) { | 2072 if (headerToolTipHandle !is null) { |
2146 if (item !is null) { | 2150 if (item !is null) { |
2147 item.handle = hNewItem; | 2151 item.handle = hNewItem; |
2148 items [id] = item; | 2152 items [id] = item; |
2149 } | 2153 } |
2150 if (hFirstItem is null) { | 2154 if (hFirstItem is null) { |
2151 switch ( cast(int) hInsertAfter) { | 2155 if (cast(int)hInsertAfter is OS.TVI_FIRST || cast(int)hInsertAfter is OS.TVI_LAST) { |
2152 case OS.TVI_FIRST: | 2156 hFirstIndexOf = hLastIndexOf = hFirstItem = hNewItem; |
2153 case OS.TVI_LAST: | 2157 itemCount = lastIndexOf = 0; |
2154 hFirstIndexOf = hLastIndexOf = hFirstItem = hNewItem; | |
2155 itemCount = lastIndexOf = 0; | |
2156 default: | |
2157 } | 2158 } |
2158 } | 2159 } |
2159 if (hFirstItem is hFirstIndexOf && itemCount !is -1) itemCount++; | 2160 if (hFirstItem is hFirstIndexOf && itemCount !is -1) itemCount++; |
2160 if (hItem is null) { | 2161 if (hItem is null) { |
2161 /* | 2162 /* |
2166 * child is added to a visible parent item and redraw the parent. | 2167 * child is added to a visible parent item and redraw the parent. |
2167 */ | 2168 */ |
2168 if (fixParent) { | 2169 if (fixParent) { |
2169 if (drawCount is 0 && OS.IsWindowVisible (handle)) { | 2170 if (drawCount is 0 && OS.IsWindowVisible (handle)) { |
2170 RECT rect; | 2171 RECT rect; |
2171 rect.left = cast(int) hParent; | 2172 if (OS.TreeView_GetItemRect (handle, hParent, &rect, false)) { |
2172 if (OS.SendMessage (handle, OS.TVM_GETITEMRECT, 0, &rect) !is 0) { | |
2173 OS.InvalidateRect (handle, &rect, true); | 2173 OS.InvalidateRect (handle, &rect, true); |
2174 } | 2174 } |
2175 } | 2175 } |
2176 } | 2176 } |
2177 /* | 2177 /* |
2182 * new area. | 2182 * new area. |
2183 */ | 2183 */ |
2184 if ((style & DWT.VIRTUAL) !is 0) { | 2184 if ((style & DWT.VIRTUAL) !is 0) { |
2185 if (currentItem !is null) { | 2185 if (currentItem !is null) { |
2186 RECT rect; | 2186 RECT rect; |
2187 rect.left = cast(int) hNewItem; | 2187 if (OS.TreeView_GetItemRect (handle, hNewItem, &rect, false)) { |
2188 if (OS.SendMessage (handle, OS.TVM_GETITEMRECT, 0, &rect) !is 0) { | |
2189 RECT damageRect; | 2188 RECT damageRect; |
2190 bool damaged = cast(bool) OS.GetUpdateRect (handle, &damageRect, true); | 2189 bool damaged = cast(bool) OS.GetUpdateRect (handle, &damageRect, true); |
2191 if (damaged && damageRect.top < rect.bottom) { | 2190 if (damaged && damageRect.top < rect.bottom) { |
2192 static if (OS.IsWinCE) { | 2191 static if (OS.IsWinCE) { |
2193 OS.OffsetRect (&damageRect, 0, rect.bottom - rect.top); | 2192 OS.OffsetRect (&damageRect, 0, rect.bottom - rect.top); |
2210 } | 2209 } |
2211 | 2210 |
2212 void createItemToolTips () { | 2211 void createItemToolTips () { |
2213 static if (OS.IsWinCE) return; | 2212 static if (OS.IsWinCE) return; |
2214 if (itemToolTipHandle !is null) return; | 2213 if (itemToolTipHandle !is null) return; |
2215 int bits = OS.GetWindowLong (handle, OS.GWL_STYLE); | 2214 int bits1 = OS.GetWindowLong (handle, OS.GWL_STYLE); |
2216 bits |= OS.TVS_NOTOOLTIPS; | 2215 bits1 |= OS.TVS_NOTOOLTIPS; |
2217 OS.SetWindowLong (handle, OS.GWL_STYLE, bits); | 2216 OS.SetWindowLong (handle, OS.GWL_STYLE, bits1); |
2217 int bits2 = 0; | |
2218 if (OS.WIN32_VERSION >= OS.VERSION (4, 10)) { | |
2219 if ((style & DWT.RIGHT_TO_LEFT) !is 0) bits2 |= OS.WS_EX_LAYOUTRTL; | |
2220 } | |
2221 /* | |
2222 * Feature in Windows. For some reason, when the user | |
2223 * clicks on a tool tip, it temporarily takes focus, even | |
2224 * when WS_EX_NOACTIVATE is specified. The fix is to | |
2225 * use WS_EX_TRANSPARENT, even though WS_EX_TRANSPARENT | |
2226 * is documented to affect painting, not hit testing. | |
2227 * | |
2228 * NOTE: Windows 2000 doesn't have the problem and | |
2229 * setting WS_EX_TRANSPARENT causes pixel corruption. | |
2230 */ | |
2231 if (OS.COMCTL32_MAJOR >= 6) bits2 |= OS.WS_EX_TRANSPARENT; | |
2218 itemToolTipHandle = OS.CreateWindowEx ( | 2232 itemToolTipHandle = OS.CreateWindowEx ( |
2219 0, | 2233 bits2, |
2220 OS.TOOLTIPS_CLASS.ptr, | 2234 OS.TOOLTIPS_CLASS.ptr, |
2221 null, | 2235 null, |
2222 0, | 2236 OS.TTS_NOPREFIX | OS.TTS_NOANIMATE | OS.TTS_NOFADE, |
2223 OS.CW_USEDEFAULT, 0, OS.CW_USEDEFAULT, 0, | 2237 OS.CW_USEDEFAULT, 0, OS.CW_USEDEFAULT, 0, |
2224 handle, | 2238 handle, |
2225 null, | 2239 null, |
2226 OS.GetModuleHandle (null), | 2240 OS.GetModuleHandle (null), |
2227 null); | 2241 null); |
2228 if (itemToolTipHandle is null) error (DWT.ERROR_NO_HANDLES); | 2242 if (itemToolTipHandle is null) error (DWT.ERROR_NO_HANDLES); |
2229 /* | 2243 OS.SendMessage (itemToolTipHandle, OS.TTM_SETDELAYTIME, OS.TTDT_INITIAL, 0); |
2230 * Feature in Windows. Despite the fact that the | |
2231 * tool tip text contains \r\n, the tooltip will | |
2232 * not honour the new line unless TTM_SETMAXTIPWIDTH | |
2233 * is set. The fix is to set TTM_SETMAXTIPWIDTH to | |
2234 * a large value. | |
2235 */ | |
2236 OS.SendMessage (itemToolTipHandle, OS.TTM_SETMAXTIPWIDTH, 0, 0x7FFF); | |
2237 TOOLINFO lpti; | 2244 TOOLINFO lpti; |
2238 lpti.cbSize = TOOLINFO.sizeof; | 2245 lpti.cbSize = TOOLINFO.sizeof; |
2239 lpti.hwnd = handle; | 2246 lpti.hwnd = handle; |
2240 lpti.uId = cast(int)handle; | 2247 lpti.uId = cast(int)handle; |
2241 lpti.uFlags = OS.TTF_SUBCLASS | OS.TTF_TRANSPARENT; | 2248 lpti.uFlags = OS.TTF_SUBCLASS | OS.TTF_TRANSPARENT; |
2264 parent.handle, | 2271 parent.handle, |
2265 null, | 2272 null, |
2266 OS.GetModuleHandle (null), | 2273 OS.GetModuleHandle (null), |
2267 null); | 2274 null); |
2268 if (hwndParent is null) error (DWT.ERROR_NO_HANDLES); | 2275 if (hwndParent is null) error (DWT.ERROR_NO_HANDLES); |
2269 OS.SetWindowLong (hwndParent, OS.GWL_ID, cast(int) hwndParent); | 2276 OS.SetWindowLongPtr (hwndParent, OS.GWLP_ID, cast(LONG_PTR)hwndParent); |
2270 int bits = 0; | 2277 int bits = 0; |
2271 if (OS.WIN32_VERSION >= OS.VERSION (4, 10)) { | 2278 if (OS.WIN32_VERSION >= OS.VERSION (4, 10)) { |
2272 bits |= OS.WS_EX_NOINHERITLAYOUT; | 2279 bits |= OS.WS_EX_NOINHERITLAYOUT; |
2273 if ((style & DWT.RIGHT_TO_LEFT) !is 0) bits |= OS.WS_EX_LAYOUTRTL; | 2280 if ((style & DWT.RIGHT_TO_LEFT) !is 0) bits |= OS.WS_EX_LAYOUTRTL; |
2274 } | 2281 } |
2281 hwndParent, | 2288 hwndParent, |
2282 null, | 2289 null, |
2283 OS.GetModuleHandle (null), | 2290 OS.GetModuleHandle (null), |
2284 null); | 2291 null); |
2285 if (hwndHeader is null) error (DWT.ERROR_NO_HANDLES); | 2292 if (hwndHeader is null) error (DWT.ERROR_NO_HANDLES); |
2286 OS.SetWindowLong (hwndHeader, OS.GWL_ID, cast(int) hwndHeader); | 2293 OS.SetWindowLongPtr (hwndHeader, OS.GWLP_ID, cast(LONG_PTR)hwndHeader); |
2287 if (OS.IsDBLocale) { | 2294 if (OS.IsDBLocale) { |
2288 auto hIMC = OS.ImmGetContext (handle); | 2295 auto hIMC = OS.ImmGetContext (handle); |
2289 OS.ImmAssociateContext (hwndParent, hIMC); | 2296 OS.ImmAssociateContext (hwndParent, hIMC); |
2290 OS.ImmAssociateContext (hwndHeader, hIMC); | 2297 OS.ImmAssociateContext (hwndHeader, hIMC); |
2291 OS.ImmReleaseContext (handle, hIMC); | 2298 OS.ImmReleaseContext (handle, hIMC); |
2321 if (hwndFocus is handle) OS.SetFocus (hwndParent); | 2328 if (hwndFocus is handle) OS.SetFocus (hwndParent); |
2322 OS.SetParent (handle, hwndParent); | 2329 OS.SetParent (handle, hwndParent); |
2323 if (hwndFocus is handle) OS.SetFocus (handle); | 2330 if (hwndFocus is handle) OS.SetFocus (handle); |
2324 register (); | 2331 register (); |
2325 subclass (); | 2332 subclass (); |
2326 createItemToolTips (); | |
2327 } | 2333 } |
2328 | 2334 |
2329 override void createWidget () { | 2335 override void createWidget () { |
2330 super.createWidget (); | 2336 super.createWidget (); |
2331 items = new TreeItem [4]; | 2337 items = new TreeItem [4]; |
2351 } | 2357 } |
2352 auto hFirstItem = cast(HANDLE) OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_CHILD, hItem); | 2358 auto hFirstItem = cast(HANDLE) OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_CHILD, hItem); |
2353 deselect (hFirstItem, tvItem, hIgnoreItem); | 2359 deselect (hFirstItem, tvItem, hIgnoreItem); |
2354 hItem = cast(HANDLE) OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_NEXT, hItem); | 2360 hItem = cast(HANDLE) OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_NEXT, hItem); |
2355 } | 2361 } |
2362 } | |
2363 | |
2364 /** | |
2365 * Deselects an item in the receiver. If the item was already | |
2366 * deselected, it remains deselected. | |
2367 * | |
2368 * @param item the item to be deselected | |
2369 * | |
2370 * @exception IllegalArgumentException <ul> | |
2371 * <li>ERROR_NULL_ARGUMENT - if the item is null</li> | |
2372 * <li>ERROR_INVALID_ARGUMENT - if the item has been disposed</li> | |
2373 * </ul> | |
2374 * @exception DWTException <ul> | |
2375 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
2376 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
2377 * </ul> | |
2378 * | |
2379 * @since 3.4 | |
2380 */ | |
2381 public void deselect (TreeItem item) { | |
2382 checkWidget (); | |
2383 if (item is null) error (DWT.ERROR_NULL_ARGUMENT); | |
2384 if (item.isDisposed ()) error (DWT.ERROR_INVALID_ARGUMENT); | |
2385 TVITEM tvItem; | |
2386 tvItem.mask = OS.TVIF_HANDLE | OS.TVIF_STATE; | |
2387 tvItem.stateMask = OS.TVIS_SELECTED; | |
2388 tvItem.hItem = item.handle; | |
2389 OS.SendMessage (handle, OS.TVM_SETITEM, 0, cast(int)&tvItem); | |
2356 } | 2390 } |
2357 | 2391 |
2358 /** | 2392 /** |
2359 * Deselects all selected items in the receiver. | 2393 * Deselects all selected items in the receiver. |
2360 * | 2394 * |
2373 if (hItem !is null) { | 2407 if (hItem !is null) { |
2374 tvItem.hItem = hItem; | 2408 tvItem.hItem = hItem; |
2375 OS.SendMessage (handle, OS.TVM_SETITEM, 0, &tvItem); | 2409 OS.SendMessage (handle, OS.TVM_SETITEM, 0, &tvItem); |
2376 } | 2410 } |
2377 } else { | 2411 } else { |
2378 int oldProc = OS.GetWindowLong (handle, OS.GWL_WNDPROC); | 2412 auto oldProc = OS.GetWindowLongPtr (handle, OS.GWLP_WNDPROC); |
2379 OS.SetWindowLong (handle, OS.GWL_WNDPROC, cast(int) TreeProc); | 2413 OS.SetWindowLongPtr (handle, OS.GWLP_WNDPROC, cast(LONG_PTR)TreeProc); |
2380 if ((style & DWT.VIRTUAL) !is 0) { | 2414 if ((style & DWT.VIRTUAL) !is 0) { |
2381 HANDLE hItem = cast(HANDLE) OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_ROOT, 0); | 2415 HANDLE hItem = cast(HANDLE) OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_ROOT, 0); |
2382 deselect (hItem, &tvItem, null); | 2416 deselect (hItem, &tvItem, null); |
2383 } else { | 2417 } else { |
2384 for (int i=0; i<items.length; i++) { | 2418 for (int i=0; i<items.length; i++) { |
2387 tvItem.hItem = item.handle; | 2421 tvItem.hItem = item.handle; |
2388 OS.SendMessage (handle, OS.TVM_SETITEM, 0, &tvItem); | 2422 OS.SendMessage (handle, OS.TVM_SETITEM, 0, &tvItem); |
2389 } | 2423 } |
2390 } | 2424 } |
2391 } | 2425 } |
2392 OS.SetWindowLong (handle, OS.GWL_WNDPROC, oldProc); | 2426 OS.SetWindowLongPtr (handle, OS.GWLP_WNDPROC, oldProc); |
2393 } | 2427 } |
2394 } | 2428 } |
2395 | 2429 |
2396 void destroyItem (TreeColumn column) { | 2430 void destroyItem (TreeColumn column) { |
2397 if (hwndHeader is null) error (DWT.ERROR_ITEM_NOT_REMOVED); | 2431 if (hwndHeader is null) error (DWT.ERROR_ITEM_NOT_REMOVED); |
2398 int columnCount = OS.SendMessage (hwndHeader, OS.HDM_GETITEMCOUNT, 0, 0); | |
2399 int index = 0; | 2432 int index = 0; |
2400 while (index < columnCount) { | 2433 while (index < columnCount) { |
2401 if (columns [index] is column) break; | 2434 if (columns [index] is column) break; |
2402 index++; | 2435 index++; |
2403 } | 2436 } |
2460 System.arraycopy (cellForeground, 0, temp, 0, index); | 2493 System.arraycopy (cellForeground, 0, temp, 0, index); |
2461 System.arraycopy (cellForeground, index + 1, temp, index, columnCount - index); | 2494 System.arraycopy (cellForeground, index + 1, temp, index, columnCount - index); |
2462 item.cellForeground = temp; | 2495 item.cellForeground = temp; |
2463 } | 2496 } |
2464 if (item.cellFont !is null) { | 2497 if (item.cellFont !is null) { |
2465 HFONT [] cellFont = item.cellFont; | 2498 Font [] cellFont = item.cellFont; |
2466 HFONT [] temp = new HFONT [columnCount]; | 2499 Font [] temp = new Font [columnCount]; |
2467 System.arraycopy (cellFont, 0, temp, 0, index); | 2500 System.arraycopy (cellFont, 0, temp, 0, index); |
2468 System.arraycopy (cellFont, index + 1, temp, index, columnCount - index); | 2501 System.arraycopy (cellFont, index + 1, temp, index, columnCount - index); |
2469 item.cellFont = temp; | 2502 item.cellFont = temp; |
2470 } | 2503 } |
2471 } | 2504 } |
2479 */ | 2512 */ |
2480 if (columnCount is 0) { | 2513 if (columnCount is 0) { |
2481 scrollWidth = 0; | 2514 scrollWidth = 0; |
2482 if (!hooks (DWT.MeasureItem)) { | 2515 if (!hooks (DWT.MeasureItem)) { |
2483 int bits = OS.GetWindowLong (handle, OS.GWL_STYLE); | 2516 int bits = OS.GetWindowLong (handle, OS.GWL_STYLE); |
2484 bits &= ~OS.TVS_NOHSCROLL; | 2517 if ((style & DWT.H_SCROLL) !is 0) bits &= ~OS.TVS_NOHSCROLL; |
2485 OS.SetWindowLong (handle, OS.GWL_STYLE, bits); | 2518 OS.SetWindowLong (handle, OS.GWL_STYLE, bits); |
2486 OS.InvalidateRect (handle, null, true); | 2519 OS.InvalidateRect (handle, null, true); |
2520 } | |
2521 if (itemToolTipHandle !is null) { | |
2522 OS.SendMessage (itemToolTipHandle, OS.TTM_SETDELAYTIME, OS.TTDT_INITIAL, 0); | |
2487 } | 2523 } |
2488 } else { | 2524 } else { |
2489 if (index is 0) { | 2525 if (index is 0) { |
2490 columns [0].style &= ~(DWT.LEFT | DWT.RIGHT | DWT.CENTER); | 2526 columns [0].style &= ~(DWT.LEFT | DWT.RIGHT | DWT.CENTER); |
2491 columns [0].style |= DWT.LEFT; | 2527 columns [0].style |= DWT.LEFT; |
2550 HANDLE hParent; | 2586 HANDLE hParent; |
2551 bool fixRedraw = false; | 2587 bool fixRedraw = false; |
2552 if ((style & DWT.DOUBLE_BUFFERED) is 0) { | 2588 if ((style & DWT.DOUBLE_BUFFERED) is 0) { |
2553 if (drawCount is 0 && OS.IsWindowVisible (handle)) { | 2589 if (drawCount is 0 && OS.IsWindowVisible (handle)) { |
2554 RECT rect; | 2590 RECT rect; |
2555 rect.left = cast(int) hItem; | 2591 fixRedraw = !OS.TreeView_GetItemRect (handle, hItem, &rect, false); |
2556 fixRedraw = OS.SendMessage (handle, OS.TVM_GETITEMRECT, 0, &rect) is 0; | |
2557 } | 2592 } |
2558 } | 2593 } |
2559 if (fixRedraw) { | 2594 if (fixRedraw) { |
2560 hParent = cast(HANDLE) OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_PARENT, hItem); | 2595 hParent = cast(HANDLE) OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_PARENT, hItem); |
2561 OS.UpdateWindow (handle); | 2596 OS.UpdateWindow (handle); |
2597 * If the item that was deleted was the last child of a tree item that | 2632 * If the item that was deleted was the last child of a tree item that |
2598 * is visible, redraw the parent item to force the + / - to be updated. | 2633 * is visible, redraw the parent item to force the + / - to be updated. |
2599 */ | 2634 */ |
2600 if (OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_CHILD, hParent) is 0) { | 2635 if (OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_CHILD, hParent) is 0) { |
2601 RECT rect; | 2636 RECT rect; |
2602 rect.left = cast(int) hParent; | 2637 if (OS.TreeView_GetItemRect (handle, hParent, &rect, false)) { |
2603 if (OS.SendMessage (handle, OS.TVM_GETITEMRECT, 0, &rect) !is 0) { | |
2604 OS.InvalidateRect (handle, &rect, true); | 2638 OS.InvalidateRect (handle, &rect, true); |
2605 } | 2639 } |
2606 } | 2640 } |
2607 } | 2641 } |
2608 int count = OS.SendMessage (handle, OS.TVM_GETCOUNT, 0, 0); | 2642 int count = OS.SendMessage (handle, OS.TVM_GETCOUNT, 0, 0); |
2620 items = new TreeItem [4]; | 2654 items = new TreeItem [4]; |
2621 scrollWidth = 0; | 2655 scrollWidth = 0; |
2622 setScrollWidth (); | 2656 setScrollWidth (); |
2623 } | 2657 } |
2624 updateScrollBar (); | 2658 updateScrollBar (); |
2659 } | |
2660 | |
2661 void destroyScrollBar (int type) { | |
2662 super.destroyScrollBar (type); | |
2663 int bits = OS.GetWindowLong (handle, OS.GWL_STYLE); | |
2664 if ((style & (DWT.H_SCROLL | DWT.V_SCROLL)) is 0) { | |
2665 bits &= ~(OS.WS_HSCROLL | OS.WS_VSCROLL); | |
2666 bits |= OS.TVS_NOSCROLL; | |
2667 } else { | |
2668 if ((style & DWT.H_SCROLL) is 0) { | |
2669 bits &= ~OS.WS_HSCROLL; | |
2670 bits |= OS.TVS_NOHSCROLL; | |
2671 } | |
2672 } | |
2673 OS.SetWindowLong (handle, OS.GWL_STYLE, bits); | |
2625 } | 2674 } |
2626 | 2675 |
2627 override void enableDrag (bool enabled) { | 2676 override void enableDrag (bool enabled) { |
2628 int bits = OS.GetWindowLong (handle, OS.GWL_STYLE); | 2677 int bits = OS.GetWindowLong (handle, OS.GWL_STYLE); |
2629 if (enabled && hooks (DWT.DragDetect)) { | 2678 if (enabled && hooks (DWT.DragDetect)) { |
2670 * as sort column. | 2719 * as sort column. |
2671 */ | 2720 */ |
2672 updateFullSelection (); | 2721 updateFullSelection (); |
2673 } | 2722 } |
2674 | 2723 |
2724 bool findCell (int x, int y, inout TreeItem item, inout int index, inout RECT cellRect, inout RECT itemRect) { | |
2725 bool found = false; | |
2726 TVHITTESTINFO lpht; | |
2727 lpht.pt.x = x; | |
2728 lpht.pt.y = y; | |
2729 OS.SendMessage (handle, OS.TVM_HITTEST, 0, &lpht); | |
2730 if (lpht.hItem !is null) { | |
2731 item = _getItem (lpht.hItem); | |
2732 POINT pt; | |
2733 pt.x = x; | |
2734 pt.y = y; | |
2735 auto hDC = OS.GetDC (handle); | |
2736 HFONT oldFont; | |
2737 auto newFont = cast(HFONT)OS.SendMessage (handle, OS.WM_GETFONT, 0, 0); | |
2738 if (newFont !is null) oldFont = OS.SelectObject (hDC, newFont); | |
2739 RECT rect; | |
2740 if (hwndParent !is null) { | |
2741 OS.GetClientRect (hwndParent, &rect); | |
2742 OS.MapWindowPoints (hwndParent, handle, cast(POINT*)&rect, 2); | |
2743 } else { | |
2744 OS.GetClientRect (handle, &rect); | |
2745 } | |
2746 int count = Math.max (1, columnCount); | |
2747 int [] order = new int [count]; | |
2748 if (hwndHeader !is null) OS.SendMessage (hwndHeader, OS.HDM_GETORDERARRAY, count, cast(int) order.ptr); | |
2749 index = 0; | |
2750 bool quit = false; | |
2751 while (index < count && !quit) { | |
2752 auto hFont = item.fontHandle (order [index]); | |
2753 if (hFont !is cast(HFONT)-1) hFont = OS.SelectObject (hDC, hFont); | |
2754 cellRect = item.getBounds (order [index], true, false, true, false, true, hDC); | |
2755 if (cellRect.left > rect.right) { | |
2756 quit = true; | |
2757 } else { | |
2758 cellRect.right = Math.min (cellRect.right, rect.right); | |
2759 if (OS.PtInRect ( &cellRect, pt)) { | |
2760 if (isCustomToolTip ()) { | |
2761 Event event = sendMeasureItemEvent (item, order [index], hDC); | |
2762 if (isDisposed () || item.isDisposed ()) break; | |
2763 //itemRect [0] = new RECT (); | |
2764 itemRect.left = event.x; | |
2765 itemRect.right = event.x + event.width; | |
2766 itemRect.top = event.y; | |
2767 itemRect.bottom = event.y + event.height; | |
2768 } else { | |
2769 itemRect = item.getBounds (order [index], true, false, false, false, false, hDC); | |
2770 } | |
2771 if (itemRect.right > cellRect.right) found = true; | |
2772 quit = true; | |
2773 } | |
2774 } | |
2775 if (hFont !is cast(HFONT)-1) OS.SelectObject (hDC, hFont); | |
2776 if (!found) index++; | |
2777 } | |
2778 if (newFont !is null) OS.SelectObject (hDC, oldFont); | |
2779 OS.ReleaseDC (handle, hDC); | |
2780 } | |
2781 return found; | |
2782 } | |
2783 | |
2675 int findIndex (HANDLE hFirstItem, HANDLE hItem) { | 2784 int findIndex (HANDLE hFirstItem, HANDLE hItem) { |
2676 if (hFirstItem is null) return -1; | 2785 if (hFirstItem is null) return -1; |
2677 if (hFirstItem is hFirstIndexOf) { | 2786 if (hFirstItem is hFirstIndexOf) { |
2678 if (hFirstIndexOf is hItem) { | 2787 if (hFirstIndexOf is hItem) { |
2679 hLastIndexOf = hFirstIndexOf; | 2788 hLastIndexOf = hFirstIndexOf; |
2901 * | 3010 * |
2902 * @since 3.1 | 3011 * @since 3.1 |
2903 */ | 3012 */ |
2904 public TreeColumn getColumn (int index) { | 3013 public TreeColumn getColumn (int index) { |
2905 checkWidget (); | 3014 checkWidget (); |
2906 if (hwndHeader is null) error (DWT.ERROR_INVALID_RANGE); | 3015 if (!(0 <= index && index < columnCount)) error (DWT.ERROR_INVALID_RANGE); |
2907 int count = OS.SendMessage (hwndHeader, OS.HDM_GETITEMCOUNT, 0, 0); | |
2908 if (!(0 <= index && index < count)) error (DWT.ERROR_INVALID_RANGE); | |
2909 return columns [index]; | 3016 return columns [index]; |
2910 } | 3017 } |
2911 | 3018 |
2912 /** | 3019 /** |
2913 * Returns the number of columns contained in the receiver. | 3020 * Returns the number of columns contained in the receiver. |
2925 * | 3032 * |
2926 * @since 3.1 | 3033 * @since 3.1 |
2927 */ | 3034 */ |
2928 public int getColumnCount () { | 3035 public int getColumnCount () { |
2929 checkWidget (); | 3036 checkWidget (); |
2930 if (hwndHeader is null) return 0; | 3037 return columnCount; |
2931 return OS.SendMessage (hwndHeader, OS.HDM_GETITEMCOUNT, 0, 0); | |
2932 } | 3038 } |
2933 | 3039 |
2934 /** | 3040 /** |
2935 * Returns an array of zero-relative integers that map | 3041 * Returns an array of zero-relative integers that map |
2936 * the creation order of the receiver's items to the | 3042 * the creation order of the receiver's items to the |
2959 * | 3065 * |
2960 * @since 3.2 | 3066 * @since 3.2 |
2961 */ | 3067 */ |
2962 public int[] getColumnOrder () { | 3068 public int[] getColumnOrder () { |
2963 checkWidget (); | 3069 checkWidget (); |
2964 if (hwndHeader is null) return new int [0]; | 3070 if (columnCount is 0) return null; |
2965 int count = OS.SendMessage (hwndHeader, OS.HDM_GETITEMCOUNT, 0, 0); | 3071 int [] order = new int [columnCount]; |
2966 int [] order = new int [count]; | 3072 OS.SendMessage (hwndHeader, OS.HDM_GETORDERARRAY, columnCount, order.ptr); |
2967 OS.SendMessage (hwndHeader, OS.HDM_GETORDERARRAY, count, order.ptr); | |
2968 return order; | 3073 return order; |
2969 } | 3074 } |
2970 | 3075 |
2971 /** | 3076 /** |
2972 * Returns an array of <code>TreeColumn</code>s which are the | 3077 * Returns an array of <code>TreeColumn</code>s which are the |
2997 * | 3102 * |
2998 * @since 3.1 | 3103 * @since 3.1 |
2999 */ | 3104 */ |
3000 public TreeColumn [] getColumns () { | 3105 public TreeColumn [] getColumns () { |
3001 checkWidget (); | 3106 checkWidget (); |
3002 if (hwndHeader is null) return new TreeColumn [0]; | 3107 TreeColumn [] result = new TreeColumn [columnCount]; |
3003 int count = OS.SendMessage (hwndHeader, OS.HDM_GETITEMCOUNT, 0, 0); | 3108 System.arraycopy (columns, 0, result, 0, columnCount); |
3004 TreeColumn [] result = new TreeColumn [count]; | |
3005 System.arraycopy (columns, 0, result, 0, count); | |
3006 return result; | 3109 return result; |
3007 } | 3110 } |
3008 | 3111 |
3009 /** | 3112 /** |
3010 * Returns the item at the given, zero-relative index in the | 3113 * Returns the item at the given, zero-relative index in the |
3084 TVHITTESTINFO lpht; | 3187 TVHITTESTINFO lpht; |
3085 lpht.pt.x = point.x; | 3188 lpht.pt.x = point.x; |
3086 lpht.pt.y = point.y; | 3189 lpht.pt.y = point.y; |
3087 OS.SendMessage (handle, OS.TVM_HITTEST, 0, &lpht); | 3190 OS.SendMessage (handle, OS.TVM_HITTEST, 0, &lpht); |
3088 if (lpht.hItem !is null) { | 3191 if (lpht.hItem !is null) { |
3089 if ((style & DWT.FULL_SELECTION) !is 0 || (lpht.flags & OS.TVHT_ONITEM) !is 0) { | 3192 int flags = OS.TVHT_ONITEM; |
3090 return _getItem (lpht.hItem); | 3193 if ((style & DWT.FULL_SELECTION) !is 0) { |
3091 } | 3194 flags |= OS.TVHT_ONITEMRIGHT | OS.TVHT_ONITEMINDENT; |
3195 } else { | |
3196 if (hooks (DWT.MeasureItem)) { | |
3197 lpht.flags &= ~(OS.TVHT_ONITEMICON | OS.TVHT_ONITEMLABEL); | |
3198 if (hitTestSelection ( lpht.hItem, lpht.pt.x, lpht.pt.y)) { | |
3199 lpht.flags |= OS.TVHT_ONITEMICON | OS.TVHT_ONITEMLABEL; | |
3200 } | |
3201 } | |
3202 } | |
3203 if ((lpht.flags & flags) !is 0) return _getItem (lpht.hItem); | |
3092 } | 3204 } |
3093 return null; | 3205 return null; |
3094 } | 3206 } |
3095 | 3207 |
3096 /** | 3208 /** |
3326 if ((tvItem.state & OS.TVIS_SELECTED) is 0) return new TreeItem [0]; | 3438 if ((tvItem.state & OS.TVIS_SELECTED) is 0) return new TreeItem [0]; |
3327 return [_getItem (tvItem.hItem, tvItem.lParam)]; | 3439 return [_getItem (tvItem.hItem, tvItem.lParam)]; |
3328 } | 3440 } |
3329 int count = 0; | 3441 int count = 0; |
3330 TreeItem [] guess = new TreeItem [(style & DWT.VIRTUAL) !is 0 ? 8 : 1]; | 3442 TreeItem [] guess = new TreeItem [(style & DWT.VIRTUAL) !is 0 ? 8 : 1]; |
3331 int oldProc = OS.GetWindowLong (handle, OS.GWL_WNDPROC); | 3443 int /*long*/ oldProc = OS.GetWindowLongPtr (handle, OS.GWLP_WNDPROC); |
3332 OS.SetWindowLong (handle, OS.GWL_WNDPROC, cast(int) TreeProc); | 3444 OS.SetWindowLongPtr (handle, OS.GWLP_WNDPROC, cast(LONG_PTR)TreeProc); |
3333 if ((style & DWT.VIRTUAL) !is 0) { | 3445 if ((style & DWT.VIRTUAL) !is 0) { |
3334 TVITEM tvItem; | 3446 TVITEM tvItem; |
3335 tvItem.mask = OS.TVIF_HANDLE | OS.TVIF_PARAM | OS.TVIF_STATE; | 3447 tvItem.mask = OS.TVIF_HANDLE | OS.TVIF_PARAM | OS.TVIF_STATE; |
3336 HANDLE hItem = cast(HANDLE) OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_ROOT, 0); | 3448 HANDLE hItem = cast(HANDLE) OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_ROOT, 0); |
3337 count = getSelection (hItem, &tvItem, guess, 0, -1, false, true); | 3449 count = getSelection (hItem, &tvItem, guess, 0, -1, false, true); |
3358 count++; | 3470 count++; |
3359 } | 3471 } |
3360 } | 3472 } |
3361 } | 3473 } |
3362 } | 3474 } |
3363 OS.SetWindowLong (handle, OS.GWL_WNDPROC, oldProc); | 3475 OS.SetWindowLongPtr (handle, OS.GWLP_WNDPROC, oldProc); |
3364 if (count is 0) return new TreeItem [0]; | 3476 if (count is 0) return new TreeItem [0]; |
3365 if (count is guess.length) return guess; | 3477 if (count is guess.length) return guess; |
3366 TreeItem [] result = new TreeItem [count]; | 3478 TreeItem [] result = new TreeItem [count]; |
3367 if (count < guess.length) { | 3479 if (count < guess.length) { |
3368 System.arraycopy (guess, 0, result, 0, count); | 3480 System.arraycopy (guess, 0, result, 0, count); |
3369 return result; | 3481 return result; |
3370 } | 3482 } |
3371 OS.SetWindowLong (handle, OS.GWL_WNDPROC, cast(int) TreeProc); | 3483 OS.SetWindowLongPtr (handle, OS.GWLP_WNDPROC, cast(LONG_PTR)TreeProc); |
3372 TVITEM tvItem; | 3484 TVITEM tvItem; |
3373 tvItem.mask = OS.TVIF_HANDLE | OS.TVIF_PARAM | OS.TVIF_STATE; | 3485 tvItem.mask = OS.TVIF_HANDLE | OS.TVIF_PARAM | OS.TVIF_STATE; |
3374 HANDLE hItem = cast(HANDLE) OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_ROOT, 0); | 3486 HANDLE hItem = cast(HANDLE) OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_ROOT, 0); |
3375 int itemCount = OS.SendMessage (handle, OS.TVM_GETCOUNT, 0, 0); | 3487 int itemCount = OS.SendMessage (handle, OS.TVM_GETCOUNT, 0, 0); |
3376 bool bigSelection = result.length > itemCount / 2; | 3488 bool bigSelection = result.length > itemCount / 2; |
3377 if (count !is getSelection (hItem, &tvItem, result, 0, count, bigSelection, false)) { | 3489 if (count !is getSelection (hItem, &tvItem, result, 0, count, bigSelection, false)) { |
3378 getSelection (hItem, &tvItem, result, 0, count, bigSelection, true); | 3490 getSelection (hItem, &tvItem, result, 0, count, bigSelection, true); |
3379 } | 3491 } |
3380 OS.SetWindowLong (handle, OS.GWL_WNDPROC, oldProc); | 3492 OS.SetWindowLongPtr (handle, OS.GWLP_WNDPROC, oldProc); |
3381 return result; | 3493 return result; |
3382 } | 3494 } |
3383 | 3495 |
3384 /** | 3496 /** |
3385 * Returns the number of selected items contained in the receiver. | 3497 * Returns the number of selected items contained in the receiver. |
3407 state = OS.SendMessage (handle, OS.TVM_GETITEMSTATE, hItem, OS.TVIS_SELECTED); | 3519 state = OS.SendMessage (handle, OS.TVM_GETITEMSTATE, hItem, OS.TVIS_SELECTED); |
3408 } | 3520 } |
3409 return (state & OS.TVIS_SELECTED) is 0 ? 0 : 1; | 3521 return (state & OS.TVIS_SELECTED) is 0 ? 0 : 1; |
3410 } | 3522 } |
3411 int count = 0; | 3523 int count = 0; |
3412 int oldProc = OS.GetWindowLong (handle, OS.GWL_WNDPROC); | 3524 int /*long*/ oldProc = OS.GetWindowLongPtr (handle, OS.GWLP_WNDPROC); |
3413 TVITEM tvItem_; | 3525 TVITEM tvItem_; |
3414 TVITEM* tvItem = null; | 3526 TVITEM* tvItem = null; |
3415 static if (OS.IsWinCE) { | 3527 static if (OS.IsWinCE) { |
3416 tvItem = &tvitem_; | 3528 tvItem = &tvitem_; |
3417 tvItem.mask = OS.TVIF_STATE; | 3529 tvItem.mask = OS.TVIF_STATE; |
3418 } | 3530 } |
3419 OS.SetWindowLong (handle, OS.GWL_WNDPROC, cast(int) TreeProc); | 3531 OS.SetWindowLongPtr (handle, OS.GWLP_WNDPROC, cast(LONG_PTR)TreeProc); |
3420 if ((style & DWT.VIRTUAL) !is 0) { | 3532 if ((style & DWT.VIRTUAL) !is 0) { |
3421 HANDLE hItem = cast(HANDLE) OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_ROOT, 0); | 3533 HANDLE hItem = cast(HANDLE) OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_ROOT, 0); |
3422 count = getSelection (hItem, tvItem, null, 0, -1, false, true); | 3534 count = getSelection (hItem, tvItem, null, 0, -1, false, true); |
3423 } else { | 3535 } else { |
3424 for (int i=0; i<items.length; i++) { | 3536 for (int i=0; i<items.length; i++) { |
3435 } | 3547 } |
3436 if ((state & OS.TVIS_SELECTED) !is 0) count++; | 3548 if ((state & OS.TVIS_SELECTED) !is 0) count++; |
3437 } | 3549 } |
3438 } | 3550 } |
3439 } | 3551 } |
3440 OS.SetWindowLong (handle, OS.GWL_WNDPROC, oldProc); | 3552 OS.SetWindowLongPtr (handle, OS.GWLP_WNDPROC, oldProc); |
3441 return count; | 3553 return count; |
3442 } | 3554 } |
3443 | 3555 |
3444 /** | 3556 /** |
3445 * Returns the column which shows the sort indicator for | 3557 * Returns the column which shows the sort indicator for |
3518 checkWidget (); | 3630 checkWidget (); |
3519 HANDLE hItem = cast(HANDLE) OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_FIRSTVISIBLE, 0); | 3631 HANDLE hItem = cast(HANDLE) OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_FIRSTVISIBLE, 0); |
3520 return hItem !is null ? _getItem (hItem) : null; | 3632 return hItem !is null ? _getItem (hItem) : null; |
3521 } | 3633 } |
3522 | 3634 |
3635 bool hitTestSelection (HANDLE hItem, int x, int y) { | |
3636 if (hItem is null) return false; | |
3637 TreeItem item = _getItem (hItem); | |
3638 if (item is null) return false; | |
3639 if (!hooks (DWT.MeasureItem)) return false; | |
3640 bool result = false; | |
3641 | |
3642 //BUG? - moved columns, only hittest first column | |
3643 //BUG? - check drag detect | |
3644 int [] order = new int [1], index = new int [1]; | |
3645 | |
3646 auto hDC = OS.GetDC (handle); | |
3647 HFONT oldFont, newFont = cast(HFONT)OS.SendMessage (handle, OS.WM_GETFONT, 0, 0); | |
3648 if (newFont !is null) oldFont = OS.SelectObject (hDC, newFont); | |
3649 auto hFont = item.fontHandle (order [index [0]]); | |
3650 if (hFont !is cast(HFONT)-1) hFont = OS.SelectObject (hDC, hFont); | |
3651 Event event = sendMeasureItemEvent (item, order [index [0]], hDC); | |
3652 if (event.getBounds ().contains (x, y)) result = true; | |
3653 if (newFont !is null) OS.SelectObject (hDC, oldFont); | |
3654 OS.ReleaseDC (handle, hDC); | |
3655 // if (isDisposed () || item.isDisposed ()) return false; | |
3656 return result; | |
3657 } | |
3658 | |
3523 int imageIndex (Image image, int index) { | 3659 int imageIndex (Image image, int index) { |
3524 if (image is null) return OS.I_IMAGENONE; | 3660 if (image is null) return OS.I_IMAGENONE; |
3525 if (imageList is null) { | 3661 if (imageList is null) { |
3526 Rectangle bounds = image.getBounds (); | 3662 Rectangle bounds = image.getBounds (); |
3527 imageList = display.getImageList (style & DWT.RIGHT_TO_LEFT, bounds.width, bounds.height); | 3663 imageList = display.getImageList (style & DWT.RIGHT_TO_LEFT, bounds.width, bounds.height); |
3528 } | 3664 } |
3529 int imageIndex = imageList.indexOf (image); | 3665 int imageIndex = imageList.indexOf (image); |
3530 if (imageIndex is -1) imageIndex = imageList.add (image); | 3666 if (imageIndex is -1) imageIndex = imageList.add (image); |
3531 if (hwndHeader is null || OS.SendMessage (hwndHeader, OS.HDM_ORDERTOINDEX, 0, 0) is index) { | 3667 if (hwndHeader is null || OS.SendMessage (hwndHeader, OS.HDM_ORDERTOINDEX, 0, 0) is index) { |
3668 /* | |
3669 * Feature in Windows. When setting the same image list multiple | |
3670 * times, Windows does work making this operation slow. The fix | |
3671 * is to test for the same image list before setting the new one. | |
3672 */ | |
3532 auto hImageList = imageList.getHandle (); | 3673 auto hImageList = imageList.getHandle (); |
3533 auto hOldImageList = cast(HANDLE) OS.SendMessage (handle, OS.TVM_GETIMAGELIST, OS.TVSIL_NORMAL, 0); | 3674 auto hOldImageList = cast(HANDLE) OS.SendMessage (handle, OS.TVM_GETIMAGELIST, OS.TVSIL_NORMAL, 0); |
3534 if (hOldImageList !is hImageList) { | 3675 if (hOldImageList !is hImageList) { |
3535 OS.SendMessage (handle, OS.TVM_SETIMAGELIST, OS.TVSIL_NORMAL, hImageList); | 3676 OS.SendMessage (handle, OS.TVM_SETIMAGELIST, OS.TVSIL_NORMAL, hImageList); |
3536 updateScrollBar (); | 3677 updateScrollBar (); |
3579 */ | 3720 */ |
3580 public int indexOf (TreeColumn column) { | 3721 public int indexOf (TreeColumn column) { |
3581 checkWidget (); | 3722 checkWidget (); |
3582 if (column is null) error (DWT.ERROR_NULL_ARGUMENT); | 3723 if (column is null) error (DWT.ERROR_NULL_ARGUMENT); |
3583 if (column.isDisposed()) error(DWT.ERROR_INVALID_ARGUMENT); | 3724 if (column.isDisposed()) error(DWT.ERROR_INVALID_ARGUMENT); |
3584 if (hwndHeader is null) return -1; | 3725 for (int i=0; i<columnCount; i++) { |
3585 int count = OS.SendMessage (hwndHeader, OS.HDM_GETITEMCOUNT, 0, 0); | |
3586 for (int i=0; i<count; i++) { | |
3587 if (columns [i] is column) return i; | 3726 if (columns [i] is column) return i; |
3588 } | 3727 } |
3589 return -1; | 3728 return -1; |
3590 } | 3729 } |
3591 | 3730 |
3613 checkWidget (); | 3752 checkWidget (); |
3614 if (item is null) error (DWT.ERROR_NULL_ARGUMENT); | 3753 if (item is null) error (DWT.ERROR_NULL_ARGUMENT); |
3615 if (item.isDisposed()) error(DWT.ERROR_INVALID_ARGUMENT); | 3754 if (item.isDisposed()) error(DWT.ERROR_INVALID_ARGUMENT); |
3616 HANDLE hItem = cast(HANDLE) OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_ROOT, 0); | 3755 HANDLE hItem = cast(HANDLE) OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_ROOT, 0); |
3617 return hItem is null ? -1 : findIndex (hItem, item.handle); | 3756 return hItem is null ? -1 : findIndex (hItem, item.handle); |
3757 } | |
3758 | |
3759 bool isCustomToolTip () { | |
3760 return hooks (DWT.MeasureItem); | |
3618 } | 3761 } |
3619 | 3762 |
3620 bool isItemSelected (NMTVCUSTOMDRAW* nmcd) { | 3763 bool isItemSelected (NMTVCUSTOMDRAW* nmcd) { |
3621 bool selected = false; | 3764 bool selected = false; |
3622 if (OS.IsWindowEnabled (handle)) { | 3765 if (OS.IsWindowEnabled (handle)) { |
3684 void redrawSelection () { | 3827 void redrawSelection () { |
3685 if ((style & DWT.SINGLE) !is 0) { | 3828 if ((style & DWT.SINGLE) !is 0) { |
3686 HANDLE hItem = cast(HANDLE) OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_CARET, 0); | 3829 HANDLE hItem = cast(HANDLE) OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_CARET, 0); |
3687 if (hItem !is null) { | 3830 if (hItem !is null) { |
3688 RECT rect; | 3831 RECT rect; |
3689 rect.left = cast(int) hItem; | 3832 if (OS.TreeView_GetItemRect (handle, hItem, &rect, false)) { |
3690 OS.SendMessage (handle, OS.TVM_GETITEMRECT, 0, &rect); | 3833 OS.InvalidateRect (handle, &rect, true); |
3691 OS.InvalidateRect (handle, &rect, true); | 3834 } |
3692 } | 3835 } |
3693 } else { | 3836 } else { |
3694 HANDLE hItem = cast(HANDLE) OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_FIRSTVISIBLE, 0); | 3837 HANDLE hItem = cast(HANDLE) OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_FIRSTVISIBLE, 0); |
3695 if (hItem !is null) { | 3838 if (hItem !is null) { |
3696 TVITEM tvItem; | 3839 TVITEM tvItem; |
3708 state = tvItem.state; | 3851 state = tvItem.state; |
3709 } else { | 3852 } else { |
3710 state = OS.SendMessage (handle, OS.TVM_GETITEMSTATE, hItem, OS.TVIS_SELECTED); | 3853 state = OS.SendMessage (handle, OS.TVM_GETITEMSTATE, hItem, OS.TVIS_SELECTED); |
3711 } | 3854 } |
3712 if ((state & OS.TVIS_SELECTED) !is 0) { | 3855 if ((state & OS.TVIS_SELECTED) !is 0) { |
3713 rect.left = cast(int) hItem; | 3856 if (OS.TreeView_GetItemRect (handle, hItem, &rect, false)) { |
3714 OS.SendMessage (handle, OS.TVM_GETITEMRECT, 0, &rect); | 3857 OS.InvalidateRect (handle, &rect, true); |
3715 OS.InvalidateRect (handle, &rect, true); | 3858 } |
3716 } | 3859 } |
3717 hItem = cast(HANDLE) OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_NEXTVISIBLE, hItem); | 3860 hItem = cast(HANDLE) OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_NEXTVISIBLE, hItem); |
3718 index++; | 3861 index++; |
3719 } | 3862 } |
3720 } | 3863 } |
3806 OS.SendMessage (handle, OS.TVM_SETIMAGELIST, OS.TVSIL_STATE, 0); | 3949 OS.SendMessage (handle, OS.TVM_SETIMAGELIST, OS.TVSIL_STATE, 0); |
3807 if (hStateList !is null) OS.ImageList_Destroy (hStateList); | 3950 if (hStateList !is null) OS.ImageList_Destroy (hStateList); |
3808 if (itemToolTipHandle !is null) OS.DestroyWindow (itemToolTipHandle); | 3951 if (itemToolTipHandle !is null) OS.DestroyWindow (itemToolTipHandle); |
3809 if (headerToolTipHandle !is null) OS.DestroyWindow (headerToolTipHandle); | 3952 if (headerToolTipHandle !is null) OS.DestroyWindow (headerToolTipHandle); |
3810 itemToolTipHandle = headerToolTipHandle = null; | 3953 itemToolTipHandle = headerToolTipHandle = null; |
3811 if (display.isXMouseActive ()) { | |
3812 Shell shell = getShell (); | |
3813 if (shell.lockToolTipControl is this) { | |
3814 shell.lockToolTipControl = null; | |
3815 } | |
3816 } | |
3817 } | 3954 } |
3818 | 3955 |
3819 /** | 3956 /** |
3820 * Removes all of the items from the receiver. | 3957 * Removes all of the items from the receiver. |
3821 * | 3958 * |
3836 } | 3973 } |
3837 ignoreDeselect = ignoreSelect = true; | 3974 ignoreDeselect = ignoreSelect = true; |
3838 bool redraw = drawCount is 0 && OS.IsWindowVisible (handle); | 3975 bool redraw = drawCount is 0 && OS.IsWindowVisible (handle); |
3839 if (redraw) OS.DefWindowProc (handle, OS.WM_SETREDRAW, 0, 0); | 3976 if (redraw) OS.DefWindowProc (handle, OS.WM_SETREDRAW, 0, 0); |
3840 shrink = ignoreShrink = true; | 3977 shrink = ignoreShrink = true; |
3841 int result = OS.SendMessage (handle, OS.TVM_DELETEITEM, 0, OS.TVI_ROOT); | 3978 int /*long*/ result = OS.SendMessage (handle, OS.TVM_DELETEITEM, 0, OS.TVI_ROOT); |
3842 ignoreShrink = false; | 3979 ignoreShrink = false; |
3843 if (redraw) { | 3980 if (redraw) { |
3844 OS.DefWindowProc (handle, OS.WM_SETREDRAW, 1, 0); | 3981 OS.DefWindowProc (handle, OS.WM_SETREDRAW, 1, 0); |
3845 OS.InvalidateRect (handle, null, true); | 3982 OS.InvalidateRect (handle, null, true); |
3846 } | 3983 } |
3970 int itemCount = 0; | 4107 int itemCount = 0; |
3971 while (hItem !is null && itemCount < count) { | 4108 while (hItem !is null && itemCount < count) { |
3972 hItem = cast(HANDLE) OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_NEXT, hItem); | 4109 hItem = cast(HANDLE) OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_NEXT, hItem); |
3973 itemCount++; | 4110 itemCount++; |
3974 } | 4111 } |
4112 bool expanded = false; | |
3975 TVITEM tvItem; | 4113 TVITEM tvItem; |
3976 tvItem.mask = OS.TVIF_HANDLE | OS.TVIF_PARAM; | 4114 tvItem.mask = OS.TVIF_HANDLE | OS.TVIF_PARAM; |
4115 if (!redraw && (style & DWT.VIRTUAL) !is 0) { | |
4116 if (OS.IsWinCE) { | |
4117 tvItem.hItem = hParent; | |
4118 tvItem.mask = OS.TVIF_STATE; | |
4119 OS.SendMessage (handle, OS.TVM_GETITEM, 0, cast(int)&tvItem); | |
4120 expanded = (tvItem.state & OS.TVIS_EXPANDED) !is 0; | |
4121 } else { | |
4122 /* | |
4123 * Bug in Windows. Despite the fact that TVM_GETITEMSTATE claims | |
4124 * to return only the bits specified by the stateMask, when called | |
4125 * with TVIS_EXPANDED, the entire state is returned. The fix is | |
4126 * to explicitly check for the TVIS_EXPANDED bit. | |
4127 */ | |
4128 int state = OS.SendMessage (handle, OS.TVM_GETITEMSTATE, hParent, OS.TVIS_EXPANDED); | |
4129 expanded = (state & OS.TVIS_EXPANDED) !is 0; | |
4130 } | |
4131 } | |
3977 while (hItem !is null) { | 4132 while (hItem !is null) { |
3978 tvItem.hItem = hItem; | 4133 tvItem.hItem = hItem; |
3979 OS.SendMessage (handle, OS.TVM_GETITEM, 0, &tvItem); | 4134 OS.SendMessage (handle, OS.TVM_GETITEM, 0, &tvItem); |
3980 hItem = cast(HANDLE) OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_NEXT, hItem); | 4135 hItem = cast(HANDLE) OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_NEXT, hItem); |
3981 TreeItem item = tvItem.lParam !is -1 ? items [tvItem.lParam] : null; | 4136 TreeItem item = tvItem.lParam !is -1 ? items [tvItem.lParam] : null; |
3986 destroyItem (null, tvItem.hItem); | 4141 destroyItem (null, tvItem.hItem); |
3987 } | 4142 } |
3988 } | 4143 } |
3989 if ((style & DWT.VIRTUAL) !is 0) { | 4144 if ((style & DWT.VIRTUAL) !is 0) { |
3990 for (int i=itemCount; i<count; i++) { | 4145 for (int i=itemCount; i<count; i++) { |
4146 if (expanded) ignoreShrink = true; | |
3991 createItem (null, hParent, cast(HANDLE) OS.TVI_LAST, null); | 4147 createItem (null, hParent, cast(HANDLE) OS.TVI_LAST, null); |
4148 if (expanded) ignoreShrink = false; | |
3992 } | 4149 } |
3993 } else { | 4150 } else { |
3994 shrink = true; | 4151 shrink = true; |
3995 int extra = Math.max (4, (count + 3) / 4 * 4); | 4152 int extra = Math.max (4, (count + 3) / 4 * 4); |
3996 TreeItem [] newItems = new TreeItem [items.length + extra]; | 4153 TreeItem [] newItems = new TreeItem [items.length + extra]; |
4051 OS.InvalidateRect (handle, null, true); | 4208 OS.InvalidateRect (handle, null, true); |
4052 } | 4209 } |
4053 | 4210 |
4054 override HWND scrolledHandle () { | 4211 override HWND scrolledHandle () { |
4055 if (hwndHeader is null) return handle; | 4212 if (hwndHeader is null) return handle; |
4056 int count = OS.SendMessage (hwndHeader, OS.HDM_GETITEMCOUNT, 0, 0); | 4213 return columnCount is 0 && scrollWidth is 0 ? handle : hwndParent; |
4057 return count is 0 ? handle : hwndParent; | |
4058 } | 4214 } |
4059 | 4215 |
4060 void select (HANDLE hItem, TVITEM* tvItem) { | 4216 void select (HANDLE hItem, TVITEM* tvItem) { |
4061 while (hItem !is null) { | 4217 while (hItem !is null) { |
4062 tvItem.hItem = hItem; | 4218 tvItem.hItem = hItem; |
4063 OS.SendMessage (handle, OS.TVM_SETITEM, 0, tvItem); | 4219 OS.SendMessage (handle, OS.TVM_SETITEM, 0, tvItem); |
4064 auto hFirstItem = cast(HANDLE) OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_CHILD, hItem); | 4220 auto hFirstItem = cast(HANDLE) OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_CHILD, hItem); |
4065 select (hFirstItem, tvItem); | 4221 select (hFirstItem, tvItem); |
4066 hItem = cast(HANDLE) OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_NEXT, hItem); | 4222 hItem = cast(HANDLE) OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_NEXT, hItem); |
4067 } | 4223 } |
4224 } | |
4225 | |
4226 /** | |
4227 * Selects an item in the receiver. If the item was already | |
4228 * selected, it remains selected. | |
4229 * | |
4230 * @param item the item to be selected | |
4231 * | |
4232 * @exception IllegalArgumentException <ul> | |
4233 * <li>ERROR_NULL_ARGUMENT - if the item is null</li> | |
4234 * <li>ERROR_INVALID_ARGUMENT - if the item has been disposed</li> | |
4235 * </ul> | |
4236 * @exception DWTException <ul> | |
4237 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> | |
4238 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> | |
4239 * </ul> | |
4240 * | |
4241 * @since 3.4 | |
4242 */ | |
4243 public void select (TreeItem item) { | |
4244 checkWidget (); | |
4245 if (item is null) error (DWT.ERROR_NULL_ARGUMENT); | |
4246 if (item.isDisposed ()) error (DWT.ERROR_INVALID_ARGUMENT); | |
4247 if ((style & DWT.SINGLE) !is 0) { | |
4248 auto hItem = item.handle; | |
4249 int state = 0; | |
4250 static if (OS.IsWinCE) { | |
4251 TVITEM tvItem; | |
4252 tvItem.hItem = hItem; | |
4253 tvItem.mask = OS.TVIF_STATE; | |
4254 OS.SendMessage (handle, OS.TVM_GETITEM, 0, cast(int)&tvItem); | |
4255 state = tvItem.state; | |
4256 } else { | |
4257 state = OS.SendMessage (handle, OS.TVM_GETITEMSTATE, cast(int)&hItem, OS.TVIS_SELECTED); | |
4258 } | |
4259 if ((state & OS.TVIS_SELECTED) !is 0) return; | |
4260 /* | |
4261 * Feature in Windows. When an item is selected with | |
4262 * TVM_SELECTITEM and TVGN_CARET, the tree expands and | |
4263 * scrolls to show the new selected item. Unfortunately, | |
4264 * there is no other way in Windows to set the focus | |
4265 * and select an item. The fix is to save the current | |
4266 * scroll bar positions, turn off redraw, select the item, | |
4267 * then scroll back to the original position and redraw | |
4268 * the entire tree. | |
4269 */ | |
4270 SCROLLINFO* hInfo = null; | |
4271 int bits = OS.GetWindowLong (handle, OS.GWL_STYLE); | |
4272 if ((bits & (OS.TVS_NOHSCROLL | OS.TVS_NOSCROLL)) is 0) { | |
4273 hInfo = new SCROLLINFO (); | |
4274 hInfo.cbSize = SCROLLINFO.sizeof; | |
4275 hInfo.fMask = OS.SIF_ALL; | |
4276 OS.GetScrollInfo (handle, OS.SB_HORZ, hInfo); | |
4277 } | |
4278 SCROLLINFO vInfo; | |
4279 vInfo.cbSize = SCROLLINFO.sizeof; | |
4280 vInfo.fMask = OS.SIF_ALL; | |
4281 OS.GetScrollInfo (handle, OS.SB_VERT, &vInfo); | |
4282 bool redraw = drawCount is 0 && OS.IsWindowVisible (handle); | |
4283 if (redraw) { | |
4284 OS.UpdateWindow (handle); | |
4285 OS.DefWindowProc (handle, OS.WM_SETREDRAW, 0, 0); | |
4286 } | |
4287 setSelection (item); | |
4288 if (hInfo !is null) { | |
4289 int /*long*/ hThumb = OS.MAKELPARAM (OS.SB_THUMBPOSITION, hInfo.nPos); | |
4290 OS.SendMessage (handle, OS.WM_HSCROLL, hThumb, 0); | |
4291 } | |
4292 int /*long*/ vThumb = OS.MAKELPARAM (OS.SB_THUMBPOSITION, vInfo.nPos); | |
4293 OS.SendMessage (handle, OS.WM_VSCROLL, vThumb, 0); | |
4294 if (redraw) { | |
4295 OS.DefWindowProc (handle, OS.WM_SETREDRAW, 1, 0); | |
4296 OS.InvalidateRect (handle, null, true); | |
4297 if ((style & DWT.DOUBLE_BUFFERED) is 0) { | |
4298 int oldStyle = style; | |
4299 style |= DWT.DOUBLE_BUFFERED; | |
4300 OS.UpdateWindow (handle); | |
4301 style = oldStyle; | |
4302 } | |
4303 } | |
4304 return; | |
4305 } | |
4306 TVITEM tvItem; | |
4307 tvItem.mask = OS.TVIF_HANDLE | OS.TVIF_STATE; | |
4308 tvItem.stateMask = OS.TVIS_SELECTED; | |
4309 tvItem.state = OS.TVIS_SELECTED; | |
4310 tvItem.hItem = item.handle; | |
4311 OS.SendMessage (handle, OS.TVM_SETITEM, 0, cast(int)&tvItem); | |
4068 } | 4312 } |
4069 | 4313 |
4070 /** | 4314 /** |
4071 * Selects all of the items in the receiver. | 4315 * Selects all of the items in the receiver. |
4072 * <p> | 4316 * <p> |
4083 if ((style & DWT.SINGLE) !is 0) return; | 4327 if ((style & DWT.SINGLE) !is 0) return; |
4084 TVITEM tvItem; | 4328 TVITEM tvItem; |
4085 tvItem.mask = OS.TVIF_HANDLE | OS.TVIF_STATE; | 4329 tvItem.mask = OS.TVIF_HANDLE | OS.TVIF_STATE; |
4086 tvItem.state = OS.TVIS_SELECTED; | 4330 tvItem.state = OS.TVIS_SELECTED; |
4087 tvItem.stateMask = OS.TVIS_SELECTED; | 4331 tvItem.stateMask = OS.TVIS_SELECTED; |
4088 int oldProc = OS.GetWindowLong (handle, OS.GWL_WNDPROC); | 4332 int /*long*/ oldProc = OS.GetWindowLongPtr (handle, OS.GWLP_WNDPROC); |
4089 OS.SetWindowLong (handle, OS.GWL_WNDPROC, cast(int) TreeProc); | 4333 OS.SetWindowLongPtr (handle, OS.GWLP_WNDPROC, cast(LONG_PTR)TreeProc); |
4090 if ((style & DWT.VIRTUAL) !is 0) { | 4334 if ((style & DWT.VIRTUAL) !is 0) { |
4091 HANDLE hItem = cast(HANDLE) OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_ROOT, 0); | 4335 HANDLE hItem = cast(HANDLE) OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_ROOT, 0); |
4092 select (hItem, &tvItem); | 4336 select (hItem, &tvItem); |
4093 } else { | 4337 } else { |
4094 for (int i=0; i<items.length; i++) { | 4338 for (int i=0; i<items.length; i++) { |
4097 tvItem.hItem = item.handle; | 4341 tvItem.hItem = item.handle; |
4098 OS.SendMessage (handle, OS.TVM_SETITEM, 0, &tvItem); | 4342 OS.SendMessage (handle, OS.TVM_SETITEM, 0, &tvItem); |
4099 } | 4343 } |
4100 } | 4344 } |
4101 } | 4345 } |
4102 OS.SetWindowLong (handle, OS.GWL_WNDPROC, oldProc); | 4346 OS.SetWindowLongPtr (handle, OS.GWLP_WNDPROC, oldProc); |
4347 } | |
4348 | |
4349 Event sendEraseItemEvent (TreeItem item, NMTTCUSTOMDRAW* nmcd, int column, RECT* cellRect) { | |
4350 int nSavedDC = OS.SaveDC (nmcd.nmcd.hdc); | |
4351 RECT* insetRect = toolTipInset (cellRect); | |
4352 OS.SetWindowOrgEx (nmcd.nmcd.hdc, insetRect.left, insetRect.top, null); | |
4353 GCData data = new GCData (); | |
4354 data.device = display; | |
4355 data.foreground = OS.GetTextColor (nmcd.nmcd.hdc); | |
4356 data.background = OS.GetBkColor (nmcd.nmcd.hdc); | |
4357 data.font = item.getFont (column); | |
4358 data.uiState = OS.SendMessage (handle, OS.WM_QUERYUISTATE, 0, 0); | |
4359 GC gc = GC.win32_new (nmcd.nmcd.hdc, data); | |
4360 Event event = new Event (); | |
4361 event.item = item; | |
4362 event.index = column; | |
4363 event.gc = gc; | |
4364 event.detail |= DWT.FOREGROUND; | |
4365 event.x = cellRect.left; | |
4366 event.y = cellRect.top; | |
4367 event.width = cellRect.right - cellRect.left; | |
4368 event.height = cellRect.bottom - cellRect.top; | |
4369 //gc.setClipping (event.x, event.y, event.width, event.height); | |
4370 sendEvent (DWT.EraseItem, event); | |
4371 event.gc = null; | |
4372 //int newTextClr = data.foreground; | |
4373 gc.dispose (); | |
4374 OS.RestoreDC (nmcd.nmcd.hdc, nSavedDC); | |
4375 return event; | |
4376 } | |
4377 | |
4378 Event sendMeasureItemEvent (TreeItem item, int index, HDC hDC) { | |
4379 RECT itemRect = item.getBounds (index, true, true, false, false, false, hDC); | |
4380 int nSavedDC = OS.SaveDC (hDC); | |
4381 GCData data = new GCData (); | |
4382 data.device = display; | |
4383 data.font = item.getFont (index); | |
4384 GC gc = GC.win32_new (hDC, data); | |
4385 Event event = new Event (); | |
4386 event.item = item; | |
4387 event.gc = gc; | |
4388 event.index = index; | |
4389 event.x = itemRect.left; | |
4390 event.y = itemRect.top; | |
4391 event.width = itemRect.right - itemRect.left; | |
4392 event.height = itemRect.bottom - itemRect.top; | |
4393 sendEvent (DWT.MeasureItem, event); | |
4394 event.gc = null; | |
4395 gc.dispose (); | |
4396 OS.RestoreDC (hDC, nSavedDC); | |
4397 if (isDisposed () || item.isDisposed ()) return null; | |
4398 if (hwndHeader !is null) { | |
4399 if (columnCount is 0) { | |
4400 if (event.x + event.width > scrollWidth) { | |
4401 setScrollWidth (scrollWidth = event.x + event.width); | |
4402 } | |
4403 } | |
4404 } | |
4405 if (event.height > getItemHeight ()) setItemHeight (event.height); | |
4406 return event; | |
4407 } | |
4408 | |
4409 Event sendPaintItemEvent (TreeItem item, NMTTCUSTOMDRAW* nmcd, int column, RECT* itemRect) { | |
4410 int nSavedDC = OS.SaveDC (nmcd.nmcd.hdc); | |
4411 RECT* insetRect = toolTipInset (itemRect); | |
4412 OS.SetWindowOrgEx (nmcd.nmcd.hdc, insetRect.left, insetRect.top, null); | |
4413 GCData data = new GCData (); | |
4414 data.device = display; | |
4415 data.font = item.getFont (column); | |
4416 data.foreground = OS.GetTextColor (nmcd.nmcd.hdc); | |
4417 data.background = OS.GetBkColor (nmcd.nmcd.hdc); | |
4418 data.uiState = OS.SendMessage (handle, OS.WM_QUERYUISTATE, 0, 0); | |
4419 GC gc = GC.win32_new (nmcd.nmcd.hdc, data); | |
4420 Event event = new Event (); | |
4421 event.item = item; | |
4422 event.index = column; | |
4423 event.gc = gc; | |
4424 event.detail |= DWT.FOREGROUND; | |
4425 event.x = itemRect.left; | |
4426 event.y = itemRect.top; | |
4427 event.width = itemRect.right - itemRect.left; | |
4428 event.height = itemRect.bottom - itemRect.top; | |
4429 //gc.setClipping (cellRect.left, cellRect.top, cellWidth, cellHeight); | |
4430 sendEvent (DWT.PaintItem, event); | |
4431 event.gc = null; | |
4432 gc.dispose (); | |
4433 OS.RestoreDC (nmcd.nmcd.hdc, nSavedDC); | |
4434 return event; | |
4103 } | 4435 } |
4104 | 4436 |
4105 override void setBackgroundImage (HBITMAP hBitmap) { | 4437 override void setBackgroundImage (HBITMAP hBitmap) { |
4106 super.setBackgroundImage (hBitmap); | 4438 super.setBackgroundImage (hBitmap); |
4107 if (hBitmap !is null) { | 4439 if (hBitmap !is null) { |
4162 * color is set. | 4494 * color is set. |
4163 */ | 4495 */ |
4164 updateFullSelection (); | 4496 updateFullSelection (); |
4165 } | 4497 } |
4166 | 4498 |
4167 override void setBounds (int x, int y, int width, int height, int flags) { | |
4168 /* | |
4169 * Ensure that the selection is visible when the tree is resized | |
4170 * from a zero size to a size that can show the selection. | |
4171 */ | |
4172 bool fixSelection = false; | |
4173 if ((flags & OS.SWP_NOSIZE) is 0 && (width !is 0 || height !is 0)) { | |
4174 if (OS.SendMessage (handle, OS.TVM_GETVISIBLECOUNT, 0, 0) is 0) { | |
4175 fixSelection = true; | |
4176 } | |
4177 } | |
4178 super.setBounds (x, y, width, height, flags); | |
4179 if (fixSelection) { | |
4180 HANDLE hItem = cast(HANDLE) OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_CARET, 0); | |
4181 if (hItem !is null) showItem (hItem); | |
4182 } | |
4183 } | |
4184 | |
4185 override void setCursor () { | 4499 override void setCursor () { |
4186 /* | 4500 /* |
4187 * Bug in Windows. Under certain circumstances, when WM_SETCURSOR | 4501 * Bug in Windows. Under certain circumstances, when WM_SETCURSOR |
4188 * is sent from SendMessage(), Windows GP's in the window proc for | 4502 * is sent from SendMessage(), Windows GP's in the window proc for |
4189 * the tree. The fix is to avoid calling the tree window proc and | 4503 * the tree. The fix is to avoid calling the tree window proc and |
4222 * @since 3.2 | 4536 * @since 3.2 |
4223 */ | 4537 */ |
4224 public void setColumnOrder (int [] order) { | 4538 public void setColumnOrder (int [] order) { |
4225 checkWidget (); | 4539 checkWidget (); |
4226 if (order is null) error (DWT.ERROR_NULL_ARGUMENT); | 4540 if (order is null) error (DWT.ERROR_NULL_ARGUMENT); |
4227 int count = 0; | 4541 if (columnCount is 0) { |
4228 if (hwndHeader !is null) { | |
4229 count = OS.SendMessage (hwndHeader, OS.HDM_GETITEMCOUNT, 0, 0); | |
4230 } | |
4231 if (count is 0) { | |
4232 if (order.length !is 0) error (DWT.ERROR_INVALID_ARGUMENT); | 4542 if (order.length !is 0) error (DWT.ERROR_INVALID_ARGUMENT); |
4233 return; | 4543 return; |
4234 } | 4544 } |
4235 if (order.length !is count) error (DWT.ERROR_INVALID_ARGUMENT); | 4545 if (order.length !is columnCount) error (DWT.ERROR_INVALID_ARGUMENT); |
4236 int [] oldOrder = new int [count]; | 4546 int [] oldOrder = new int [columnCount]; |
4237 OS.SendMessage (hwndHeader, OS.HDM_GETORDERARRAY, count, oldOrder.ptr); | 4547 OS.SendMessage (hwndHeader, OS.HDM_GETORDERARRAY, columnCount, oldOrder.ptr); |
4238 bool reorder = false; | 4548 bool reorder = false; |
4239 bool [] seen = new bool [count]; | 4549 bool [] seen = new bool [columnCount]; |
4240 for (int i=0; i<order.length; i++) { | 4550 for (int i=0; i<order.length; i++) { |
4241 int index = order [i]; | 4551 int index = order [i]; |
4242 if (index < 0 || index >= count) error (DWT.ERROR_INVALID_RANGE); | 4552 if (index < 0 || index >= columnCount) error (DWT.ERROR_INVALID_RANGE); |
4243 if (seen [index]) error (DWT.ERROR_INVALID_ARGUMENT); | 4553 if (seen [index]) error (DWT.ERROR_INVALID_ARGUMENT); |
4244 seen [index] = true; | 4554 seen [index] = true; |
4245 if (index !is oldOrder [i]) reorder = true; | 4555 if (index !is oldOrder [i]) reorder = true; |
4246 } | 4556 } |
4247 if (reorder) { | 4557 if (reorder) { |
4248 RECT [] oldRects = new RECT [count]; | 4558 RECT [] oldRects = new RECT [columnCount]; |
4249 for (int i=0; i<count; i++) { | 4559 for (int i=0; i<columnCount; i++) { |
4250 //oldRects [i] = new RECT (); | 4560 //oldRects [i] = new RECT (); |
4251 OS.SendMessage (hwndHeader, OS.HDM_GETITEMRECT, i, & oldRects [i]); | 4561 OS.SendMessage (hwndHeader, OS.HDM_GETITEMRECT, i, & oldRects [i]); |
4252 } | 4562 } |
4253 OS.SendMessage (hwndHeader, OS.HDM_SETORDERARRAY, order.length, order.ptr); | 4563 OS.SendMessage (hwndHeader, OS.HDM_SETORDERARRAY, order.length, order.ptr); |
4254 OS.InvalidateRect (handle, null, true); | 4564 OS.InvalidateRect (handle, null, true); |
4255 updateImageList (); | 4565 updateImageList (); |
4256 TreeColumn [] newColumns = new TreeColumn [count]; | 4566 TreeColumn [] newColumns = new TreeColumn [columnCount]; |
4257 System.arraycopy (columns, 0, newColumns, 0, count); | 4567 System.arraycopy (columns, 0, newColumns, 0, columnCount); |
4258 RECT newRect; | 4568 RECT newRect; |
4259 for (int i=0; i<count; i++) { | 4569 for (int i=0; i<columnCount; i++) { |
4260 TreeColumn column = newColumns [i]; | 4570 TreeColumn column = newColumns [i]; |
4261 if (!column.isDisposed ()) { | 4571 if (!column.isDisposed ()) { |
4262 OS.SendMessage (hwndHeader, OS.HDM_GETITEMRECT, i, &newRect); | 4572 OS.SendMessage (hwndHeader, OS.HDM_GETITEMRECT, i, &newRect); |
4263 if (newRect.left !is oldRects [i].left) { | 4573 if (newRect.left !is oldRects [i].left) { |
4264 column.updateToolTip (i); | 4574 column.updateToolTip (i); |
4451 TVINSERTSTRUCT tvInsert; | 4761 TVINSERTSTRUCT tvInsert; |
4452 tvInsert.hInsertAfter = cast(HANDLE) OS.TVI_FIRST; | 4762 tvInsert.hInsertAfter = cast(HANDLE) OS.TVI_FIRST; |
4453 hItem = cast(HANDLE) OS.SendMessage (handle, OS.TVM_INSERTITEM, 0, &tvInsert); | 4763 hItem = cast(HANDLE) OS.SendMessage (handle, OS.TVM_INSERTITEM, 0, &tvInsert); |
4454 } | 4764 } |
4455 OS.DefWindowProc (handle, OS.WM_SETREDRAW, 1, 0); | 4765 OS.DefWindowProc (handle, OS.WM_SETREDRAW, 1, 0); |
4766 updateScrollBar (); | |
4456 } | 4767 } |
4457 } | 4768 } |
4458 super.setRedraw (redraw); | 4769 super.setRedraw (redraw); |
4459 if (!redraw) { | 4770 if (!redraw) { |
4460 if (drawCount is 1) OS.DefWindowProc (handle, OS.WM_SETREDRAW, 0, 0); | 4771 if (drawCount is 1) OS.DefWindowProc (handle, OS.WM_SETREDRAW, 0, 0); |
4468 | 4779 |
4469 void setScrollWidth () { | 4780 void setScrollWidth () { |
4470 if (hwndHeader is null || hwndParent is null) return; | 4781 if (hwndHeader is null || hwndParent is null) return; |
4471 int width = 0; | 4782 int width = 0; |
4472 HDITEM hdItem; | 4783 HDITEM hdItem; |
4473 int count = OS.SendMessage (hwndHeader, OS.HDM_GETITEMCOUNT, 0, 0); | 4784 for (int i=0; i<columnCount; i++) { |
4474 for (int i=0; i<count; i++) { | |
4475 hdItem.mask = OS.HDI_WIDTH; | 4785 hdItem.mask = OS.HDI_WIDTH; |
4476 OS.SendMessage (hwndHeader, OS.HDM_GETITEM, i, &hdItem); | 4786 OS.SendMessage (hwndHeader, OS.HDM_GETITEM, i, &hdItem); |
4477 width += hdItem.cxy; | 4787 width += hdItem.cxy; |
4478 } | 4788 } |
4479 setScrollWidth (Math.max (scrollWidth, width)); | 4789 setScrollWidth (Math.max (scrollWidth, width)); |
4486 int left = 0; | 4796 int left = 0; |
4487 RECT rect; | 4797 RECT rect; |
4488 SCROLLINFO info; | 4798 SCROLLINFO info; |
4489 info.cbSize = SCROLLINFO.sizeof; | 4799 info.cbSize = SCROLLINFO.sizeof; |
4490 info.fMask = OS.SIF_RANGE | OS.SIF_PAGE; | 4800 info.fMask = OS.SIF_RANGE | OS.SIF_PAGE; |
4491 int count = OS.SendMessage (hwndHeader, OS.HDM_GETITEMCOUNT, 0, 0); | 4801 if (columnCount is 0 && width is 0) { |
4492 if (count is 0 && width is 0) { | |
4493 OS.GetScrollInfo (hwndParent, OS.SB_HORZ, &info); | 4802 OS.GetScrollInfo (hwndParent, OS.SB_HORZ, &info); |
4494 info.nPage = info.nMax + 1; | 4803 info.nPage = info.nMax + 1; |
4495 OS.SetScrollInfo (hwndParent, OS.SB_HORZ, &info, true); | 4804 OS.SetScrollInfo (hwndParent, OS.SB_HORZ, &info, true); |
4496 OS.GetScrollInfo (hwndParent, OS.SB_VERT, &info); | 4805 OS.GetScrollInfo (hwndParent, OS.SB_VERT, &info); |
4497 info.nPage = info.nMax + 1; | 4806 info.nPage = info.nMax + 1; |
4498 OS.SetScrollInfo (hwndParent, OS.SB_VERT, &info, true); | 4807 OS.SetScrollInfo (hwndParent, OS.SB_VERT, &info, true); |
4499 } else { | 4808 } else { |
4500 OS.GetClientRect (hwndParent, &rect); | 4809 if ((style & DWT.H_SCROLL) !is 0) { |
4501 OS.GetScrollInfo (hwndParent, OS.SB_HORZ, &info); | 4810 OS.GetClientRect (hwndParent, &rect); |
4502 info.nMax = width; | 4811 OS.GetScrollInfo (hwndParent, OS.SB_HORZ, &info); |
4503 info.nPage = rect.right - rect.left + 1; | 4812 info.nMax = width; |
4504 OS.SetScrollInfo (hwndParent, OS.SB_HORZ, &info, true); | 4813 info.nPage = rect.right - rect.left + 1; |
4505 info.fMask = OS.SIF_POS; | 4814 OS.SetScrollInfo (hwndParent, OS.SB_HORZ, &info, true); |
4506 OS.GetScrollInfo (hwndParent, OS.SB_HORZ, &info); | 4815 info.fMask = OS.SIF_POS; |
4507 left = info.nPos; | 4816 OS.GetScrollInfo (hwndParent, OS.SB_HORZ, &info); |
4817 left = info.nPos; | |
4818 } | |
4508 } | 4819 } |
4509 if (horizontalBar !is null) { | 4820 if (horizontalBar !is null) { |
4510 horizontalBar.setIncrement (INCREMENT); | 4821 horizontalBar.setIncrement (INCREMENT); |
4511 horizontalBar.setPageIncrement (info.nPage); | 4822 horizontalBar.setPageIncrement (info.nPage); |
4512 } | 4823 } |
4518 playout.pwpos = &pos; | 4829 playout.pwpos = &pos; |
4519 OS.SendMessage (hwndHeader, OS.HDM_LAYOUT, 0, &playout); | 4830 OS.SendMessage (hwndHeader, OS.HDM_LAYOUT, 0, &playout); |
4520 SetWindowPos (hwndHeader, cast(HWND)OS.HWND_TOP, pos.x - left, pos.y, pos.cx + left, pos.cy, OS.SWP_NOACTIVATE); | 4831 SetWindowPos (hwndHeader, cast(HWND)OS.HWND_TOP, pos.x - left, pos.y, pos.cx + left, pos.cy, OS.SWP_NOACTIVATE); |
4521 int bits = OS.GetWindowLong (handle, OS.GWL_EXSTYLE); | 4832 int bits = OS.GetWindowLong (handle, OS.GWL_EXSTYLE); |
4522 int b = (bits & OS.WS_EX_CLIENTEDGE) !is 0 ? OS.GetSystemMetrics (OS.SM_CXEDGE) : 0; | 4833 int b = (bits & OS.WS_EX_CLIENTEDGE) !is 0 ? OS.GetSystemMetrics (OS.SM_CXEDGE) : 0; |
4523 int w = pos.cx + (count is 0 && width is 0 ? 0 : OS.GetSystemMetrics (OS.SM_CXVSCROLL)); | 4834 int w = pos.cx + (columnCount is 0 && width is 0 ? 0 : OS.GetSystemMetrics (OS.SM_CXVSCROLL)); |
4524 int h = rect.bottom - rect.top - pos.cy; | 4835 int h = rect.bottom - rect.top - pos.cy; |
4525 bool oldIgnore = ignoreResize; | 4836 bool oldIgnore = ignoreResize; |
4526 ignoreResize = true; | 4837 ignoreResize = true; |
4527 SetWindowPos (handle, null, pos.x - left - b, pos.y + pos.cy - b, w + left + b * 2, h + b * 2, OS.SWP_NOACTIVATE | OS.SWP_NOZORDER); | 4838 SetWindowPos (handle, null, pos.x - left - b, pos.y + pos.cy - b, w + left + b * 2, h + b * 2, OS.SWP_NOACTIVATE | OS.SWP_NOZORDER); |
4528 ignoreResize = oldIgnore; | 4839 ignoreResize = oldIgnore; |
4639 ignoreSelect = true; | 4950 ignoreSelect = true; |
4640 OS.SendMessage (handle, OS.TVM_SELECTITEM, OS.TVGN_CARET, hNewItem); | 4951 OS.SendMessage (handle, OS.TVM_SELECTITEM, OS.TVGN_CARET, hNewItem); |
4641 ignoreSelect = false; | 4952 ignoreSelect = false; |
4642 if (OS.SendMessage (handle, OS.TVM_GETVISIBLECOUNT, 0, 0) is 0) { | 4953 if (OS.SendMessage (handle, OS.TVM_GETVISIBLECOUNT, 0, 0) is 0) { |
4643 OS.SendMessage (handle, OS.TVM_SELECTITEM, OS.TVGN_FIRSTVISIBLE, hNewItem); | 4954 OS.SendMessage (handle, OS.TVM_SELECTITEM, OS.TVGN_FIRSTVISIBLE, hNewItem); |
4644 int hParent = OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_PARENT, hNewItem); | 4955 int /*long*/ hParent = OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_PARENT, hNewItem); |
4645 if (hParent is 0) OS.SendMessage (handle, OS.WM_HSCROLL, OS.SB_TOP, 0); | 4956 if (hParent is 0) OS.SendMessage (handle, OS.WM_HSCROLL, OS.SB_TOP, 0); |
4646 } | 4957 } |
4647 if (fixScroll) { | 4958 if (fixScroll) { |
4648 OS.DefWindowProc (handle, OS.WM_SETREDRAW, 1, 0); | 4959 OS.DefWindowProc (handle, OS.WM_SETREDRAW, 1, 0); |
4649 OS.SendMessage (handle, OS.WM_SETREDRAW, 0, 0); | 4960 OS.SendMessage (handle, OS.WM_SETREDRAW, 0, 0); |
4670 | 4981 |
4671 /* Select/deselect the rest of the items */ | 4982 /* Select/deselect the rest of the items */ |
4672 TVITEM tvItem; | 4983 TVITEM tvItem; |
4673 tvItem.mask = OS.TVIF_HANDLE | OS.TVIF_STATE; | 4984 tvItem.mask = OS.TVIF_HANDLE | OS.TVIF_STATE; |
4674 tvItem.stateMask = OS.TVIS_SELECTED; | 4985 tvItem.stateMask = OS.TVIS_SELECTED; |
4675 int oldProc = OS.GetWindowLong (handle, OS.GWL_WNDPROC); | 4986 int /*long*/ oldProc = OS.GetWindowLongPtr (handle, OS.GWLP_WNDPROC); |
4676 OS.SetWindowLong (handle, OS.GWL_WNDPROC, cast(int) TreeProc); | 4987 OS.SetWindowLongPtr (handle, OS.GWLP_WNDPROC, cast(LONG_PTR)TreeProc); |
4677 if ((style & DWT.VIRTUAL) !is 0) { | 4988 if ((style & DWT.VIRTUAL) !is 0) { |
4678 HANDLE hItem = cast(HANDLE) OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_ROOT, 0); | 4989 HANDLE hItem = cast(HANDLE) OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_ROOT, 0); |
4679 setSelection (hItem, &tvItem, items); | 4990 setSelection (hItem, &tvItem, items); |
4680 } else { | 4991 } else { |
4681 for (int i=0; i<this.items.length; i++) { | 4992 for (int i=0; i<this.items.length; i++) { |
4700 } | 5011 } |
4701 } | 5012 } |
4702 } | 5013 } |
4703 } | 5014 } |
4704 } | 5015 } |
4705 OS.SetWindowLong (handle, OS.GWL_WNDPROC, oldProc); | 5016 OS.SetWindowLongPtr (handle, OS.GWLP_WNDPROC, oldProc); |
4706 } | 5017 } |
4707 | 5018 |
4708 /** | 5019 /** |
4709 * Sets the column used by the sort indicator for the receiver. A null | 5020 * Sets the column used by the sort indicator for the receiver. A null |
4710 * value will clear the sort indicator. The current sort column is cleared | 5021 * value will clear the sort indicator. The current sort column is cleared |
4832 OS.SendMessage (handle, OS.WM_SETREDRAW, 0, 0); | 5143 OS.SendMessage (handle, OS.WM_SETREDRAW, 0, 0); |
4833 } | 5144 } |
4834 } else { | 5145 } else { |
4835 bool scroll = true; | 5146 bool scroll = true; |
4836 RECT itemRect; | 5147 RECT itemRect; |
4837 itemRect.left = cast(int) hItem; | 5148 if (OS.TreeView_GetItemRect (handle, hItem, &itemRect, true)) { |
4838 if (OS.SendMessage (handle, OS.TVM_GETITEMRECT, 1, &itemRect) !is 0) { | |
4839 forceResize (); | 5149 forceResize (); |
4840 RECT rect; | 5150 RECT rect; |
4841 OS.GetClientRect (handle, &rect); | 5151 OS.GetClientRect (handle, &rect); |
4842 POINT pt; | 5152 POINT pt; |
4843 pt.x = itemRect.left; | 5153 pt.x = itemRect.left; |
4860 } | 5170 } |
4861 } | 5171 } |
4862 } | 5172 } |
4863 if (hwndParent !is null) { | 5173 if (hwndParent !is null) { |
4864 RECT itemRect; | 5174 RECT itemRect; |
4865 itemRect.left = cast(int) hItem; | 5175 if (OS.TreeView_GetItemRect (handle, hItem, &itemRect, true)) { |
4866 if (OS.SendMessage (handle, OS.TVM_GETITEMRECT, 1, &itemRect) !is 0) { | |
4867 forceResize (); | 5176 forceResize (); |
4868 RECT rect; | 5177 RECT rect; |
4869 OS.GetClientRect (hwndParent, &rect); | 5178 OS.GetClientRect (hwndParent, &rect); |
4870 OS.MapWindowPoints (hwndParent, handle, cast(POINT*) &rect, 2); | 5179 OS.MapWindowPoints (hwndParent, handle, cast(POINT*) &rect, 2); |
4871 POINT pt; | 5180 POINT pt; |
4910 if (column is null) error (DWT.ERROR_NULL_ARGUMENT); | 5219 if (column is null) error (DWT.ERROR_NULL_ARGUMENT); |
4911 if (column.isDisposed ()) error(DWT.ERROR_INVALID_ARGUMENT); | 5220 if (column.isDisposed ()) error(DWT.ERROR_INVALID_ARGUMENT); |
4912 if (column.parent !is this) return; | 5221 if (column.parent !is this) return; |
4913 int index = indexOf (column); | 5222 int index = indexOf (column); |
4914 if (index is -1) return; | 5223 if (index is -1) return; |
4915 int count = OS.SendMessage (hwndHeader, OS.HDM_GETITEMCOUNT, 0, 0); | 5224 if (0 <= index && index < columnCount) { |
4916 if (0 <= index && index < count) { | 5225 forceResize (); |
4917 if (hwndParent !is null) { | 5226 RECT rect; |
4918 forceResize (); | 5227 OS.GetClientRect (hwndParent, &rect); |
4919 RECT rect; | 5228 OS.MapWindowPoints (hwndParent, handle, cast(POINT*) &rect, 2); |
4920 OS.GetClientRect (hwndParent, &rect); | 5229 RECT headerRect; |
4921 OS.MapWindowPoints (hwndParent, handle, cast(POINT*) &rect, 2); | 5230 OS.SendMessage (hwndHeader, OS.HDM_GETITEMRECT, index, &headerRect); |
4922 RECT headerRect; | 5231 bool scroll = headerRect.left < rect.left; |
4923 OS.SendMessage (hwndHeader, OS.HDM_GETITEMRECT, index, &headerRect); | 5232 if (!scroll) { |
4924 bool scroll = headerRect.left < rect.left; | 5233 int width = Math.min (rect.right - rect.left, headerRect.right - headerRect.left); |
4925 if (!scroll) { | 5234 scroll = headerRect.left + width > rect.right; |
4926 int width = Math.min (rect.right - rect.left, headerRect.right - headerRect.left); | 5235 } |
4927 scroll = headerRect.left + width > rect.right; | 5236 if (scroll) { |
4928 } | 5237 SCROLLINFO info; |
4929 if (scroll) { | 5238 info.cbSize = SCROLLINFO.sizeof; |
4930 SCROLLINFO info; | 5239 info.fMask = OS.SIF_POS; |
4931 info.cbSize = SCROLLINFO.sizeof; | 5240 info.nPos = Math.max (0, headerRect.left - Tree.INSET / 2); |
4932 info.fMask = OS.SIF_POS; | 5241 OS.SetScrollInfo (hwndParent, OS.SB_HORZ, &info, true); |
4933 info.nPos = Math.max (0, headerRect.left - Tree.INSET / 2); | 5242 setScrollWidth (); |
4934 OS.SetScrollInfo (hwndParent, OS.SB_HORZ, &info, true); | |
4935 setScrollWidth (); | |
4936 } | |
4937 } | 5243 } |
4938 } | 5244 } |
4939 } | 5245 } |
4940 | 5246 |
4941 /** | 5247 /** |
4991 } else { | 5297 } else { |
4992 state = OS.SendMessage (handle, OS.TVM_GETITEMSTATE, hItem, OS.TVIS_SELECTED); | 5298 state = OS.SendMessage (handle, OS.TVM_GETITEMSTATE, hItem, OS.TVIS_SELECTED); |
4993 } | 5299 } |
4994 if ((state & OS.TVIS_SELECTED) is 0) return; | 5300 if ((state & OS.TVIS_SELECTED) is 0) return; |
4995 } else { | 5301 } else { |
4996 int oldProc = OS.GetWindowLong (handle, OS.GWL_WNDPROC); | 5302 int /*long*/ oldProc = OS.GetWindowLongPtr (handle, OS.GWLP_WNDPROC); |
4997 OS.SetWindowLong (handle, OS.GWL_WNDPROC, cast(int) TreeProc); | 5303 OS.SetWindowLongPtr (handle, OS.GWLP_WNDPROC, cast(LONG_PTR)TreeProc); |
4998 TVITEM tvItem_; | 5304 TVITEM tvItem_; |
4999 TVITEM* tvItem; | 5305 TVITEM* tvItem; |
5000 static if (OS.IsWinCE) { | 5306 static if (OS.IsWinCE) { |
5001 tvItem = &tvItem_; | 5307 tvItem = &tvItem_; |
5002 tvItem.mask = OS.TVIF_STATE; | 5308 tvItem.mask = OS.TVIF_STATE; |
5024 } | 5330 } |
5025 } | 5331 } |
5026 index++; | 5332 index++; |
5027 } | 5333 } |
5028 } | 5334 } |
5029 OS.SetWindowLong (handle, OS.GWL_WNDPROC, oldProc); | 5335 OS.SetWindowLongPtr (handle, OS.GWLP_WNDPROC, oldProc); |
5030 } | 5336 } |
5031 if (hItem !is null) showItem (hItem); | 5337 if (hItem !is null) showItem (hItem); |
5032 } | 5338 } |
5033 | 5339 |
5034 /*public*/ void sort () { | 5340 /*public*/ void sort () { |
5059 } | 5365 } |
5060 | 5366 |
5061 override void subclass () { | 5367 override void subclass () { |
5062 super.subclass (); | 5368 super.subclass (); |
5063 if (hwndHeader !is null) { | 5369 if (hwndHeader !is null) { |
5064 OS.SetWindowLong (hwndHeader, OS.GWL_WNDPROC, display.windowProc); | 5370 OS.SetWindowLongPtr (hwndHeader, OS.GWLP_WNDPROC, display.windowProc); |
5065 } | 5371 } |
5372 } | |
5373 | |
5374 RECT* toolTipInset (RECT* rect) { | |
5375 if (!OS.IsWinCE && OS.WIN32_VERSION >= OS.VERSION (6, 0)) { | |
5376 RECT* insetRect = new RECT(); | |
5377 OS.SetRect (insetRect, rect.left - 1, rect.top - 1, rect.right + 1, rect.bottom + 1); | |
5378 return insetRect; | |
5379 } | |
5380 return rect; | |
5381 } | |
5382 | |
5383 RECT* toolTipRect (RECT* rect) { | |
5384 RECT* toolRect = new RECT (); | |
5385 if (!OS.IsWinCE && OS.WIN32_VERSION >= OS.VERSION (6, 0)) { | |
5386 OS.SetRect (toolRect, rect.left - 1, rect.top - 1, rect.right + 1, rect.bottom + 1); | |
5387 } else { | |
5388 OS.SetRect (toolRect, rect.left, rect.top, rect.right, rect.bottom); | |
5389 int dwStyle = OS.GetWindowLong (itemToolTipHandle, OS.GWL_STYLE); | |
5390 int dwExStyle = OS.GetWindowLong (itemToolTipHandle, OS.GWL_EXSTYLE); | |
5391 OS.AdjustWindowRectEx (toolRect, dwStyle, false, dwExStyle); | |
5392 } | |
5393 return toolRect; | |
5066 } | 5394 } |
5067 | 5395 |
5068 override String toolTipText (NMTTDISPINFO* hdr) { | 5396 override String toolTipText (NMTTDISPINFO* hdr) { |
5069 auto hwndToolTip = cast(HWND) OS.SendMessage (handle, OS.TVM_GETTOOLTIPS, 0, 0); | 5397 auto hwndToolTip = cast(HWND) OS.SendMessage (handle, OS.TVM_GETTOOLTIPS, 0, 0); |
5070 if (hwndToolTip is hdr.hdr.hwndFrom && toolTipText_ !is null) return ""; //$NON-NLS-1$ | 5398 if (hwndToolTip is hdr.hdr.hwndFrom && toolTipText_ !is null) return ""; //$NON-NLS-1$ |
5071 if (headerToolTipHandle is hdr.hdr.hwndFrom) { | 5399 if (headerToolTipHandle is hdr.hdr.hwndFrom) { |
5072 int count = OS.SendMessage (hwndHeader, OS.HDM_GETITEMCOUNT, 0, 0); | 5400 for (int i=0; i<columnCount; i++) { |
5073 for (int i=0; i<count; i++) { | |
5074 TreeColumn column = columns [i]; | 5401 TreeColumn column = columns [i]; |
5075 if (column.id is hdr.hdr.idFrom) return column.toolTipText; | 5402 if (column.id is hdr.hdr.idFrom) return column.toolTipText; |
5076 } | 5403 } |
5077 return super.toolTipText (hdr); | 5404 return super.toolTipText (hdr); |
5078 } | 5405 } |
5079 if (itemToolTipHandle is hdr.hdr.hwndFrom && hwndHeader !is null) { | 5406 if (itemToolTipHandle is hdr.hdr.hwndFrom) { |
5080 if (toolTipText_ !is null) return ""; | 5407 if (toolTipText_ !is null) return ""; |
5081 if (!hooks (DWT.EraseItem) && !hooks (DWT.PaintItem)) { | 5408 int pos = OS.GetMessagePos (); |
5082 int pos = OS.GetMessagePos (); | 5409 POINT pt; |
5083 POINT pt; | 5410 OS.POINTSTOPOINT (pt, pos); |
5084 pt.x = cast(short) (pos & 0xFFFF); | 5411 OS.ScreenToClient (handle, &pt); |
5085 pt.y = cast(short) (pos >> 16); | 5412 int index; |
5086 OS.ScreenToClient (handle, &pt); | 5413 TreeItem item; |
5087 TVHITTESTINFO lpht; | 5414 RECT cellRect, itemRect; |
5088 lpht.pt.x = pt.x; | 5415 if (findCell (pt.x, pt.y, item, index, cellRect, itemRect)) { |
5089 lpht.pt.y = pt.y; | 5416 String text = null; |
5090 OS.SendMessage (handle, OS.TVM_HITTEST, 0, &lpht); | 5417 if (index is 0) { |
5091 if (lpht.hItem !is null) { | 5418 text = item.text; |
5092 auto hDC = OS.GetDC (handle); | 5419 } else { |
5093 HFONT oldFont, newFont = cast(HFONT) OS.SendMessage (handle, OS.WM_GETFONT, 0, 0); | 5420 String[] strings = item.strings; |
5094 if (newFont !is null) oldFont = OS.SelectObject (hDC, newFont); | 5421 if (strings !is null) text = strings [index]; |
5095 RECT rect; | 5422 } |
5096 OS.GetClientRect (hwndParent, &rect); | 5423 //TEMPORARY CODE |
5097 OS.MapWindowPoints (hwndParent, handle, cast(POINT*) &rect, 2); | 5424 if (!OS.IsWinCE && OS.WIN32_VERSION >= OS.VERSION (6, 0)) { |
5098 TreeItem item = _getItem (lpht.hItem); | 5425 if (isCustomToolTip ()) text = " "; |
5099 String text = null; | 5426 } |
5100 int index = 0, count = Math.max (1, OS.SendMessage (hwndHeader, OS.HDM_GETITEMCOUNT, 0, 0)); | 5427 if (text !is null) return text; |
5101 int [] order = new int [count]; | |
5102 OS.SendMessage (hwndHeader, OS.HDM_GETORDERARRAY, count, order.ptr); | |
5103 while (index < count) { | |
5104 HFONT hFont = item.cellFont !is null ? item.cellFont [order [index]] : cast(HFONT)-1; | |
5105 if (hFont is cast(HFONT)-1) hFont = item.font; | |
5106 if (hFont !is cast(HFONT)-1) hFont = OS.SelectObject (hDC, hFont); | |
5107 RECT cellRect = item.getBounds (order [index], true, false, true, false, true, hDC); | |
5108 if (hFont !is cast(HFONT)-1) OS.SelectObject (hDC, hFont); | |
5109 if (cellRect.left > rect.right) break; | |
5110 cellRect.right = Math.min (cellRect.right, rect.right); | |
5111 if (OS.PtInRect (&cellRect, pt)) { | |
5112 RECT textRect = item.getBounds (order [index], true, false, false, false, false, hDC); | |
5113 if (textRect.right > cellRect.right) { | |
5114 if (order [index] is 0) { | |
5115 text = item.text; | |
5116 } else { | |
5117 String[] strings = item.strings; | |
5118 if (strings !is null) text = strings [order [index]]; | |
5119 } | |
5120 } | |
5121 break; | |
5122 } | |
5123 index++; | |
5124 } | |
5125 if (newFont !is null) OS.SelectObject (hDC, oldFont); | |
5126 OS.ReleaseDC (handle, hDC); | |
5127 if (text !is null) return text; | |
5128 } | |
5129 } | 5428 } |
5130 } | 5429 } |
5131 return super.toolTipText (hdr); | 5430 return super.toolTipText (hdr); |
5132 } | 5431 } |
5133 | 5432 |
5162 TOOLINFO lpti; | 5461 TOOLINFO lpti; |
5163 lpti.cbSize = TOOLINFO.sizeof; | 5462 lpti.cbSize = TOOLINFO.sizeof; |
5164 lpti.uFlags = OS.TTF_SUBCLASS; | 5463 lpti.uFlags = OS.TTF_SUBCLASS; |
5165 lpti.hwnd = hwndHeader; | 5464 lpti.hwnd = hwndHeader; |
5166 lpti.lpszText = OS.LPSTR_TEXTCALLBACK; | 5465 lpti.lpszText = OS.LPSTR_TEXTCALLBACK; |
5167 int count = OS.SendMessage (hwndHeader, OS.HDM_GETITEMCOUNT, 0, 0); | 5466 for (int i=0; i<columnCount; i++) { |
5168 for (int i=0; i<count; i++) { | |
5169 TreeColumn column = columns [i]; | 5467 TreeColumn column = columns [i]; |
5170 if (OS.SendMessage (hwndHeader, OS.HDM_GETITEMRECT, i, &rect) !is 0) { | 5468 if (OS.SendMessage (hwndHeader, OS.HDM_GETITEMRECT, i, &rect) !is 0) { |
5171 lpti.uId = column.id = display.nextToolTipId++; | 5469 lpti.uId = column.id = display.nextToolTipId++; |
5172 lpti.rect.left = rect.left; | 5470 lpti.rect.left = rect.left; |
5173 lpti.rect.top = rect.top; | 5471 lpti.rect.top = rect.top; |
5222 } | 5520 } |
5223 } | 5521 } |
5224 | 5522 |
5225 void updateScrollBar () { | 5523 void updateScrollBar () { |
5226 if (hwndParent !is null) { | 5524 if (hwndParent !is null) { |
5227 int columnCount = OS.SendMessage (hwndHeader, OS.HDM_GETITEMCOUNT, 0, 0); | |
5228 if (columnCount !is 0 || scrollWidth !is 0) { | 5525 if (columnCount !is 0 || scrollWidth !is 0) { |
5229 SCROLLINFO info; | 5526 SCROLLINFO info; |
5230 info.cbSize = SCROLLINFO.sizeof; | 5527 info.cbSize = SCROLLINFO.sizeof; |
5231 info.fMask = OS.SIF_ALL; | 5528 info.fMask = OS.SIF_ALL; |
5232 int itemCount = OS.SendMessage (handle, OS.TVM_GETCOUNT, 0, 0); | 5529 int itemCount = OS.SendMessage (handle, OS.TVM_GETCOUNT, 0, 0); |
5234 OS.GetScrollInfo (hwndParent, OS.SB_VERT, &info); | 5531 OS.GetScrollInfo (hwndParent, OS.SB_VERT, &info); |
5235 info.nPage = info.nMax + 1; | 5532 info.nPage = info.nMax + 1; |
5236 OS.SetScrollInfo (hwndParent, OS.SB_VERT, &info, true); | 5533 OS.SetScrollInfo (hwndParent, OS.SB_VERT, &info, true); |
5237 } else { | 5534 } else { |
5238 OS.GetScrollInfo (handle, OS.SB_VERT, &info); | 5535 OS.GetScrollInfo (handle, OS.SB_VERT, &info); |
5239 if (info.nPage is 0) info.nPage = info.nMax + 1; | 5536 if (!OS.IsWinCE && OS.WIN32_VERSION >= OS.VERSION(4, 10)) { |
5537 if (info.nPage is 0) { | |
5538 SCROLLBARINFO psbi; | |
5539 psbi.cbSize = SCROLLBARINFO.sizeof; | |
5540 OS.GetScrollBarInfo (handle, OS.OBJID_VSCROLL, &psbi); | |
5541 if ((psbi.rgstate [0] & OS.STATE_SYSTEM_INVISIBLE) !is 0) { | |
5542 info.nPage = info.nMax + 1; | |
5543 } | |
5544 } | |
5545 } | |
5240 OS.SetScrollInfo (hwndParent, OS.SB_VERT, &info, true); | 5546 OS.SetScrollInfo (hwndParent, OS.SB_VERT, &info, true); |
5241 } | 5547 } |
5242 } | 5548 } |
5243 } | 5549 } |
5244 } | 5550 } |
5245 | 5551 |
5246 override void unsubclass () { | 5552 override void unsubclass () { |
5247 super.unsubclass (); | 5553 super.unsubclass (); |
5248 if (hwndHeader !is null) { | 5554 if (hwndHeader !is null) { |
5249 OS.SetWindowLong (hwndHeader, OS.GWL_WNDPROC, cast(int) HeaderProc); | 5555 OS.SetWindowLongPtr (hwndHeader, OS.GWLP_WNDPROC, cast(LONG_PTR)HeaderProc); |
5250 } | 5556 } |
5251 } | 5557 } |
5252 | 5558 |
5253 override int widgetStyle () { | 5559 override int widgetStyle () { |
5254 int bits = super.widgetStyle () | OS.TVS_SHOWSELALWAYS | OS.TVS_LINESATROOT | OS.TVS_HASBUTTONS | OS.TVS_NONEVENHEIGHT; | 5560 int bits = super.widgetStyle () | OS.TVS_SHOWSELALWAYS | OS.TVS_LINESATROOT | OS.TVS_HASBUTTONS | OS.TVS_NONEVENHEIGHT; |
5255 if (EXPLORER_THEME && !OS.IsWinCE && OS.WIN32_VERSION >= OS.VERSION (6, 0)) { | 5561 if (EXPLORER_THEME && !OS.IsWinCE && OS.WIN32_VERSION >= OS.VERSION (6, 0) && OS.IsAppThemed ()) { |
5256 bits |= OS.TVS_TRACKSELECT; | 5562 bits |= OS.TVS_TRACKSELECT; |
5257 if ((style & DWT.FULL_SELECTION) !is 0) bits |= OS.TVS_FULLROWSELECT; | 5563 if ((style & DWT.FULL_SELECTION) !is 0) bits |= OS.TVS_FULLROWSELECT; |
5258 } else { | 5564 } else { |
5259 if ((style & DWT.FULL_SELECTION) !is 0) { | 5565 if ((style & DWT.FULL_SELECTION) !is 0) { |
5260 bits |= OS.TVS_FULLROWSELECT; | 5566 bits |= OS.TVS_FULLROWSELECT; |
5261 } else { | 5567 } else { |
5262 bits |= OS.TVS_HASLINES; | 5568 bits |= OS.TVS_HASLINES; |
5569 } | |
5570 } | |
5571 if ((style & (DWT.H_SCROLL | DWT.V_SCROLL)) is 0) { | |
5572 bits &= ~(OS.WS_HSCROLL | OS.WS_VSCROLL); | |
5573 bits |= OS.TVS_NOSCROLL; | |
5574 } else { | |
5575 if ((style & DWT.H_SCROLL) is 0) { | |
5576 bits &= ~OS.WS_HSCROLL; | |
5577 bits |= OS.TVS_NOHSCROLL; | |
5263 } | 5578 } |
5264 } | 5579 } |
5265 // bits |= OS.TVS_NOTOOLTIPS | OS.TVS_DISABLEDRAGDROP; | 5580 // bits |= OS.TVS_NOTOOLTIPS | OS.TVS_DISABLEDRAGDROP; |
5266 return bits | OS.TVS_DISABLEDRAGDROP; | 5581 return bits | OS.TVS_DISABLEDRAGDROP; |
5267 } | 5582 } |
5329 } | 5644 } |
5330 break; | 5645 break; |
5331 } | 5646 } |
5332 case OS.WM_SETCURSOR: { | 5647 case OS.WM_SETCURSOR: { |
5333 if (cast(HWND)wParam is hwnd) { | 5648 if (cast(HWND)wParam is hwnd) { |
5334 int hitTest = cast(short) (lParam & 0xFFFF); | 5649 int hitTest = cast(short) OS.LOWORD (lParam); |
5335 if (hitTest is OS.HTCLIENT) { | 5650 if (hitTest is OS.HTCLIENT) { |
5336 HDHITTESTINFO pinfo; | 5651 HDHITTESTINFO pinfo; |
5337 int pos = OS.GetMessagePos (); | 5652 int pos = OS.GetMessagePos (); |
5338 POINT pt; | 5653 POINT pt; |
5339 pt.x = cast(short) (pos & 0xFFFF); | 5654 OS.POINTSTOPOINT (pt, pos); |
5340 pt.y = cast(short) (pos >> 16); | |
5341 OS.ScreenToClient (hwnd, &pt); | 5655 OS.ScreenToClient (hwnd, &pt); |
5342 pinfo.pt.x = pt.x; | 5656 pinfo.pt.x = pt.x; |
5343 pinfo.pt.y = pt.y; | 5657 pinfo.pt.y = pt.y; |
5344 int columnCount = OS.SendMessage (hwndHeader, OS.HDM_GETITEMCOUNT, 0, 0); | |
5345 int index = OS.SendMessage (hwndHeader, OS.HDM_HITTEST, 0, &pinfo); | 5658 int index = OS.SendMessage (hwndHeader, OS.HDM_HITTEST, 0, &pinfo); |
5346 if (0 <= index && index < columnCount && !columns [index].resizable) { | 5659 if (0 <= index && index < columnCount && !columns [index].resizable) { |
5347 if ((pinfo.flags & (OS.HHT_ONDIVIDER | OS.HHT_ONDIVOPEN)) !is 0) { | 5660 if ((pinfo.flags & (OS.HHT_ONDIVIDER | OS.HHT_ONDIVOPEN)) !is 0) { |
5348 OS.SetCursor (OS.LoadCursor (null, cast(TCHAR*) OS.IDC_ARROW)); | 5661 OS.SetCursor (OS.LoadCursor (null, cast(TCHAR*) OS.IDC_ARROW)); |
5349 return 1; | 5662 return 1; |
5365 } | 5678 } |
5366 case OS.WM_SIZE: { | 5679 case OS.WM_SIZE: { |
5367 setScrollWidth (); | 5680 setScrollWidth (); |
5368 if (ignoreResize) return 0; | 5681 if (ignoreResize) return 0; |
5369 setResizeChildren (false); | 5682 setResizeChildren (false); |
5370 int code = callWindowProc (hwnd, OS.WM_SIZE, wParam, lParam); | 5683 int /*long*/ code = callWindowProc (hwnd, OS.WM_SIZE, wParam, lParam); |
5371 sendEvent (DWT.Resize); | 5684 sendEvent (DWT.Resize); |
5372 if (isDisposed ()) return 0; | 5685 if (isDisposed ()) return 0; |
5373 if (layout_ !is null) { | 5686 if (layout_ !is null) { |
5374 markLayout (false, false); | 5687 markLayout (false, false); |
5375 updateLayout (false, false); | 5688 updateLayout (false, false); |
5419 * | 5732 * |
5420 * NOTE: For some reason, this code is only necessary | 5733 * NOTE: For some reason, this code is only necessary |
5421 * on Windows Vista. | 5734 * on Windows Vista. |
5422 */ | 5735 */ |
5423 if (!OS.IsWinCE && OS.WIN32_VERSION >= OS.VERSION (6, 0)) { | 5736 if (!OS.IsWinCE && OS.WIN32_VERSION >= OS.VERSION (6, 0)) { |
5424 if ((wParam & 0xFFFF) is OS.SB_THUMBTRACK) { | 5737 if (OS.LOWORD (wParam) is OS.SB_THUMBTRACK) { |
5425 info.nPos = info.nTrackPos; | 5738 info.nPos = info.nTrackPos; |
5426 } | 5739 } |
5427 } | 5740 } |
5428 OS.SetScrollInfo (handle, OS.SB_VERT, &info, true); | 5741 OS.SetScrollInfo (handle, OS.SB_VERT, &info, true); |
5429 int code = OS.SendMessage (handle, OS.WM_VSCROLL, wParam, lParam); | 5742 int /*long*/ code = OS.SendMessage (handle, OS.WM_VSCROLL, wParam, lParam); |
5430 OS.GetScrollInfo (handle, OS.SB_VERT, &info); | 5743 OS.GetScrollInfo (handle, OS.SB_VERT, &info); |
5431 OS.SetScrollInfo (hwndParent, OS.SB_VERT, &info, true); | 5744 OS.SetScrollInfo (hwndParent, OS.SB_VERT, &info, true); |
5432 return code; | 5745 return code; |
5433 } | 5746 } |
5434 default: | 5747 default: |
5435 } | 5748 } |
5436 return callWindowProc (hwnd, msg, wParam, lParam); | 5749 return callWindowProc (hwnd, msg, wParam, lParam); |
5750 } | |
5751 if (msg is Display.DI_GETDRAGIMAGE) { | |
5752 //TEMPORARY CODE | |
5753 if (hooks (DWT.EraseItem) || hooks (DWT.PaintItem)) return 0; | |
5754 /* | |
5755 * When there is more than one item selected, DI_GETDRAGIMAGE | |
5756 * returns the item under the cursor. This happens because | |
5757 * the tree does not have implement multi-select. The fix | |
5758 * is to disable DI_GETDRAGIMAGE when more than one item is | |
5759 * selected. | |
5760 */ | |
5761 if ((style & DWT.MULTI) !is 0) { | |
5762 if (getSelectionCount () !is 1) return 0; | |
5763 } | |
5437 } | 5764 } |
5438 return super.windowProc (hwnd, msg, wParam, lParam); | 5765 return super.windowProc (hwnd, msg, wParam, lParam); |
5439 } | 5766 } |
5440 | 5767 |
5441 override LRESULT WM_CHAR (int wParam, int lParam) { | 5768 override LRESULT WM_CHAR (int wParam, int lParam) { |
5543 if (accessible is null) accessible = new_Accessible (this); | 5870 if (accessible is null) accessible = new_Accessible (this); |
5544 } | 5871 } |
5545 return super.WM_GETOBJECT (wParam, lParam); | 5872 return super.WM_GETOBJECT (wParam, lParam); |
5546 } | 5873 } |
5547 | 5874 |
5548 override LRESULT WM_KEYDOWN (int wParam, int lParam) { | 5875 override LRESULT WM_HSCROLL (int wParam, int lParam) { |
5876 bool fixScroll = false; | |
5877 if ((style & DWT.DOUBLE_BUFFERED) !is 0) { | |
5878 fixScroll = (style & DWT.VIRTUAL) !is 0 || hooks (DWT.EraseItem) || hooks (DWT.PaintItem); | |
5879 } | |
5880 if (fixScroll) { | |
5881 style &= ~DWT.DOUBLE_BUFFERED; | |
5882 if (explorerTheme) { | |
5883 OS.SendMessage (handle, OS.TVM_SETEXTENDEDSTYLE, OS.TVS_EX_DOUBLEBUFFER, 0); | |
5884 } | |
5885 } | |
5886 LRESULT result = super.WM_HSCROLL (wParam, lParam); | |
5887 if (fixScroll) { | |
5888 style |= DWT.DOUBLE_BUFFERED; | |
5889 if (explorerTheme) { | |
5890 OS.SendMessage (handle, OS.TVM_SETEXTENDEDSTYLE, OS.TVS_EX_DOUBLEBUFFER, OS.TVS_EX_DOUBLEBUFFER); | |
5891 } | |
5892 } | |
5893 if (result !is null) return result; | |
5894 return result; | |
5895 } | |
5896 | |
5897 override LRESULT WM_KEYDOWN (int /*long*/ wParam, int /*long*/ lParam) { | |
5549 LRESULT result = super.WM_KEYDOWN (wParam, lParam); | 5898 LRESULT result = super.WM_KEYDOWN (wParam, lParam); |
5550 if (result !is null) return result; | 5899 if (result !is null) return result; |
5551 switch (wParam) { | 5900 switch (wParam) { |
5552 case OS.VK_SPACE: | 5901 case OS.VK_SPACE: |
5553 /* | 5902 /* |
5558 */ | 5907 */ |
5559 return LRESULT.ZERO; | 5908 return LRESULT.ZERO; |
5560 case OS.VK_ADD: | 5909 case OS.VK_ADD: |
5561 if (OS.GetKeyState (OS.VK_CONTROL) < 0) { | 5910 if (OS.GetKeyState (OS.VK_CONTROL) < 0) { |
5562 if (hwndHeader !is null) { | 5911 if (hwndHeader !is null) { |
5563 int count = OS.SendMessage (hwndHeader, OS.HDM_GETITEMCOUNT, 0, 0); | 5912 TreeColumn [] newColumns = new TreeColumn [columnCount]; |
5564 TreeColumn [] newColumns = new TreeColumn [count]; | 5913 System.arraycopy (columns, 0, newColumns, 0, columnCount); |
5565 System.arraycopy (columns, 0, newColumns, 0, count); | 5914 for (int i=0; i<columnCount; i++) { |
5566 for (int i=0; i<count; i++) { | |
5567 TreeColumn column = newColumns [i]; | 5915 TreeColumn column = newColumns [i]; |
5568 if (!column.isDisposed () && column.getResizable ()) { | 5916 if (!column.isDisposed () && column.getResizable ()) { |
5569 column.pack (); | 5917 column.pack (); |
5570 } | 5918 } |
5571 } | 5919 } |
5583 if (OS.GetKeyState (OS.VK_SHIFT) < 0) { | 5931 if (OS.GetKeyState (OS.VK_SHIFT) < 0) { |
5584 HANDLE hItem = cast(HANDLE) OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_CARET, 0); | 5932 HANDLE hItem = cast(HANDLE) OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_CARET, 0); |
5585 if (hItem !is null) { | 5933 if (hItem !is null) { |
5586 if (hAnchor is null) hAnchor = hItem; | 5934 if (hAnchor is null) hAnchor = hItem; |
5587 ignoreSelect = ignoreDeselect = true; | 5935 ignoreSelect = ignoreDeselect = true; |
5588 int code = callWindowProc (handle, OS.WM_KEYDOWN, wParam, lParam); | 5936 int /*long*/ code = callWindowProc (handle, OS.WM_KEYDOWN, wParam, lParam); |
5589 ignoreSelect = ignoreDeselect = false; | 5937 ignoreSelect = ignoreDeselect = false; |
5590 auto hNewItem = cast(HANDLE) OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_CARET, 0); | 5938 auto hNewItem = cast(HANDLE) OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_CARET, 0); |
5591 TVITEM tvItem; | 5939 TVITEM tvItem; |
5592 tvItem.mask = OS.TVIF_HANDLE | OS.TVIF_STATE; | 5940 tvItem.mask = OS.TVIF_HANDLE | OS.TVIF_STATE; |
5593 tvItem.stateMask = OS.TVIS_SELECTED; | 5941 tvItem.stateMask = OS.TVIS_SELECTED; |
5594 auto hDeselectItem = hItem; | 5942 auto hDeselectItem = hItem; |
5595 RECT rect1; | 5943 RECT rect1; |
5596 rect1.left = cast(int)hAnchor; | 5944 if (!OS.TreeView_GetItemRect (handle, hAnchor, &rect1, false)) { |
5597 OS.SendMessage (handle, OS.TVM_GETITEMRECT, 0, &rect1); | 5945 hAnchor = hItem; |
5946 OS.TreeView_GetItemRect (handle, hAnchor, &rect1, false); | |
5947 } | |
5598 RECT rect2; | 5948 RECT rect2; |
5599 rect2.left = cast(int)hDeselectItem; | 5949 OS.TreeView_GetItemRect (handle, hDeselectItem, &rect2, false); |
5600 OS.SendMessage (handle, OS.TVM_GETITEMRECT, 0, &rect2); | |
5601 int flags = rect1.top < rect2.top ? OS.TVGN_PREVIOUSVISIBLE : OS.TVGN_NEXTVISIBLE; | 5950 int flags = rect1.top < rect2.top ? OS.TVGN_PREVIOUSVISIBLE : OS.TVGN_NEXTVISIBLE; |
5602 while (hDeselectItem !is hAnchor) { | 5951 while (hDeselectItem !is hAnchor) { |
5603 tvItem.hItem = hDeselectItem; | 5952 tvItem.hItem = hDeselectItem; |
5604 OS.SendMessage (handle, OS.TVM_SETITEM, 0, &tvItem); | 5953 OS.SendMessage (handle, OS.TVM_SETITEM, 0, &tvItem); |
5605 hDeselectItem = cast(HANDLE) OS.SendMessage (handle, OS.TVM_GETNEXTITEM, flags, hDeselectItem); | 5954 hDeselectItem = cast(HANDLE) OS.SendMessage (handle, OS.TVM_GETNEXTITEM, flags, hDeselectItem); |
5606 } | 5955 } |
5607 auto hSelectItem = hAnchor; | 5956 auto hSelectItem = hAnchor; |
5608 rect1.left = cast(int)hNewItem; | 5957 OS.TreeView_GetItemRect (handle, hNewItem, &rect1, false); |
5609 OS.SendMessage (handle, OS.TVM_GETITEMRECT, 0, &rect1); | 5958 OS.TreeView_GetItemRect (handle, hSelectItem, &rect2, false); |
5610 rect2.left = cast(int)hSelectItem; | |
5611 OS.SendMessage (handle, OS.TVM_GETITEMRECT, 0, &rect2); | |
5612 tvItem.state = OS.TVIS_SELECTED; | 5959 tvItem.state = OS.TVIS_SELECTED; |
5613 flags = rect1.top < rect2.top ? OS.TVGN_PREVIOUSVISIBLE : OS.TVGN_NEXTVISIBLE; | 5960 flags = rect1.top < rect2.top ? OS.TVGN_PREVIOUSVISIBLE : OS.TVGN_NEXTVISIBLE; |
5614 while (hSelectItem !is hNewItem) { | 5961 while (hSelectItem !is hNewItem) { |
5615 tvItem.hItem = hSelectItem; | 5962 tvItem.hItem = hSelectItem; |
5616 OS.SendMessage (handle, OS.TVM_SETITEM, 0, &tvItem); | 5963 OS.SendMessage (handle, OS.TVM_SETITEM, 0, &tvItem); |
5659 OS.GetClientRect (handle, &clientRect); | 6006 OS.GetClientRect (handle, &clientRect); |
5660 hNewItem = cast(HANDLE) OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_FIRSTVISIBLE, 0); | 6007 hNewItem = cast(HANDLE) OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_FIRSTVISIBLE, 0); |
5661 do { | 6008 do { |
5662 auto hVisible = cast(HANDLE) OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_NEXTVISIBLE, hNewItem); | 6009 auto hVisible = cast(HANDLE) OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_NEXTVISIBLE, hNewItem); |
5663 if (hVisible is null) break; | 6010 if (hVisible is null) break; |
5664 rect.left = cast(int)hVisible; | 6011 if (!OS.TreeView_GetItemRect (handle, hVisible, &rect, false)) break; |
5665 OS.SendMessage (handle, OS.TVM_GETITEMRECT, 0, &rect); | |
5666 if (rect.bottom > clientRect.bottom) break; | 6012 if (rect.bottom > clientRect.bottom) break; |
5667 if ((hNewItem = hVisible) is hItem) { | 6013 if ((hNewItem = hVisible) is hItem) { |
5668 OS.SendMessage (handle, OS.WM_VSCROLL, OS.SB_PAGEDOWN, 0); | 6014 OS.SendMessage (handle, OS.WM_VSCROLL, OS.SB_PAGEDOWN, 0); |
5669 } | 6015 } |
5670 } while (hNewItem !is null); | 6016 } while (hNewItem !is null); |
5699 tvItem.hItem = hNewItem; | 6045 tvItem.hItem = hNewItem; |
5700 OS.SendMessage (handle, OS.TVM_SETITEM, 0, &tvItem); | 6046 OS.SendMessage (handle, OS.TVM_SETITEM, 0, &tvItem); |
5701 } | 6047 } |
5702 if (redraw) { | 6048 if (redraw) { |
5703 RECT rect1, rect2; | 6049 RECT rect1, rect2; |
5704 rect1.left = cast(int) hItem; rect2.left = cast(int) hNewItem; | 6050 bool fItemRect = (style & DWT.FULL_SELECTION) is 0; |
5705 int fItemRect = (style & DWT.FULL_SELECTION) !is 0 ? 0 : 1; | 6051 if (hooks (DWT.EraseItem) || hooks (DWT.PaintItem)) fItemRect = false; |
5706 if (hooks (DWT.EraseItem) || hooks (DWT.PaintItem)) fItemRect = 0; | 6052 if (!OS.IsWinCE && OS.WIN32_VERSION >= OS.VERSION (6, 0)) fItemRect = false; |
5707 if (!OS.IsWinCE && OS.WIN32_VERSION >= OS.VERSION (6, 0)) fItemRect = 0; | 6053 OS.TreeView_GetItemRect (handle, hItem, &rect1, fItemRect); |
5708 OS.SendMessage (handle, OS.TVM_GETITEMRECT, fItemRect, &rect1); | 6054 OS.TreeView_GetItemRect (handle, hNewItem, &rect2, fItemRect); |
5709 OS.SendMessage (handle, OS.TVM_GETITEMRECT, fItemRect, &rect2); | |
5710 OS.DefWindowProc (handle, OS.WM_SETREDRAW, 1, 0); | 6055 OS.DefWindowProc (handle, OS.WM_SETREDRAW, 1, 0); |
5711 OS.InvalidateRect (handle, &rect1, true); | 6056 OS.InvalidateRect (handle, &rect1, true); |
5712 OS.InvalidateRect (handle, &rect2, true); | 6057 OS.InvalidateRect (handle, &rect2, true); |
5713 OS.UpdateWindow (handle); | 6058 OS.UpdateWindow (handle); |
5714 } | 6059 } |
5715 return LRESULT.ZERO; | 6060 return LRESULT.ZERO; |
5716 } | 6061 } |
5717 } | 6062 } |
5718 } | 6063 } |
5719 int code = callWindowProc (handle, OS.WM_KEYDOWN, wParam, lParam); | 6064 int /*long*/ code = callWindowProc (handle, OS.WM_KEYDOWN, wParam, lParam); |
5720 hAnchor = cast(HANDLE) OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_CARET, 0); | 6065 hAnchor = cast(HANDLE) OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_CARET, 0); |
5721 return new LRESULT (code); | 6066 return new LRESULT (code); |
5722 } | 6067 } |
5723 default: | 6068 default: |
5724 } | 6069 } |
5755 return super.WM_KILLFOCUS (wParam, lParam); | 6100 return super.WM_KILLFOCUS (wParam, lParam); |
5756 } | 6101 } |
5757 | 6102 |
5758 override LRESULT WM_LBUTTONDBLCLK (int wParam, int lParam) { | 6103 override LRESULT WM_LBUTTONDBLCLK (int wParam, int lParam) { |
5759 TVHITTESTINFO lpht; | 6104 TVHITTESTINFO lpht; |
5760 lpht.pt.x = cast(short) (lParam & 0xFFFF); | 6105 lpht.pt.x = OS.GET_X_LPARAM (lParam); |
5761 lpht.pt.y = cast(short) (lParam >> 16); | 6106 lpht.pt.y = OS.GET_Y_LPARAM (lParam); |
5762 OS.SendMessage (handle, OS.TVM_HITTEST, 0, &lpht); | 6107 OS.SendMessage (handle, OS.TVM_HITTEST, 0, &lpht); |
5763 if (lpht.hItem !is null) { | 6108 if (lpht.hItem !is null) { |
5764 if ((style & DWT.CHECK) !is 0) { | 6109 if ((style & DWT.CHECK) !is 0) { |
5765 if ((lpht.flags & OS.TVHT_ONITEMSTATEICON) !is 0) { | 6110 if ((lpht.flags & OS.TVHT_ONITEMSTATEICON) !is 0) { |
5766 Display display = this.display; | 6111 Display display = this.display; |
5805 } | 6150 } |
5806 } | 6151 } |
5807 LRESULT result = super.WM_LBUTTONDBLCLK (wParam, lParam); | 6152 LRESULT result = super.WM_LBUTTONDBLCLK (wParam, lParam); |
5808 if (result is LRESULT.ZERO) return result; | 6153 if (result is LRESULT.ZERO) return result; |
5809 if (lpht.hItem !is null) { | 6154 if (lpht.hItem !is null) { |
5810 if ((style & DWT.FULL_SELECTION) !is 0 || (lpht.flags & OS.TVHT_ONITEM) !is 0) { | 6155 int flags = OS.TVHT_ONITEM; |
6156 if ((style & DWT.FULL_SELECTION) !is 0) { | |
6157 flags |= OS.TVHT_ONITEMRIGHT | OS.TVHT_ONITEMINDENT; | |
6158 } else { | |
6159 if (hooks (DWT.MeasureItem)) { | |
6160 lpht.flags &= ~(OS.TVHT_ONITEMICON | OS.TVHT_ONITEMLABEL); | |
6161 if (hitTestSelection (lpht.hItem, lpht.pt.x, lpht.pt.y)) { | |
6162 lpht.flags |= OS.TVHT_ONITEMICON | OS.TVHT_ONITEMLABEL; | |
6163 } | |
6164 } | |
6165 } | |
6166 if ((lpht.flags & flags) !is 0) { | |
5811 Event event = new Event (); | 6167 Event event = new Event (); |
5812 event.item = _getItem (lpht.hItem); | 6168 event.item = _getItem (lpht.hItem); |
5813 postEvent (DWT.DefaultSelection, event); | 6169 postEvent (DWT.DefaultSelection, event); |
5814 } | 6170 } |
5815 } | 6171 } |
5823 * issue a selection event. Only items that are selected and visible | 6179 * issue a selection event. Only items that are selected and visible |
5824 * are cleared. This code also runs in the case when the white space | 6180 * are cleared. This code also runs in the case when the white space |
5825 * below the last item is selected. | 6181 * below the last item is selected. |
5826 */ | 6182 */ |
5827 TVHITTESTINFO lpht; | 6183 TVHITTESTINFO lpht; |
5828 lpht.pt.x = cast(short) (lParam & 0xFFFF); | 6184 lpht.pt.x = OS.GET_X_LPARAM (lParam); |
5829 lpht.pt.y = cast(short) (lParam >> 16); | 6185 lpht.pt.y = OS.GET_Y_LPARAM (lParam); |
5830 OS.SendMessage (handle, OS.TVM_HITTEST, 0, &lpht); | 6186 OS.SendMessage (handle, OS.TVM_HITTEST, 0, &lpht); |
5831 if (lpht.hItem is null || (lpht.flags & OS.TVHT_ONITEMBUTTON) !is 0) { | 6187 if (lpht.hItem is null || (lpht.flags & OS.TVHT_ONITEMBUTTON) !is 0) { |
5832 Display display = this.display; | 6188 Display display = this.display; |
5833 display.captureChanged = false; | 6189 display.captureChanged = false; |
5834 if (!sendMouseEvent (DWT.MouseDown, 1, handle, OS.WM_LBUTTONDOWN, wParam, lParam)) { | 6190 if (!sendMouseEvent (DWT.MouseDown, 1, handle, OS.WM_LBUTTONDOWN, wParam, lParam)) { |
5836 if (OS.GetCapture () !is handle) OS.SetCapture (handle); | 6192 if (OS.GetCapture () !is handle) OS.SetCapture (handle); |
5837 } | 6193 } |
5838 return LRESULT.ZERO; | 6194 return LRESULT.ZERO; |
5839 } | 6195 } |
5840 bool fixSelection = false, deselected = false; | 6196 bool fixSelection = false, deselected = false; |
6197 HANDLE hOldSelection = cast(HANDLE) OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_CARET, 0); | |
5841 if (lpht.hItem !is null && (style & DWT.MULTI) !is 0) { | 6198 if (lpht.hItem !is null && (style & DWT.MULTI) !is 0) { |
5842 int hSelection = OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_CARET, 0); | 6199 if (hOldSelection !is null) { |
5843 if (hSelection !is 0) { | |
5844 TVITEM tvItem; | 6200 TVITEM tvItem; |
5845 tvItem.mask = OS.TVIF_HANDLE | OS.TVIF_STATE; | 6201 tvItem.mask = OS.TVIF_HANDLE | OS.TVIF_STATE; |
5846 tvItem.hItem = lpht.hItem; | 6202 tvItem.hItem = lpht.hItem; |
5847 OS.SendMessage (handle, OS.TVM_GETITEM, 0, &tvItem); | 6203 OS.SendMessage (handle, OS.TVM_GETITEM, 0, &tvItem); |
5848 if ((tvItem.state & OS.TVIS_EXPANDED) !is 0) { | 6204 if ((tvItem.state & OS.TVIS_EXPANDED) !is 0) { |
5849 fixSelection = true; | 6205 fixSelection = true; |
5850 tvItem.stateMask = OS.TVIS_SELECTED; | 6206 tvItem.stateMask = OS.TVIS_SELECTED; |
5851 auto hNext = cast(HANDLE) OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_NEXTVISIBLE, lpht.hItem); | 6207 auto hNext = cast(HANDLE) OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_NEXTVISIBLE, lpht.hItem); |
5852 while (hNext !is null) { | 6208 while (hNext !is null) { |
6209 if (hNext is hAnchor) hAnchor = null; | |
5853 tvItem.hItem = hNext; | 6210 tvItem.hItem = hNext; |
5854 OS.SendMessage (handle, OS.TVM_GETITEM, 0, &tvItem); | 6211 OS.SendMessage (handle, OS.TVM_GETITEM, 0, &tvItem); |
5855 if ((tvItem.state & OS.TVIS_SELECTED) !is 0) deselected = true; | 6212 if ((tvItem.state & OS.TVIS_SELECTED) !is 0) deselected = true; |
5856 tvItem.state = 0; | 6213 tvItem.state = 0; |
5857 OS.SendMessage (handle, OS.TVM_SETITEM, 0, &tvItem); | 6214 OS.SendMessage (handle, OS.TVM_SETITEM, 0, &tvItem); |
5864 } | 6221 } |
5865 } | 6222 } |
5866 } | 6223 } |
5867 dragStarted = gestureCompleted = false; | 6224 dragStarted = gestureCompleted = false; |
5868 if (fixSelection) ignoreDeselect = ignoreSelect = lockSelection = true; | 6225 if (fixSelection) ignoreDeselect = ignoreSelect = lockSelection = true; |
5869 int code = callWindowProc (handle, OS.WM_LBUTTONDOWN, wParam, lParam); | 6226 int /*long*/ code = callWindowProc (handle, OS.WM_LBUTTONDOWN, wParam, lParam); |
5870 if (fixSelection) ignoreDeselect = ignoreSelect = lockSelection = false; | 6227 if (fixSelection) ignoreDeselect = ignoreSelect = lockSelection = false; |
6228 HANDLE hNewSelection = cast(HANDLE) OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_CARET, 0); | |
6229 if (hOldSelection !is hNewSelection) hAnchor = hNewSelection; | |
5871 if (dragStarted) { | 6230 if (dragStarted) { |
5872 if (!display.captureChanged && !isDisposed ()) { | 6231 if (!display.captureChanged && !isDisposed ()) { |
5873 if (OS.GetCapture () !is handle) OS.SetCapture (handle); | 6232 if (OS.GetCapture () !is handle) OS.SetCapture (handle); |
6233 } | |
6234 } | |
6235 /* | |
6236 * Bug in Windows. When a tree has no images and an item is | |
6237 * expanded or collapsed, for some reason, Windows changes | |
6238 * the size of the selection. When the user expands a tree | |
6239 * item, the selection rectangle is made a few pixels larger. | |
6240 * When the user collapses an item, the selection rectangle | |
6241 * is restored to the original size but the selection is not | |
6242 * redrawn, causing pixel corruption. The fix is to detect | |
6243 * this case and redraw the item. | |
6244 */ | |
6245 if ((lpht.flags & OS.TVHT_ONITEMBUTTON) !is 0) { | |
6246 int bits = OS.GetWindowLong (handle, OS.GWL_STYLE); | |
6247 if ((bits & OS.TVS_FULLROWSELECT) is 0) { | |
6248 if (OS.SendMessage (handle, OS.TVM_GETIMAGELIST, OS.TVSIL_NORMAL, 0) is 0) { | |
6249 auto hItem = cast(HANDLE) OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_CARET, 0); | |
6250 if (hItem !is null) { | |
6251 RECT rect; | |
6252 if (OS.TreeView_GetItemRect (handle, hItem, &rect, false)) { | |
6253 OS.InvalidateRect (handle, &rect, true); | |
6254 } | |
6255 } | |
6256 } | |
5874 } | 6257 } |
5875 } | 6258 } |
5876 if (deselected) { | 6259 if (deselected) { |
5877 Event event = new Event (); | 6260 Event event = new Event (); |
5878 event.item = _getItem (lpht.hItem); | 6261 event.item = _getItem (lpht.hItem); |
5922 postEvent (DWT.Selection, event); | 6305 postEvent (DWT.Selection, event); |
5923 return LRESULT.ZERO; | 6306 return LRESULT.ZERO; |
5924 } | 6307 } |
5925 } | 6308 } |
5926 | 6309 |
6310 /* | |
6311 * Feature in Windows. When the tree has the style | |
6312 * TVS_FULLROWSELECT, the background color for the | |
6313 * entire row is filled when an item is painted, | |
6314 * drawing on top of any custom drawing. The fix | |
6315 * is to emulate TVS_FULLROWSELECT. | |
6316 */ | |
6317 bool selected = false; | |
6318 bool fakeSelection = false; | |
6319 if (lpht.hItem !is null) { | |
6320 if ((style & DWT.FULL_SELECTION) !is 0) { | |
6321 int bits = OS.GetWindowLong (handle, OS.GWL_STYLE); | |
6322 if ((bits & OS.TVS_FULLROWSELECT) is 0) fakeSelection = true; | |
6323 } else { | |
6324 if (hooks (DWT.MeasureItem)) { | |
6325 selected = hitTestSelection (lpht.hItem, lpht.pt.x, lpht.pt.y) !is 0; | |
6326 if (selected) { | |
6327 if ((lpht.flags & OS.TVHT_ONITEM) is 0) fakeSelection = true; | |
6328 } | |
6329 } | |
6330 } | |
6331 } | |
6332 | |
5927 /* Process the mouse when an item is not selected */ | 6333 /* Process the mouse when an item is not selected */ |
5928 if ((style & DWT.FULL_SELECTION) is 0) { | 6334 if (!selected && (style & DWT.FULL_SELECTION) is 0) { |
5929 if ((lpht.flags & OS.TVHT_ONITEM) is 0) { | 6335 if ((lpht.flags & OS.TVHT_ONITEM) is 0) { |
5930 Display display = this.display; | 6336 Display display = this.display; |
5931 display.captureChanged = false; | 6337 display.captureChanged = false; |
5932 if (!sendMouseEvent (DWT.MouseDown, 1, handle, OS.WM_LBUTTONDOWN, wParam, lParam)) { | 6338 if (!sendMouseEvent (DWT.MouseDown, 1, handle, OS.WM_LBUTTONDOWN, wParam, lParam)) { |
5933 if (!display.captureChanged && !isDisposed ()) { | 6339 if (!display.captureChanged && !isDisposed ()) { |
5934 if (OS.GetCapture () !is handle) OS.SetCapture (handle); | 6340 if (OS.GetCapture () !is handle) OS.SetCapture (handle); |
5935 } | 6341 } |
5936 return LRESULT.ZERO; | 6342 return LRESULT.ZERO; |
5937 } | 6343 } |
5938 int code = callWindowProc (handle, OS.WM_LBUTTONDOWN, wParam, lParam); | 6344 int /*long*/ code = callWindowProc (handle, OS.WM_LBUTTONDOWN, wParam, lParam); |
5939 if (!display.captureChanged && !isDisposed ()) { | 6345 if (!display.captureChanged && !isDisposed ()) { |
5940 if (OS.GetCapture () !is handle) OS.SetCapture (handle); | 6346 if (OS.GetCapture () !is handle) OS.SetCapture (handle); |
5941 } | 6347 } |
5942 return new LRESULT (code); | 6348 return new LRESULT (code); |
5943 } | 6349 } |
5945 | 6351 |
5946 /* Get the selected state of the item under the mouse */ | 6352 /* Get the selected state of the item under the mouse */ |
5947 TVITEM tvItem; | 6353 TVITEM tvItem; |
5948 tvItem.mask = OS.TVIF_HANDLE | OS.TVIF_STATE; | 6354 tvItem.mask = OS.TVIF_HANDLE | OS.TVIF_STATE; |
5949 tvItem.stateMask = OS.TVIS_SELECTED; | 6355 tvItem.stateMask = OS.TVIS_SELECTED; |
5950 bool hittestSelected = false, focused = false; | 6356 bool hittestSelected = false; |
5951 if ((style & DWT.MULTI) !is 0) { | 6357 if ((style & DWT.MULTI) !is 0) { |
5952 tvItem.hItem = lpht.hItem; | 6358 tvItem.hItem = lpht.hItem; |
5953 OS.SendMessage (handle, OS.TVM_GETITEM, 0, &tvItem); | 6359 OS.SendMessage (handle, OS.TVM_GETITEM, 0, &tvItem); |
5954 hittestSelected = (tvItem.state & OS.TVIS_SELECTED) !is 0; | 6360 hittestSelected = (tvItem.state & OS.TVIS_SELECTED) !is 0; |
5955 focused = OS.GetFocus () is handle; | |
5956 } | 6361 } |
5957 | 6362 |
5958 /* Get the selected state of the last selected item */ | 6363 /* Get the selected state of the last selected item */ |
5959 bool redraw = false; | |
5960 auto hOldItem = cast(HANDLE) OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_CARET, 0); | 6364 auto hOldItem = cast(HANDLE) OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_CARET, 0); |
5961 if ((style & DWT.MULTI) !is 0) { | 6365 if ((style & DWT.MULTI) !is 0) { |
5962 tvItem.hItem = hOldItem; | 6366 tvItem.hItem = hOldItem; |
5963 OS.SendMessage (handle, OS.TVM_GETITEM, 0, &tvItem); | 6367 OS.SendMessage (handle, OS.TVM_GETITEM, 0, &tvItem); |
5964 | 6368 |
5965 /* Check for CONTROL or drag selection */ | 6369 /* Check for CONTROL or drag selection */ |
5966 if (hittestSelected || (wParam & OS.MK_CONTROL) !is 0) { | 6370 if (hittestSelected || (wParam & OS.MK_CONTROL) !is 0) { |
5967 /* | 6371 /* |
5968 * Feature in Windows. When the tree is not drawing focus | 6372 * Feature in Windows. When the tree is not drawing focus |
5969 * and the user selects a tree item using while the CONTROL | 6373 * and the user selects a tree item while the CONTROL key |
5970 * key is down, the tree window proc sends WM_UPDATEUISTATE | 6374 * is down, the tree window proc sends WM_UPDATEUISTATE |
5971 * to the top level window, causing controls within the shell | 6375 * to the top level window, causing controls within the shell |
5972 * to redraw. When drag detect is enabled, the tree window | 6376 * to redraw. When drag detect is enabled, the tree window |
5973 * proc runs a modal loop that allows WM_PAINT messages to be | 6377 * proc runs a modal loop that allows WM_PAINT messages to be |
5974 * delivered during WM_LBUTTONDOWN. When WM_SETREDRAW is used | 6378 * delivered during WM_LBUTTONDOWN. When WM_SETREDRAW is used |
5975 * to disable drawing for the tree and a WM_PAINT happens for | 6379 * to disable drawing for the tree and a WM_PAINT happens for |
5976 * a parent of the tree (or a sibling that overlaps), the parent | 6380 * a parent of the tree (or a sibling that overlaps), the parent |
5977 * will draw on top of the tree. If WM_SETREDRAW is turned back | 6381 * will draw on top of the tree. If WM_SETREDRAW is turned back |
5978 * on without redrawing the entire tree, pixel corruption occurs. | 6382 * on without redrawing the entire tree, pixel corruption occurs. |
5979 * This case only seems to happen when the tree has been given | 6383 * This case only seems to happen when the tree has been given |
5980 * focus from WM_MOUSEACTIVATE of the shell. The fix is to | 6384 * focus from WM_MOUSEACTIVATE of the shell. The fix is to |
5981 * detect that WM_UPDATEUISTATE will be sent and avoid using | 6385 * force the WM_UPDATEUISTATE to be sent before disabling |
5982 * WM_SETREDRAW to disable drawing. | 6386 * the drawing. |
5983 * | 6387 * |
5984 * NOTE: Any redraw of a parent (or sibling) will be dispatched | 6388 * NOTE: Any redraw of a parent (or sibling) will be dispatched |
5985 * during the modal drag detect loop. This code only fixes the | 6389 * during the modal drag detect loop. This code only fixes the |
5986 * case where the tree causes a redraw from WM_UPDATEUISTATE. | 6390 * case where the tree causes a redraw from WM_UPDATEUISTATE. |
5987 * In DWT, the InvalidateRect() that causes the pixel corruption | 6391 * In DWT, the InvalidateRect() that caused the pixel corruption |
5988 * is found in Composite.WM_UPDATEUISTATE(). | 6392 * is found in Composite.WM_UPDATEUISTATE(). |
5989 */ | 6393 */ |
5990 int uiState = OS.SendMessage (handle, OS.WM_QUERYUISTATE, 0, 0); | 6394 int uiState = OS.SendMessage (handle, OS.WM_QUERYUISTATE, 0, 0); |
5991 if ((uiState & OS.UISF_HIDEFOCUS) is 0) { | 6395 if ((uiState & OS.UISF_HIDEFOCUS) !is 0) { |
5992 redraw = focused && drawCount is 0 && OS.IsWindowVisible (handle); | 6396 OS.SendMessage (handle, OS.WM_CHANGEUISTATE, OS.UIS_INITIALIZE, 0); |
5993 } | 6397 } |
5994 if (redraw) { | 6398 OS.UpdateWindow (handle); |
5995 OS.UpdateWindow (handle); | 6399 OS.DefWindowProc (handle, OS.WM_SETREDRAW, 0, 0); |
5996 OS.DefWindowProc (handle, OS.WM_SETREDRAW, 0, 0); | |
5997 } | |
5998 } else { | 6400 } else { |
5999 deselectAll (); | 6401 deselectAll (); |
6000 } | 6402 } |
6001 } | 6403 } |
6002 | 6404 |
6010 return LRESULT.ZERO; | 6412 return LRESULT.ZERO; |
6011 } | 6413 } |
6012 hSelect = lpht.hItem; | 6414 hSelect = lpht.hItem; |
6013 dragStarted = gestureCompleted = false; | 6415 dragStarted = gestureCompleted = false; |
6014 ignoreDeselect = ignoreSelect = true; | 6416 ignoreDeselect = ignoreSelect = true; |
6015 int code = callWindowProc (handle, OS.WM_LBUTTONDOWN, wParam, lParam); | 6417 int /*long*/ code = callWindowProc (handle, OS.WM_LBUTTONDOWN, wParam, lParam); |
6016 auto hNewItem = cast(HANDLE) OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_CARET, 0); | 6418 auto hNewItem = cast(HANDLE) OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_CARET, 0); |
6017 /* | 6419 if (fakeSelection) { |
6018 * Feature in Windows. When the tree has the style | 6420 if (hOldItem is null || (hNewItem is hOldItem && lpht.hItem !is hOldItem)) { |
6019 * TVS_FULLROWSELECT, the background color for the | 6421 OS.SendMessage (handle, OS.TVM_SELECTITEM, OS.TVGN_CARET, lpht.hItem); |
6020 * entire row is filled when an item is painted, | 6422 hNewItem = cast(HANDLE) OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_CARET, 0); |
6021 * drawing on top of any custom drawing. The fix | 6423 } |
6022 * is to emulate TVS_FULLROWSELECT. | 6424 if (!dragStarted && (state & DRAG_DETECT) !is 0 && hooks (DWT.DragDetect)) { |
6023 */ | 6425 dragStarted = dragDetect (handle, lpht.pt.x, lpht.pt.y, false, null, null); |
6024 if ((style & DWT.FULL_SELECTION) !is 0) { | |
6025 int bits = OS.GetWindowLong (handle, OS.GWL_STYLE); | |
6026 if ((bits & OS.TVS_FULLROWSELECT) is 0) { | |
6027 if (hNewItem is hOldItem && lpht.hItem !is hOldItem) { | |
6028 OS.SendMessage (handle, OS.TVM_SELECTITEM, OS.TVGN_CARET, lpht.hItem); | |
6029 hNewItem = cast(HANDLE) OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_CARET, 0); | |
6030 } | |
6031 if (!dragStarted && lpht.hItem !is null && (state & DRAG_DETECT) !is 0 && hooks (DWT.DragDetect)) { | |
6032 dragStarted = dragDetect (handle, lpht.pt.x, lpht.pt.y, false, null, null); | |
6033 } | |
6034 } | 6426 } |
6035 } | 6427 } |
6036 ignoreDeselect = ignoreSelect = false; | 6428 ignoreDeselect = ignoreSelect = false; |
6037 hSelect = null; | 6429 hSelect = null; |
6038 if (dragStarted) { | 6430 if (dragStarted) { |
6081 tvItem.hItem = lpht.hItem; | 6473 tvItem.hItem = lpht.hItem; |
6082 OS.SendMessage (handle, OS.TVM_SETITEM, 0, &tvItem); | 6474 OS.SendMessage (handle, OS.TVM_SETITEM, 0, &tvItem); |
6083 } | 6475 } |
6084 } | 6476 } |
6085 } | 6477 } |
6086 if (redraw) { | 6478 RECT rect1, rect2; |
6087 RECT rect1, rect2; | 6479 bool fItemRect = (style & DWT.FULL_SELECTION) is 0; |
6088 rect1.left = cast(int) hOldItem; rect2.left = cast(int) hNewItem; | 6480 if (hooks (DWT.EraseItem) || hooks (DWT.PaintItem)) fItemRect = false; |
6089 int fItemRect = (style & DWT.FULL_SELECTION) !is 0 ? 0 : 1; | 6481 if (!OS.IsWinCE && OS.WIN32_VERSION >= OS.VERSION (6, 0)) fItemRect = false; |
6090 if (hooks (DWT.EraseItem) || hooks (DWT.PaintItem)) fItemRect = 0; | 6482 OS.TreeView_GetItemRect (handle, hOldItem, &rect1, fItemRect); |
6091 if (!OS.IsWinCE && OS.WIN32_VERSION >= OS.VERSION (6, 0)) fItemRect = 0; | 6483 OS.TreeView_GetItemRect (handle, hNewItem, &rect2, fItemRect); |
6092 OS.SendMessage (handle, OS.TVM_GETITEMRECT, fItemRect, &rect1); | 6484 OS.DefWindowProc (handle, OS.WM_SETREDRAW, 1, 0); |
6093 OS.SendMessage (handle, OS.TVM_GETITEMRECT, fItemRect, &rect2); | 6485 OS.InvalidateRect (handle, &rect1, true); |
6094 OS.DefWindowProc (handle, OS.WM_SETREDRAW, 1, 0); | 6486 OS.InvalidateRect (handle, &rect2, true); |
6095 OS.InvalidateRect (handle, &rect1, true); | 6487 OS.UpdateWindow (handle); |
6096 OS.InvalidateRect (handle, &rect2, true); | |
6097 OS.UpdateWindow (handle); | |
6098 } | |
6099 } | 6488 } |
6100 | 6489 |
6101 /* Check for SHIFT or normal select and deselect/reselect items */ | 6490 /* Check for SHIFT or normal select and deselect/reselect items */ |
6102 if ((wParam & OS.MK_CONTROL) is 0) { | 6491 if ((wParam & OS.MK_CONTROL) is 0) { |
6103 if (!hittestSelected || !dragStarted) { | 6492 if (!hittestSelected || !dragStarted) { |
6104 tvItem.state = 0; | 6493 tvItem.state = 0; |
6105 int oldProc = OS.GetWindowLong (handle, OS.GWL_WNDPROC); | 6494 auto oldProc = OS.GetWindowLongPtr (handle, OS.GWLP_WNDPROC); |
6106 OS.SetWindowLong (handle, OS.GWL_WNDPROC, cast(int) TreeProc); | 6495 OS.SetWindowLongPtr (handle, OS.GWLP_WNDPROC, cast(LONG_PTR)TreeProc); |
6107 if ((style & DWT.VIRTUAL) !is 0) { | 6496 if ((style & DWT.VIRTUAL) !is 0) { |
6108 HANDLE hItem = cast(HANDLE) OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_ROOT, 0); | 6497 HANDLE hItem = cast(HANDLE) OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_ROOT, 0); |
6109 deselect (hItem, &tvItem, hNewItem); | 6498 deselect (hItem, &tvItem, hNewItem); |
6110 } else { | 6499 } else { |
6111 for (int i=0; i<items.length; i++) { | 6500 for (int i=0; i<items.length; i++) { |
6117 } | 6506 } |
6118 } | 6507 } |
6119 tvItem.hItem = hNewItem; | 6508 tvItem.hItem = hNewItem; |
6120 tvItem.state = OS.TVIS_SELECTED; | 6509 tvItem.state = OS.TVIS_SELECTED; |
6121 OS.SendMessage (handle, OS.TVM_SETITEM, 0, &tvItem); | 6510 OS.SendMessage (handle, OS.TVM_SETITEM, 0, &tvItem); |
6122 OS.SetWindowLong (handle, OS.GWL_WNDPROC, oldProc); | 6511 OS.SetWindowLongPtr (handle, OS.GWLP_WNDPROC, oldProc); |
6123 if ((wParam & OS.MK_SHIFT) !is 0) { | 6512 if ((wParam & OS.MK_SHIFT) !is 0) { |
6124 RECT rect1; | 6513 RECT rect1; |
6125 if (hAnchor is null) hAnchor = hNewItem; | 6514 if (hAnchor is null) hAnchor = hNewItem; |
6126 rect1.left = cast(int) hAnchor; | 6515 if (OS.TreeView_GetItemRect (handle, hAnchor, &rect1, false)) { |
6127 if (OS.SendMessage (handle, OS.TVM_GETITEMRECT, 0, &rect1) !is 0) { | |
6128 RECT rect2; | 6516 RECT rect2; |
6129 rect2.left = cast(int) hNewItem; | 6517 if (OS.TreeView_GetItemRect (handle, hNewItem, &rect2, false)) { |
6130 OS.SendMessage (handle, OS.TVM_GETITEMRECT, 0, &rect2); | 6518 int flags = rect1.top < rect2.top ? OS.TVGN_NEXTVISIBLE : OS.TVGN_PREVIOUSVISIBLE; |
6131 int flags = rect1.top < rect2.top ? OS.TVGN_NEXTVISIBLE : OS.TVGN_PREVIOUSVISIBLE; | 6519 tvItem.state = OS.TVIS_SELECTED; |
6132 tvItem.state = OS.TVIS_SELECTED; | 6520 auto hItem = tvItem.hItem = hAnchor; |
6133 auto hItem = tvItem.hItem = hAnchor; | |
6134 OS.SendMessage (handle, OS.TVM_SETITEM, 0, &tvItem); | |
6135 while (hItem !is hNewItem) { | |
6136 tvItem.hItem = hItem; | |
6137 OS.SendMessage (handle, OS.TVM_SETITEM, 0, &tvItem); | 6521 OS.SendMessage (handle, OS.TVM_SETITEM, 0, &tvItem); |
6138 hItem = cast(HANDLE) OS.SendMessage (handle, OS.TVM_GETNEXTITEM, flags, hItem); | 6522 while (hItem !is hNewItem) { |
6523 tvItem.hItem = hItem; | |
6524 OS.SendMessage (handle, OS.TVM_SETITEM, 0, &tvItem); | |
6525 hItem = cast(HANDLE) OS.SendMessage (handle, OS.TVM_GETNEXTITEM, flags, hItem); | |
6526 } | |
6139 } | 6527 } |
6140 } | 6528 } |
6141 } | 6529 } |
6142 } | 6530 } |
6143 } | 6531 } |
6162 * this modal loop eats the corresponding mouse up. The fix is to | 6550 * this modal loop eats the corresponding mouse up. The fix is to |
6163 * detect the cases when the modal loop has eaten the mouse up and | 6551 * detect the cases when the modal loop has eaten the mouse up and |
6164 * issue a fake mouse up. | 6552 * issue a fake mouse up. |
6165 */ | 6553 */ |
6166 if (dragStarted) { | 6554 if (dragStarted) { |
6167 sendDragEvent (1, cast(short) (lParam & 0xFFFF), cast(short) (lParam >> 16)); | 6555 sendDragEvent (1, OS.GET_X_LPARAM (lParam), OS.GET_Y_LPARAM (lParam)); |
6168 } else { | 6556 } else { |
6169 int bits = OS.GetWindowLong (handle, OS.GWL_STYLE); | 6557 int bits = OS.GetWindowLong (handle, OS.GWL_STYLE); |
6170 if ((bits & OS.TVS_DISABLEDRAGDROP) is 0) { | 6558 if ((bits & OS.TVS_DISABLEDRAGDROP) is 0) { |
6171 sendMouseEvent (DWT.MouseUp, 1, handle, OS.WM_LBUTTONUP, wParam, lParam); | 6559 sendMouseEvent (DWT.MouseUp, 1, handle, OS.WM_LBUTTONUP, wParam, lParam); |
6172 } | 6560 } |
6177 | 6565 |
6178 override LRESULT WM_MOUSEMOVE (int wParam, int lParam) { | 6566 override LRESULT WM_MOUSEMOVE (int wParam, int lParam) { |
6179 Display display = this.display; | 6567 Display display = this.display; |
6180 LRESULT result = super.WM_MOUSEMOVE (wParam, lParam); | 6568 LRESULT result = super.WM_MOUSEMOVE (wParam, lParam); |
6181 if (result !is null) return result; | 6569 if (result !is null) return result; |
6182 if (itemToolTipHandle !is null && hwndHeader !is null) { | 6570 if (itemToolTipHandle !is null) { |
6183 /* | 6571 /* |
6184 * Bug in Windows. On some machines that do not have XBUTTONs, | 6572 * Bug in Windows. On some machines that do not have XBUTTONs, |
6185 * the MK_XBUTTON1 and OS.MK_XBUTTON2 bits are sometimes set, | 6573 * the MK_XBUTTON1 and OS.MK_XBUTTON2 bits are sometimes set, |
6186 * causing mouse capture to become stuck. The fix is to test | 6574 * causing mouse capture to become stuck. The fix is to test |
6187 * for the extra buttons only when they exist. | 6575 * for the extra buttons only when they exist. |
6188 */ | 6576 */ |
6189 int mask = OS.MK_LBUTTON | OS.MK_MBUTTON | OS.MK_RBUTTON; | 6577 int mask = OS.MK_LBUTTON | OS.MK_MBUTTON | OS.MK_RBUTTON; |
6190 if (display.xMouse) mask |= OS.MK_XBUTTON1 | OS.MK_XBUTTON2; | 6578 if (display.xMouse) mask |= OS.MK_XBUTTON1 | OS.MK_XBUTTON2; |
6191 if (((wParam & 0xFFFF) & mask) is 0) { | 6579 if ((wParam & mask) is 0) { |
6192 TVHITTESTINFO lpht; | 6580 int x = OS.GET_X_LPARAM (lParam); |
6193 lpht.pt.x = cast(short) (lParam & 0xFFFF); | 6581 int y = OS.GET_Y_LPARAM (lParam); |
6194 lpht.pt.y = cast(short) (lParam >> 16); | 6582 int index; |
6195 OS.SendMessage (handle, OS.TVM_HITTEST, 0, &lpht); | 6583 TreeItem item; |
6196 if (lpht.hItem !is null) { | 6584 RECT cellRect, itemRect; |
6197 auto hDC = OS.GetDC (handle); | 6585 if (findCell (x, y, item, index, cellRect, itemRect)) { |
6198 HFONT oldFont, newFont = cast(HFONT) OS.SendMessage (handle, OS.WM_GETFONT, 0, 0); | 6586 /* |
6199 if (newFont !is null) oldFont = OS.SelectObject (hDC, newFont); | 6587 * Feature in Windows. When the new tool rectangle is |
6200 POINT pt; | 6588 * set using TTM_NEWTOOLRECT and the tooltip is visible, |
6201 pt.x = lpht.pt.x; | 6589 * Windows draws the tooltip right away and the sends |
6202 pt.y = lpht.pt.y; | 6590 * WM_NOTIFY with TTN_SHOW. This means that the tooltip |
6203 RECT rect; | 6591 * shows first at the wrong location and then moves to |
6204 OS.GetClientRect (hwndParent, &rect); | 6592 * the right one. The fix is to hide the tooltip window. |
6205 OS.MapWindowPoints (hwndParent, handle, cast(POINT*) &rect, 2); | 6593 */ |
6206 TreeItem item = _getItem (lpht.hItem); | 6594 if (OS.SendMessage (itemToolTipHandle, OS.TTM_GETCURRENTTOOL, 0, 0) is 0) { |
6207 int index = 0, count = Math.max (1, OS.SendMessage (hwndHeader, OS.HDM_GETITEMCOUNT, 0, 0)); | 6595 if (OS.IsWindowVisible (itemToolTipHandle)) { |
6208 int [] order = new int [count]; | 6596 OS.ShowWindow (itemToolTipHandle, OS.SW_HIDE); |
6209 OS.SendMessage (hwndHeader, OS.HDM_GETORDERARRAY, count, order.ptr); | |
6210 while (index < count) { | |
6211 HFONT hFont = item.cellFont !is null ? item.cellFont [order [index]] : cast(HFONT)-1; | |
6212 if (hFont is cast(HFONT)-1) hFont = item.font; | |
6213 if (hFont !is cast(HFONT)-1) hFont = OS.SelectObject (hDC, hFont); | |
6214 RECT cellRect = item.getBounds (order [index], true, false, true, false, true, hDC); | |
6215 if (hFont !is cast(HFONT)-1) OS.SelectObject (hDC, hFont); | |
6216 if (cellRect.left > rect.right) break; | |
6217 cellRect.right = Math.min (cellRect.right, rect.right); | |
6218 if (OS.PtInRect (&cellRect, pt)) { | |
6219 RECT textRect = item.getBounds (order [index], true, false, false, false, false, hDC); | |
6220 if (textRect.right > cellRect.right) { | |
6221 TOOLINFO lpti; | |
6222 lpti.cbSize = TOOLINFO.sizeof; | |
6223 lpti.hwnd = handle; | |
6224 lpti.uId = cast(int) handle; | |
6225 lpti.uFlags = OS.TTF_SUBCLASS | OS.TTF_TRANSPARENT; | |
6226 lpti.rect.left = cellRect.left; | |
6227 lpti.rect.top = cellRect.top; | |
6228 lpti.rect.right = cellRect.right; | |
6229 lpti.rect.bottom = cellRect.bottom; | |
6230 OS.SendMessage (itemToolTipHandle, OS.TTM_NEWTOOLRECT, 0, &lpti); | |
6231 } | |
6232 break; | |
6233 } | 6597 } |
6234 index++; | 6598 } |
6235 } | 6599 TOOLINFO lpti; |
6236 if (newFont !is null) OS.SelectObject (hDC, oldFont); | 6600 lpti.cbSize = TOOLINFO.sizeof; |
6237 OS.ReleaseDC (handle, hDC); | 6601 lpti.hwnd = handle; |
6602 lpti.uId = cast(int) handle; | |
6603 lpti.uFlags = OS.TTF_SUBCLASS | OS.TTF_TRANSPARENT; | |
6604 lpti.rect.left = cellRect.left; | |
6605 lpti.rect.top = cellRect.top; | |
6606 lpti.rect.right = cellRect.right; | |
6607 lpti.rect.bottom = cellRect.bottom; | |
6608 OS.SendMessage (itemToolTipHandle, OS.TTM_NEWTOOLRECT, 0, &lpti); | |
6238 } | 6609 } |
6239 } | 6610 } |
6240 } | 6611 } |
6241 return result; | 6612 return result; |
6242 } | 6613 } |
6281 * menu, the selection snaps back. The fix is to avoid | 6652 * menu, the selection snaps back. The fix is to avoid |
6282 * calling the window proc and do the selection ourselves. | 6653 * calling the window proc and do the selection ourselves. |
6283 * This behavior is consistent with the table. | 6654 * This behavior is consistent with the table. |
6284 */ | 6655 */ |
6285 TVHITTESTINFO lpht; | 6656 TVHITTESTINFO lpht; |
6286 lpht.pt.x = cast(short) (lParam & 0xFFFF); | 6657 lpht.pt.x = OS.GET_X_LPARAM (lParam); |
6287 lpht.pt.y = cast(short) (lParam >> 16); | 6658 lpht.pt.y = OS.GET_Y_LPARAM (lParam); |
6288 OS.SendMessage (handle, OS.TVM_HITTEST, 0, &lpht); | 6659 OS.SendMessage (handle, OS.TVM_HITTEST, 0, &lpht); |
6289 if (lpht.hItem !is null) { | 6660 if (lpht.hItem !is null) { |
6290 int flags = OS.TVHT_ONITEMICON | OS.TVHT_ONITEMLABEL; | 6661 bool fakeSelection = (style & DWT.FULL_SELECTION) !is 0; |
6291 if ((style & DWT.FULL_SELECTION) !is 0 || (lpht.flags & flags) !is 0) { | 6662 if (!fakeSelection) { |
6663 if (hooks (DWT.MeasureItem)) { | |
6664 fakeSelection = hitTestSelection (lpht.hItem, lpht.pt.x, lpht.pt.y); | |
6665 } else { | |
6666 int flags = OS.TVHT_ONITEMICON | OS.TVHT_ONITEMLABEL; | |
6667 fakeSelection = (lpht.flags & flags) !is 0; | |
6668 } | |
6669 } | |
6670 if (fakeSelection) { | |
6292 if ((wParam & (OS.MK_CONTROL | OS.MK_SHIFT)) is 0) { | 6671 if ((wParam & (OS.MK_CONTROL | OS.MK_SHIFT)) is 0) { |
6293 TVITEM tvItem; | 6672 TVITEM tvItem; |
6294 tvItem.mask = OS.TVIF_HANDLE | OS.TVIF_STATE; | 6673 tvItem.mask = OS.TVIF_HANDLE | OS.TVIF_STATE; |
6295 tvItem.stateMask = OS.TVIS_SELECTED; | 6674 tvItem.stateMask = OS.TVIS_SELECTED; |
6296 tvItem.hItem = lpht.hItem; | 6675 tvItem.hItem = lpht.hItem; |
6324 } | 6703 } |
6325 shrink = false; | 6704 shrink = false; |
6326 } | 6705 } |
6327 if ((style & DWT.DOUBLE_BUFFERED) !is 0 || findImageControl () !is null) { | 6706 if ((style & DWT.DOUBLE_BUFFERED) !is 0 || findImageControl () !is null) { |
6328 bool doubleBuffer = true; | 6707 bool doubleBuffer = true; |
6329 if (EXPLORER_THEME) { | 6708 if (explorerTheme) { |
6330 if (!OS.IsWinCE && OS.WIN32_VERSION >= OS.VERSION (6, 0)) { | 6709 int exStyle = OS.SendMessage (handle, OS.TVM_GETEXTENDEDSTYLE, 0, 0); |
6331 int exStyle = OS.SendMessage (handle, OS.TVM_GETEXTENDEDSTYLE, 0, 0); | 6710 if ((exStyle & OS.TVS_EX_DOUBLEBUFFER) !is 0) doubleBuffer = false; |
6332 if ((exStyle & OS.TVS_EX_DOUBLEBUFFER) !is 0) doubleBuffer = false; | |
6333 } | |
6334 } | 6711 } |
6335 if (doubleBuffer) { | 6712 if (doubleBuffer) { |
6336 GC gc = null; | 6713 GC gc = null; |
6337 HDC paintDC; | 6714 HDC paintDC; |
6338 PAINTSTRUCT ps; | 6715 PAINTSTRUCT ps; |
6400 * during WM_PAINT. The fix is to draw without clipping and | 6777 * during WM_PAINT. The fix is to draw without clipping and |
6401 * then draw the rest of the columns on top. Since the drawing | 6778 * then draw the rest of the columns on top. Since the drawing |
6402 * is happening in WM_PRINTCLIENT, the redrawing is not visible. | 6779 * is happening in WM_PRINTCLIENT, the redrawing is not visible. |
6403 */ | 6780 */ |
6404 printClient = true; | 6781 printClient = true; |
6405 int code = callWindowProc (handle, OS.WM_PRINTCLIENT, wParam, lParam); | 6782 int /*long*/ code = callWindowProc (handle, OS.WM_PRINTCLIENT, wParam, lParam); |
6406 printClient = false; | 6783 printClient = false; |
6407 return new LRESULT (code); | 6784 return new LRESULT (code); |
6408 } | 6785 } |
6409 | 6786 |
6410 override LRESULT WM_SETFOCUS (int wParam, int lParam) { | 6787 override LRESULT WM_SETFOCUS (int wParam, int lParam) { |
6473 * | 6850 * |
6474 * NOTE: This problem is intermittent and happens on | 6851 * NOTE: This problem is intermittent and happens on |
6475 * Windows Vista running under the theme manager. | 6852 * Windows Vista running under the theme manager. |
6476 */ | 6853 */ |
6477 if (!OS.IsWinCE && OS.WIN32_VERSION >= OS.VERSION (6, 0)) { | 6854 if (!OS.IsWinCE && OS.WIN32_VERSION >= OS.VERSION (6, 0)) { |
6478 int code = OS.DefWindowProc (handle, OS.WM_SETREDRAW, wParam, lParam); | 6855 int /*long*/ code = OS.DefWindowProc (handle, OS.WM_SETREDRAW, wParam, lParam); |
6479 return code is 0 ? LRESULT.ZERO : new LRESULT (code); | 6856 return code is 0 ? LRESULT.ZERO : new LRESULT (code); |
6480 } | 6857 } |
6481 return result; | 6858 return result; |
6482 } | 6859 } |
6483 | 6860 |
6497 * is used with a full selection tree, when the tree | 6874 * is used with a full selection tree, when the tree |
6498 * is resized to be smaller, the rounded right edge | 6875 * is resized to be smaller, the rounded right edge |
6499 * of the selected items is not drawn. The fix is the | 6876 * of the selected items is not drawn. The fix is the |
6500 * redraw the entire tree. | 6877 * redraw the entire tree. |
6501 */ | 6878 */ |
6502 if (EXPLORER_THEME) { | 6879 if (explorerTheme && (style & DWT.FULL_SELECTION) !is 0) { |
6503 if (!OS.IsWinCE && OS.WIN32_VERSION >= OS.VERSION (6, 0)) { | 6880 OS.InvalidateRect (handle, null, false); |
6504 if ((style & DWT.FULL_SELECTION) !is 0) { | |
6505 OS.InvalidateRect (handle, null, false); | |
6506 } | |
6507 } | |
6508 } | 6881 } |
6509 if (ignoreResize) return null; | 6882 if (ignoreResize) return null; |
6510 return super.WM_SIZE (wParam, lParam); | 6883 return super.WM_SIZE (wParam, lParam); |
6511 } | 6884 } |
6512 | 6885 |
6524 } | 6897 } |
6525 if ((style & DWT.CHECK) !is 0) setCheckboxImageList (); | 6898 if ((style & DWT.CHECK) !is 0) setCheckboxImageList (); |
6526 return result; | 6899 return result; |
6527 } | 6900 } |
6528 | 6901 |
6902 override LRESULT WM_VSCROLL (int /*long*/ wParam, int /*long*/ lParam) { | |
6903 bool fixScroll = false; | |
6904 if ((style & DWT.DOUBLE_BUFFERED) !is 0) { | |
6905 int code = OS.LOWORD (wParam); | |
6906 switch (code) { | |
6907 case OS.SB_TOP: | |
6908 case OS.SB_BOTTOM: | |
6909 case OS.SB_LINEDOWN: | |
6910 case OS.SB_LINEUP: | |
6911 case OS.SB_PAGEDOWN: | |
6912 case OS.SB_PAGEUP: | |
6913 fixScroll = (style & DWT.VIRTUAL) !is 0 || hooks (DWT.EraseItem) || hooks (DWT.PaintItem); | |
6914 break; | |
6915 } | |
6916 } | |
6917 if (fixScroll) { | |
6918 style &= ~DWT.DOUBLE_BUFFERED; | |
6919 if (explorerTheme) { | |
6920 OS.SendMessage (handle, OS.TVM_SETEXTENDEDSTYLE, OS.TVS_EX_DOUBLEBUFFER, 0); | |
6921 } | |
6922 } | |
6923 LRESULT result = super.WM_VSCROLL (wParam, lParam); | |
6924 if (fixScroll) { | |
6925 style |= DWT.DOUBLE_BUFFERED; | |
6926 if (explorerTheme) { | |
6927 OS.SendMessage (handle, OS.TVM_SETEXTENDEDSTYLE, OS.TVS_EX_DOUBLEBUFFER, OS.TVS_EX_DOUBLEBUFFER); | |
6928 } | |
6929 } | |
6930 if (result !is null) return result; | |
6931 return result; | |
6932 } | |
6933 | |
6529 override LRESULT wmColorChild (int wParam, int lParam) { | 6934 override LRESULT wmColorChild (int wParam, int lParam) { |
6530 if (findImageControl () !is null) { | 6935 if (findImageControl () !is null) { |
6531 if (OS.COMCTL32_MAJOR < 6) { | 6936 if (OS.COMCTL32_MAJOR < 6) { |
6532 return super.wmColorChild (wParam, lParam); | 6937 return super.wmColorChild (wParam, lParam); |
6533 } | 6938 } |
6542 */ | 6947 */ |
6543 return null; | 6948 return null; |
6544 } | 6949 } |
6545 | 6950 |
6546 override LRESULT wmNotify (NMHDR* hdr, int wParam, int lParam) { | 6951 override LRESULT wmNotify (NMHDR* hdr, int wParam, int lParam) { |
6547 if (hdr.hwndFrom is itemToolTipHandle && hwndHeader !is null) { | 6952 if (hdr.hwndFrom is itemToolTipHandle) { |
6548 static if (!OS.IsWinCE) { | 6953 LRESULT result = wmNotifyToolTip (hdr, wParam, lParam); |
6549 switch (hdr.code) { | 6954 if (result !is null) return result; |
6550 case OS.TTN_POP: { | |
6551 if (display.isXMouseActive ()) { | |
6552 Shell shell = getShell (); | |
6553 shell.lockToolTipControl = null; | |
6554 } | |
6555 break; | |
6556 } | |
6557 case OS.TTN_SHOW: { | |
6558 if (display.isXMouseActive ()) { | |
6559 Shell shell = getShell (); | |
6560 shell.lockToolTipControl = this; | |
6561 } | |
6562 int pos = OS.GetMessagePos (); | |
6563 POINT pt; | |
6564 pt.x = cast(short) (pos & 0xFFFF); | |
6565 pt.y = cast(short) (pos >> 16); | |
6566 OS.ScreenToClient (handle, &pt); | |
6567 TVHITTESTINFO lpht; | |
6568 lpht.pt.x = pt.x; | |
6569 lpht.pt.y = pt.y; | |
6570 OS.SendMessage (handle, OS.TVM_HITTEST, 0, &lpht); | |
6571 if (lpht.hItem !is null) { | |
6572 auto hDC = OS.GetDC (handle); | |
6573 HFONT oldFont, newFont = cast(HFONT) OS.SendMessage (handle, OS.WM_GETFONT, 0, 0); | |
6574 if (newFont !is null) oldFont = OS.SelectObject (hDC, newFont); | |
6575 LRESULT result = null; | |
6576 RECT rect; | |
6577 OS.GetClientRect (hwndParent, &rect); | |
6578 OS.MapWindowPoints (hwndParent, handle, cast(POINT*) &rect, 2); | |
6579 TreeItem item = _getItem (lpht.hItem); | |
6580 int index = 0, count = Math.max (1, OS.SendMessage (hwndHeader, OS.HDM_GETITEMCOUNT, 0, 0)); | |
6581 int [] order = new int [count]; | |
6582 OS.SendMessage (hwndHeader, OS.HDM_GETORDERARRAY, count, order.ptr); | |
6583 while (index < count) { | |
6584 HFONT hFont = item.cellFont !is null ? item.cellFont [order [index]] : cast(HFONT)-1; | |
6585 if (hFont is cast(HFONT)-1) hFont = item.font; | |
6586 if (hFont !is cast(HFONT)-1) hFont = OS.SelectObject (hDC, hFont); | |
6587 RECT cellRect = item.getBounds (order [index], true, false, true, false, true, hDC); | |
6588 if (hFont !is cast(HFONT)-1) OS.SelectObject (hDC, hFont); | |
6589 if (cellRect.left > rect.right) break; | |
6590 cellRect.right = Math.min (cellRect.right, rect.right); | |
6591 if (OS.PtInRect (&cellRect, pt)) { | |
6592 RECT textRect = item.getBounds (order [index], true, false, false, false, false, hDC); | |
6593 if (textRect.right > cellRect.right) { | |
6594 OS.MapWindowPoints (handle, null, cast(POINT*) &textRect, 2); | |
6595 int flags = OS.SWP_NOACTIVATE | OS.SWP_NOSIZE | OS.SWP_NOZORDER; | |
6596 SetWindowPos (itemToolTipHandle, null, textRect.left, textRect.top, 0, 0, flags); | |
6597 result = LRESULT.ONE; | |
6598 } | |
6599 break; | |
6600 } | |
6601 index++; | |
6602 } | |
6603 if (newFont !is null) OS.SelectObject (hDC, oldFont); | |
6604 OS.ReleaseDC (handle, hDC); | |
6605 if (result !is null) return result; | |
6606 } | |
6607 } | |
6608 default: | |
6609 } | |
6610 } | |
6611 } | 6955 } |
6612 if (hdr.hwndFrom is hwndHeader) { | 6956 if (hdr.hwndFrom is hwndHeader) { |
6613 /* | 6957 LRESULT result = wmNotifyHeader (hdr, wParam, lParam); |
6614 * Feature in Windows. On NT, the automatically created | 6958 if (result !is null) return result; |
6615 * header control is created as a UNICODE window, not an | |
6616 * ANSI window despite the fact that the parent is created | |
6617 * as an ANSI window. This means that it sends UNICODE | |
6618 * notification messages to the parent window on NT for | |
6619 * no good reason. The data and size in the NMHEADER and | |
6620 * HDITEM structs is identical between the platforms so no | |
6621 * different message is actually necessary. Despite this, | |
6622 * Windows sends different messages. The fix is to look | |
6623 * for both messages, despite the platform. This works | |
6624 * because only one will be sent on either platform, never | |
6625 * both. | |
6626 */ | |
6627 switch (hdr.code) { | |
6628 case OS.HDN_BEGINTRACKW: | |
6629 case OS.HDN_BEGINTRACKA: | |
6630 case OS.HDN_DIVIDERDBLCLICKW: | |
6631 case OS.HDN_DIVIDERDBLCLICKA: { | |
6632 NMHEADER* phdn = cast(NMHEADER*)lParam; | |
6633 //OS.MoveMemory (phdn, lParam, NMHEADER.sizeof); | |
6634 TreeColumn column = columns [phdn.iItem]; | |
6635 if (column !is null && !column.getResizable ()) { | |
6636 return LRESULT.ONE; | |
6637 } | |
6638 ignoreColumnMove = true; | |
6639 switch (hdr.code) { | |
6640 case OS.HDN_DIVIDERDBLCLICKW: | |
6641 case OS.HDN_DIVIDERDBLCLICKA: | |
6642 if (column !is null) column.pack (); | |
6643 default: | |
6644 } | |
6645 break; | |
6646 } | |
6647 case OS.NM_RELEASEDCAPTURE: { | |
6648 if (!ignoreColumnMove) { | |
6649 int count = OS.SendMessage (hwndHeader, OS.HDM_GETITEMCOUNT, 0, 0); | |
6650 for (int i=0; i<count; i++) { | |
6651 TreeColumn column = columns [i]; | |
6652 column.updateToolTip (i); | |
6653 } | |
6654 updateImageList (); | |
6655 } | |
6656 ignoreColumnMove = false; | |
6657 break; | |
6658 } | |
6659 case OS.HDN_BEGINDRAG: { | |
6660 if (ignoreColumnMove) return LRESULT.ONE; | |
6661 NMHEADER* phdn = cast(NMHEADER*)lParam; | |
6662 //OS.MoveMemory (phdn, lParam, NMHEADER.sizeof); | |
6663 if (phdn.iItem !is -1) { | |
6664 TreeColumn column = columns [phdn.iItem]; | |
6665 if (column !is null && !column.getMoveable ()) { | |
6666 ignoreColumnMove = true; | |
6667 return LRESULT.ONE; | |
6668 } | |
6669 } | |
6670 break; | |
6671 } | |
6672 case OS.HDN_ENDDRAG: { | |
6673 NMHEADER* phdn = cast(NMHEADER*)lParam; | |
6674 //OS.MoveMemory (phdn, lParam, NMHEADER.sizeof); | |
6675 if (phdn.iItem !is -1 && phdn.pitem !is null) { | |
6676 HDITEM* pitem = phdn.pitem; | |
6677 //OS.MoveMemory (pitem, phdn.pitem, HDITEM.sizeof); | |
6678 if ((pitem.mask & OS.HDI_ORDER) !is 0 && pitem.iOrder !is -1) { | |
6679 int count = OS.SendMessage (hwndHeader, OS.HDM_GETITEMCOUNT, 0, 0); | |
6680 int [] order = new int [count]; | |
6681 OS.SendMessage (hwndHeader, OS.HDM_GETORDERARRAY, count, order.ptr); | |
6682 int index = 0; | |
6683 while (index < order.length) { | |
6684 if (order [index] is phdn.iItem) break; | |
6685 index++; | |
6686 } | |
6687 if (index is order.length) index = 0; | |
6688 if (index is pitem.iOrder) break; | |
6689 int start = Math.min (index, pitem.iOrder); | |
6690 int end = Math.max (index, pitem.iOrder); | |
6691 RECT rect, headerRect; | |
6692 OS.GetClientRect (handle, &rect); | |
6693 OS.SendMessage (hwndHeader, OS.HDM_GETITEMRECT, order [start], &headerRect); | |
6694 rect.left = Math.max (rect.left, headerRect.left); | |
6695 OS.SendMessage (hwndHeader, OS.HDM_GETITEMRECT, order [end], &headerRect); | |
6696 rect.right = Math.min (rect.right, headerRect.right); | |
6697 OS.InvalidateRect (handle, &rect, true); | |
6698 ignoreColumnMove = false; | |
6699 for (int i=start; i<=end; i++) { | |
6700 TreeColumn column = columns [order [i]]; | |
6701 if (!column.isDisposed ()) { | |
6702 column.postEvent (DWT.Move); | |
6703 } | |
6704 } | |
6705 } | |
6706 } | |
6707 break; | |
6708 } | |
6709 case OS.HDN_ITEMCHANGINGW: | |
6710 case OS.HDN_ITEMCHANGINGA: { | |
6711 NMHEADER* phdn = cast(NMHEADER*)lParam; | |
6712 //OS.MoveMemory (phdn, lParam, NMHEADER.sizeof); | |
6713 if (phdn.pitem !is null) { | |
6714 HDITEM* newItem = phdn.pitem; | |
6715 //OS.MoveMemory (newItem, phdn.pitem, HDITEM.sizeof); | |
6716 if ((newItem.mask & OS.HDI_WIDTH) !is 0) { | |
6717 RECT rect; | |
6718 OS.GetClientRect (handle, &rect); | |
6719 HDITEM oldItem; | |
6720 oldItem.mask = OS.HDI_WIDTH; | |
6721 OS.SendMessage (hwndHeader, OS.HDM_GETITEM, phdn.iItem, &oldItem); | |
6722 int deltaX = newItem.cxy - oldItem.cxy; | |
6723 RECT headerRect; | |
6724 OS.SendMessage (hwndHeader, OS.HDM_GETITEMRECT, phdn.iItem, &headerRect); | |
6725 int gridWidth = linesVisible ? GRID_WIDTH : 0; | |
6726 rect.left = headerRect.right - gridWidth; | |
6727 int newX = rect.left + deltaX; | |
6728 rect.right = Math.max (rect.right, rect.left + Math.abs (deltaX)); | |
6729 if (explorerTheme || (findImageControl () !is null || hooks (DWT.EraseItem) || hooks (DWT.PaintItem))) { | |
6730 OS.InvalidateRect (handle, &rect, true); | |
6731 OS.OffsetRect (&rect, deltaX, 0); | |
6732 OS.InvalidateRect (handle, &rect, true); | |
6733 } else { | |
6734 int flags = OS.SW_INVALIDATE | OS.SW_ERASE; | |
6735 OS.ScrollWindowEx (handle, deltaX, 0, &rect, null, null, null, flags); | |
6736 } | |
6737 if (OS.SendMessage (hwndHeader, OS.HDM_ORDERTOINDEX, phdn.iItem, 0) !is 0) { | |
6738 rect.left = headerRect.left; | |
6739 rect.right = newX; | |
6740 OS.InvalidateRect (handle, &rect, true); | |
6741 } | |
6742 setScrollWidth (); | |
6743 } | |
6744 } | |
6745 break; | |
6746 } | |
6747 case OS.HDN_ITEMCHANGEDW: | |
6748 case OS.HDN_ITEMCHANGEDA: { | |
6749 NMHEADER* phdn = cast(NMHEADER*)lParam; | |
6750 //OS.MoveMemory (phdn, lParam, NMHEADER.sizeof); | |
6751 if (phdn.pitem !is null) { | |
6752 HDITEM* pitem = phdn.pitem; | |
6753 //OS.MoveMemory (pitem, phdn.pitem, HDITEM.sizeof); | |
6754 if ((pitem.mask & OS.HDI_WIDTH) !is 0) { | |
6755 if (ignoreColumnMove) { | |
6756 if (!OS.IsWinCE && OS.WIN32_VERSION >= OS.VERSION (6, 0)) { | |
6757 int flags = OS.RDW_UPDATENOW | OS.RDW_ALLCHILDREN; | |
6758 OS.RedrawWindow (handle, null, null, flags); | |
6759 } else { | |
6760 if ((style & DWT.DOUBLE_BUFFERED) is 0) { | |
6761 int oldStyle = style; | |
6762 style |= DWT.DOUBLE_BUFFERED; | |
6763 OS.UpdateWindow (handle); | |
6764 style = oldStyle; | |
6765 } | |
6766 } | |
6767 } | |
6768 TreeColumn column = columns [phdn.iItem]; | |
6769 if (column !is null) { | |
6770 column.updateToolTip (phdn.iItem); | |
6771 column.sendEvent (DWT.Resize); | |
6772 if (isDisposed ()) return LRESULT.ZERO; | |
6773 int count = OS.SendMessage (hwndHeader, OS.HDM_GETITEMCOUNT, 0, 0); | |
6774 TreeColumn [] newColumns = new TreeColumn [count]; | |
6775 System.arraycopy (columns, 0, newColumns, 0, count); | |
6776 int [] order = new int [count]; | |
6777 OS.SendMessage (hwndHeader, OS.HDM_GETORDERARRAY, count, order.ptr); | |
6778 bool moved = false; | |
6779 for (int i=0; i<count; i++) { | |
6780 TreeColumn nextColumn = newColumns [order [i]]; | |
6781 if (moved && !nextColumn.isDisposed ()) { | |
6782 nextColumn.updateToolTip (order [i]); | |
6783 nextColumn.sendEvent (DWT.Move); | |
6784 } | |
6785 if (nextColumn is column) moved = true; | |
6786 } | |
6787 } | |
6788 } | |
6789 setScrollWidth (); | |
6790 } | |
6791 break; | |
6792 } | |
6793 case OS.HDN_ITEMCLICKW: | |
6794 case OS.HDN_ITEMCLICKA: { | |
6795 NMHEADER* phdn = cast(NMHEADER*)lParam; | |
6796 //OS.MoveMemory (phdn, lParam, NMHEADER.sizeof); | |
6797 TreeColumn column = columns [phdn.iItem]; | |
6798 if (column !is null) { | |
6799 column.postEvent (DWT.Selection); | |
6800 } | |
6801 break; | |
6802 } | |
6803 case OS.HDN_ITEMDBLCLICKW: | |
6804 case OS.HDN_ITEMDBLCLICKA: { | |
6805 NMHEADER* phdn = cast(NMHEADER*)lParam; | |
6806 //OS.MoveMemory (phdn, lParam, NMHEADER.sizeof); | |
6807 TreeColumn column = columns [phdn.iItem]; | |
6808 if (column !is null) { | |
6809 column.postEvent (DWT.DefaultSelection); | |
6810 } | |
6811 break; | |
6812 } | |
6813 default: | |
6814 } | |
6815 } | 6959 } |
6816 return super.wmNotify (hdr, wParam, lParam); | 6960 return super.wmNotify (hdr, wParam, lParam); |
6817 } | 6961 } |
6818 | 6962 |
6819 override LRESULT wmNotifyChild (NMHDR* hdr, int wParam, int lParam) { | 6963 override LRESULT wmNotifyChild (NMHDR* hdr, int wParam, int lParam) { |
6850 } | 6994 } |
6851 } | 6995 } |
6852 if (checkVisible) { | 6996 if (checkVisible) { |
6853 if (drawCount !is 0 || !OS.IsWindowVisible (handle)) break; | 6997 if (drawCount !is 0 || !OS.IsWindowVisible (handle)) break; |
6854 RECT itemRect; | 6998 RECT itemRect; |
6855 itemRect.left = cast(int) lptvdi.item.hItem; | 6999 if (!OS.TreeView_GetItemRect (handle, lptvdi.item.hItem, &itemRect, false)) { |
6856 if (OS.SendMessage (handle, OS.TVM_GETITEMRECT, 0, &itemRect) is 0) { | |
6857 break; | 7000 break; |
6858 } | 7001 } |
6859 RECT rect; | 7002 RECT rect; |
6860 OS.GetClientRect (handle, &rect); | 7003 OS.GetClientRect (handle, &rect); |
6861 if (!OS.IntersectRect (&rect, &rect, &itemRect)) break; | 7004 if (!OS.IntersectRect (&rect, &rect, &itemRect)) break; |
6983 * with double clicking, then the tree expand | 7126 * with double clicking, then the tree expand |
6984 * is unexpected and unwanted. The fix is to | 7127 * is unexpected and unwanted. The fix is to |
6985 * avoid the operation by testing to see whether | 7128 * avoid the operation by testing to see whether |
6986 * the mouse was inside a tree item. | 7129 * the mouse was inside a tree item. |
6987 */ | 7130 */ |
7131 if (hooks (DWT.MeasureItem)) return LRESULT.ONE; | |
6988 if (hooks (DWT.DefaultSelection)) { | 7132 if (hooks (DWT.DefaultSelection)) { |
6989 POINT pt; | 7133 POINT pt; |
6990 int pos = OS.GetMessagePos (); | 7134 int pos = OS.GetMessagePos (); |
6991 pt.x = cast(short) (pos & 0xFFFF); | 7135 OS.POINTSTOPOINT (pt, pos); |
6992 pt.y = cast(short) (pos >> 16); | |
6993 OS.ScreenToClient (handle, &pt); | 7136 OS.ScreenToClient (handle, &pt); |
6994 TVHITTESTINFO lpht; | 7137 TVHITTESTINFO lpht; |
6995 lpht.pt.x = pt.x; | 7138 lpht.pt.x = pt.x; |
6996 lpht.pt.y = pt.y; | 7139 lpht.pt.y = pt.y; |
6997 OS.SendMessage (handle, OS.TVM_HITTEST, 0, &lpht); | 7140 OS.SendMessage (handle, OS.TVM_HITTEST, 0, &lpht); |
7026 case OS.TVN_SELCHANGINGA: | 7169 case OS.TVN_SELCHANGINGA: |
7027 case OS.TVN_SELCHANGINGW: { | 7170 case OS.TVN_SELCHANGINGW: { |
7028 if ((style & DWT.MULTI) !is 0) { | 7171 if ((style & DWT.MULTI) !is 0) { |
7029 if (lockSelection) { | 7172 if (lockSelection) { |
7030 /* Save the old selection state for both items */ | 7173 /* Save the old selection state for both items */ |
7031 TVITEM tvItem; | 7174 auto treeView = cast(NMTREEVIEW*)lParam; |
7032 int offset1 = NMHDR.sizeof + 4; | 7175 TVITEM* tvItem = &treeView.itemOld; |
7033 OS.MoveMemory (&tvItem, lParam + offset1, TVITEM.sizeof); | |
7034 oldSelected = (tvItem.state & OS.TVIS_SELECTED) !is 0; | 7176 oldSelected = (tvItem.state & OS.TVIS_SELECTED) !is 0; |
7035 int offset2 = NMHDR.sizeof + 4 + TVITEM.sizeof; | 7177 tvItem = &treeView.itemNew; |
7036 OS.MoveMemory (&tvItem, lParam + offset2, TVITEM.sizeof); | |
7037 newSelected = (tvItem.state & OS.TVIS_SELECTED) !is 0; | 7178 newSelected = (tvItem.state & OS.TVIS_SELECTED) !is 0; |
7038 } | 7179 } |
7039 } | 7180 } |
7040 if (!ignoreSelect && !ignoreDeselect) { | 7181 if (!ignoreSelect && !ignoreDeselect) { |
7041 hAnchor = null; | 7182 hAnchor = null; |
7043 } | 7184 } |
7044 break; | 7185 break; |
7045 } | 7186 } |
7046 case OS.TVN_SELCHANGEDA: | 7187 case OS.TVN_SELCHANGEDA: |
7047 case OS.TVN_SELCHANGEDW: { | 7188 case OS.TVN_SELCHANGEDW: { |
7189 NMTREEVIEW* treeView = null; | |
7048 if ((style & DWT.MULTI) !is 0) { | 7190 if ((style & DWT.MULTI) !is 0) { |
7049 if (lockSelection) { | 7191 if (lockSelection) { |
7050 /* Restore the old selection state of both items */ | 7192 /* Restore the old selection state of both items */ |
7051 if (oldSelected) { | 7193 if (oldSelected) { |
7052 TVITEM tvItem; | 7194 if (treeView is null) { |
7053 int offset = NMHDR.sizeof + 4; | 7195 treeView = cast(NMTREEVIEW*)lParam; |
7054 OS.MoveMemory (&tvItem, lParam + offset, TVITEM.sizeof); | 7196 } |
7197 TVITEM tvItem = treeView.itemOld; | |
7055 tvItem.mask = OS.TVIF_STATE; | 7198 tvItem.mask = OS.TVIF_STATE; |
7056 tvItem.stateMask = OS.TVIS_SELECTED; | 7199 tvItem.stateMask = OS.TVIS_SELECTED; |
7057 tvItem.state = OS.TVIS_SELECTED; | 7200 tvItem.state = OS.TVIS_SELECTED; |
7058 OS.SendMessage (handle, OS.TVM_SETITEM, 0, &tvItem); | 7201 OS.SendMessage (handle, OS.TVM_SETITEM, 0, &tvItem); |
7059 } | 7202 } |
7060 if (!newSelected && ignoreSelect) { | 7203 if (!newSelected && ignoreSelect) { |
7061 TVITEM tvItem; | 7204 if (treeView is null) { |
7062 int offset = NMHDR.sizeof + 4 + TVITEM.sizeof; | 7205 treeView = cast(NMTREEVIEW*)lParam; |
7063 OS.MoveMemory (&tvItem, lParam + offset, TVITEM.sizeof); | 7206 } |
7207 TVITEM tvItem = treeView.itemNew; | |
7064 tvItem.mask = OS.TVIF_STATE; | 7208 tvItem.mask = OS.TVIF_STATE; |
7065 tvItem.stateMask = OS.TVIS_SELECTED; | 7209 tvItem.stateMask = OS.TVIS_SELECTED; |
7066 tvItem.state = 0; | 7210 tvItem.state = 0; |
7067 OS.SendMessage (handle, OS.TVM_SETITEM, 0, &tvItem); | 7211 OS.SendMessage (handle, OS.TVM_SETITEM, 0, &tvItem); |
7068 } | 7212 } |
7069 } | 7213 } |
7070 } | 7214 } |
7071 if (!ignoreSelect) { | 7215 if (!ignoreSelect) { |
7072 TVITEM tvItem; | 7216 if (treeView is null) { |
7073 int offset = NMHDR.sizeof + 4 + TVITEM.sizeof; | 7217 treeView = cast(NMTREEVIEW*)lParam; |
7074 OS.MoveMemory (&tvItem, lParam + offset, TVITEM.sizeof); | 7218 } |
7219 TVITEM tvItem = treeView.itemNew; | |
7075 hAnchor = tvItem.hItem; | 7220 hAnchor = tvItem.hItem; |
7076 Event event = new Event (); | 7221 Event event = new Event (); |
7077 event.item = _getItem (&tvItem.hItem, tvItem.lParam); | 7222 event.item = _getItem (&tvItem.hItem, tvItem.lParam); |
7078 postEvent (DWT.Selection, event); | 7223 postEvent (DWT.Selection, event); |
7079 } | 7224 } |
7097 */ | 7242 */ |
7098 if (hInsert !is null) { | 7243 if (hInsert !is null) { |
7099 OS.SendMessage (handle, OS.TVM_SETINSERTMARK, 0, 0); | 7244 OS.SendMessage (handle, OS.TVM_SETINSERTMARK, 0, 0); |
7100 } | 7245 } |
7101 if (!ignoreExpand) { | 7246 if (!ignoreExpand) { |
7102 TVITEM tvItem; | 7247 NMTREEVIEW* treeView = cast(NMTREEVIEW*)lParam; |
7103 int offset = NMHDR.sizeof + 4 + TVITEM.sizeof; | 7248 |
7104 OS.MoveMemory (&tvItem, lParam + offset, TVITEM.sizeof); | 7249 TVITEM* tvItem = &treeView.itemNew; |
7105 /* | 7250 /* |
7106 * Feature in Windows. In some cases, TVM_ITEMEXPANDING | 7251 * Feature in Windows. In some cases, TVM_ITEMEXPANDING |
7107 * is sent from within TVM_DELETEITEM for the tree item | 7252 * is sent from within TVM_DELETEITEM for the tree item |
7108 * being destroyed. By the time the message is sent, | 7253 * being destroyed. By the time the message is sent, |
7109 * the item has already been removed from the list of | 7254 * the item has already been removed from the list of |
7112 if (items is null) break; | 7257 if (items is null) break; |
7113 TreeItem item = _getItem (tvItem.hItem, tvItem.lParam); | 7258 TreeItem item = _getItem (tvItem.hItem, tvItem.lParam); |
7114 if (item is null) break; | 7259 if (item is null) break; |
7115 Event event = new Event (); | 7260 Event event = new Event (); |
7116 event.item = item; | 7261 event.item = item; |
7117 int action = *cast(int*)(lParam + NMHDR.sizeof); | 7262 switch (treeView.action) { |
7118 //OS.MoveMemory (action, lParam + NMHDR.sizeof, 4); | |
7119 switch (action) { | |
7120 case OS.TVE_EXPAND: | 7263 case OS.TVE_EXPAND: |
7121 /* | 7264 /* |
7122 * Bug in Windows. When the numeric keypad asterisk | 7265 * Bug in Windows. When the numeric keypad asterisk |
7123 * key is used to expand every item in the tree, Windows | 7266 * key is used to expand every item in the tree, Windows |
7124 * sends TVN_ITEMEXPANDING to items in the tree that | 7267 * sends TVN_ITEMEXPANDING to items in the tree that |
7174 * This means that the image gets darker each time. | 7317 * This means that the image gets darker each time. |
7175 * The fix is to redraw the item. | 7318 * The fix is to redraw the item. |
7176 */ | 7319 */ |
7177 if (!OS.IsWinCE && OS.COMCTL32_MAJOR >= 6) { | 7320 if (!OS.IsWinCE && OS.COMCTL32_MAJOR >= 6) { |
7178 if (imageList !is null) { | 7321 if (imageList !is null) { |
7179 TVITEM tvItem; | 7322 NMTREEVIEW* treeView = cast(NMTREEVIEW*)lParam; |
7180 int offset = NMHDR.sizeof + 4 + TVITEM.sizeof; | 7323 |
7181 OS.MoveMemory (&tvItem, lParam + offset, TVITEM.sizeof); | 7324 TVITEM* tvItem = &treeView.itemNew; |
7182 if (tvItem.hItem !is null) { | 7325 if (tvItem.hItem !is null) { |
7183 int bits = OS.GetWindowLong (handle, OS.GWL_STYLE); | 7326 int bits = OS.GetWindowLong (handle, OS.GWL_STYLE); |
7184 if ((bits & OS.TVS_FULLROWSELECT) is 0) { | 7327 if ((bits & OS.TVS_FULLROWSELECT) is 0) { |
7185 RECT rect; | 7328 RECT rect; |
7186 rect.left = cast(int)tvItem.hItem; | 7329 if (OS.TreeView_GetItemRect (handle, tvItem.hItem, &rect, false)) { |
7187 OS.SendMessage (handle, OS.TVM_GETITEMRECT, 0, &rect); | 7330 OS.InvalidateRect (handle, &rect, true); |
7188 OS.InvalidateRect (handle, &rect, true); | 7331 } |
7189 } | 7332 } |
7190 } | 7333 } |
7191 } | 7334 } |
7192 } | 7335 } |
7193 updateScrollBar (); | 7336 updateScrollBar (); |
7194 break; | 7337 break; |
7195 } | 7338 } |
7196 case OS.TVN_BEGINDRAGA: | 7339 case OS.TVN_BEGINDRAGA: |
7197 case OS.TVN_BEGINDRAGW: | 7340 case OS.TVN_BEGINDRAGW: |
7341 if (OS.GetKeyState (OS.VK_LBUTTON) >= 0) break; | |
7342 //FALL THROUGH | |
7198 case OS.TVN_BEGINRDRAGA: | 7343 case OS.TVN_BEGINRDRAGA: |
7199 case OS.TVN_BEGINRDRAGW: { | 7344 case OS.TVN_BEGINRDRAGW: { |
7200 TVITEM tvItem; | 7345 dragStarted = true; |
7201 int offset = NMHDR.sizeof + 4 + TVITEM.sizeof; | 7346 NMTREEVIEW* treeView = cast(NMTREEVIEW*)lParam; |
7202 OS.MoveMemory (&tvItem, lParam + offset, TVITEM.sizeof); | 7347 TVITEM* tvItem = &treeView.itemNew; |
7203 if (tvItem.hItem !is null && (tvItem.state & OS.TVIS_SELECTED) is 0) { | 7348 if (tvItem.hItem !is null && (tvItem.state & OS.TVIS_SELECTED) is 0) { |
7204 hSelect = tvItem.hItem; | 7349 hSelect = tvItem.hItem; |
7205 ignoreSelect = ignoreDeselect = true; | 7350 ignoreSelect = ignoreDeselect = true; |
7206 OS.SendMessage (handle, OS.TVM_SELECTITEM, OS.TVGN_CARET, tvItem.hItem); | 7351 OS.SendMessage (handle, OS.TVM_SELECTITEM, OS.TVGN_CARET, tvItem.hItem); |
7207 ignoreSelect = ignoreDeselect = false; | 7352 ignoreSelect = ignoreDeselect = false; |
7208 hSelect = null; | 7353 hSelect = null; |
7209 } | 7354 } |
7210 dragStarted = true; | |
7211 break; | 7355 break; |
7212 } | 7356 } |
7213 case OS.NM_RECOGNIZEGESTURE: { | 7357 case OS.NM_RECOGNIZEGESTURE: { |
7214 /* | 7358 /* |
7215 * Feature in Pocket PC. The tree and table controls detect the tap | 7359 * Feature in Pocket PC. The tree and table controls detect the tap |
7242 default: | 7386 default: |
7243 } | 7387 } |
7244 return super.wmNotifyChild (hdr, wParam, lParam); | 7388 return super.wmNotifyChild (hdr, wParam, lParam); |
7245 } | 7389 } |
7246 | 7390 |
7247 } | 7391 LRESULT wmNotifyHeader (NMHDR* hdr, int /*long*/ wParam, int /*long*/ lParam) { |
7392 /* | |
7393 * Feature in Windows. On NT, the automatically created | |
7394 * header control is created as a UNICODE window, not an | |
7395 * ANSI window despite the fact that the parent is created | |
7396 * as an ANSI window. This means that it sends UNICODE | |
7397 * notification messages to the parent window on NT for | |
7398 * no good reason. The data and size in the NMHEADER and | |
7399 * HDITEM structs is identical between the platforms so no | |
7400 * different message is actually necessary. Despite this, | |
7401 * Windows sends different messages. The fix is to look | |
7402 * for both messages, despite the platform. This works | |
7403 * because only one will be sent on either platform, never | |
7404 * both. | |
7405 */ | |
7406 switch (hdr.code) { | |
7407 case OS.HDN_BEGINTRACKW: | |
7408 case OS.HDN_BEGINTRACKA: | |
7409 case OS.HDN_DIVIDERDBLCLICKW: | |
7410 case OS.HDN_DIVIDERDBLCLICKA: { | |
7411 NMHEADER* phdn = cast(NMHEADER*)lParam; | |
7412 TreeColumn column = columns [phdn.iItem]; | |
7413 if (column !is null && !column.getResizable ()) { | |
7414 return LRESULT.ONE; | |
7415 } | |
7416 ignoreColumnMove = true; | |
7417 switch (hdr.code) { | |
7418 case OS.HDN_DIVIDERDBLCLICKW: | |
7419 case OS.HDN_DIVIDERDBLCLICKA: | |
7420 if (column !is null) column.pack (); | |
7421 } | |
7422 break; | |
7423 } | |
7424 case OS.NM_RELEASEDCAPTURE: { | |
7425 if (!ignoreColumnMove) { | |
7426 for (int i=0; i<columnCount; i++) { | |
7427 TreeColumn column = columns [i]; | |
7428 column.updateToolTip (i); | |
7429 } | |
7430 updateImageList (); | |
7431 } | |
7432 ignoreColumnMove = false; | |
7433 break; | |
7434 } | |
7435 case OS.HDN_BEGINDRAG: { | |
7436 if (ignoreColumnMove) return LRESULT.ONE; | |
7437 NMHEADER* phdn = cast(NMHEADER*)lParam; | |
7438 if (phdn.iItem !is -1) { | |
7439 TreeColumn column = columns [phdn.iItem]; | |
7440 if (column !is null && !column.getMoveable ()) { | |
7441 ignoreColumnMove = true; | |
7442 return LRESULT.ONE; | |
7443 } | |
7444 } | |
7445 break; | |
7446 } | |
7447 case OS.HDN_ENDDRAG: { | |
7448 NMHEADER* phdn = cast(NMHEADER*)lParam; | |
7449 if (cast(int)phdn.iItem !is -1 && phdn.pitem !is null) { | |
7450 HDITEM* pitem = cast(HDITEM*)phdn.pitem; | |
7451 if ((pitem.mask & OS.HDI_ORDER) !is 0 && pitem.iOrder !is -1) { | |
7452 int [] order = new int [columnCount]; | |
7453 OS.SendMessage (hwndHeader, OS.HDM_GETORDERARRAY, columnCount, order.ptr); | |
7454 int index = 0; | |
7455 while (index < order.length) { | |
7456 if (order [index] is phdn.iItem) break; | |
7457 index++; | |
7458 } | |
7459 if (index is order.length) index = 0; | |
7460 if (index is pitem.iOrder) break; | |
7461 int start = Math.min (index, pitem.iOrder); | |
7462 int end = Math.max (index, pitem.iOrder); | |
7463 RECT rect, headerRect; | |
7464 OS.GetClientRect (handle, &rect); | |
7465 OS.SendMessage (hwndHeader, OS.HDM_GETITEMRECT, order [start], &headerRect); | |
7466 rect.left = Math.max (rect.left, headerRect.left); | |
7467 OS.SendMessage (hwndHeader, OS.HDM_GETITEMRECT, order [end], &headerRect); | |
7468 rect.right = Math.min (rect.right, headerRect.right); | |
7469 OS.InvalidateRect (handle, &rect, true); | |
7470 ignoreColumnMove = false; | |
7471 for (int i=start; i<=end; i++) { | |
7472 TreeColumn column = columns [order [i]]; | |
7473 if (!column.isDisposed ()) { | |
7474 column.postEvent (DWT.Move); | |
7475 } | |
7476 } | |
7477 } | |
7478 } | |
7479 break; | |
7480 } | |
7481 case OS.HDN_ITEMCHANGINGW: | |
7482 case OS.HDN_ITEMCHANGINGA: { | |
7483 NMHEADER* phdn = cast(NMHEADER*)lParam; | |
7484 if (phdn.pitem !is null) { | |
7485 HDITEM* newItem = cast(HDITEM*)phdn.pitem; | |
7486 if ((newItem.mask & OS.HDI_WIDTH) !is 0) { | |
7487 RECT rect; | |
7488 OS.GetClientRect (handle, &rect); | |
7489 HDITEM oldItem; | |
7490 oldItem.mask = OS.HDI_WIDTH; | |
7491 OS.SendMessage (hwndHeader, OS.HDM_GETITEM, phdn.iItem, &oldItem); | |
7492 int deltaX = newItem.cxy - oldItem.cxy; | |
7493 RECT headerRect; | |
7494 OS.SendMessage (hwndHeader, OS.HDM_GETITEMRECT, phdn.iItem, &headerRect); | |
7495 int gridWidth = linesVisible ? GRID_WIDTH : 0; | |
7496 rect.left = headerRect.right - gridWidth; | |
7497 int newX = rect.left + deltaX; | |
7498 rect.right = Math.max (rect.right, rect.left + Math.abs (deltaX)); | |
7499 if (explorerTheme || (findImageControl () !is null || hooks (DWT.MeasureItem) || hooks (DWT.EraseItem) || hooks (DWT.PaintItem))) { | |
7500 rect.left -= OS.GetSystemMetrics (OS.SM_CXFOCUSBORDER); | |
7501 OS.InvalidateRect (handle, &rect, true); | |
7502 OS.OffsetRect (&rect, deltaX, 0); | |
7503 OS.InvalidateRect (handle, &rect, true); | |
7504 } else { | |
7505 int flags = OS.SW_INVALIDATE | OS.SW_ERASE; | |
7506 OS.ScrollWindowEx (handle, deltaX, 0, &rect, null, null, null, flags); | |
7507 } | |
7508 if (OS.SendMessage (hwndHeader, OS.HDM_ORDERTOINDEX, phdn.iItem, 0) !is 0) { | |
7509 rect.left = headerRect.left; | |
7510 rect.right = newX; | |
7511 OS.InvalidateRect (handle, &rect, true); | |
7512 } | |
7513 setScrollWidth (); | |
7514 } | |
7515 } | |
7516 break; | |
7517 } | |
7518 case OS.HDN_ITEMCHANGEDW: | |
7519 case OS.HDN_ITEMCHANGEDA: { | |
7520 NMHEADER* phdn = cast(NMHEADER*)lParam; | |
7521 if (phdn.pitem !is null) { | |
7522 HDITEM* pitem = cast(HDITEM*)phdn.pitem; | |
7523 if ((pitem.mask & OS.HDI_WIDTH) !is 0) { | |
7524 if (ignoreColumnMove) { | |
7525 if (!OS.IsWinCE && OS.WIN32_VERSION >= OS.VERSION (6, 0)) { | |
7526 int flags = OS.RDW_UPDATENOW | OS.RDW_ALLCHILDREN; | |
7527 OS.RedrawWindow (handle, null, null, flags); | |
7528 } else { | |
7529 if ((style & DWT.DOUBLE_BUFFERED) is 0) { | |
7530 int oldStyle = style; | |
7531 style |= DWT.DOUBLE_BUFFERED; | |
7532 OS.UpdateWindow (handle); | |
7533 style = oldStyle; | |
7534 } | |
7535 } | |
7536 } | |
7537 TreeColumn column = columns [phdn.iItem]; | |
7538 if (column !is null) { | |
7539 column.updateToolTip (phdn.iItem); | |
7540 column.sendEvent (DWT.Resize); | |
7541 if (isDisposed ()) return LRESULT.ZERO; | |
7542 TreeColumn [] newColumns = new TreeColumn [columnCount]; | |
7543 System.arraycopy (columns, 0, newColumns, 0, columnCount); | |
7544 int [] order = new int [columnCount]; | |
7545 OS.SendMessage (hwndHeader, OS.HDM_GETORDERARRAY, columnCount, order.ptr); | |
7546 bool moved = false; | |
7547 for (int i=0; i<columnCount; i++) { | |
7548 TreeColumn nextColumn = newColumns [order [i]]; | |
7549 if (moved && !nextColumn.isDisposed ()) { | |
7550 nextColumn.updateToolTip (order [i]); | |
7551 nextColumn.sendEvent (DWT.Move); | |
7552 } | |
7553 if (nextColumn is column) moved = true; | |
7554 } | |
7555 } | |
7556 } | |
7557 setScrollWidth (); | |
7558 } | |
7559 break; | |
7560 } | |
7561 case OS.HDN_ITEMCLICKW: | |
7562 case OS.HDN_ITEMCLICKA: { | |
7563 NMHEADER* phdn = cast(NMHEADER*)lParam; | |
7564 TreeColumn column = columns [phdn.iItem]; | |
7565 if (column !is null) { | |
7566 column.postEvent (DWT.Selection); | |
7567 } | |
7568 break; | |
7569 } | |
7570 case OS.HDN_ITEMDBLCLICKW: | |
7571 case OS.HDN_ITEMDBLCLICKA: { | |
7572 NMHEADER* phdn = cast(NMHEADER*)lParam; | |
7573 TreeColumn column = columns [phdn.iItem]; | |
7574 if (column !is null) { | |
7575 column.postEvent (DWT.DefaultSelection); | |
7576 } | |
7577 break; | |
7578 } | |
7579 } | |
7580 return null; | |
7581 } | |
7582 | |
7583 LRESULT wmNotifyToolTip (NMHDR* hdr, int /*long*/ wParam, int /*long*/ lParam) { | |
7584 if (OS.IsWinCE) return null; | |
7585 switch (hdr.code) { | |
7586 case OS.NM_CUSTOMDRAW: { | |
7587 NMTTCUSTOMDRAW* nmcd = cast(NMTTCUSTOMDRAW*)lParam; | |
7588 return wmNotifyToolTip (nmcd, lParam); | |
7589 } | |
7590 case OS.TTN_SHOW: { | |
7591 LRESULT result = super.wmNotify (hdr, wParam, lParam); | |
7592 if (result !is null) return result; | |
7593 int pos = OS.GetMessagePos (); | |
7594 POINT pt; | |
7595 OS.POINTSTOPOINT (pt, pos); | |
7596 OS.ScreenToClient (handle, &pt); | |
7597 int index; | |
7598 TreeItem item; | |
7599 RECT cellRect, itemRect; | |
7600 if (findCell (pt.x, pt.y, item, index, cellRect, itemRect)) { | |
7601 RECT* toolRect = toolTipRect (&itemRect); | |
7602 OS.MapWindowPoints (handle, null, cast(POINT*)toolRect, 2); | |
7603 int width = toolRect.right - toolRect.left; | |
7604 int height = toolRect.bottom - toolRect.top; | |
7605 int flags = OS.SWP_NOACTIVATE | OS.SWP_NOZORDER | OS.SWP_NOSIZE; | |
7606 if (isCustomToolTip ()) flags &= ~OS.SWP_NOSIZE; | |
7607 SetWindowPos (itemToolTipHandle, null, toolRect.left, toolRect.top, width, height, flags); | |
7608 return LRESULT.ONE; | |
7609 } | |
7610 return result; | |
7611 } | |
7612 } | |
7613 return null; | |
7614 } | |
7615 | |
7616 LRESULT wmNotifyToolTip (NMTTCUSTOMDRAW* nmcd, int /*long*/ lParam) { | |
7617 if (OS.IsWinCE) return null; | |
7618 switch (nmcd.nmcd.dwDrawStage) { | |
7619 case OS.CDDS_PREPAINT: { | |
7620 if (isCustomToolTip ()) { | |
7621 //TEMPORARY CODE | |
7622 //nmcd.uDrawFlags |= OS.DT_CALCRECT; | |
7623 //OS.MoveMemory (lParam, nmcd, NMTTCUSTOMDRAW.sizeof); | |
7624 if (!OS.IsWinCE && OS.WIN32_VERSION < OS.VERSION (6, 0)) { | |
7625 OS.SetTextColor (nmcd.nmcd.hdc, OS.GetSysColor (OS.COLOR_INFOBK)); | |
7626 } | |
7627 return new LRESULT (OS.CDRF_NOTIFYPOSTPAINT | OS.CDRF_NEWFONT); | |
7628 } | |
7629 break; | |
7630 } | |
7631 case OS.CDDS_POSTPAINT: { | |
7632 if (!OS.IsWinCE && OS.WIN32_VERSION < OS.VERSION (6, 0)) { | |
7633 OS.SetTextColor (nmcd.nmcd.hdc, OS.GetSysColor (OS.COLOR_INFOTEXT)); | |
7634 } | |
7635 if (OS.SendMessage (itemToolTipHandle, OS.TTM_GETCURRENTTOOL, 0, 0) !is 0) { | |
7636 TOOLINFO lpti; | |
7637 lpti.cbSize = TOOLINFO.sizeof; | |
7638 if (OS.SendMessage (itemToolTipHandle, OS.TTM_GETCURRENTTOOL, 0, cast(int)&lpti) !is 0) { | |
7639 int index; | |
7640 TreeItem item; | |
7641 RECT cellRect, itemRect; | |
7642 int pos = OS.GetMessagePos (); | |
7643 POINT pt; | |
7644 OS.POINTSTOPOINT (pt, pos); | |
7645 OS.ScreenToClient (handle, &pt); | |
7646 if (findCell (pt.x, pt.y, item, index, cellRect, itemRect)) { | |
7647 auto hDC = OS.GetDC (handle); | |
7648 auto hFont = item.fontHandle (index); | |
7649 if (hFont is cast(HFONT)-1) hFont = cast(HFONT) OS.SendMessage (handle, OS.WM_GETFONT, 0, 0); | |
7650 HFONT oldFont = OS.SelectObject (hDC, hFont); | |
7651 LRESULT result = null; | |
7652 bool drawForeground = true; | |
7653 cellRect = item.getBounds (index, true, true, false, false, false, hDC); | |
7654 if (hooks (DWT.EraseItem)) { | |
7655 Event event = sendEraseItemEvent (item, nmcd, index, &cellRect); | |
7656 if (isDisposed () || item.isDisposed ()) break; | |
7657 if (event.doit) { | |
7658 drawForeground = (event.detail & DWT.FOREGROUND) !is 0; | |
7659 } else { | |
7660 drawForeground = false; | |
7661 } | |
7662 } | |
7663 if (drawForeground) { | |
7664 int nSavedDC = OS.SaveDC (nmcd.nmcd.hdc); | |
7665 int gridWidth = getLinesVisible () ? Table.GRID_WIDTH : 0; | |
7666 RECT* insetRect = toolTipInset (&cellRect); | |
7667 OS.SetWindowOrgEx (nmcd.nmcd.hdc, insetRect.left, insetRect.top, null); | |
7668 GCData data = new GCData (); | |
7669 data.device = display; | |
7670 data.foreground = OS.GetTextColor (nmcd.nmcd.hdc); | |
7671 data.background = OS.GetBkColor (nmcd.nmcd.hdc); | |
7672 data.font = Font.win32_new (display, hFont); | |
7673 GC gc = GC.win32_new (nmcd.nmcd.hdc, data); | |
7674 int x = cellRect.left + INSET; | |
7675 if (index !is 0) x -= gridWidth; | |
7676 Image image = item.getImage (index); | |
7677 if (image !is null || index is 0) { | |
7678 Point size = getImageSize (); | |
7679 RECT imageRect = item.getBounds (index, false, true, false, false, false, hDC); | |
7680 if (imageList is null) size.x = imageRect.right - imageRect.left; | |
7681 if (image !is null) { | |
7682 Rectangle rect = image.getBounds (); | |
7683 gc.drawImage (image, rect.x, rect.y, rect.width, rect.height, x, imageRect.top, size.x, size.y); | |
7684 x += INSET + (index is 0 ? 1 : 0); | |
7685 } | |
7686 x += size.x; | |
7687 } else { | |
7688 x += INSET; | |
7689 } | |
7690 String string = item.getText (index); | |
7691 if (string !is null) { | |
7692 int flags = OS.DT_NOPREFIX | OS.DT_SINGLELINE | OS.DT_VCENTER; | |
7693 TreeColumn column = columns !is null ? columns [index] : null; | |
7694 if (column !is null) { | |
7695 if ((column.style & DWT.CENTER) !is 0) flags |= OS.DT_CENTER; | |
7696 if ((column.style & DWT.RIGHT) !is 0) flags |= OS.DT_RIGHT; | |
7697 } | |
7698 TCHAR[] buffer = StrToTCHARs (getCodePage (), string, false); | |
7699 RECT textRect; | |
7700 OS.SetRect (&textRect, x, cellRect.top, cellRect.right, cellRect.bottom); | |
7701 OS.DrawText (nmcd.nmcd.hdc, buffer.ptr, buffer.length, &textRect, flags); | |
7702 } | |
7703 gc.dispose (); | |
7704 OS.RestoreDC (nmcd.nmcd.hdc, nSavedDC); | |
7705 } | |
7706 if (hooks (DWT.PaintItem)) { | |
7707 itemRect = item.getBounds (index, true, true, false, false, false, hDC); | |
7708 sendPaintItemEvent (item, nmcd, index, &itemRect); | |
7709 } | |
7710 OS.SelectObject (hDC, oldFont); | |
7711 OS.ReleaseDC (handle, hDC); | |
7712 if (result !is null) return result; | |
7713 } | |
7714 break; | |
7715 } | |
7716 } | |
7717 break; | |
7718 } | |
7719 } | |
7720 return null; | |
7721 } | |
7722 | |
7723 } |