- 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);