- Add code for hot tracking.
- Draw hot items with underline and with highlight colour with
  TVS_TRACKSELECT style.
- Set cursor to hand cursor with TVS_TRACKSELECT style.
- Make sure uInternalStatus is consistent with actual scrollbar state
  by forcing scrollbars off in WM_CREATE handler.

diff --git a/dlls/comctl32/treeview.c b/dlls/comctl32/treeview.c
index ef6f09a..aa12715 100644
--- a/dlls/comctl32/treeview.c
+++ b/dlls/comctl32/treeview.c
@@ -31,7 +31,6 @@
  *      TVN_SETDISPINFO, TVN_SINGLEEXPAND
  *
  *   missing styles: TVS_FULLROWSELECT, TVS_INFOTIP, TVS_RTLREADING,
- *      TVS_TRACKSELECT
  *
  *   missing item styles: TVIS_CUT, TVIS_EXPANDPARTIAL
  *
@@ -132,6 +131,8 @@
   HFONT         hFont;
   HFONT         hDefaultFont;
   HFONT         hBoldFont;
+  HFONT         hUnderlineFont;
+  HCURSOR       hcurHand;
   HWND          hwndToolTip;
 
   HWND          hwndEdit;
@@ -263,10 +264,24 @@
     return CreateFontIndirectW(&font);
 }
 
+static HFONT
+TREEVIEW_CreateUnderlineFont(HFONT hOrigFont)
+{
+    LOGFONTW font;
+
+    GetObjectW(hOrigFont, sizeof(font), &font);
+    font.lfUnderline = TRUE;
+    return CreateFontIndirectW(&font);
+}
+
 static inline HFONT
 TREEVIEW_FontForItem(TREEVIEW_INFO *infoPtr, TREEVIEW_ITEM *item)
 {
-    return (item->state & TVIS_BOLD) ? infoPtr->hBoldFont : infoPtr->hFont;
+    if ((infoPtr->dwStyle & TVS_TRACKSELECT) && (item == infoPtr->hotItem))
+        return infoPtr->hUnderlineFont;
+    if (item->state & TVIS_BOLD)
+        return infoPtr->hBoldFont;
+    return infoPtr->hFont;
 }
 
 /* for trace/debugging purposes only */
@@ -1814,6 +1829,7 @@
 
     DeleteObject(infoPtr->hBoldFont);
     infoPtr->hBoldFont = TREEVIEW_CreateBoldFont(infoPtr->hFont);
+    infoPtr->hUnderlineFont = TREEVIEW_CreateUnderlineFont(infoPtr->hFont);
 
     if (!infoPtr->bHeightSet)
 	infoPtr->uItemHeight = TREEVIEW_NaturalHeight(infoPtr);
@@ -2486,7 +2502,9 @@
 	    }
 	    else
 	    {
-		if (infoPtr->clrText == -1)
+		if (wineItem == infoPtr->hotItem)
+		    oldTextColor = SetTextColor(hdc, comctl32_color.clrHighlight);
+		else if (infoPtr->clrText == -1)
 		    oldTextColor =
 			SetTextColor(hdc, GetSysColor(COLOR_WINDOWTEXT));
 		else
@@ -4701,7 +4719,6 @@
 
     infoPtr->hwnd = hwnd;
     infoPtr->dwStyle = GetWindowLongW(hwnd, GWL_STYLE);
-    infoPtr->uInternalStatus = 0;
     infoPtr->Timer = 0;
     infoPtr->uNumItems = 0;
     infoPtr->cdmode = 0;
@@ -4713,6 +4730,7 @@
     /* No scroll bars yet. */
     infoPtr->clientWidth = rcClient.right;
     infoPtr->clientHeight = rcClient.bottom;
+    infoPtr->uInternalStatus = 0;
 
     infoPtr->treeWidth = 0;
     infoPtr->treeHeight = 0;
@@ -4754,6 +4772,8 @@
     SystemParametersInfoW(SPI_GETICONTITLELOGFONT, sizeof(lf), &lf, 0);
     infoPtr->hFont = infoPtr->hDefaultFont = CreateFontIndirectW(&lf);
     infoPtr->hBoldFont = TREEVIEW_CreateBoldFont(infoPtr->hFont);
+    infoPtr->hUnderlineFont = TREEVIEW_CreateUnderlineFont(infoPtr->hFont);
+    infoPtr->hcurHand = LoadCursorW(NULL, (LPWSTR)IDC_HAND);
 
     infoPtr->uItemHeight = TREEVIEW_NaturalHeight(infoPtr);
 
@@ -4821,6 +4841,11 @@
 	infoPtr->stateImageWidth = 16;
 	infoPtr->stateImageHeight = 16;
     }
