boolean hot = (nmcd.uItemState & OS.CDIS_HOT) != 0; if (selected || hot) { RECT pRect = new RECT (); OS.SetRect (pRect, nmcd.left, nmcd.top, nmcd.right, nmcd.bottom); if (count > 0 && hwndHeader != 0) { int totalWidth = 0; HDITEM hdItem = new HDITEM (); hdItem.mask = OS.HDI_WIDTH; for (int j=0; j<count; j++) { OS.SendMessage (hwndHeader, OS.HDM_GETITEM, j, hdItem); totalWidth += hdItem.cxy;
if (explorerTheme) { boolean hot = (nmcd.uItemState & OS.CDIS_HOT) != 0; if (selected || hot) { RECT pRect = new RECT (); OS.SetRect (pRect, nmcd.left, nmcd.top, nmcd.right, nmcd.bottom); if (count > 0 && hwndHeader != 0) { int totalWidth = 0; HDITEM hdItem = new HDITEM (); hdItem.mask = OS.HDI_WIDTH; for (int j=0; j<count; j++) { OS.SendMessage (hwndHeader, OS.HDM_GETITEM, j, hdItem); totalWidth += hdItem.cxy; } if (totalWidth > clientRect.right - clientRect.left) { pRect.left = 0; pRect.right = totalWidth; } else { pRect.left = clientRect.left; pRect.right = clientRect.right; }
LRESULT CDDS_ITEMPOSTPAINT (int wParam, int lParam) {	if (ignoreCustomDraw) return null;	NMTVCUSTOMDRAW nmcd = new NMTVCUSTOMDRAW ();	OS.MoveMemory (nmcd, lParam, NMTVCUSTOMDRAW.sizeof);	if (nmcd.left == nmcd.right) {		return new LRESULT (OS.CDRF_DODEFAULT);	}	int hDC = nmcd.hdc;	OS.RestoreDC (hDC, -1);	/*	* Bug in Windows.  If the lParam field of TVITEM	* is changed during custom draw using TVM_SETITEM,	* the lItemlParam field of the NMTVCUSTOMDRAW struct	* is not updated until the next custom draw.  The	* fix is to query the field from the item instead	* of using the struct.	*/	int id = nmcd.lItemlParam;	if ((style & SWT.VIRTUAL) != 0) {		if (id == -1) {			TVITEM tvItem = new TVITEM ();			tvItem.mask = OS.TVIF_HANDLE | OS.TVIF_PARAM;			tvItem.hItem = nmcd.dwItemSpec;			OS.SendMessage (handle, OS.TVM_GETITEM, 0, tvItem);			id = tvItem.lParam;		}	}	TreeItem item = _getItem (nmcd.dwItemSpec, id);		/*	* Feature in Windows.  When a new tree item is inserted	* using TVM_INSERTITEM and the tree is using custom draw,	* a NM_CUSTOMDRAW is sent before TVM_INSERTITEM returns	* and before the item is added to the items array.  The	* fix is to check for null.	* 	* NOTE: This only happens on XP with the version 6.00 of	* COMCTL32.DLL,	*/	if (item == null) return null;	/*	* Feature in Windows.  Under certain circumstances, Windows	* sends CDDS_ITEMPOSTPAINT for an empty rectangle.  This is	* not a problem providing that graphics do not occur outside	* the rectangle.  The fix is to test for the rectangle and	* draw nothing.	* 	* NOTE:  This seems to happen when both I_IMAGECALLBACK	* and LPSTR_TEXTCALLBACK are used at the same time with	* TVM_SETITEM.	*/	if (nmcd.left >= nmcd.right || nmcd.top >= nmcd.bottom) return null;	if (!OS.IsWindowVisible (handle)) return null;	if ((style & SWT.FULL_SELECTION) != 0 || findImageControl () != null || ignoreDrawSelection) {		OS.SetBkMode (hDC, OS.TRANSPARENT);	}	boolean selected = false;	if (OS.IsWindowEnabled (handle)) {		TVITEM tvItem = new TVITEM ();		tvItem.mask = OS.TVIF_HANDLE | OS.TVIF_STATE;		tvItem.hItem = item.handle;		OS.SendMessage (handle, OS.TVM_GETITEM, 0, tvItem);		if ((tvItem.state & (OS.TVIS_SELECTED | OS.TVIS_DROPHILITED)) != 0) {			selected = true;			/*			* Feature in Windows.  When the mouse is pressed and the			* selection is first drawn for a tree, the previously			* selected item is redrawn but the the TVIS_SELECTED bits			* are not cleared.  When the user moves the mouse slightly			* and a drag and drop operation is not started, the item is			* drawn again and this time with TVIS_SELECTED is cleared.			* This means that an item that contains colored cells will			* not draw with the correct background until the mouse is			* moved.  The fix is to test for the selection colors and			* guess that the item is not selected.			* 			* NOTE: This code does not work when the foreground and			* background of the tree are set to the selection colors			* but this does not happen in a regular application.			*/			if (handle == OS.GetFocus ()) {				if (OS.GetTextColor (hDC) != OS.GetSysColor (OS.COLOR_HIGHLIGHTTEXT)) {					selected = false;				} else {					if (OS.GetBkColor (hDC) != OS.GetSysColor (OS.COLOR_HIGHLIGHT)) {						selected = false;					}				}			}		} else {			/*			* Feature in Windows.  When the mouse is pressed and the			* selection is first drawn for a tree, the item is drawn			* selected, but the TVIS_SELECTED bits for the item are			* not set.  When the user moves the mouse slightly and			* a drag and drop operation is not started, the item is			* drawn again and this time TVIS_SELECTED is set.  This			* means that an item that is in a tree that has the style			* TVS_FULLROWSELECT and that also contains colored cells			* will not draw the entire row selected until the user			* moves the mouse.  The fix is to test for the selection			* colors and guess that the item is selected.			* 			* NOTE: This code does not work when the foreground and			* background of the tree are set to the selection colors			* but this does not happen in a regular application.			*/			if (OS.GetTextColor (hDC) == OS.GetSysColor (OS.COLOR_HIGHLIGHTTEXT)) {				if (OS.GetBkColor (hDC) == OS.GetSysColor (OS.COLOR_HIGHLIGHT)) {					selected = true;				}			}		}		if (EXPLORER_THEME) {			if (!OS.IsWinCE && OS.WIN32_VERSION >= OS.VERSION (6, 0)) {				int bits = OS.GetWindowLong (handle, OS.GWL_STYLE);				if ((bits & OS.TVS_TRACKSELECT) != 0) {					OS.SetTextColor (hDC, getForegroundPixel ());				}			}		}	}	int count = 0;	int [] order = null;	RECT clientRect = new RECT (), focusRect = null;	OS.GetClientRect (scrolledHandle (), clientRect);	if (hwndHeader != 0) {		OS.MapWindowPoints (hwndParent, handle, clientRect, 2);		count = OS.SendMessage (hwndHeader, OS.HDM_GETITEMCOUNT, 0, 0);		if (count != 0) {			order = new int [count];			OS.SendMessage (hwndHeader, OS.HDM_GETORDERARRAY, count, order);		}	}	int sortIndex = -1, clrSortBk = -1;	if (OS.COMCTL32_MAJOR >= 6 && OS.IsAppThemed ()) {		if (sortColumn != null && sortDirection != SWT.NONE) {			if (findImageControl () == null) {				sortIndex = indexOf (sortColumn);				clrSortBk = getSortColumnPixel ();			}		}	}	Point size = null;	int x = 0, gridWidth = linesVisible ? GRID_WIDTH : 0;	for (int i=0; i<Math.max (1, count); i++) {		int index = order == null ? i : order [i], width = nmcd.right - nmcd.left;		if (count > 0 && hwndHeader != 0) {			HDITEM hdItem = new HDITEM ();			hdItem.mask = OS.HDI_WIDTH;			OS.SendMessage (hwndHeader, OS.HDM_GETITEM, index, hdItem);			width = hdItem.cxy;		}		if (i == 0) {			if ((style & SWT.FULL_SELECTION) != 0) {				if ((selected || findImageControl () == null) && !ignoreDrawSelection && !ignoreDrawBackground) {					boolean drawBackground = true;					RECT pClipRect = new RECT ();					OS.SetRect (pClipRect, width, nmcd.top, nmcd.right, nmcd.bottom);					if (EXPLORER_THEME) {						if (!OS.IsWinCE && OS.WIN32_VERSION >= OS.VERSION (6, 0)) {							boolean hot = (nmcd.uItemState & OS.CDIS_HOT) != 0;							if (selected || hot) {								RECT pRect = new RECT ();								OS.SetRect (pRect, nmcd.left, nmcd.top, nmcd.right, nmcd.bottom);								if (count > 0 && hwndHeader != 0) {									int totalWidth = 0;									HDITEM hdItem = new HDITEM ();									hdItem.mask = OS.HDI_WIDTH;									for (int j=0; j<count; j++) {										OS.SendMessage (hwndHeader, OS.HDM_GETITEM, j, hdItem);										totalWidth += hdItem.cxy;									}									if (totalWidth > clientRect.right - clientRect.left) {										pRect.left = 0;										pRect.right = totalWidth;									} else {										pRect.left = clientRect.left;										pRect.right = clientRect.right;									}								}								drawBackground = false;								int hTheme = OS.OpenThemeData (handle, Display.TREEVIEW);								int iStateId = selected ? OS.TREIS_SELECTED : OS.TREIS_HOT;								if (OS.GetFocus () != handle && selected && !hot) iStateId = OS.TREIS_SELECTEDNOTFOCUS;								OS.DrawThemeBackground (hTheme, hDC, OS.TVP_TREEITEM, iStateId, pRect, pClipRect);									OS.CloseThemeData (hTheme);							}						}					}					if (drawBackground) fillBackground (hDC, OS.GetBkColor (hDC), pClipRect);				}			}		}		if (x + width > clientRect.left) {			RECT rect = new RECT (), backgroundRect = null;			boolean drawItem = true, drawText = true, drawImage = true, drawBackground = false;			if (i == 0) {				drawItem = drawImage = drawText = false;				if (findImageControl () != null) {					drawItem = drawText = drawBackground = true;					rect = item.getBounds (index, true, false, false, false, true, hDC);					if (linesVisible) {						rect.right++;						rect.bottom++;					}				}				if (selected && !ignoreDrawSelection && !ignoreDrawBackground) {					fillBackground (hDC, OS.GetBkColor (hDC), rect);					drawBackground = false;				}				backgroundRect = rect;				if (hooks (SWT.EraseItem)) {					drawItem = drawText = drawImage = true;					rect = item.getBounds (index, true, true, false, false, true, hDC);					if ((style & SWT.FULL_SELECTION) != 0) {						backgroundRect = rect;					} else {						backgroundRect = item.getBounds (index, true, false, false, false, true, hDC);					}				}			} else {				selectionForeground = -1;				ignoreDrawForeground = ignoreDrawBackground = ignoreDrawSelection = false;				OS.SetRect (rect, x, nmcd.top, x + width, nmcd.bottom - gridWidth);				backgroundRect = rect;			}			int clrText = -1, clrTextBk = -1;			int hFont = item.cellFont != null ? item.cellFont [index] : -1;			if (hFont == -1) hFont = item.font;			if (selectionForeground != -1) clrText = selectionForeground;			if (OS.IsWindowEnabled (handle)) {				boolean drawForeground = false;				if (selected) {					if (i != 0 && (style & SWT.FULL_SELECTION) == 0) {						OS.SetTextColor (hDC, getForegroundPixel ());						OS.SetBkColor (hDC, getBackgroundPixel ());						drawForeground = drawBackground = true;					}				} else {					drawForeground = drawBackground = true;				}				if (drawForeground) {					clrText = item.cellForeground != null ? item.cellForeground [index] : -1;					if (clrText == -1) clrText = item.foreground;				}				if (drawBackground) {					clrTextBk = item.cellBackground != null ? item.cellBackground [index] : -1;					if (clrTextBk == -1) clrTextBk = item.background;					if (index == sortIndex) clrTextBk = clrSortBk;				}			} else {				if (index == sortIndex) {					drawBackground = true;					clrTextBk = clrSortBk;				}			}			if (drawItem) {				if (i != 0) {					if (hooks (SWT.MeasureItem)) {						RECT itemRect = item.getBounds (index, true, true, false, false, false, hDC);						int nSavedDC = OS.SaveDC (hDC);						GCData data = new GCData ();						data.device = display;						data.hFont = hFont;						GC gc = GC.win32_new (hDC, data);						Event event = new Event ();						event.item = item;						event.index = index;						event.gc = gc;						event.x = itemRect.left;						event.y = itemRect.top;						event.width = itemRect.right - itemRect.left;						event.height = itemRect.bottom - itemRect.top;						sendEvent (SWT.MeasureItem, event);						event.gc = null;						gc.dispose ();						OS.RestoreDC (hDC, nSavedDC);						if (isDisposed () || item.isDisposed ()) break;						if (event.height > getItemHeight ()) setItemHeight (event.height);					}					if (hooks (SWT.EraseItem)) {						RECT cellRect = item.getBounds (index, true, true, true, true, true, hDC);						int nSavedDC = OS.SaveDC (hDC);						GCData data = new GCData ();						data.device = display;						data.foreground = OS.GetTextColor (hDC);						data.background = OS.GetBkColor (hDC);						if (!selected || (style & SWT.FULL_SELECTION) == 0) {							if (clrText != -1) data.foreground = clrText;							if (clrTextBk != -1) data.background = clrTextBk;						}						data.hPen = OS.CreatePen (OS.PS_SOLID, 0, data.foreground);						data.hBrush = OS.CreateSolidBrush (data.background);						data.hFont = hFont;						GC gc = GC.win32_new (hDC, data);						Event event = new Event ();						event.item = item;						event.index = index;						event.gc = gc;						event.detail |= SWT.FOREGROUND;						if (clrTextBk != -1) event.detail |= SWT.BACKGROUND;						if (selected && (style & SWT.FULL_SELECTION) != 0) event.detail |= SWT.SELECTED;						if ((nmcd.uItemState & OS.CDIS_FOCUS) != 0) {							if (/*nmcd.iSubItem == 0 ||*/ (style & SWT.FULL_SELECTION) != 0) {								if (handle == OS.GetFocus ()) {									int uiState = OS.SendMessage (handle, OS.WM_QUERYUISTATE, 0, 0);									if ((uiState & OS.UISF_HIDEFOCUS) == 0) event.detail |= SWT.FOCUSED;								}							}						}						event.x = cellRect.left;						event.y = cellRect.top;						event.width = cellRect.right - cellRect.left;						event.height = cellRect.bottom - cellRect.top;						gc.setClipping (event.x, event.y, event.width, event.height);						sendEvent (SWT.EraseItem, event);						event.gc = null;						int newTextClr = OS.GetTextColor (hDC);						gc.dispose ();						OS.RestoreDC (hDC, nSavedDC);						if (isDisposed () || item.isDisposed ()) break;						if (event.doit) {							ignoreDrawForeground = (event.detail & SWT.FOREGROUND) == 0;							ignoreDrawBackground = (event.detail & SWT.BACKGROUND) == 0;							ignoreDrawSelection = (event.detail & SWT.SELECTED) == 0;						} else {							ignoreDrawForeground = ignoreDrawBackground = ignoreDrawSelection = true;						}						if ((style & SWT.FULL_SELECTION) != 0) {							if (ignoreDrawSelection) ignoreFullSelection = true;							if (!ignoreDrawSelection) {								if (!selected) {									selectionForeground = OS.GetSysColor (OS.COLOR_HIGHLIGHTTEXT);								} else {									drawBackground = true;									ignoreDrawBackground = false;									if (handle == OS.GetFocus () && OS.IsWindowEnabled (handle)) {										clrTextBk = OS.GetSysColor (OS.COLOR_HIGHLIGHT);									} else {										clrTextBk = OS.GetSysColor (OS.COLOR_3DFACE);									}									if (!ignoreFullSelection && index == count - 1) {										RECT selectionRect = new RECT ();										OS.SetRect (selectionRect, backgroundRect.left, backgroundRect.top, nmcd.right, backgroundRect.bottom);										backgroundRect = selectionRect;									}								}							} else {								if (selected) {									selectionForeground = newTextClr;									if (clrTextBk == -1 && OS.IsWindowEnabled (handle)) {										Control control = findBackgroundControl ();										if (control == null) control = this;										clrTextBk = control.getBackgroundPixel ();									}								}							}						}					}					if (selectionForeground != -1) clrText = selectionForeground;				}				if (!ignoreDrawBackground) {					if (clrTextBk != -1) {						if (drawBackground) fillBackground (hDC, clrTextBk, backgroundRect);					} else {						Control control = findImageControl ();						if (control != null) {							if (i == 0) {								int right = Math.min (rect.right, width);								OS.SetRect (rect, rect.left, rect.top, right, rect.bottom);								if (drawBackground) fillImageBackground (hDC, control, rect);								if (!ignoreDrawSelection) {									if (handle == OS.GetFocus ()) {										int uiState = OS.SendMessage (handle, OS.WM_QUERYUISTATE, 0, 0);										if ((uiState & OS.UISF_HIDEFOCUS) == 0) {											int hItem = OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_CARET, 0);											if (hItem == item.handle) {												if ((style & SWT.FULL_SELECTION) != 0) {													focusRect = new RECT ();													OS.SetRect (focusRect, nmcd.left, nmcd.top, nmcd.right, nmcd.bottom);												} else {													focusRect = item.getBounds (index, true, false, false, false, true, hDC);												}											}										}									}								}							} else {								if (drawBackground) fillImageBackground (hDC, control, rect);							}						}					}				}				if (drawImage) {					Image image = null;					if (index == 0) {						image = item.image;					} else {						Image [] images  = item.images;						if (images != null) image = images [index];					}					int inset = i != 0 ? INSET : 0;					if (image != null) {						if (index == 0) rect.left = Math.min (rect.right, rect.left + 2);						Rectangle bounds = image.getBounds ();						if (size == null) size = getImageSize ();						//int y = rect.top + (index == 0 ? (getItemHeight () - size.y) / 2 : 0);						int y = rect.top;						if (!ignoreDrawForeground) {							//TODO - share GC, clip the drawing for index == 0							GCData data = new GCData();							data.device = display;							GC gc = GC.win32_new (hDC, data);							//if (index == 0) { //must clear								//gc.setClipping (rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top);							//}							gc.drawImage (image, 0, 0, bounds.width, bounds.height, rect.left, y, size.x, size.y);							gc.dispose ();						}						OS.SetRect (rect, rect.left + size.x + INSET, rect.top, rect.right - inset, rect.bottom);					} else {						OS.SetRect (rect, rect.left + INSET, rect.top, rect.right - inset, rect.bottom);						if (i == 0 && OS.SendMessage (handle, OS.TVM_GETIMAGELIST, OS.TVSIL_NORMAL, 0) != 0) {							if (size == null) size = getImageSize ();							rect.left = Math.min (rect.left + size.x, rect.right);						}					}				}				if (drawText) {					/*					* Bug in Windows.  When DrawText() is used with DT_VCENTER					* and DT_ENDELLIPSIS, the ellipsis can draw outside of the					* rectangle when the rectangle is empty.  The fix is avoid					* all text drawing for empty rectangles.					*/					if (rect.left < rect.right) {						String string = null;						if (index == 0) {							string = item.text;							rect.left = Math.min (rect.right, rect.left + 2);						} else {							String [] strings  = item.strings;							if (strings != null) string = strings [index];						}						if (string != null) {							if (hFont != -1) hFont = OS.SelectObject (hDC, hFont);							if (clrText != -1) clrText = OS.SetTextColor (hDC, clrText);							if (clrTextBk != -1) clrTextBk = OS.SetBkColor (hDC, clrTextBk);							int flags = OS.DT_NOPREFIX | OS.DT_SINGLELINE | OS.DT_VCENTER;							if (i != 0) flags |= OS.DT_ENDELLIPSIS;							TreeColumn column = columns != null ? columns [index] : null;							if (column != null) {								if ((column.style & SWT.CENTER) != 0) flags |= OS.DT_CENTER;								if ((column.style & SWT.RIGHT) != 0) flags |= OS.DT_RIGHT;							}							TCHAR buffer = new TCHAR (getCodePage (), string, false);							if (!ignoreDrawForeground) OS.DrawText (hDC, buffer, buffer.length (), rect, flags);							OS.DrawText (hDC, buffer, buffer.length (), rect, flags | OS.DT_CALCRECT);							if (hFont != -1) hFont = OS.SelectObject (hDC, hFont);							if (clrText != -1) clrText = OS.SetTextColor (hDC, clrText);							if (clrTextBk != -1) clrTextBk = OS.SetBkColor (hDC, clrTextBk);						}					}				}			}			if (selectionForeground != -1) clrText = selectionForeground;			if (hooks (SWT.PaintItem)) {				RECT itemRect = item.getBounds (index, true, true, false, false, false, hDC);				int nSavedDC = OS.SaveDC (hDC);				GCData data = new GCData ();				data.device = display;				data.hFont = hFont;				data.foreground = OS.GetTextColor (hDC);				data.background = OS.GetBkColor (hDC);				if (selected && (style & SWT.FULL_SELECTION) != 0) {					if (selectionForeground != -1) data.foreground = selectionForeground;				} else {					if (clrText != -1) data.foreground = clrText;					if (clrTextBk != -1) data.background = clrTextBk;				}				data.hPen = OS.CreatePen (OS.PS_SOLID, 0, data.foreground);				data.hBrush = OS.CreateSolidBrush (data.background);				OS.SelectObject (hDC, data.hPen);				OS.SelectObject (hDC, data.hBrush);				GC gc = GC.win32_new (hDC, data);				Event event = new Event ();				event.item = item;				event.index = index;				event.gc = gc;				event.detail |= SWT.FOREGROUND;				if (clrTextBk != -1) event.detail |= SWT.BACKGROUND;				if (selected && (i == 0 /*nmcd.iSubItem == 0*/ || (style & SWT.FULL_SELECTION) != 0)) {					event.detail |= SWT.SELECTED;				}				if ((nmcd.uItemState & OS.CDIS_FOCUS) != 0) {					if (i == 0 /*nmcd.iSubItem == 0*/ || (style & SWT.FULL_SELECTION) != 0) {						if (handle == OS.GetFocus ()) {							int uiState = OS.SendMessage (handle, OS.WM_QUERYUISTATE, 0, 0);							if ((uiState & OS.UISF_HIDEFOCUS) == 0) event.detail |= SWT.FOCUSED;						}					}				}								event.x = itemRect.left;				event.y = itemRect.top;				event.width = itemRect.right - itemRect.left;				event.height = itemRect.bottom - itemRect.top;				RECT cellRect = item.getBounds (index, true, true, true, true, true, hDC);				int cellWidth = cellRect.right - cellRect.left;				int cellHeight = cellRect.bottom - cellRect.top;				gc.setClipping (cellRect.left, cellRect.top, cellWidth, cellHeight);				sendEvent (SWT.PaintItem, event);				event.gc = null;				gc.dispose ();				OS.RestoreDC (hDC, nSavedDC);				if (isDisposed () || item.isDisposed ()) break;			}		}		x += width;		if (x > clientRect.right) break;	}	if (linesVisible) {		if ((style & SWT.FULL_SELECTION) != 0) {			if (hwndHeader != 0) {				if (OS.SendMessage (hwndHeader, OS.HDM_GETITEMCOUNT, 0, 0) != 0) {					HDITEM hdItem = new HDITEM ();					hdItem.mask = OS.HDI_WIDTH;					OS.SendMessage (hwndHeader, OS.HDM_GETITEM, 0, hdItem);					RECT rect = new RECT ();					OS.SetRect (rect, nmcd.left + hdItem.cxy, nmcd.top, nmcd.right, nmcd.bottom);					OS.DrawEdge (hDC, rect, OS.BDR_SUNKENINNER, OS.BF_BOTTOM);				}			}		}		RECT rect = new RECT ();		OS.SetRect (rect, nmcd.left, nmcd.top, nmcd.right, nmcd.bottom);		OS.DrawEdge (hDC, rect, OS.BDR_SUNKENINNER, OS.BF_BOTTOM);	}	if (focusRect != null) OS.DrawFocusRect (hDC, focusRect);	return new LRESULT (OS.CDRF_DODEFAULT);}