if ((tvItem.state & OS.TVIS_SELECTED) == 0) {
if ((tvItem.state & OS.TVIS_SELECTED) == 0 && (tvItem.state & OS.TVIS_DROPHILITED) == 0) {
LRESULT wmNotifyChild (int wParam, int lParam) {	NMHDR hdr = new NMHDR ();	OS.MoveMemory (hdr, lParam, NMHDR.sizeof);	int code = hdr.code;	switch (code) {		case OS.NM_CUSTOMDRAW: {			if (!customDraw) break;			NMTVCUSTOMDRAW nmcd = new NMTVCUSTOMDRAW ();			OS.MoveMemory (nmcd, lParam, NMTVCUSTOMDRAW.sizeof);					switch (nmcd.dwDrawStage) {				case OS.CDDS_PREPAINT: return new LRESULT (OS.CDRF_NOTIFYITEMDRAW);				case OS.CDDS_ITEMPREPAINT:					/*					* Feature on 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,					*/					TreeItem item = items [nmcd.lItemlParam];					if (item == null) break;					TVITEM tvItem = new TVITEM ();					tvItem.mask = OS.TVIF_STATE;					tvItem.hItem = item.handle;					OS.SendMessage (handle, OS.TVM_GETITEM, 0, tvItem);					int hFont = item.font, clrText = item.foreground, clrTextBk = item.background;					if (hFont == -1 && clrText == -1 && clrTextBk == -1) break;					if (hFont != -1) OS.SelectObject (nmcd.hdc, hFont);					if ((tvItem.state & OS.TVIS_SELECTED) == 0) {						nmcd.clrText = clrText == -1 ? getForegroundPixel () : clrText;						nmcd.clrTextBk = clrTextBk == -1 ? getBackgroundPixel () : clrTextBk;					}					OS.MoveMemory (lParam, nmcd, NMTVCUSTOMDRAW.sizeof);					return new LRESULT (OS.CDRF_NEWFONT);			}			break;		}		case OS.NM_DBLCLK:			int pos = OS.GetMessagePos ();			POINT pt = new POINT ();			pt.x = (short) (pos & 0xFFFF);			pt.y = (short) (pos >> 16);			OS.ScreenToClient (handle, pt);			TVHITTESTINFO lpht = new TVHITTESTINFO ();			lpht.x = pt.x;			lpht.y = pt.y;			OS.SendMessage (handle, OS.TVM_HITTEST, 0, lpht);			if ((lpht.flags & OS.TVHT_ONITEM) == 0) break;			// FALL THROUGH		case OS.TVN_SELCHANGEDA:		case OS.TVN_SELCHANGEDW:			if (!ignoreSelect) {				TVITEM tvItem = null;				if (code == OS.TVN_SELCHANGED) {					tvItem = new TVITEM ();					int offset = NMHDR.sizeof + 4 + TVITEM.sizeof;					OS.MoveMemory (tvItem, lParam + offset, TVITEM.sizeof);					hAnchor = tvItem.hItem;				} else {					int hItem = OS.SendMessage (handle, OS.TVM_GETNEXTITEM, OS.TVGN_CARET, 0);					if (hItem != 0) {						tvItem = new TVITEM ();						tvItem.hItem = hItem;						tvItem.mask = OS.TVIF_PARAM;						OS.SendMessage (handle, OS.TVM_GETITEM, 0, tvItem);					}				}				Event event = new Event ();				if (tvItem != null) {					event.item = items [tvItem.lParam];				}				if (code == OS.TVN_SELCHANGED) {					postEvent (SWT.Selection, event);				} else {					postEvent (SWT.DefaultSelection, event);				}			}			if (code == OS.NM_DBLCLK && hooks (SWT.DefaultSelection)) {				return LRESULT.ONE;			}			break;		case OS.TVN_SELCHANGINGA:		case OS.TVN_SELCHANGINGW:			if (!ignoreSelect && !ignoreDeselect) {				hAnchor = 0;				if ((style & SWT.MULTI) != 0) deselectAll ();			}			break;		case OS.TVN_ITEMEXPANDINGA:		case OS.TVN_ITEMEXPANDINGW:			if (!ignoreExpand) {				TVITEM tvItem = new TVITEM ();				int offset = NMHDR.sizeof + 4 + TVITEM.sizeof;				OS.MoveMemory (tvItem, lParam + offset, TVITEM.sizeof);				int [] action = new int [1];				OS.MoveMemory (action, lParam + NMHDR.sizeof, 4);				/*				* Feature on Windows.  In some cases, TVM_ITEMEXPANDING				* is sent from within TVM_DELETEITEM for the tree item				* being destroyed.  By the time the message is sent,				* the item has already been removed from the list of				* items.  The fix is to check for null. 				*/				TreeItem item = items [tvItem.lParam];				if (item == null) break;				Event event = new Event ();				event.item = item;				/*				* It is possible (but unlikely), that application				* code could have disposed the widget in the expand				* or collapse event.  If this happens, end the				* processing of the Windows message by returning				* zero as the result of the window proc.				*/				if (action [0] == OS.TVE_EXPAND) {					sendEvent (SWT.Expand, event);					if (isDisposed ()) return LRESULT.ZERO;				}				if (action [0] == OS.TVE_COLLAPSE) {					sendEvent (SWT.Collapse, event);					if (isDisposed ()) return LRESULT.ZERO;				}			}			break;		case OS.TVN_BEGINDRAGA:		case OS.TVN_BEGINDRAGW:		case OS.TVN_BEGINRDRAGA:		case OS.TVN_BEGINRDRAGW:			TVITEM tvItem = new TVITEM ();			int offset = NMHDR.sizeof + 4 + TVITEM.sizeof;			OS.MoveMemory (tvItem, lParam + offset, TVITEM.sizeof);			if (tvItem.hItem != 0 && (tvItem.state & OS.TVIS_SELECTED) == 0) {				ignoreSelect = ignoreDeselect = true;				OS.SendMessage (handle, OS.TVM_SELECTITEM, OS.TVGN_CARET, tvItem.hItem);				ignoreSelect = ignoreDeselect = false;			}			dragStarted = true;			break;		case OS.NM_RECOGNIZEGESTURE:			/* 			* Feature on Pocket PC.  The tree and table controls detect the tap			* and hold gesture by default. They send a GN_CONTEXTMENU message to show			* the popup menu.  This default behaviour is unwanted on Pocket PC 2002			* when no menu has been set, as it still draws a red circle.  The fix			* is to disable this default behaviour when no menu is set by returning			* TRUE when receiving the Pocket PC 2002 specific NM_RECOGNIZEGESTURE			* message.			*/			if (OS.IsPPC) {				boolean hasMenu = menu != null && !menu.isDisposed ();				if (!hasMenu && !hooks (SWT.MenuDetect)) return LRESULT.ONE;			}			break;		case OS.GN_CONTEXTMENU:			if (OS.IsPPC) {				boolean hasMenu = menu != null && !menu.isDisposed ();				if (hasMenu || hooks (SWT.MenuDetect)) {					NMRGINFO nmrg = new NMRGINFO ();					OS.MoveMemory (nmrg, lParam, NMRGINFO.sizeof);					showMenu (nmrg.x, nmrg.y);					gestureCompleted = true;					return LRESULT.ONE;				}			}			break;	}	return super.wmNotifyChild (wParam, lParam);}