+
+    /* Make sure actual scrollbar state is consistent with uInternalStatus */
+    ShowScrollBar(hwnd, SB_VERT, FALSE);
+    ShowScrollBar(hwnd, SB_HORZ, FALSE);
+
     return 0;
 }
 
@@ -4844,6 +4869,7 @@
 
     DeleteObject(infoPtr->hDefaultFont);
     DeleteObject(infoPtr->hBoldFont);
+    DeleteObject(infoPtr->hUnderlineFont);
     Free(infoPtr);
 
     return 0;
@@ -5012,6 +5038,63 @@
 }
 
 static LRESULT
+TREEVIEW_MouseLeave (TREEVIEW_INFO * infoPtr)
+{
+    if (infoPtr->hotItem)
+    {
+        /* remove hot effect from item */
+        InvalidateRect(infoPtr->hwnd, &infoPtr->hotItem->rect, TRUE);
+        infoPtr->hotItem = NULL;
+    }
+    return 0;
+}
+
+static LRESULT
+TREEVIEW_MouseMove (TREEVIEW_INFO * infoPtr, WPARAM wParam, LPARAM lParam)
+{
+    POINT pt;
+    TRACKMOUSEEVENT trackinfo;
+    TREEVIEW_ITEM * item;
+
+    /* fill in the TRACKMOUSEEVENT struct */
+    trackinfo.cbSize = sizeof(TRACKMOUSEEVENT);
+    trackinfo.dwFlags = TME_QUERY;
+    trackinfo.hwndTrack = infoPtr->hwnd;
+    trackinfo.dwHoverTime = HOVER_DEFAULT;
+
+    /* call _TrackMouseEvent to see if we are currently tracking for this hwnd */
+    _TrackMouseEvent(&trackinfo);
+
+    /* Make sure tracking is enabled so we receive a WM_MOUSELEAVE message */
+    if(!(trackinfo.dwFlags & TME_LEAVE))
+    {
+        trackinfo.dwFlags = TME_LEAVE; /* notify upon leaving */
+
+        /* call TRACKMOUSEEVENT so we receive a WM_MOUSELEAVE message */
+        /* and can properly deactivate the hot item */
+        _TrackMouseEvent(&trackinfo);
+    }
+
+    pt.x = (INT)LOWORD(lParam);
+    pt.y = (INT)HIWORD(lParam);
+
+    item = TREEVIEW_HitTestPoint(infoPtr, pt);
+
+    if (item != infoPtr->hotItem)
+    {
+        /* redraw old hot item */
+        if (infoPtr->hotItem)
+            InvalidateRect(infoPtr->hwnd, &infoPtr->hotItem->rect, TRUE);
+        infoPtr->hotItem = item;
+        /* redraw new hot item */
+        if (infoPtr->hotItem)
+            InvalidateRect(infoPtr->hwnd, &infoPtr->hotItem->rect, TRUE);
+    }
+
+    return 0;
+}
+
+static LRESULT
 TREEVIEW_Notify(TREEVIEW_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
 {
     LPNMHDR lpnmh = (LPNMHDR)lParam;
@@ -5108,6 +5191,28 @@
 }
 
 static LRESULT
+TREEVIEW_SetCursor(TREEVIEW_INFO *infoPtr, WPARAM wParam, LPARAM lParam)
+{
+    POINT pt;
+    TREEVIEW_ITEM * item;
+
+    GetCursorPos(&pt);
+    ScreenToClient(infoPtr->hwnd, &pt);
+
+    item = TREEVIEW_HitTestPoint(infoPtr, pt);
+
+    /* FIXME: send NM_SETCURSOR */
+
+    if (item && (infoPtr->dwStyle & TVS_TRACKSELECT))
+    {
+        SetCursor(infoPtr->hcurHand);
+        return 0;
+    }
+    else
+        return DefWindowProcW(infoPtr->hwnd, WM_SETCURSOR, wParam, lParam);
+}
+
+static LRESULT
 TREEVIEW_SetFocus(TREEVIEW_INFO *infoPtr)
 {
     TRACE("\n");
@@ -5329,7 +5434,11 @@
 
 	/* WM_MBUTTONDOWN */
 
-	/* WM_MOUSEMOVE */
+    case WM_MOUSELEAVE:
+	return TREEVIEW_MouseLeave(infoPtr);
+
+    case WM_MOUSEMOVE:
+	return TREEVIEW_MouseMove(infoPtr, wParam, lParam);
 
     case WM_NOTIFY:
 	return TREEVIEW_Notify(infoPtr, wParam, lParam);
@@ -5345,6 +5454,9 @@
     case WM_RBUTTONDOWN:
 	return TREEVIEW_RButtonDown(infoPtr, lParam);
 
+    case WM_SETCURSOR:
+	return TREEVIEW_SetCursor(infoPtr, wParam, lParam);
+
     case WM_SETFOCUS:
 	return TREEVIEW_SetFocus(infoPtr);