53 static PVOID ComCtl32Handle;
54 static LONG SmallIconWidth;
55 static LONG SmallIconHeight;
61 WNDCLASSEX c = {
sizeof(c) };
63 c.style = CS_DBLCLKS | CS_GLOBALCLASS;
66 c.cbWndExtra =
sizeof(PVOID);
69 c.hCursor = LoadCursor(NULL, IDC_ARROW);
70 c.hbrBackground = NULL;
71 c.lpszMenuName = NULL;
75 if (!RegisterClassEx(&c))
78 ComCtl32Handle = GetModuleHandle(L
"comctl32.dll");
79 SmallIconWidth = GetSystemMetrics(SM_CXSMICON);
80 SmallIconHeight = GetSystemMetrics(SM_CYSMICON);
96 if (uMsg == WM_CREATE)
99 SetWindowLongPtr(hwnd, 0, (LONG_PTR)context);
103 return DefWindowProc(hwnd, uMsg, wParam, lParam);
105 if (context->
Tracking && (GetAsyncKeyState(VK_ESCAPE) & 0x1))
125 SetWindowLongPtr(hwnd, 0, (LONG_PTR)NULL);
152 return (LRESULT)context->
Font;
158 case WM_STYLECHANGED:
163 case WM_SETTINGCHANGE:
168 case WM_THEMECHANGED:
201 PhTnpOnMouseMove(hwnd, context, (ULONG)wParam, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
214 case WM_LBUTTONDBLCLK:
217 case WM_RBUTTONDBLCLK:
220 case WM_MBUTTONDBLCLK:
223 PhTnpOnXxxButtonXxx(hwnd, context, uMsg, (ULONG)wParam, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
226 case WM_CAPTURECHANGED:
240 PhTnpOnChar(hwnd, context, (ULONG)wParam, (ULONG)lParam);
245 PhTnpOnMouseWheel(hwnd, context, (SHORT)HIWORD(wParam), LOWORD(wParam), GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
250 PhTnpOnMouseHWheel(hwnd, context, (SHORT)HIWORD(wParam), LOWORD(wParam), GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
298 message.message = uMsg;
299 message.wParam = wParam;
300 message.lParam = lParam;
301 SendMessage(context->
TooltipsHandle, TTM_RELAYEVENT, 0, (LPARAM)&message);
307 return DefWindowProc(hwnd, uMsg, wParam, lParam);
313 _In_opt_ PVOID Parameter1,
314 _In_opt_ PVOID Parameter2,
315 _In_opt_ PVOID Context
349 if (Context->Columns)
351 for (i = 0; i < Context->NextId; i++)
353 if (Context->Columns[i])
354 PhFree(Context->Columns[i]);
360 if (Context->ColumnsByDisplay)
361 PhFree(Context->ColumnsByDisplay);
365 if (Context->FontOwned)
366 DeleteObject(Context->Font);
368 if (Context->ThemeData)
371 if (Context->SearchString)
372 PhFree(Context->SearchString);
374 if (Context->TooltipText)
377 if (Context->BufferedContext)
380 if (Context->SuspendUpdateRegion)
381 DeleteObject(Context->SuspendUpdateRegion);
389 _In_ CREATESTRUCT *CreateStruct
394 Context->Handle = hwnd;
395 Context->InstanceHandle = CreateStruct->hInstance;
396 Context->Style = CreateStruct->style;
397 Context->ExtendedStyle = CreateStruct->dwExStyle;
400 Context->DoubleBuffered =
TRUE;
402 Context->AnimateDivider =
TRUE;
404 headerStyle = HDS_HORZ | HDS_FULLDRAG;
407 headerStyle |= HDS_BUTTONS;
409 headerStyle |= WS_VISIBLE;
411 if (!(Context->FixedHeaderHandle = CreateWindow(
414 WS_CHILD | WS_CLIPSIBLINGS | headerStyle,
421 CreateStruct->hInstance,
429 headerStyle |= HDS_DRAGDROP;
431 if (!(Context->HeaderHandle = CreateWindow(
434 WS_CHILD | WS_CLIPSIBLINGS | headerStyle,
441 CreateStruct->hInstance,
448 if (!(Context->VScrollHandle = CreateWindow(
451 WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | SBS_VERT,
458 CreateStruct->hInstance,
465 if (!(Context->HScrollHandle = CreateWindow(
468 WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | SBS_HORZ,
475 CreateStruct->hInstance,
482 if (!(Context->FillerBoxHandle = CreateWindow(
485 WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE,
492 CreateStruct->hInstance,
511 GetClientRect(hwnd, &Context->ClientRect);
513 if (Context->BufferedContext && (
514 Context->BufferedContextRect.right < Context->ClientRect.right ||
515 Context->BufferedContextRect.bottom < Context->ClientRect.bottom))
523 if (Context->TooltipsHandle)
527 memset(&toolInfo, 0,
sizeof(TOOLINFO));
528 toolInfo.cbSize =
sizeof(TOOLINFO);
529 toolInfo.hwnd = hwnd;
531 toolInfo.rect = Context->ClientRect;
532 SendMessage(Context->TooltipsHandle, TTM_NEWTOOLRECT, 0, (LPARAM)&toolInfo);
551 _In_ STYLESTRUCT *StyleStruct
554 if (Type == GWL_EXSTYLE)
555 Context->ExtendedStyle = StyleStruct->styleNew;
579 _In_ ULONG VirtualKey,
580 _In_opt_ PMSG Message
585 if (Context->Callback(hwnd,
TreeNewGetDialogCode, UlongToPtr(VirtualKey), &code, Context->CallbackContext))
590 return DLGC_WANTARROWS | DLGC_WANTCHARS;
600 PAINTSTRUCT paintStruct;
602 if (GetUpdateRect(hwnd, &updateRect,
FALSE) && (updateRect.left | updateRect.right | updateRect.top | updateRect.bottom))
604 if (Context->EnableRedraw <= 0)
608 updateRegion = CreateRectRgn(0, 0, 0, 0);
609 GetUpdateRgn(hwnd, updateRegion,
FALSE);
611 if (!Context->SuspendUpdateRegion)
613 Context->SuspendUpdateRegion = updateRegion;
617 CombineRgn(Context->SuspendUpdateRegion, Context->SuspendUpdateRegion, updateRegion, RGN_OR);
618 DeleteObject(updateRegion);
622 if (BeginPaint(hwnd, &paintStruct))
623 EndPaint(hwnd, &paintStruct);
628 if (Context->DoubleBuffered)
630 if (!Context->BufferedContext)
636 if (hdc = BeginPaint(hwnd, &paintStruct))
638 updateRect = paintStruct.rcPaint;
640 if (Context->BufferedContext)
642 PhTnpPaint(hwnd, Context, Context->BufferedContext, &updateRect);
647 updateRect.right - updateRect.left,
648 updateRect.bottom - updateRect.top,
649 Context->BufferedContext,
660 EndPaint(hwnd, &paintStruct);
672 PhTnpPaint(hwnd, Context, hdc, &Context->ClientRect);
678 _In_opt_ HRGN UpdateRegion
684 if ((Context->ExtendedStyle & WS_EX_CLIENTEDGE) && Context->ThemeData)
694 flags = DCX_WINDOW | DCX_LOCKWINDOWUPDATE | 0x10000;
697 flags |= DCX_INTERSECTRGN | 0x40000;
699 if (hdc = GetDCEx(hwnd, UpdateRegion, flags))
702 ReleaseDC(hwnd, hdc);
713 _In_ HWND CursorWindowHandle
722 if (!Context->DividerCursor)
723 Context->DividerCursor = LoadCursor(ComCtl32Handle, MAKEINTRESOURCE(106));
725 SetCursor(Context->DividerCursor);
731 SetCursor(Context->Cursor);
748 dividerRect.left = Context->FixedWidth;
749 dividerRect.top = Context->HeaderHeight;
750 dividerRect.right = Context->FixedWidth + 1;
751 dividerRect.bottom = Context->ClientRect.bottom;
753 if (Context->AnimateDividerFadingIn)
757 if (Context->DividerHot >= 100)
759 Context->DividerHot = 100;
760 Context->AnimateDividerFadingIn =
FALSE;
764 InvalidateRect(hwnd, ÷rRect,
FALSE);
766 else if (Context->AnimateDividerFadingOut)
770 Context->DividerHot = 0;
771 Context->AnimateDividerFadingOut =
FALSE;
779 InvalidateRect(hwnd, ÷rRect,
FALSE);
787 _In_ ULONG VirtualKeys,
792 TRACKMOUSEEVENT trackMouseEvent;
794 trackMouseEvent.cbSize =
sizeof(TRACKMOUSEEVENT);
795 trackMouseEvent.dwFlags = TME_LEAVE;
796 trackMouseEvent.hwndTrack = hwnd;
797 trackMouseEvent.dwHoverTime = 0;
798 TrackMouseEvent(&trackMouseEvent);
800 if (Context->Tracking)
804 newFixedWidth = Context->TrackOldFixedWidth + (CursorX - Context->TrackStartX);
818 if (Context->HotNodeIndex != -1 && Context->ThemeData)
823 InvalidateRect(Context->Handle, &rect,
FALSE);
827 Context->HotNodeIndex = -1;
829 if (Context->AnimateDivider && Context->FixedDividerVisible)
831 if ((Context->DividerHot != 0 || Context->AnimateDividerFadingIn) && !Context->AnimateDividerFadingOut)
834 Context->AnimateDividerFadingOut =
TRUE;
835 Context->AnimateDividerFadingIn =
FALSE;
845 _In_ ULONG VirtualKeys,
850 BOOLEAN startingTracking;
861 if (Message == WM_LBUTTONDOWN || Message == WM_RBUTTONDOWN)
866 startingTracking =
FALSE;
874 startingTracking =
TRUE;
875 Context->Tracking =
TRUE;
876 Context->TrackStartX = CursorX;
877 Context->TrackOldFixedWidth = Context->FixedWidth;
881 GetAsyncKeyState(VK_ESCAPE);
887 if (Context->Tracking)
895 if (Context->Tracking)
903 if (!startingTracking && Context->Tracking)
906 hitTest.
Point.x = CursorX;
907 hitTest.
Point.y = CursorY;
911 controlKey = VirtualKeys & MK_CONTROL;
912 shiftKey = VirtualKeys & MK_SHIFT;
929 allowDragSelect =
TRUE;
933 allowDragSelect =
FALSE;
934 Context->FocusNode = hitTest.
Node;
947 allowDragSelect =
TRUE;
950 allowDragSelect =
FALSE;
955 allowDragSelect =
FALSE;
968 BOOLEAN selectionProcessed;
969 BOOLEAN showContextMenu;
973 selectionProcessed =
FALSE;
974 showContextMenu =
FALSE;
981 ULONG cancelledByMessage;
1001 if (saveIndex == -1)
1002 hitTest.
Node = NULL;
1003 else if (saveIndex < Context->FlatList->Count)
1004 hitTest.
Node = Context->FlatList->Items[saveIndex];
1024 if ((Message == WM_LBUTTONDOWN && cancelledByMessage == WM_LBUTTONUP) ||
1025 (Message == WM_RBUTTONDOWN && cancelledByMessage == WM_RBUTTONUP))
1032 selectionProcessed =
TRUE;
1040 if (point.x == CursorX && point.y == CursorY)
1053 if (Message == WM_RBUTTONDOWN)
1054 showContextMenu =
TRUE;
1059 if (!selectionProcessed && !controlKey && !shiftKey)
1067 InvalidateRect(hwnd, &rect,
FALSE);
1076 if (showContextMenu)
1078 SendMessage(Context->Handle, WM_CONTEXTMENU, (WPARAM)Context->Handle, GetMessagePos());
1092 if (Message == WM_LBUTTONDOWN || Message == WM_RBUTTONDOWN)
1094 if (Context->MouseDownLast != 0 && Context->MouseDownLast != Message)
1099 if (Context->MouseDownLast == WM_LBUTTONDOWN)
1105 Context->MouseDownLast = Message;
1106 Context->MouseDownLocation.x = CursorX;
1107 Context->MouseDownLocation.y = CursorY;
1109 else if (Message == WM_LBUTTONUP || Message == WM_RBUTTONUP)
1111 if (Context->MouseDownLast != 0 &&
1112 Context->MouseDownLocation.x == CursorX && Context->MouseDownLocation.y == CursorY)
1114 if (Context->MouseDownLast == WM_LBUTTONDOWN)
1120 Context->MouseDownLast = 0;
1122 else if (Message == WM_LBUTTONDBLCLK)
1126 else if (Message == WM_RBUTTONDBLCLK)
1142 Context->Tracking =
FALSE;
1149 _In_ ULONG VirtualKey,
1157 keyEvent.
Data = Data;
1158 Context->Callback(Context->Handle,
TreeNewKeyDown, &keyEvent, NULL, Context->CallbackContext);
1172 _In_ ULONG Character,
1177 if (Character >=
' ' && Character <=
'~')
1187 _In_ ULONG VirtualKeys,
1194 if (Context->VScrollVisible)
1198 else if (Context->HScrollVisible)
1208 _In_ ULONG VirtualKeys,
1219 _In_
LONG CursorScreenX,
1220 _In_
LONG CursorScreenY
1224 BOOLEAN keyboardInvoked;
1228 if (CursorScreenX == -1 && CursorScreenY == -1)
1235 keyboardInvoked =
TRUE;
1242 for (i = 0; i < Context->FlatList->Count; i++)
1252 rect.top >= Context->ClientRect.top && rect.top < Context->ClientRect.bottom)
1254 clientPoint.x = rect.left + SmallIconWidth / 2;
1255 clientPoint.y = rect.top + Context->RowHeight / 2;
1263 GetWindowRect(hwnd, &windowRect);
1264 CursorScreenX = windowRect.left + clientPoint.x;
1265 CursorScreenY = windowRect.top + clientPoint.y;
1269 keyboardInvoked =
FALSE;
1271 clientPoint.x = CursorScreenX;
1272 clientPoint.y = CursorScreenY;
1273 ScreenToClient(hwnd, &clientPoint);
1275 if (clientPoint.y < Context->HeaderHeight)
1282 hitTest.
Point = clientPoint;
1286 contextMenu.
Location.x = CursorScreenX;
1287 contextMenu.
Location.y = CursorScreenY;
1292 Context->Callback(hwnd,
TreeNewContextMenu, &contextMenu, NULL, Context->CallbackContext);
1299 _In_ USHORT Position
1302 SCROLLINFO scrollInfo;
1305 scrollInfo.cbSize =
sizeof(SCROLLINFO);
1306 scrollInfo.fMask = SIF_ALL;
1307 GetScrollInfo(Context->VScrollHandle, SB_CTL, &scrollInfo);
1308 oldPosition = scrollInfo.nPos;
1319 scrollInfo.nPos -= scrollInfo.nPage;
1322 scrollInfo.nPos += scrollInfo.nPage;
1324 case SB_THUMBPOSITION:
1327 if (Context->FlatList->Count <= 0xffff)
1328 scrollInfo.nPos = Position;
1331 scrollInfo.nPos = scrollInfo.nTrackPos;
1334 scrollInfo.nPos = 0;
1337 scrollInfo.nPos = MAXINT;
1341 scrollInfo.fMask = SIF_POS;
1342 SetScrollInfo(Context->VScrollHandle, SB_CTL, &scrollInfo,
TRUE);
1343 GetScrollInfo(Context->VScrollHandle, SB_CTL, &scrollInfo);
1345 if (scrollInfo.nPos != oldPosition)
1347 Context->VScrollPosition = scrollInfo.nPos;
1356 _In_ USHORT Position
1359 SCROLLINFO scrollInfo;
1362 scrollInfo.cbSize =
sizeof(SCROLLINFO);
1363 scrollInfo.fMask = SIF_ALL;
1364 GetScrollInfo(Context->HScrollHandle, SB_CTL, &scrollInfo);
1365 oldPosition = scrollInfo.nPos;
1370 scrollInfo.nPos -= Context->TextMetrics.tmAveCharWidth;
1373 scrollInfo.nPos += Context->TextMetrics.tmAveCharWidth;
1376 scrollInfo.nPos -= scrollInfo.nPage;
1379 scrollInfo.nPos += scrollInfo.nPage;
1381 case SB_THUMBPOSITION:
1384 if (Context->FlatList->Count <= 0xffff)
1385 scrollInfo.nPos = Position;
1388 scrollInfo.nPos = scrollInfo.nTrackPos;
1391 scrollInfo.nPos = 0;
1394 scrollInfo.nPos = MAXINT;
1398 scrollInfo.fMask = SIF_POS;
1399 SetScrollInfo(Context->HScrollHandle, SB_CTL, &scrollInfo,
TRUE);
1400 GetScrollInfo(Context->HScrollHandle, SB_CTL, &scrollInfo);
1402 if (scrollInfo.nPos != oldPosition)
1404 Context->HScrollPosition = scrollInfo.nPos;
1413 _Out_ LRESULT *Result
1416 switch (Header->code)
1418 case HDN_ITEMCHANGING:
1419 case HDN_ITEMCHANGED:
1421 NMHEADER *nmHeader = (NMHEADER *)Header;
1423 if (Header->code == HDN_ITEMCHANGING && Header->hwndFrom == Context->FixedHeaderHandle)
1425 if (nmHeader->pitem->mask & HDI_WIDTH)
1427 if (Context->FixedColumnVisible)
1429 Context->FixedWidth = nmHeader->pitem->cxy - 1;
1431 if (Context->FixedWidth < Context->FixedWidthMinimum)
1432 Context->FixedWidth = Context->FixedWidthMinimum;
1434 Context->NormalLeft = Context->FixedWidth + 1;
1435 nmHeader->pitem->cxy = Context->FixedWidth + 1;
1439 Context->FixedWidth = 0;
1440 Context->NormalLeft = 0;
1445 if (Header->hwndFrom == Context->FixedHeaderHandle || Header->hwndFrom == Context->HeaderHandle)
1447 if (nmHeader->pitem->mask & HDI_WIDTH)
1453 if (Header->code == HDN_ITEMCHANGING)
1457 item.mask = HDI_WIDTH | HDI_LPARAM;
1459 if (Header_GetItem(Header->hwndFrom, nmHeader->iItem, &item))
1462 Context->OldColumnWidth = item.cxy;
1466 Context->ResizingColumn = NULL;
1467 Context->OldColumnWidth = -1;
1470 else if (Header->code == HDN_ITEMCHANGED)
1472 if (Context->ResizingColumn)
1476 delta = nmHeader->pitem->cxy - Context->OldColumnWidth;
1481 Context->Callback(Context->Handle,
TreeNewColumnResized, Context->ResizingColumn, NULL, Context->CallbackContext);
1484 Context->ResizingColumn = NULL;
1487 if (Context->FlatList->Count == 0 && Context->EmptyText.Length != 0)
1488 InvalidateRect(Context->Handle, NULL,
FALSE);
1493 InvalidateRect(Context->Handle, NULL,
FALSE);
1502 if ((Header->hwndFrom == Context->FixedHeaderHandle || Header->hwndFrom == Context->HeaderHandle) &&
1505 NMHEADER *nmHeader = (NMHEADER *)Header;
1511 item.mask = HDI_LPARAM;
1513 if (Header_GetItem(Header->hwndFrom, nmHeader->iItem, &item))
1522 case NM_RELEASEDCAPTURE:
1524 if (Header->hwndFrom == Context->HeaderHandle)
1531 InvalidateRect(Context->Handle, NULL,
FALSE);
1535 case HDN_DIVIDERDBLCLICK:
1537 if (Header->hwndFrom == Context->FixedHeaderHandle || Header->hwndFrom == Context->HeaderHandle)
1539 NMHEADER *nmHeader = (NMHEADER *)Header;
1542 if (Context->SuspendUpdateStructure)
1545 item.mask = HDI_LPARAM;
1547 if (Header_GetItem(Header->hwndFrom, nmHeader->iItem, &item))
1561 if (Header->hwndFrom == Context->FixedHeaderHandle || Header->hwndFrom == Context->HeaderHandle)
1566 position = GetMessagePos();
1571 ScreenToClient(hwnd, &mouseEvent.
Location);
1579 case TTN_GETDISPINFO:
1581 if (Header->hwndFrom == Context->TooltipsHandle)
1583 NMTTDISPINFO *info = (NMTTDISPINFO *)Header;
1593 if (Header->hwndFrom == Context->TooltipsHandle)
1602 if (Header->hwndFrom == Context->TooltipsHandle)
1617 _In_ ULONG_PTR WParam,
1618 _In_ ULONG_PTR LParam
1626 Context->CallbackContext = (PVOID)WParam;
1628 if (!Context->Callback)
1634 if (Context->EnableRedraw <= 0)
1636 Context->SuspendUpdateStructure =
TRUE;
1637 Context->SuspendUpdateLayout =
TRUE;
1638 InvalidateRect(Context->Handle, NULL,
FALSE);
1644 InvalidateRect(Context->Handle, NULL,
FALSE);
1662 ULONG count = (ULONG)WParam;
1663 PULONG order = (PULONG)LParam;
1666 if (count != Context->NumberOfColumnsByDisplay)
1669 for (i = 0; i < count; i++)
1671 order[i] = Context->ColumnsByDisplay[i]->Id;
1677 ULONG count = (ULONG)WParam;
1678 PULONG order = (PULONG)LParam;
1683 newOrder = PhAllocate(count *
sizeof(ULONG));
1685 for (i = 0; i < count; i++)
1696 if (!Header_SetOrderArray(Context->HeaderHandle, count, newOrder))
1710 Context->Cursor = (HCURSOR)LParam;
1715 PULONG sortColumn = (PULONG)WParam;
1719 *sortColumn = Context->SortColumn;
1721 *sortOrder = Context->SortOrder;
1726 ULONG sortColumn = (ULONG)WParam;
1741 Context->SortColumn = sortColumn;
1742 Context->SortOrder = sortOrder;
1746 Context->Callback(Context->Handle,
TreeNewSortChanged, NULL, NULL, Context->CallbackContext);
1750 Context->TriState = !!WParam;
1758 return (LRESULT)Context->FlatList->Count;
1761 ULONG index = (ULONG)WParam;
1763 if (index >= Context->FlatList->Count)
1764 return (LRESULT)NULL;
1766 return (LRESULT)Context->FlatList->Items[index];
1785 return (LRESULT)(Context->NextId - 1);
1788 ULONG maxId = (ULONG)WParam;
1790 if (Context->NextId < maxId + 1)
1792 Context->NextId = maxId + 1;
1794 if (Context->AllocatedColumns < Context->NextId)
1812 InvalidateRect(hwnd, &rect,
FALSE);
1822 InvalidateRect(hwnd, &rect,
FALSE);
1826 return (LRESULT)Context->FixedHeaderHandle;
1828 return (LRESULT)Context->HeaderHandle;
1830 return (LRESULT)Context->TooltipsHandle;
1844 PhTnpSelectRange(Context, (ULONG)WParam, (ULONG)LParam, flags, &changedStart, &changedEnd);
1848 InvalidateRect(hwnd, &rect,
FALSE);
1853 return (LRESULT)Context->NumberOfColumns;
1856 return (LRESULT)Context->EnableRedraw;
1864 parts->
VScrollWidth = Context->VScrollVisible ? Context->VScrollWidth : 0;
1865 parts->
HScrollHeight = Context->HScrollHeight ? Context->HScrollHeight : 0;
1874 return (LRESULT)Context->FixedColumn;
1876 return (LRESULT)Context->FirstColumn;
1887 Context->ExtendedFlags = (Context->ExtendedFlags & ~(ULONG)WParam) | ((ULONG)LParam & (ULONG)WParam);
1892 PVOID *callbackContext = (PVOID *)WParam;
1897 *callback = Context->Callback;
1902 if (callbackContext)
1904 *callbackContext = Context->CallbackContext;
1912 return Context->NumberOfColumnsByDisplay + (Context->FixedColumnVisible ? 1 : 0);
1915 ULONG
id = (ULONG)WParam;
1916 ULONG flags = (ULONG)LParam;
1927 column->
Fixed ? Context->FixedHeaderHandle : Context->HeaderHandle,
1936 ULONG flags = (ULONG)WParam;
1938 Context->EmptyText = *text;
1947 Context->CustomRowHeight =
TRUE;
1948 Context->RowHeight = rowHeight;
1952 Context->CustomRowHeight =
FALSE;
1964 _In_opt_ HFONT Font,
1968 if (Context->FontOwned)
1970 DeleteObject(Context->Font);
1971 Context->FontOwned =
FALSE;
1974 Context->Font = Font;
1980 if (SystemParametersInfo(SPI_GETICONTITLELOGFONT,
sizeof(LOGFONT), &logFont, 0))
1982 Context->Font = CreateFontIndirect(&logFont);
1983 Context->FontOwned =
TRUE;
1987 SendMessage(Context->FixedHeaderHandle, WM_SETFONT, (WPARAM)Context->Font, Redraw);
1988 SendMessage(Context->HeaderHandle, WM_SETFONT, (WPARAM)Context->Font, Redraw);
1990 if (Context->TooltipsHandle)
1992 SendMessage(Context->TooltipsHandle, WM_SETFONT, (WPARAM)Context->Font,
FALSE);
1993 Context->TooltipFont = Context->Font;
2003 Context->VScrollWidth = GetSystemMetrics(SM_CXVSCROLL);
2004 Context->HScrollHeight = GetSystemMetrics(SM_CYHSCROLL);
2005 Context->SystemBorderX = GetSystemMetrics(SM_CXBORDER);
2006 Context->SystemBorderY = GetSystemMetrics(SM_CYBORDER);
2007 Context->SystemEdgeX = GetSystemMetrics(SM_CXEDGE);
2008 Context->SystemEdgeY = GetSystemMetrics(SM_CYEDGE);
2009 Context->SystemDragX = GetSystemMetrics(SM_CXDRAG);
2010 Context->SystemDragY = GetSystemMetrics(SM_CYDRAG);
2012 if (Context->SystemDragX < 2)
2013 Context->SystemDragX = 2;
2014 if (Context->SystemDragY < 2)
2015 Context->SystemDragY = 2;
2024 if (hdc = GetDC(Context->Handle))
2026 SelectObject(hdc, Context->Font);
2027 GetTextMetrics(hdc, &Context->TextMetrics);
2029 if (!Context->CustomRowHeight)
2035 Context->RowHeight = Context->TextMetrics.tmHeight;
2039 if (Context->RowHeight < SmallIconHeight)
2040 Context->RowHeight = SmallIconHeight;
2045 Context->RowHeight += 1;
2048 Context->RowHeight += 1;
2051 Context->RowHeight += 2;
2054 ReleaseDC(Context->Handle, hdc);
2073 if (Context->ThemeData)
2076 Context->ThemeData = NULL;
2081 if (Context->ThemeData)
2089 Context->ThemeHasItemBackground =
FALSE;
2090 Context->ThemeHasGlyph =
FALSE;
2091 Context->ThemeHasHotGlyph =
FALSE;
2096 Context->ThemeData = NULL;
2097 Context->ThemeActive =
FALSE;
2098 Context->ThemeHasItemBackground =
FALSE;
2099 Context->ThemeHasGlyph =
FALSE;
2100 Context->ThemeHasHotGlyph =
FALSE;
2108 if (!Context->ThemeInitialized)
2111 Context->ThemeInitialized =
TRUE;
2129 if (Context->EnableRedraw <= 0)
2131 Context->SuspendUpdateLayout =
TRUE;
2135 clientRect = Context->ClientRect;
2140 if (Context->VScrollVisible)
2143 Context->VScrollHandle,
2144 clientRect.right - Context->VScrollWidth,
2146 Context->VScrollWidth,
2147 clientRect.bottom - (Context->HScrollVisible ? Context->HScrollHeight : 0),
2153 if (Context->HScrollVisible)
2156 Context->HScrollHandle,
2157 Context->NormalLeft,
2158 clientRect.bottom - Context->HScrollHeight,
2159 clientRect.right - Context->NormalLeft - (Context->VScrollVisible ? Context->VScrollWidth : 0),
2160 Context->HScrollHeight,
2166 if (Context->VScrollVisible && Context->HScrollVisible)
2169 Context->FillerBoxHandle,
2170 clientRect.right - Context->VScrollWidth,
2171 clientRect.bottom - Context->HScrollHeight,
2172 Context->VScrollWidth,
2173 Context->HScrollHeight,
2181 if (Context->FlatList->Count == 0 && Context->EmptyText.Length != 0)
2182 InvalidateRect(Context->Handle, NULL,
FALSE);
2191 WINDOWPOS windowPos;
2194 hdl.pwpos = &windowPos;
2201 rect.right = Context->NormalLeft;
2202 rect.bottom = Context->ClientRect.bottom;
2203 Header_Layout(Context->FixedHeaderHandle, &hdl);
2204 SetWindowPos(Context->FixedHeaderHandle, NULL, windowPos.x, windowPos.y, windowPos.cx, windowPos.cy, windowPos.flags);
2205 Context->HeaderHeight = windowPos.cy;
2208 rect.left = Context->NormalLeft - Context->HScrollPosition;
2210 rect.right = Context->ClientRect.right - (Context->VScrollVisible ? Context->VScrollWidth : 0);
2211 rect.bottom = Context->ClientRect.bottom;
2212 Header_Layout(Context->HeaderHandle, &hdl);
2213 SetWindowPos(Context->HeaderHandle, NULL, windowPos.x, windowPos.y, windowPos.cx, windowPos.cy, windowPos.flags);
2217 Context->HeaderHeight = 0;
2220 if (Context->TooltipsHandle)
2224 memset(&toolInfo, 0,
sizeof(TOOLINFO));
2225 toolInfo.cbSize =
sizeof(TOOLINFO);
2226 toolInfo.hwnd = Context->FixedHeaderHandle;
2228 GetClientRect(Context->FixedHeaderHandle, &toolInfo.rect);
2229 SendMessage(Context->TooltipsHandle, TTM_NEWTOOLRECT, 0, (LPARAM)&toolInfo);
2231 toolInfo.hwnd = Context->HeaderHandle;
2233 GetClientRect(Context->HeaderHandle, &toolInfo.rect);
2234 SendMessage(Context->TooltipsHandle, TTM_NEWTOOLRECT, 0, (LPARAM)&toolInfo);
2240 _In_ ULONG FixedWidth
2245 if (Context->FixedColumnVisible)
2247 Context->FixedWidth = FixedWidth;
2249 if (Context->FixedWidth < Context->FixedWidthMinimum)
2250 Context->FixedWidth = Context->FixedWidthMinimum;
2252 Context->NormalLeft = Context->FixedWidth + 1;
2254 item.mask = HDI_WIDTH;
2255 item.cxy = Context->FixedWidth + 1;
2256 Header_SetItem(Context->FixedHeaderHandle, 0, &item);
2260 Context->FixedWidth = 0;
2261 Context->NormalLeft = 0;
2271 Context->EnableRedraw++;
2273 Context->EnableRedraw--;
2275 if (Context->EnableRedraw == 1)
2277 if (Context->SuspendUpdateStructure)
2282 if (Context->SuspendUpdateLayout)
2287 if (Context->SuspendUpdateMoveMouse)
2295 Context->SuspendUpdateStructure =
FALSE;
2296 Context->SuspendUpdateLayout =
FALSE;
2297 Context->SuspendUpdateMoveMouse =
FALSE;
2299 if (Context->SuspendUpdateRegion)
2301 InvalidateRgn(Context->Handle, Context->SuspendUpdateRegion,
FALSE);
2302 DeleteObject(Context->SuspendUpdateRegion);
2303 Context->SuspendUpdateRegion = NULL;
2315 _In_ ULONG VirtualKeys
2322 mouseEvent.
Node = Node;
2323 mouseEvent.
Column = Column;
2325 Context->Callback(Context->Handle, Message, &mouseEvent, NULL, Context->CallbackContext);
2333 if (Id >= Context->AllocatedColumns)
2336 return Context->Columns[Id];
2347 if (Column->Id < Context->AllocatedColumns && Context->Columns[Column->Id])
2350 if (Context->NextId < Column->Id + 1)
2351 Context->NextId = Column->Id + 1;
2355 if (Context->AllocatedColumns < Context->NextId)
2360 Context->Columns[Column->Id] = realColumn;
2361 Context->NumberOfColumns++;
2363 if (realColumn->
Fixed)
2365 if (Context->FixedColumn)
2372 Context->FixedColumn = realColumn;
2381 BOOLEAN updateHeaders;
2383 updateHeaders =
FALSE;
2385 if (!realColumn->
Fixed && realColumn->
DisplayIndex != Header_GetItemCount(Context->HeaderHandle))
2386 updateHeaders =
TRUE;
2412 BOOLEAN updateLayout;
2417 updateLayout =
FALSE;
2420 updateLayout =
TRUE;
2423 Context->Columns[realColumn->
Id] = NULL;
2430 Context->NumberOfColumns--;
2459 BOOLEAN addingOrRemoving;
2464 addingOrRemoving =
FALSE;
2468 if (realColumn->
Visible != Column->Visible)
2470 addingOrRemoving =
TRUE;
2486 BOOLEAN updateHeaders;
2488 BOOLEAN updateLayout;
2490 updateHeaders =
FALSE;
2492 updateLayout =
FALSE;
2496 realColumn->
Text = Column->Text;
2501 realColumn->
Width = Column->Width;
2507 realColumn->
Alignment = Column->Alignment;
2513 updateHeaders =
TRUE;
2515 updateLayout =
TRUE;
2518 if (!addingOrRemoving && realColumn->
Visible)
2533 realColumn->
Context = Column->Context;
2538 realColumn->
TextFlags = Column->TextFlags;
2541 if (addingOrRemoving)
2543 if (Column->Visible)
2545 BOOLEAN updateHeaders;
2547 updateHeaders =
FALSE;
2549 if (realColumn->
Fixed)
2556 updateHeaders =
TRUE;
2558 realColumn->
DisplayIndex = Header_GetItemCount(Context->HeaderHandle);
2582 if (Context->Columns)
2584 ULONG oldAllocatedColumns;
2586 oldAllocatedColumns = Context->AllocatedColumns;
2587 Context->AllocatedColumns *= 2;
2589 if (Context->AllocatedColumns < Context->NextId)
2590 Context->AllocatedColumns = Context->NextId;
2592 Context->Columns = PhReAllocate(
2599 &Context->Columns[oldAllocatedColumns],
2606 Context->AllocatedColumns = 16;
2608 if (Context->AllocatedColumns < Context->NextId)
2609 Context->AllocatedColumns = Context->NextId;
2611 Context->Columns = PhAllocate(
2625 if (Context->AllocatedColumnsByDisplay < Context->NumberOfColumns)
2627 if (Context->ColumnsByDisplay)
2628 PhFree(Context->ColumnsByDisplay);
2630 Context->ColumnsByDisplay = PhAllocate(
sizeof(
PPH_TREENEW_COLUMN) * Context->NumberOfColumns);
2631 Context->AllocatedColumnsByDisplay = Context->NumberOfColumns;
2634 memset(Context->ColumnsByDisplay, 0,
sizeof(
PPH_TREENEW_COLUMN) * Context->AllocatedColumnsByDisplay);
2636 for (i = 0; i < Context->NextId; i++)
2638 if (!Context->Columns[i])
2641 if (Context->Columns[i]->Visible && !Context->Columns[i]->Fixed && Context->Columns[i]->DisplayIndex != -1)
2643 if (Context->Columns[i]->DisplayIndex >= Context->NumberOfColumns)
2646 Context->ColumnsByDisplay[Context->Columns[i]->DisplayIndex] = Context->Columns[i];
2652 for (i = 0; i < Context->AllocatedColumnsByDisplay; i++)
2654 if (!Context->ColumnsByDisplay[i])
2657 Context->ColumnsByDisplay[i]->s.ViewX = x;
2658 x += Context->ColumnsByDisplay[i]->Width;
2661 Context->NumberOfColumnsByDisplay = i;
2662 Context->TotalViewX = x;
2664 if (Context->FixedColumnVisible)
2665 Context->FirstColumn = Context->FixedColumn;
2666 else if (Context->NumberOfColumnsByDisplay != 0)
2667 Context->FirstColumn = Context->ColumnsByDisplay[0];
2669 Context->FirstColumn = NULL;
2671 if (Context->NumberOfColumnsByDisplay != 0)
2672 Context->LastColumn = Context->ColumnsByDisplay[Context->NumberOfColumnsByDisplay - 1];
2673 else if (Context->FixedColumnVisible)
2674 Context->LastColumn = Context->FixedColumn;
2676 Context->LastColumn = NULL;
2688 if (Column->Width < Context->FixedWidthMinimum)
2689 Column->Width = Context->FixedWidthMinimum;
2691 Context->FixedWidth = Column->Width;
2692 Context->NormalLeft = Context->FixedWidth + 1;
2693 Context->FixedColumnVisible =
TRUE;
2696 Context->FixedDividerVisible =
TRUE;
2699 memset(&item, 0,
sizeof(HDITEM));
2700 item.mask = HDI_WIDTH | HDI_TEXT | HDI_FORMAT | HDI_LPARAM | HDI_ORDER;
2701 item.cxy = Column->Width;
2702 item.pszText = Column->Text;
2704 item.lParam = (LPARAM)Column;
2712 item.iOrder = Column->DisplayIndex;
2715 item.fmt |= HDF_LEFT;
2717 item.fmt |= HDF_RIGHT;
2719 item.fmt |= HDF_CENTER;
2721 if (Column->Id == Context->SortColumn)
2724 item.fmt |= HDF_SORTUP;
2726 item.fmt |= HDF_SORTDOWN;
2729 Column->Visible =
TRUE;
2732 return Header_InsertItem(Context->FixedHeaderHandle, 0, &item);
2734 return Header_InsertItem(Context->HeaderHandle, MAXINT, &item);
2745 memset(&item, 0,
sizeof(HDITEM));
2750 item.mask |= HDI_TEXT;
2751 item.pszText = Column->Text;
2756 item.mask |= HDI_WIDTH;
2757 item.cxy = Column->Width;
2765 item.mask |= HDI_FORMAT;
2769 item.fmt |= HDF_LEFT;
2771 item.fmt |= HDF_RIGHT;
2773 item.fmt |= HDF_CENTER;
2775 if (Column->Id == Context->SortColumn)
2778 item.fmt |= HDF_SORTUP;
2780 item.fmt |= HDF_SORTDOWN;
2786 item.mask |= HDI_ORDER;
2791 item.iOrder = Column->DisplayIndex;
2795 Header_SetItem(Context->FixedHeaderHandle, 0, &item);
2797 Header_SetItem(Context->HeaderHandle, Column->s.ViewIndex, &item);
2807 Context->FixedColumn = NULL;
2808 Context->FixedWidth = 0;
2809 Context->NormalLeft = 0;
2810 Context->FixedColumnVisible =
FALSE;
2811 Context->FixedDividerVisible =
FALSE;
2815 Header_DeleteItem(Context->FixedHeaderHandle, Column->s.ViewIndex);
2817 Header_DeleteItem(Context->HeaderHandle, Column->s.ViewIndex);
2819 Column->Visible =
FALSE;
2820 Column->s.ViewIndex = -1;
2833 item.mask = HDI_WIDTH | HDI_LPARAM | HDI_ORDER;
2837 if (Context->FixedColumnVisible && Header_GetItem(Context->FixedHeaderHandle, 0, &item))
2839 column = Context->FixedColumn;
2840 column->
Width = item.cxy - 1;
2845 count = Header_GetItemCount(Context->HeaderHandle);
2849 for (i = 0; i < count; i++)
2851 if (Header_GetItem(Context->HeaderHandle, i, &item))
2855 column->
Width = item.cxy;
2877 columnLeft = Context->NormalLeft + Column->s.ViewX - Context->HScrollPosition;
2885 rect.left = columnLeft + Column->Width;
2886 rect.top = Context->HeaderHeight;
2887 rect.right = Context->ClientRect.right - (Context->VScrollVisible ? Context->VScrollWidth : 0);
2888 rect.bottom = Context->ClientRect.bottom - (Context->HScrollVisible ? Context->HScrollHeight : 0);
2905 UpdateWindow(Context->Handle);
2907 if (Context->HScrollVisible)
2910 rect.top = rect.bottom;
2911 rect.bottom = Context->ClientRect.bottom;
2912 InvalidateRect(Context->Handle, &rect,
FALSE);
2918 rect.left = columnLeft;
2919 rect.top = Context->HeaderHeight;
2920 rect.right = columnLeft + Column->Width;
2921 RedrawWindow(Context->Handle, &rect, NULL, RDW_INVALIDATE | RDW_UPDATENOW);
2929 if (NewColumn->Id == Context->SortColumn)
2931 if (Context->TriState)
2933 if (!NewColumn->SortDescending)
2966 Context->SortColumn = NewColumn->Id;
2968 if (!NewColumn->SortDescending)
2976 Context->Callback(Context->Handle,
TreeNewSortChanged, NULL, NULL, Context->CallbackContext);
2987 Context->FixedHeaderHandle,
2992 Context->HeaderHandle,
3000 if (!SortColumnPointer)
3006 if (SortColumnPointer->Fixed)
3009 Context->FixedHeaderHandle,
3014 Context->HeaderHandle,
3022 Context->FixedHeaderHandle,
3027 Context->HeaderHandle,
3028 SortColumnPointer->s.ViewIndex,
3038 _In_ HWND HeaderHandle,
3048 newWidth = Context->ClientRect.right - (Context->TotalViewX - Column->Width);
3050 if (Context->FixedColumn)
3051 newWidth -= Context->FixedColumn->Width;
3052 if (Context->VScrollVisible)
3053 newWidth -= Context->VScrollWidth;
3065 if (Context->FlatList->Count == 0)
3067 if (Column->CustomDraw)
3072 for (i = 0; i < Context->FlatList->Count; i++)
3080 if (maximumWidth < width)
3081 maximumWidth = width;
3091 item.mask = HDI_WIDTH;
3092 item.cxy = newWidth;
3094 Header_SetItem(HeaderHandle, Column->s.ViewIndex, &item);
3101 _Out_ PULONG NumberOfChildren
3106 getChildren.
Flags = 0;
3107 getChildren.
Node = Node;
3111 if (Context->Callback(
3116 Context->CallbackContext
3139 if (Context->Callback(
3144 Context->CallbackContext
3163 if (Id < Node->TextCacheSize && Node->TextCache[Id].Buffer)
3165 *Text = Node->TextCache[Id];
3169 getCellText.
Flags = 0;
3170 getCellText.
Node = Node;
3171 getCellText.
Id = Id;
3174 if (Context->Callback(
3179 Context->CallbackContext
3182 *Text = getCellText.
Text;
3184 if ((getCellText.
Flags &
TN_CACHE) && Id < Node->TextCacheSize)
3185 Node->TextCache[Id] = getCellText.
Text;
3198 ULONG numberOfChildren;
3208 Context->FocusNodeFound =
FALSE;
3211 Context->CanAnyExpand =
FALSE;
3213 for (i = 0; i < numberOfChildren; i++)
3218 if (!Context->FocusNodeFound)
3219 Context->FocusNode = NULL;
3221 if (Context->HotNodeIndex >= Context->FlatList->Count)
3222 Context->HotNodeIndex = -1;
3224 if (Context->MarkNodeIndex >= Context->FlatList->Count)
3225 Context->MarkNodeIndex = -1;
3235 ULONG numberOfChildren;
3241 Node->
Level = Level;
3243 Node->Index = Context->FlatList->Count;
3246 if (Context->FocusNode == Node)
3247 Context->FocusNodeFound =
TRUE;
3249 nextLevel = Level + 1;
3258 Context->CanAnyExpand =
TRUE;
3264 for (i = 0; i < numberOfChildren; i++)
3269 if (numberOfChildren == 0)
3270 Node->s.IsLeaf =
TRUE;
3279 _In_ BOOLEAN Expanded
3282 if (Node->Expanded != Expanded)
3287 Context->Callback(Context->Handle,
TreeNewNodeExpanding, Node, &nodeEvent, Context->CallbackContext);
3303 for (i = Node->Index + 1; i < Context->FlatList->Count; i++)
3305 node = Context->FlatList->Items[i];
3307 if (node->
Level <= Node->Level)
3323 Node->Expanded = Expanded;
3327 InvalidateRect(Context->Handle, NULL,
FALSE);
3328 UpdateWindow(Context->Handle);
3345 LONG iconVerticalMargin;
3348 if (Index >= Context->FlatList->Count)
3351 node = Context->FlatList->Items[Index];
3352 nodeY = Context->HeaderHeight + ((
LONG)Index - Context->VScrollPosition) * Context->RowHeight;
3355 Parts->RowRect.left = 0;
3356 Parts->RowRect.right = Context->NormalLeft + Context->TotalViewX - Context->HScrollPosition;
3357 Parts->RowRect.top = nodeY;
3358 Parts->RowRect.bottom = nodeY + Context->RowHeight;
3360 viewWidth = Context->ClientRect.right - (Context->VScrollVisible ? Context->VScrollWidth : 0);
3362 if (Parts->RowRect.right > viewWidth)
3363 Parts->RowRect.right = viewWidth;
3367 if (!Column->Visible)
3370 iconVerticalMargin = (Context->RowHeight - SmallIconHeight) / 2;
3378 currentX = Context->NormalLeft + Column->s.ViewX - Context->HScrollPosition;
3382 Parts->CellRect.left = currentX;
3383 Parts->CellRect.right = currentX + Column->Width;
3384 Parts->CellRect.top = Parts->RowRect.top;
3385 Parts->CellRect.bottom = Parts->RowRect.bottom;
3389 if (Column == Context->FirstColumn)
3391 currentX += (
LONG)node->
Level * SmallIconWidth;
3393 if (Context->CanAnyExpand)
3398 Parts->PlusMinusRect.left = currentX;
3399 Parts->PlusMinusRect.right = currentX + SmallIconWidth;
3400 Parts->PlusMinusRect.top = Parts->RowRect.top + iconVerticalMargin;
3401 Parts->PlusMinusRect.bottom = Parts->RowRect.bottom - iconVerticalMargin;
3404 currentX += SmallIconWidth;
3410 Parts->IconRect.left = currentX;
3411 Parts->IconRect.right = currentX + SmallIconWidth;
3412 Parts->IconRect.top = Parts->RowRect.top + iconVerticalMargin;
3413 Parts->IconRect.bottom = Parts->RowRect.bottom - iconVerticalMargin;
3420 Parts->ContentRect.left = currentX;
3422 Parts->ContentRect.top = Parts->RowRect.top;
3423 Parts->ContentRect.bottom = Parts->RowRect.bottom;
3432 if (hdc = GetDC(Context->Handle))
3441 font = Context->Font;
3443 SelectObject(hdc, font);
3445 if (GetTextExtentPoint32(hdc, text.
Buffer, (ULONG)text.
Length /
sizeof(WCHAR), &textSize))
3448 Parts->TextRect.left = currentX;
3449 Parts->TextRect.right = currentX + textSize.cx;
3450 Parts->TextRect.top = Parts->RowRect.top + (Context->RowHeight - textSize.cy) / 2;
3451 Parts->TextRect.bottom = Parts->RowRect.bottom - (Context->RowHeight - textSize.cy) / 2;
3453 if (Column->TextFlags & DT_CENTER)
3455 Parts->TextRect.left = Parts->ContentRect.left / 2 + (Parts->ContentRect.right - textSize.cx) / 2;
3456 Parts->TextRect.right = Parts->ContentRect.left + textSize.cx;
3458 else if (Column->TextFlags & DT_RIGHT)
3460 Parts->TextRect.right = Parts->ContentRect.right;
3461 Parts->TextRect.left = Parts->TextRect.right - textSize.cx;
3469 ReleaseDC(Context->Handle, hdc);
3488 if (End >= Context->FlatList->Count)
3493 startY = Context->HeaderHeight + ((
LONG)Start - Context->VScrollPosition) * Context->RowHeight;
3494 endY = Context->HeaderHeight + ((
LONG)End - Context->VScrollPosition) * Context->RowHeight;
3497 Rect->right = Context->NormalLeft + Context->TotalViewX - Context->HScrollPosition;
3499 Rect->bottom = endY + Context->RowHeight;
3501 viewWidth = Context->ClientRect.right - (Context->VScrollVisible ? Context->VScrollWidth : 0);
3503 if (Rect->right > viewWidth)
3504 Rect->right = viewWidth;
3508 if (Rect->top < Context->HeaderHeight)
3509 Rect->top = Context->HeaderHeight;
3510 if (Rect->bottom > Context->ClientRect.bottom)
3511 Rect->bottom = Context->ClientRect.bottom;
3529 HitTest->Node = NULL;
3530 HitTest->Column = NULL;
3532 clientRect = Context->ClientRect;
3533 x = HitTest->Point.x;
3534 y = HitTest->Point.y;
3538 if (x >= clientRect.right)
3542 if (y >= clientRect.bottom)
3545 if (HitTest->Flags == 0)
3552 if (y >= Context->HeaderHeight && x < Context->FixedWidth + Context->TotalViewX)
3554 index = (y - Context->HeaderHeight) / Context->RowHeight + Context->VScrollPosition;
3556 if (index < Context->FlatList->Count)
3559 node = Context->FlatList->Items[index];
3560 HitTest->Node = node;
3569 if (x < Context->FixedWidth && Context->FixedColumnVisible)
3571 column = Context->FixedColumn;
3580 currentX = Context->NormalLeft - Context->HScrollPosition;
3582 for (i = 0; i < Context->NumberOfColumnsByDisplay; i++)
3584 currentColumn = Context->ColumnsByDisplay[i];
3586 if (x >= currentX && x < currentX + currentColumn->Width)
3588 column = currentColumn;
3593 currentX += currentColumn->
Width;
3597 HitTest->Column = column;
3601 BOOLEAN isFirstColumn;
3604 isFirstColumn = HitTest->Column == Context->FirstColumn;
3611 currentX += (
LONG)node->
Level * SmallIconWidth;
3615 if (x >= currentX && x < currentX + SmallIconWidth)
3618 currentX += SmallIconWidth;
3623 if (x >= currentX && x < currentX + SmallIconWidth)
3646 _Out_opt_ PULONG ChangedStart,
3647 _Out_opt_ PULONG ChangedEnd
3653 BOOLEAN targetValue;
3657 if (Context->FlatList->Count == 0)
3660 maximum = Context->FlatList->Count - 1;
3671 Start = maximum + 1;
3676 changedStart = maximum;
3681 for (i = 0; i < Start; i++)
3683 node = Context->FlatList->Items[i];
3689 if (changedStart > i)
3697 for (i = Start; i <= End; i++)
3699 node = Context->FlatList->Items[i];
3705 if (changedStart > i)
3712 if (Flags & TN_SELECT_RESET)
3714 for (i = End + 1; i <= maximum; i++)
3716 node = Context->FlatList->Items[i];
3722 if (changedStart > i)
3730 if (changedStart <= changedEnd)
3736 *ChangedStart = changedStart;
3738 *ChangedEnd = changedEnd;
3744 _In_ BOOLEAN NewPlusMinusHot
3747 ULONG newHotNodeIndex;
3749 BOOLEAN needsInvalidate;
3752 newHotNodeIndex = NewHotNode->Index;
3754 newHotNodeIndex = -1;
3756 needsInvalidate =
FALSE;
3758 if (Context->HotNodeIndex != newHotNodeIndex)
3760 if (Context->HotNodeIndex != -1)
3762 if (Context->ThemeData &&
PhTnpGetRowRects(Context, Context->HotNodeIndex, Context->HotNodeIndex,
TRUE, &rowRect))
3765 InvalidateRect(Context->Handle, &rowRect,
FALSE);
3769 Context->HotNodeIndex = newHotNodeIndex;
3773 needsInvalidate =
TRUE;
3779 if (NewHotNode->s.PlusMinusHot != NewPlusMinusHot)
3781 NewHotNode->s.PlusMinusHot = NewPlusMinusHot;
3782 needsInvalidate =
TRUE;
3785 if (needsInvalidate && Context->ThemeData &&
PhTnpGetRowRects(Context, newHotNodeIndex, newHotNodeIndex,
TRUE, &rowRect))
3787 InvalidateRect(Context->Handle, &rowRect,
FALSE);
3811 if (!ControlKey && !ShiftKey && !Node->Selected)
3814 Context->MarkNodeIndex = Node->Index;
3818 InvalidateRect(Context->Handle, &rect,
FALSE);
3822 else if (ShiftKey && Context->MarkNodeIndex != -1)
3829 if (Node->Index > Context->MarkNodeIndex)
3831 start = Context->MarkNodeIndex;
3836 start = Node->Index;
3837 end = Context->MarkNodeIndex;
3844 InvalidateRect(Context->Handle, &rect,
FALSE);
3847 else if (ControlKey)
3852 Context->MarkNodeIndex = Node->Index;
3856 InvalidateRect(Context->Handle, &rect,
FALSE);
3864 Context->MarkNodeIndex = Node->Index;
3868 InvalidateRect(Context->Handle, &rect,
FALSE);
3885 if (Index >= Context->FlatList->Count)
3888 viewTop = Context->HeaderHeight;
3889 viewBottom = Context->ClientRect.bottom - (Context->HScrollVisible ? Context->HScrollHeight : 0);
3890 rowTop = Context->HeaderHeight + ((
LONG)Index - Context->VScrollPosition) * Context->RowHeight;
3891 rowBottom = rowTop + Context->RowHeight;
3894 if (rowTop >= viewTop && rowBottom <= viewBottom)
3897 deltaY = rowTop - viewTop;
3903 deltaY = rowBottom - viewBottom;
3904 deltaRows = (deltaY + Context->RowHeight - 1) / Context->RowHeight;
3908 deltaRows = deltaY / Context->RowHeight;
3925 hitTest.
Point.x = CursorX;
3926 hitTest.
Point.y = CursorY;
3931 hotNode = hitTest.
Node;
3937 if (Context->AnimateDivider && Context->FixedDividerVisible)
3941 if ((Context->DividerHot < 100 || Context->AnimateDividerFadingOut) && !Context->AnimateDividerFadingIn)
3944 Context->AnimateDividerFadingIn =
TRUE;
3945 Context->AnimateDividerFadingOut =
FALSE;
3951 if ((Context->DividerHot != 0 || Context->AnimateDividerFadingIn) && !Context->AnimateDividerFadingOut)
3953 Context->AnimateDividerFadingOut =
TRUE;
3954 Context->AnimateDividerFadingIn =
FALSE;
3960 if (Context->TooltipsHandle)
3980 if (Context->TooltipIndex != index || Context->TooltipId !=
id)
3992 ULONG wheelScrollLines;
3993 FLOAT linesToScroll;
3994 LONG wholeLinesToScroll;
3995 SCROLLINFO scrollInfo;
3998 if (!SystemParametersInfo(SPI_GETWHEELSCROLLLINES, 0, &wheelScrollLines, 0))
3999 wheelScrollLines = 3;
4002 if (wheelScrollLines == -1)
4003 wheelScrollLines = (Context->ClientRect.bottom - Context->HeaderHeight - (Context->HScrollVisible ? Context->HScrollHeight : 0)) / Context->RowHeight;
4006 if ((Context->VScrollRemainder > 0) != (Distance > 0))
4007 Context->VScrollRemainder = 0;
4009 linesToScroll = (FLOAT)wheelScrollLines * Distance / WHEEL_DELTA + Context->VScrollRemainder;
4010 wholeLinesToScroll = (
LONG)linesToScroll;
4011 Context->VScrollRemainder = linesToScroll - wholeLinesToScroll;
4013 scrollInfo.cbSize =
sizeof(SCROLLINFO);
4014 scrollInfo.fMask = SIF_ALL;
4015 GetScrollInfo(Context->VScrollHandle, SB_CTL, &scrollInfo);
4016 oldPosition = scrollInfo.nPos;
4018 scrollInfo.nPos += wholeLinesToScroll;
4020 scrollInfo.fMask = SIF_POS;
4021 SetScrollInfo(Context->VScrollHandle, SB_CTL, &scrollInfo,
TRUE);
4022 GetScrollInfo(Context->VScrollHandle, SB_CTL, &scrollInfo);
4024 if (scrollInfo.nPos != oldPosition)
4026 Context->VScrollPosition = scrollInfo.nPos;
4029 if (Context->TooltipsHandle)
4037 if (point.x >= 0 && point.y >= 0 && point.x < Context->ClientRect.right && point.y < Context->ClientRect.bottom)
4040 message.hwnd = Context->Handle;
4041 message.message = WM_MOUSEMOVE;
4043 message.lParam = MAKELPARAM(point.x, point.y);
4044 SendMessage(Context->TooltipsHandle, TTM_RELAYEVENT, 0, (LPARAM)&message);
4055 ULONG wheelScrollChars;
4056 FLOAT pixelsToScroll;
4057 LONG wholePixelsToScroll;
4058 SCROLLINFO scrollInfo;
4061 if (!SystemParametersInfo(SPI_GETWHEELSCROLLCHARS, 0, &wheelScrollChars, 0))
4062 wheelScrollChars = 3;
4065 if ((Context->HScrollRemainder > 0) != (Distance > 0))
4066 Context->HScrollRemainder = 0;
4068 pixelsToScroll = (FLOAT)wheelScrollChars * Context->TextMetrics.tmAveCharWidth * Distance / WHEEL_DELTA + Context->HScrollRemainder;
4069 wholePixelsToScroll = (
LONG)pixelsToScroll;
4070 Context->HScrollRemainder = pixelsToScroll - wholePixelsToScroll;
4072 scrollInfo.cbSize =
sizeof(SCROLLINFO);
4073 scrollInfo.fMask = SIF_ALL;
4074 GetScrollInfo(Context->HScrollHandle, SB_CTL, &scrollInfo);
4075 oldPosition = scrollInfo.nPos;
4077 scrollInfo.nPos += wholePixelsToScroll;
4079 scrollInfo.fMask = SIF_POS;
4080 SetScrollInfo(Context->HScrollHandle, SB_CTL, &scrollInfo,
TRUE);
4081 GetScrollInfo(Context->HScrollHandle, SB_CTL, &scrollInfo);
4083 if (scrollInfo.nPos != oldPosition)
4085 Context->HScrollPosition = scrollInfo.nPos;
4092 _In_ ULONG VirtualKey
4105 if (VirtualKey != VK_UP && VirtualKey != VK_DOWN &&
4106 VirtualKey != VK_HOME && VirtualKey != VK_END &&
4107 VirtualKey != VK_PRIOR && VirtualKey != VK_NEXT)
4112 count = Context->FlatList->Count;
4123 if (Context->FocusNode && Context->FocusNode->Index > 0)
4125 index = Context->FocusNode->Index - 1;
4135 if (Context->FocusNode)
4137 index = Context->FocusNode->Index + 1;
4159 if (Context->FocusNode)
4160 index = Context->FocusNode->Index;
4164 rowsPerPage = Context->ClientRect.bottom - Context->HeaderHeight - (Context->HScrollVisible ? Context->HScrollHeight : 0);
4166 if (rowsPerPage < 0)
4169 rowsPerPage = rowsPerPage / Context->RowHeight - 1;
4171 if (rowsPerPage < 0)
4174 if (VirtualKey == VK_PRIOR)
4176 ULONG startOfPageIndex;
4178 startOfPageIndex = Context->VScrollPosition;
4180 if (index > startOfPageIndex)
4182 index = startOfPageIndex;
4187 if (index >= (ULONG)rowsPerPage)
4188 index -= rowsPerPage;
4195 ULONG endOfPageIndex;
4197 endOfPageIndex = Context->VScrollPosition + rowsPerPage;
4199 if (endOfPageIndex >= count)
4200 endOfPageIndex = count - 1;
4202 if (index < endOfPageIndex)
4204 index = endOfPageIndex;
4209 index += rowsPerPage;
4221 controlKey = GetKeyState(VK_CONTROL) < 0;
4222 shiftKey = GetKeyState(VK_SHIFT) < 0;
4224 Context->FocusNode = Context->FlatList->Items[index];
4227 if (shiftKey && Context->MarkNodeIndex != -1)
4229 if (index > Context->MarkNodeIndex)
4231 start = Context->MarkNodeIndex;
4237 end = Context->MarkNodeIndex;
4244 InvalidateRect(Context->Handle, &rect,
FALSE);
4247 else if (!controlKey)
4249 Context->MarkNodeIndex = Context->FocusNode->Index;
4254 InvalidateRect(Context->Handle, &rect,
FALSE);
4266 _In_ ULONG VirtualKey
4275 if (VirtualKey != VK_SPACE && VirtualKey != VK_LEFT && VirtualKey != VK_RIGHT)
4280 if (!Context->FocusNode)
4283 controlKey = GetKeyState(VK_CONTROL) < 0;
4284 shiftKey = GetKeyState(VK_SHIFT) < 0;
4294 Context->MarkNodeIndex = Context->FocusNode->Index;
4299 InvalidateRect(Context->Handle, &rect,
FALSE);
4309 if (Context->FocusNode->Index > Context->MarkNodeIndex)
4311 start = Context->MarkNodeIndex;
4312 end = Context->FocusNode->Index;
4316 start = Context->FocusNode->Index;
4317 end = Context->MarkNodeIndex;
4324 InvalidateRect(Context->Handle, &rect,
FALSE);
4337 if (!Context->FocusNode->s.IsLeaf && Context->FocusNode->Expanded)
4341 else if (Context->FocusNode->Level != 0)
4343 i = Context->FocusNode->Index;
4344 targetLevel = Context->FocusNode->Level - 1;
4349 newNode = Context->FlatList->Items[i];
4351 if (newNode->
Level == targetLevel)
4353 Context->FocusNode = newNode;
4354 Context->MarkNodeIndex = newNode->
Index;
4361 InvalidateRect(Context->Handle, &rect,
FALSE);
4376 if (!Context->FocusNode->s.IsLeaf)
4380 if (!Context->FocusNode->Expanded)
4386 if (Context->FocusNode->Index + 1 < Context->FlatList->Count)
4388 newNode = Context->FlatList->Items[Context->FocusNode->Index + 1];
4390 if (newNode->
Level == Context->FocusNode->Level + 1)
4392 Context->FocusNode = newNode;
4393 Context->MarkNodeIndex = newNode->
Index;
4400 InvalidateRect(Context->Handle, &rect,
FALSE);
4417 _In_ ULONG Character
4428 if (Context->FlatList->Count == 0)
4431 messageTime = GetMessageTime();
4437 Context->SearchStringCount = 0;
4438 Context->SearchFailed =
FALSE;
4440 Context->SearchSingleCharMode =
TRUE;
4443 Context->SearchMessageTime = messageTime;
4447 if (!Context->SearchString)
4449 Context->AllocatedSearchString = 32;
4450 Context->SearchString = PhAllocate(Context->AllocatedSearchString *
sizeof(WCHAR));
4452 Context->SearchSingleCharMode =
TRUE;
4458 if (!Context->SearchFailed)
4461 Context->SearchFailed =
TRUE;
4465 else if (Context->SearchStringCount == Context->AllocatedSearchString)
4467 Context->AllocatedSearchString *= 2;
4468 Context->SearchString = PhReAllocate(Context->SearchString, Context->AllocatedSearchString *
sizeof(WCHAR));
4471 Context->SearchString[Context->SearchStringCount++] = (WCHAR)Character;
4473 if (Context->SearchString[Context->SearchStringCount - 1] != Context->SearchString[0])
4477 Context->SearchSingleCharMode =
FALSE;
4482 if (Context->FocusNode)
4484 searchEvent.
StartIndex = Context->FocusNode->Index;
4486 if (newSearch || Context->SearchSingleCharMode)
4491 if (searchEvent.
StartIndex == Context->FlatList->Count)
4502 if (!Context->SearchSingleCharMode)
4503 searchEvent.
String.
Length = Context->SearchStringCount *
sizeof(WCHAR);
4517 if (searchEvent.
FoundIndex == -1 && !Context->SearchFailed)
4527 Context->SearchFailed =
TRUE;
4534 foundNode = Context->FlatList->Items[searchEvent.
FoundIndex];
4535 Context->FocusNode = foundNode;
4542 InvalidateRect(Context->Handle, &rect,
FALSE);
4551 _In_ BOOLEAN Partial,
4560 if (Context->FlatList->Count == 0)
4562 if (!Context->FirstColumn)
4565 startIndex = SearchEvent->StartIndex;
4566 currentIndex = startIndex;
4574 if (currentIndex >= (
LONG)Context->FlatList->Count)
4587 if (!firstTime && currentIndex == startIndex)
4590 if (
PhTnpGetCellText(Context, Context->FlatList->Items[currentIndex], Context->FirstColumn->Id, &text))
4596 foundIndex = currentIndex;
4604 foundIndex = currentIndex;
4614 SearchEvent->FoundIndex = foundIndex;
4628 SCROLLINFO scrollInfo;
4635 clientRect = Context->ClientRect;
4636 width = clientRect.right - Context->FixedWidth;
4637 height = clientRect.bottom - Context->HeaderHeight;
4639 contentWidth = Context->TotalViewX;
4640 contentHeight = (
LONG)Context->FlatList->Count * Context->RowHeight;
4642 if (contentHeight > height)
4645 width -= Context->VScrollWidth;
4648 if (contentWidth > width)
4650 height -= Context->HScrollHeight;
4658 scrollInfo.cbSize =
sizeof(SCROLLINFO);
4659 scrollInfo.fMask = SIF_POS;
4660 GetScrollInfo(Context->VScrollHandle, SB_CTL, &scrollInfo);
4661 oldPosition = scrollInfo.nPos;
4663 scrollInfo.fMask = SIF_RANGE | SIF_PAGE;
4664 scrollInfo.nMin = 0;
4665 scrollInfo.nMax = Context->FlatList->Count != 0 ? Context->FlatList->Count - 1 : 0;
4666 scrollInfo.nPage = height / Context->RowHeight;
4667 SetScrollInfo(Context->VScrollHandle, SB_CTL, &scrollInfo,
TRUE);
4670 scrollInfo.fMask = SIF_POS;
4671 GetScrollInfo(Context->VScrollHandle, SB_CTL, &scrollInfo);
4672 deltaRows = scrollInfo.nPos - oldPosition;
4673 Context->VScrollPosition = scrollInfo.nPos;
4675 if (contentHeight > height && contentHeight != 0)
4677 ShowWindow(Context->VScrollHandle, SW_SHOW);
4678 Context->VScrollVisible =
TRUE;
4682 ShowWindow(Context->VScrollHandle, SW_HIDE);
4683 Context->VScrollVisible =
FALSE;
4688 scrollInfo.cbSize =
sizeof(SCROLLINFO);
4689 scrollInfo.fMask = SIF_POS;
4690 GetScrollInfo(Context->HScrollHandle, SB_CTL, &scrollInfo);
4691 oldPosition = scrollInfo.nPos;
4693 scrollInfo.fMask = SIF_RANGE | SIF_PAGE;
4694 scrollInfo.nMin = 0;
4695 scrollInfo.nMax = contentWidth != 0 ? contentWidth - 1 : 0;
4696 scrollInfo.nPage = width;
4697 SetScrollInfo(Context->HScrollHandle, SB_CTL, &scrollInfo,
TRUE);
4699 scrollInfo.fMask = SIF_POS;
4700 GetScrollInfo(Context->HScrollHandle, SB_CTL, &scrollInfo);
4701 deltaX = scrollInfo.nPos - oldPosition;
4702 Context->HScrollPosition = scrollInfo.nPos;
4704 oldHScrollVisible = Context->HScrollVisible;
4706 if (contentWidth > width && contentWidth != 0)
4708 ShowWindow(Context->HScrollHandle, SW_SHOW);
4709 Context->HScrollVisible =
TRUE;
4713 ShowWindow(Context->HScrollHandle, SW_HIDE);
4714 Context->HScrollVisible =
FALSE;
4717 if ((Context->HScrollVisible != oldHScrollVisible) && Context->FixedDividerVisible && Context->AnimateDivider)
4719 rect.left = Context->FixedWidth;
4720 rect.top = Context->HeaderHeight;
4721 rect.right = Context->FixedWidth + 1;
4722 rect.bottom = Context->ClientRect.bottom;
4723 InvalidateRect(Context->Handle, &rect,
FALSE);
4726 if (deltaRows != 0 || deltaX != 0)
4729 ShowWindow(Context->FillerBoxHandle, (Context->VScrollVisible && Context->HScrollVisible) ? SW_SHOW : SW_HIDE);
4734 _In_
LONG DeltaRows,
4738 SCROLLINFO scrollInfo;
4746 scrollInfo.cbSize =
sizeof(SCROLLINFO);
4747 scrollInfo.fMask = SIF_POS;
4749 if (DeltaRows != 0 && Context->VScrollVisible)
4751 GetScrollInfo(Context->VScrollHandle, SB_CTL, &scrollInfo);
4752 oldPosition = scrollInfo.nPos;
4754 if (DeltaRows == MINLONG)
4755 scrollInfo.nPos = 0;
4756 else if (DeltaRows == MAXLONG)
4757 scrollInfo.nPos = Context->FlatList->Count - 1;
4759 scrollInfo.nPos += DeltaRows;
4761 SetScrollInfo(Context->VScrollHandle, SB_CTL, &scrollInfo,
TRUE);
4762 GetScrollInfo(Context->VScrollHandle, SB_CTL, &scrollInfo);
4763 Context->VScrollPosition = scrollInfo.nPos;
4764 deltaRows = scrollInfo.nPos - oldPosition;
4767 if (DeltaX != 0 && Context->HScrollVisible)
4769 GetScrollInfo(Context->HScrollHandle, SB_CTL, &scrollInfo);
4770 oldPosition = scrollInfo.nPos;
4772 if (DeltaX == MINLONG)
4773 scrollInfo.nPos = 0;
4774 else if (DeltaX == MAXLONG)
4775 scrollInfo.nPos = Context->TotalViewX;
4777 scrollInfo.nPos += DeltaX;
4779 SetScrollInfo(Context->HScrollHandle, SB_CTL, &scrollInfo,
TRUE);
4780 GetScrollInfo(Context->HScrollHandle, SB_CTL, &scrollInfo);
4781 Context->HScrollPosition = scrollInfo.nPos;
4782 deltaX = scrollInfo.nPos - oldPosition;
4785 if (deltaRows != 0 || deltaX != 0)
4791 _In_
LONG DeltaRows,
4798 rect.top = Context->HeaderHeight;
4799 rect.bottom = Context->ClientRect.bottom;
4804 rect.right = Context->ClientRect.right - (Context->VScrollVisible ? Context->VScrollWidth : 0);
4808 -DeltaRows * Context->RowHeight,
4819 if (Context->FlatList->Count != 0)
4821 deltaY = DeltaRows * Context->RowHeight;
4829 rect.right = Context->NormalLeft;
4842 rect.left = Context->NormalLeft;
4843 rect.right = Context->ClientRect.right - (Context->VScrollVisible ? Context->VScrollWidth : 0);
4862 _In_ BOOLEAN Horizontal,
4863 _In_ BOOLEAN Positive
4866 SCROLLINFO scrollInfo;
4868 scrollInfo.cbSize =
sizeof(SCROLLINFO);
4869 scrollInfo.fMask = SIF_RANGE | SIF_PAGE | SIF_POS;
4872 GetScrollInfo(Context->VScrollHandle, SB_CTL, &scrollInfo);
4874 GetScrollInfo(Context->HScrollHandle, SB_CTL, &scrollInfo);
4878 if (scrollInfo.nPage != 0)
4879 scrollInfo.nMax -= scrollInfo.nPage - 1;
4881 return scrollInfo.nPos < scrollInfo.nMax;
4885 return scrollInfo.nPos > scrollInfo.nMin;
4893 _In_ PRECT PaintRect
4897 LONG vScrollPosition;
4898 LONG hScrollPosition;
4899 LONG firstRowToUpdate;
4900 LONG lastRowToUpdate;
4907 BOOLEAN fixedUpdate;
4908 LONG normalUpdateLeftX;
4909 LONG normalUpdateRightX;
4910 LONG normalUpdateLeftIndex;
4911 LONG normalUpdateRightIndex;
4919 viewRect = Context->ClientRect;
4921 if (Context->VScrollVisible)
4922 viewRect.right -= Context->VScrollWidth;
4924 vScrollPosition = Context->VScrollPosition;
4925 hScrollPosition = Context->HScrollPosition;
4929 firstRowToUpdate = (PaintRect->top - Context->HeaderHeight) / Context->RowHeight;
4930 lastRowToUpdate = (PaintRect->bottom - 1 - Context->HeaderHeight) / Context->RowHeight;
4932 if (firstRowToUpdate < 0)
4933 firstRowToUpdate = 0;
4936 rowRect.top = Context->HeaderHeight + firstRowToUpdate * Context->RowHeight;
4937 rowRect.right = Context->NormalLeft + Context->TotalViewX - Context->HScrollPosition;
4938 rowRect.bottom = rowRect.top + Context->RowHeight;
4942 firstRowToUpdate += vScrollPosition;
4943 lastRowToUpdate += vScrollPosition;
4945 if (lastRowToUpdate >= (
LONG)Context->FlatList->Count)
4946 lastRowToUpdate = Context->FlatList->Count - 1;
4950 fixedUpdate =
FALSE;
4952 if (Context->FixedColumnVisible && PaintRect->left < Context->FixedWidth)
4955 x = Context->NormalLeft - hScrollPosition;
4956 normalUpdateLeftX = viewRect.right;
4957 normalUpdateLeftIndex = 0;
4958 normalUpdateRightX = 0;
4959 normalUpdateRightIndex = -1;
4961 for (j = 0; j < (
LONG)Context->NumberOfColumnsByDisplay; j++)
4963 column = Context->ColumnsByDisplay[j];
4965 if (x + column->
Width >= Context->NormalLeft && x + column->
Width > PaintRect->left && x < PaintRect->right)
4967 if (normalUpdateLeftX > x)
4969 normalUpdateLeftX = x;
4970 normalUpdateLeftIndex = j;
4973 if (normalUpdateRightX < x + column->Width)
4975 normalUpdateRightX = x + column->
Width;
4976 normalUpdateRightIndex = j;
4985 if (normalUpdateRightIndex >= (
LONG)Context->NumberOfColumnsByDisplay)
4986 normalUpdateRightIndex = Context->NumberOfColumnsByDisplay - 1;
4990 SelectObject(hdc, Context->Font);
4991 SetBkMode(hdc, TRANSPARENT);
4993 for (i = firstRowToUpdate; i <= lastRowToUpdate; i++)
4995 node = Context->FlatList->Items[i];
5001 if (node->
Selected && !Context->ThemeHasItemBackground)
5004 if (Context->HasFocus)
5006 SetTextColor(hdc, GetSysColor(COLOR_HIGHLIGHTTEXT));
5007 backBrush = GetSysColorBrush(COLOR_HIGHLIGHT);
5011 SetTextColor(hdc, GetSysColor(COLOR_BTNTEXT));
5012 backBrush = GetSysColorBrush(COLOR_BTNFACE);
5019 backBrush = GetStockObject(DC_BRUSH);
5022 FillRect(hdc, &rowRect, backBrush);
5024 if (Context->ThemeHasItemBackground)
5032 if (i == Context->HotNodeIndex)
5033 stateId = TREIS_HOTSELECTED;
5034 else if (!Context->HasFocus)
5035 stateId = TREIS_SELECTEDNOTFOCUS;
5037 stateId = TREIS_SELECTED;
5041 if (i == Context->HotNodeIndex)
5042 stateId = TREIS_HOT;
5049 if (!Context->FixedColumnVisible)
5051 rowRect.left = Context->NormalLeft - hScrollPosition;
5067 cellRect.top = rowRect.top;
5068 cellRect.bottom = rowRect.bottom;
5073 cellRect.right = Context->FixedWidth;
5074 PhTnpDrawCell(Context, hdc, &cellRect, node, Context->FixedColumn, i, -1);
5079 if (normalUpdateLeftX < normalUpdateRightX)
5081 cellRect.left = normalUpdateLeftX;
5082 cellRect.right = cellRect.left;
5084 oldClipRegion = CreateRectRgn(0, 0, 0, 0);
5086 if (GetClipRgn(hdc, oldClipRegion) != 1)
5088 DeleteObject(oldClipRegion);
5089 oldClipRegion = NULL;
5092 IntersectClipRect(hdc, Context->NormalLeft, cellRect.top, viewRect.right, cellRect.bottom);
5094 for (j = normalUpdateLeftIndex; j <= normalUpdateRightIndex; j++)
5096 column = Context->ColumnsByDisplay[j];
5098 cellRect.left = cellRect.right;
5099 cellRect.right = cellRect.left + column->
Width;
5103 SelectClipRgn(hdc, oldClipRegion);
5107 DeleteObject(oldClipRegion);
5111 rowRect.top += Context->RowHeight;
5112 rowRect.bottom += Context->RowHeight;
5115 if (lastRowToUpdate == Context->FlatList->Count - 1)
5118 rowRect.bottom = viewRect.bottom;
5119 FillRect(hdc, &rowRect, GetSysColorBrush(COLOR_WINDOW));
5122 if (normalTotalX < viewRect.right && viewRect.right > PaintRect->left && normalTotalX < PaintRect->right)
5125 rowRect.left = normalTotalX;
5126 rowRect.top = Context->HeaderHeight;
5127 rowRect.right = viewRect.right;
5128 rowRect.bottom = viewRect.bottom;
5129 FillRect(hdc, &rowRect, GetSysColorBrush(COLOR_WINDOW));
5132 if (Context->FlatList->Count == 0 && Context->EmptyText.Length != 0)
5137 textRect.top = Context->HeaderHeight + 10;
5138 textRect.right = viewRect.right - 20;
5139 textRect.bottom = viewRect.bottom - 5;
5141 SetTextColor(hdc, GetSysColor(COLOR_GRAYTEXT));
5144 Context->EmptyText.Buffer,
5145 (ULONG)Context->EmptyText.Length / 2,
5147 DT_NOPREFIX | DT_CENTER | DT_END_ELLIPSIS
5151 if (Context->FixedDividerVisible && Context->FixedWidth >= PaintRect->left && Context->FixedWidth < PaintRect->right)
5156 if (Context->DragSelectionActive)
5168 if (!Node->s.CachedColorValid)
5172 getNodeColor.
Flags = 0;
5173 getNodeColor.
Node = Node;
5174 getNodeColor.
BackColor = RGB(0xff, 0xff, 0xff);
5175 getNodeColor.
ForeColor = RGB(0x00, 0x00, 0x00);
5177 if (Context->Callback(
5182 Context->CallbackContext
5185 Node->BackColor = getNodeColor.
BackColor;
5186 Node->ForeColor = getNodeColor.
ForeColor;
5190 Node->s.CachedColorValid =
TRUE;
5194 Node->BackColor = getNodeColor.
BackColor;
5195 Node->ForeColor = getNodeColor.
ForeColor;
5199 Node->s.DrawForeColor = Node->ForeColor;
5201 if (Node->UseTempBackColor)
5202 Node->s.DrawBackColor = Node->TempBackColor;
5204 Node->s.DrawBackColor = Node->BackColor;
5206 if (!Node->s.CachedFontValid)
5210 getNodeFont.
Flags = 0;
5211 getNodeFont.
Node = Node;
5212 getNodeFont.
Font = NULL;
5214 if (Context->Callback(
5219 Context->CallbackContext
5222 Node->Font = getNodeFont.
Font;
5225 Node->s.CachedFontValid =
TRUE;
5233 if (!Node->s.CachedIconValid)
5237 getNodeIcon.
Flags = 0;
5238 getNodeIcon.
Node = Node;
5239 getNodeIcon.
Icon = NULL;
5241 if (Context->Callback(
5246 Context->CallbackContext
5249 Node->Icon = getNodeIcon.
Icon;
5252 Node->s.CachedIconValid =
TRUE;
5260 if (Node->UseAutoForeColor || Node->UseTempBackColor)
5263 Node->s.DrawForeColor = RGB(0x00, 0x00, 0x00);
5265 Node->s.DrawForeColor = RGB(0xff, 0xff, 0xff);
5272 _In_ PRECT CellRect,
5276 _In_
LONG ColumnIndex
5284 LONG iconVerticalMargin;
5287 textFlags = Column->TextFlags;
5289 textRect = *CellRect;
5296 iconVerticalMargin = ((textRect.bottom - textRect.top) - SmallIconHeight) / 2;
5298 textRect.top += iconVerticalMargin;
5299 textRect.bottom -= iconVerticalMargin;
5301 if (Column == Context->FirstColumn)
5306 textRect.left += Node->Level * SmallIconWidth;
5309 needsClip = Column->Width < textRect.left + (Context->CanAnyExpand ? SmallIconWidth : 0) + (Node->Icon ? SmallIconWidth : 0);
5313 oldClipRegion = CreateRectRgn(0, 0, 0, 0);
5315 if (GetClipRgn(hdc, oldClipRegion) != 1)
5317 DeleteObject(oldClipRegion);
5318 oldClipRegion = NULL;
5322 IntersectClipRect(hdc, CellRect->left, textRect.top, CellRect->right, textRect.bottom);
5325 if (Context->CanAnyExpand)
5327 BOOLEAN drewUsingTheme =
FALSE;
5330 if (!Node->s.IsLeaf)
5334 themeRect.left = textRect.left;
5335 themeRect.right = themeRect.left + SmallIconWidth;
5336 themeRect.top = textRect.top;
5337 themeRect.bottom = themeRect.top + SmallIconHeight;
5339 if (Context->ThemeHasGlyph)
5344 partId = (RowIndex == Context->HotNodeIndex && Node->s.PlusMinusHot && Context->ThemeHasHotGlyph) ? TVP_HOTGLYPH : TVP_GLYPH;
5345 stateId = Node->Expanded ? GLPS_OPENED : GLPS_CLOSED;
5355 drewUsingTheme =
TRUE;
5358 if (!drewUsingTheme)
5364 glyphWidth = SmallIconWidth / 2;
5365 glyphHeight = SmallIconHeight / 2;
5367 glyphRect.left = textRect.left + (SmallIconWidth - glyphWidth) / 2;
5368 glyphRect.right = glyphRect.left + glyphWidth;
5369 glyphRect.top = textRect.top + (SmallIconHeight - glyphHeight) / 2;
5370 glyphRect.bottom = glyphRect.top + glyphHeight;
5376 textRect.left += SmallIconWidth;
5399 SelectClipRgn(hdc, oldClipRegion);
5402 DeleteObject(oldClipRegion);
5405 if (textRect.left > textRect.right)
5406 textRect.left = textRect.right;
5409 if (Column->CustomDraw)
5415 customDraw.
Node = Node;
5416 customDraw.
Column = Column;
5417 customDraw.
Dc = hdc;
5427 savedDc = SaveDC(hdc);
5428 result = Context->Callback(Context->Handle,
TreeNewCustomDraw, &customDraw, NULL, Context->CallbackContext);
5429 RestoreDC(hdc, savedDc);
5437 if (!(textFlags & (DT_PATH_ELLIPSIS | DT_WORD_ELLIPSIS)))
5438 textFlags |= DT_END_ELLIPSIS;
5440 textFlags |= DT_NOPREFIX | DT_VCENTER | DT_SINGLELINE;
5442 textRect.top = CellRect->top;
5443 textRect.bottom = CellRect->bottom;
5446 oldFont = SelectObject(hdc, font);
5457 SelectObject(hdc, oldFont);
5468 if (Context->AnimateDivider)
5470 if (Context->DividerHot == 0 && !Context->HScrollVisible)
5473 if (Context->DividerHot < 100)
5475 BLENDFUNCTION blendFunction;
5481 points[0].x = Context->ClientRect.right;
5482 points[0].y = Context->HeaderHeight;
5483 points[1].x = Context->ClientRect.right;
5484 points[1].y = Context->ClientRect.bottom;
5485 SetDCPenColor(Context->BufferedContext, RGB(0x77, 0x77, 0x77));
5486 SelectObject(Context->BufferedContext, GetStockObject(DC_PEN));
5487 Polyline(Context->BufferedContext, points, 2);
5489 blendFunction.BlendOp = AC_SRC_OVER;
5490 blendFunction.BlendFlags = 0;
5491 blendFunction.AlphaFormat = 0;
5495 if (!Context->HScrollVisible)
5496 blendFunction.SourceConstantAlpha = (UCHAR)(Context->DividerHot * 255 / 100);
5498 blendFunction.SourceConstantAlpha = 55 + (UCHAR)(Context->DividerHot * 2);
5502 Context->FixedWidth,
5503 Context->HeaderHeight,
5505 Context->ClientRect.bottom - Context->HeaderHeight,
5506 Context->BufferedContext,
5507 Context->ClientRect.right,
5508 Context->HeaderHeight,
5510 Context->ClientRect.bottom - Context->HeaderHeight,
5518 points[0].x = Context->FixedWidth;
5519 points[0].y = Context->HeaderHeight;
5520 points[1].x = Context->FixedWidth;
5521 points[1].y = Context->ClientRect.bottom;
5522 SetDCPenColor(hdc, RGB(0x77, 0x77, 0x77));
5523 SelectObject(hdc, GetStockObject(DC_PEN));
5524 Polyline(hdc, points, 2);
5538 savedDc = SaveDC(hdc);
5540 SelectObject(hdc, GetStockObject(DC_PEN));
5541 SetDCPenColor(hdc, RGB(0x55, 0x55, 0x55));
5542 SelectObject(hdc, GetStockObject(DC_BRUSH));
5543 SetDCBrushColor(hdc, RGB(0xff, 0xff, 0xff));
5545 width = Rect->right - Rect->left;
5546 height = Rect->bottom - Rect->top;
5549 Rectangle(hdc, Rect->left, Rect->top, Rect->right + 1, Rect->bottom + 1);
5551 SetDCPenColor(hdc, RGB(0x00, 0x00, 0x00));
5554 points[0].x = Rect->left + 2;
5555 points[0].y = Rect->top + height / 2;
5556 points[1].x = Rect->right - 2 + 1;
5557 points[1].y = points[0].y;
5558 Polyline(hdc, points, 2);
5563 points[0].x = Rect->left + width / 2;
5564 points[0].y = Rect->top + 2;
5565 points[1].x = points[0].x;
5566 points[1].y = Rect->bottom - 2 + 1;
5567 Polyline(hdc, points, 2);
5570 RestoreDC(hdc, savedDc);
5580 BOOLEAN drewWithAlpha;
5586 if (rect.right - rect.left == 0 || rect.bottom - rect.top == 0)
5589 drewWithAlpha =
FALSE;
5591 if (Context->SelectionRectangleAlpha)
5594 BITMAPINFOHEADER header;
5599 BLENDFUNCTION blendFunction;
5601 tempDc = CreateCompatibleDC(hdc);
5605 memset(&header, 0,
sizeof(BITMAPINFOHEADER));
5606 header.biSize =
sizeof(BITMAPINFOHEADER);
5608 header.biHeight = 1;
5609 header.biPlanes = 1;
5610 header.biBitCount = 24;
5611 bitmap = CreateDIBSection(tempDc, (BITMAPINFO *)&header, DIB_RGB_COLORS, &bits, NULL, 0);
5616 FrameRect(hdc, &rect, GetSysColorBrush(COLOR_HIGHLIGHT));
5620 oldBitmap = SelectObject(tempDc, bitmap);
5624 tempRect.bottom = 1;
5625 FillRect(tempDc, &tempRect, GetSysColorBrush(COLOR_HOTLIGHT));
5627 blendFunction.BlendOp = AC_SRC_OVER;
5628 blendFunction.BlendFlags = 0;
5629 blendFunction.SourceConstantAlpha = 70;
5630 blendFunction.AlphaFormat = 0;
5636 rect.right - rect.left,
5637 rect.bottom - rect.top,
5646 drewWithAlpha =
TRUE;
5648 SelectObject(tempDc, oldBitmap);
5649 DeleteObject(bitmap);
5658 DrawFocusRect(hdc, &rect);
5669 LONG sizingBorderWidth;
5673 GetWindowRect(Context->Handle, &windowRect);
5674 windowRect.right -= windowRect.left;
5675 windowRect.bottom -= windowRect.top;
5676 windowRect.left = 0;
5679 clientRect.left = windowRect.left + Context->SystemEdgeX;
5680 clientRect.top = windowRect.top + Context->SystemEdgeY;
5681 clientRect.right = windowRect.right - Context->SystemEdgeX;
5682 clientRect.bottom = windowRect.bottom - Context->SystemEdgeY;
5685 ExcludeClipRect(hdc, clientRect.left, clientRect.top, clientRect.right, clientRect.bottom);
5693 if (SUCCEEDED(
GetThemeInt_I(Context->ThemeData, 0, 0, TMT_SIZINGBORDERWIDTH, &sizingBorderWidth)))
5695 borderX = sizingBorderWidth;
5696 borderY = sizingBorderWidth;
5700 borderX = Context->SystemBorderX;
5701 borderY = Context->SystemBorderY;
5704 if (borderX < Context->SystemEdgeX || borderY < Context->SystemEdgeY)
5706 windowRect.left += Context->SystemEdgeX - borderX;
5707 windowRect.top += Context->SystemEdgeY - borderY;
5708 windowRect.right -= Context->SystemEdgeX - borderX;
5709 windowRect.bottom -= Context->SystemEdgeY - borderY;
5710 FillRect(hdc, &windowRect, GetSysColorBrush(COLOR_WINDOW));
5720 Context->TooltipsHandle = CreateWindowEx(
5724 WS_POPUP | TTS_NOPREFIX,
5731 Context->InstanceHandle,
5735 if (!Context->TooltipsHandle)
5739 memset(&toolInfo, 0,
sizeof(TOOLINFO));
5740 toolInfo.cbSize =
sizeof(TOOLINFO);
5741 toolInfo.uFlags = TTF_TRANSPARENT;
5742 toolInfo.hwnd = Context->Handle;
5744 toolInfo.lpszText = LPSTR_TEXTCALLBACK;
5746 SendMessage(Context->TooltipsHandle, TTM_ADDTOOL, 0, (LPARAM)&toolInfo);
5749 toolInfo.uFlags = 0;
5750 toolInfo.hwnd = Context->FixedHeaderHandle;
5752 toolInfo.lpszText = LPSTR_TEXTCALLBACK;
5754 SendMessage(Context->TooltipsHandle, TTM_ADDTOOL, 0, (LPARAM)&toolInfo);
5757 toolInfo.uFlags = 0;
5758 toolInfo.hwnd = Context->HeaderHandle;
5760 toolInfo.lpszText = LPSTR_TEXTCALLBACK;
5762 SendMessage(Context->TooltipsHandle, TTM_ADDTOOL, 0, (LPARAM)&toolInfo);
5766 Context->FixedHeaderOldWndProc = (WNDPROC)GetWindowLongPtr(Context->FixedHeaderHandle, GWLP_WNDPROC);
5769 Context->HeaderOldWndProc = (WNDPROC)GetWindowLongPtr(Context->HeaderHandle, GWLP_WNDPROC);
5771 SetWindowLongPtr(Context->HeaderHandle, GWLP_WNDPROC, (LONG_PTR)PhTnpHeaderHookWndProc);
5773 SendMessage(Context->TooltipsHandle, TTM_SETMAXTIPWIDTH, 0, MAXSHORT);
5774 SendMessage(Context->TooltipsHandle, WM_SETFONT, (WPARAM)Context->Font,
FALSE);
5775 Context->TooltipFont = Context->Font;
5785 BOOLEAN unfoldingTooltip;
5786 BOOLEAN unfoldingTooltipFromViewCancelled;
5791 hitTest.
Point = *Point;
5795 if (Context->DragSelectionActive)
5804 if (Context->TooltipIndex != hitTest.
Node->
Index || Context->TooltipId != hitTest.
Column->
Id)
5806 Context->TooltipIndex = hitTest.
Node->
Index;
5807 Context->TooltipId = hitTest.
Column->
Id;
5809 getCellTooltip.
Flags = 0;
5810 getCellTooltip.
Node = hitTest.
Node;
5814 getCellTooltip.
Font = Context->Font;
5817 unfoldingTooltip =
FALSE;
5818 unfoldingTooltipFromViewCancelled =
FALSE;
5824 viewRight = Context->ClientRect.right - (Context->VScrollVisible ? Context->VScrollWidth : 0);
5831 unfoldingTooltip =
TRUE;
5837 unfoldingTooltip =
TRUE;
5839 unfoldingTooltipFromViewCancelled =
TRUE;
5842 if (unfoldingTooltip)
5848 Context->TooltipRect = parts.
TextRect;
5852 Context->Callback(Context->Handle,
TreeNewGetCellTooltip, &getCellTooltip, NULL, Context->CallbackContext);
5854 Context->TooltipUnfolding = getCellTooltip.
Unfolding;
5864 if (unfoldingTooltipFromViewCancelled)
5868 Context->TooltipIndex = -1;
5869 Context->TooltipId = -1;
5873 Context->NewTooltipFont = getCellTooltip.
Font;
5875 if (!Context->NewTooltipFont)
5876 Context->NewTooltipFont = Context->Font;
5879 SendMessage(Context->TooltipsHandle, TTM_SETMAXTIPWIDTH, 0, getCellTooltip.
MaximumWidth);
5881 SendMessage(Context->TooltipsHandle, TTM_SETMAXTIPWIDTH, 0, MAXSHORT);
5884 if (Context->TooltipText)
5885 *Text = Context->TooltipText->Buffer;
5894 if (Context->TooltipFont != Context->NewTooltipFont)
5896 Context->TooltipFont = Context->NewTooltipFont;
5897 SendMessage(Context->TooltipsHandle, WM_SETFONT, (WPARAM)Context->TooltipFont,
FALSE);
5900 if (!Context->TooltipUnfolding)
5903 Context->TooltipsHandle,
5909 SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE | SWP_HIDEWINDOW
5915 rect = Context->TooltipRect;
5916 SendMessage(Context->TooltipsHandle, TTM_ADJUSTRECT,
TRUE, (LPARAM)&rect);
5917 MapWindowPoints(Context->Handle, NULL, (POINT *)&rect, 2);
5919 Context->TooltipsHandle,
5925 SWP_NOSIZE | SWP_NOACTIVATE | SWP_HIDEWINDOW
5935 Context->TooltipIndex = -1;
5936 Context->TooltipId = -1;
5937 Context->TooltipColumnId = -1;
5944 if (Context->TooltipsHandle)
5946 SendMessage(Context->TooltipsHandle, TTM_POP, 0, 0);
5955 _Out_opt_ PRECT ItemRect
5963 if (!Context->FixedColumnVisible)
5966 column = Context->FixedColumn;
5968 if (!Header_GetItemRect(Context->FixedHeaderHandle, 0, &itemRect))
5973 HDHITTESTINFO hitTestInfo;
5975 hitTestInfo.pt = *Point;
5976 hitTestInfo.flags = 0;
5977 hitTestInfo.iItem = -1;
5979 if (SendMessage(Context->HeaderHandle, HDM_HITTEST, 0, (LPARAM)&hitTestInfo) != -1 && hitTestInfo.iItem != -1)
5983 item.mask = HDI_LPARAM;
5985 if (!Header_GetItem(Context->HeaderHandle, hitTestInfo.iItem, &item))
5990 if (!Header_GetItemRect(Context->HeaderHandle, hitTestInfo.iItem, &itemRect))
6000 *ItemRect = itemRect;
6025 if (Context->TooltipColumnId != column->
Id)
6029 text = column->
Text;
6032 if (!(hdc = GetDC(Context->Handle)))
6035 SelectObject(hdc, Context->Font);
6037 result = GetTextExtentPoint32(hdc, text, (ULONG)textCount, &textSize);
6038 ReleaseDC(Context->Handle, hdc);
6043 if (textSize.cx + 6 + 6 <= itemRect.right - itemRect.left)
6046 Context->TooltipColumnId = column->
Id;
6050 *Text = Context->TooltipText->Buffer;
6053 Context->NewTooltipFont = Context->Font;
6054 Context->TooltipUnfolding =
FALSE;
6086 SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)oldWndProc);
6097 point.x = GET_X_LPARAM(lParam);
6098 point.y = GET_Y_LPARAM(lParam);
6114 NMHDR *header = (NMHDR *)lParam;
6116 switch (header->code)
6118 case TTN_GETDISPINFO:
6122 NMTTDISPINFO *info = (NMTTDISPINFO *)header;
6154 case WM_LBUTTONDOWN:
6156 case WM_RBUTTONDOWN:
6158 case WM_MBUTTONDOWN:
6165 message.hwnd = hwnd;
6166 message.message = uMsg;
6167 message.wParam = wParam;
6168 message.lParam = lParam;
6169 SendMessage(context->
TooltipsHandle, TTM_RELAYEVENT, 0, (LPARAM)&message);
6175 return CallWindowProc(oldWndProc, hwnd, uMsg, wParam, lParam);
6182 _In_ BOOLEAN DispatchMessages,
6183 _Out_opt_ PULONG CancelledByMessage
6191 dragRect.left = CursorX - Context->SystemDragX;
6192 dragRect.top = CursorY - Context->SystemDragY;
6193 dragRect.right = CursorX + Context->SystemDragX;
6194 dragRect.bottom = CursorY + Context->SystemDragY;
6195 MapWindowPoints(Context->Handle, NULL, (POINT *)&dragRect, 2);
6197 SetCapture(Context->Handle);
6199 if (CancelledByMessage)
6200 *CancelledByMessage = 0;
6206 if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
6208 switch (msg.message)
6210 case WM_LBUTTONDOWN:
6212 case WM_RBUTTONDOWN:
6216 if (CancelledByMessage)
6217 *CancelledByMessage = msg.message;
6221 if (msg.pt.x < dragRect.left || msg.pt.x >= dragRect.right ||
6222 msg.pt.y < dragRect.top || msg.pt.y >= dragRect.bottom)
6224 if (IsWindow(Context->Handle))
6231 if (DispatchMessages)
6233 TranslateMessage(&msg);
6234 DispatchMessage(&msg);
6243 }
while (IsWindow(Context->Handle) && GetCapture() == Context->Handle);
6257 BOOLEAN originFixed;
6262 BOOLEAN showContextMenu;
6266 originFixed = cursorX < Context->FixedWidth;
6268 dragRect.left = cursorX;
6269 dragRect.top = cursorY;
6270 dragRect.right = cursorX;
6271 dragRect.bottom = cursorY;
6272 oldDragRect = dragRect;
6273 Context->DragRect = dragRect;
6274 Context->DragSelectionActive =
TRUE;
6276 if (Context->DoubleBuffered)
6277 Context->SelectionRectangleAlpha =
TRUE;
6280 GetWindowRect(Context->Handle, &windowRect);
6282 cursorPoint.x = windowRect.left + cursorX;
6283 cursorPoint.y = windowRect.top + cursorY;
6285 showContextMenu =
FALSE;
6287 SetCapture(Context->Handle);
6291 if (!PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
6293 BOOLEAN leftOrRight;
6294 BOOLEAN aboveOrBelow;
6299 leftOrRight = cursorPoint.x < windowRect.left || cursorPoint.x > windowRect.right;
6300 aboveOrBelow = cursorPoint.y < windowRect.top || cursorPoint.y > windowRect.bottom;
6302 if ((Context->VScrollVisible && aboveOrBelow &&
PhTnpCanScroll(Context,
FALSE, cursorPoint.y > windowRect.bottom)) ||
6303 (Context->HScrollVisible && leftOrRight &&
PhTnpCanScroll(Context,
TRUE, cursorPoint.x > windowRect.right)))
6305 SetCursorPos(cursorPoint.x, cursorPoint.y);
6315 cursorPoint = msg.pt;
6317 switch (msg.message)
6319 case WM_LBUTTONDOWN:
6321 case WM_RBUTTONDOWN:
6322 case WM_MBUTTONDOWN:
6328 showContextMenu =
TRUE;
6336 LONG oldVScrollPosition;
6337 LONG oldHScrollPosition;
6347 newCursorX = GET_X_LPARAM(msg.lParam);
6348 newCursorY = GET_Y_LPARAM(msg.lParam);
6355 if (Context->VScrollVisible)
6357 if (cursorPoint.y < windowRect.top)
6358 deltaRows = -(windowRect.top - cursorPoint.y + Context->RowHeight - 1) / Context->RowHeight;
6359 else if (cursorPoint.y >= windowRect.bottom)
6360 deltaRows = (cursorPoint.y - windowRect.bottom + Context->RowHeight - 1) / Context->RowHeight;
6363 if (Context->HScrollVisible)
6365 if (cursorPoint.x < windowRect.left)
6366 deltaX = -(windowRect.left - cursorPoint.x);
6367 else if (cursorPoint.x >= windowRect.right)
6368 deltaX = cursorPoint.x - windowRect.right;
6371 oldVScrollPosition = Context->VScrollPosition;
6372 oldHScrollPosition = Context->HScrollPosition;
6374 if (deltaRows != 0 || deltaX != 0)
6377 newDeltaX = oldHScrollPosition - Context->HScrollPosition;
6378 newDeltaY = (oldVScrollPosition - Context->VScrollPosition) * Context->RowHeight;
6382 cursorX += newDeltaX;
6383 cursorY += newDeltaY;
6387 oldDragRect.left += newDeltaX;
6388 oldDragRect.top += newDeltaY;
6390 oldDragRect.right += newDeltaX;
6391 oldDragRect.bottom += newDeltaY;
6395 viewLeft = Context->FixedColumnVisible ? 0 : -Context->HScrollPosition;
6396 viewTop = Context->HeaderHeight - Context->VScrollPosition;
6397 viewRight = Context->NormalLeft + Context->TotalViewX - Context->HScrollPosition;
6398 viewBottom = Context->HeaderHeight + ((
LONG)Context->FlatList->Count - Context->VScrollPosition) * Context->RowHeight;
6400 temp = Context->ClientRect.right - (Context->VScrollVisible ? Context->VScrollWidth : 0);
6401 viewRight = max(viewRight, temp);
6402 temp = Context->ClientRect.bottom - ((!Context->FixedColumnVisible && Context->HScrollVisible) ? Context->HScrollHeight : 0);
6403 viewBottom = max(viewBottom, temp);
6405 if (newCursorX < viewLeft)
6406 newCursorX = viewLeft;
6407 if (newCursorX > viewRight)
6408 newCursorX = viewRight;
6409 if (newCursorY < viewTop)
6410 newCursorY = viewTop;
6411 if (newCursorY > viewBottom)
6412 newCursorY = viewBottom;
6416 if (cursorX < newCursorX)
6418 dragRect.left = cursorX;
6419 dragRect.right = newCursorX;
6423 dragRect.left = newCursorX;
6424 dragRect.right = cursorX;
6427 if (cursorY < newCursorY)
6429 dragRect.top = cursorY;
6430 dragRect.bottom = newCursorY;
6434 dragRect.top = newCursorY;
6435 dragRect.bottom = cursorY;
6439 if (dragRect.left == oldDragRect.left && dragRect.top == oldDragRect.top &&
6440 dragRect.right == oldDragRect.right && dragRect.bottom == oldDragRect.bottom)
6445 Context->DragRect = dragRect;
6448 totalRect.left = min(dragRect.left, oldDragRect.left);
6449 totalRect.top = min(dragRect.top, oldDragRect.top);
6450 totalRect.right = max(dragRect.right, oldDragRect.right);
6451 totalRect.bottom = max(dragRect.bottom, oldDragRect.bottom);
6455 RedrawWindow(Context->Handle, &totalRect, NULL, RDW_INVALIDATE | RDW_UPDATENOW);
6457 oldDragRect = dragRect;
6465 if (msg.wParam == VK_ESCAPE)
6475 InvalidateRect(Context->Handle, &rect,
FALSE);
6484 TranslateMessage(&msg);
6485 DispatchMessage(&msg);
6490 if (GetCapture() != Context->Handle)
6494 Context->DragSelectionActive =
FALSE;
6495 RedrawWindow(Context->Handle, &dragRect, NULL, RDW_INVALIDATE | RDW_UPDATENOW);
6497 if (showContextMenu)
6500 SendMessage(Context->Handle, WM_CONTEXTMENU, (WPARAM)Context->Handle, MAKELPARAM(windowRect.left + CursorX, windowRect.top + CursorY));
6506 _In_ ULONG VirtualKeys,
6509 _In_ PRECT TotalRect
6523 firstRow = (TotalRect->top - Context->HeaderHeight + Context->VScrollPosition * Context->RowHeight) / Context->RowHeight;
6524 lastRow = (TotalRect->bottom - 1 - Context->HeaderHeight + Context->VScrollPosition * Context->RowHeight) / Context->RowHeight;
6528 if (lastRow >= (
LONG)Context->FlatList->Count)
6529 lastRow = Context->FlatList->Count - 1;
6532 rowRect.top = Context->HeaderHeight + (firstRow - Context->VScrollPosition) * Context->RowHeight;
6533 rowRect.right = Context->NormalLeft + Context->TotalViewX - Context->HScrollPosition;
6534 rowRect.bottom = rowRect.top + Context->RowHeight;
6536 changedStart = lastRow;
6537 changedEnd = firstRow;
6540 for (i = firstRow; i <= lastRow; i++)
6545 node = Context->FlatList->Items[i];
6547 inOldRect = rowRect.top < OldRect->bottom && rowRect.bottom > OldRect->top &&
6548 rowRect.left < OldRect->right && rowRect.right > OldRect->left;
6549 inNewRect = rowRect.top < NewRect->bottom && rowRect.bottom > NewRect->top &&
6550 rowRect.left < NewRect->right && rowRect.right > NewRect->left;
6552 if (VirtualKeys & MK_CONTROL)
6558 if (changedStart > i)
6570 if (changedStart > i)
6577 rowRect.top = rowRect.bottom;
6578 rowRect.bottom += Context->RowHeight;
6581 if (changedStart <= changedEnd)
6588 InvalidateRect(Context->Handle, &rect,
FALSE);
6598 if (hdc = GetDC(Context->Handle))
6600 Context->BufferedContext = CreateCompatibleDC(hdc);
6602 if (!Context->BufferedContext)
6605 Context->BufferedContextRect = Context->ClientRect;
6606 Context->BufferedBitmap = CreateCompatibleBitmap(
6608 Context->BufferedContextRect.right + 1,
6609 Context->BufferedContextRect.bottom
6612 if (!Context->BufferedBitmap)
6614 DeleteDC(Context->BufferedContext);
6615 Context->BufferedContext = NULL;
6619 ReleaseDC(Context->Handle, hdc);
6620 Context->BufferedOldBitmap = SelectObject(Context->BufferedContext, Context->BufferedBitmap);
6630 SelectObject(Context->BufferedContext, Context->BufferedOldBitmap);
6631 DeleteObject(Context->BufferedBitmap);
6632 DeleteDC(Context->BufferedContext);
6634 Context->BufferedContext = NULL;
6635 Context->BufferedBitmap = NULL;
6640 _Out_ PPOINT ClientPoint
6646 position = GetMessagePos();
6647 point.x = GET_X_LPARAM(position);
6648 point.y = GET_Y_LPARAM(position);
6649 ScreenToClient(hwnd, &point);
6651 *ClientPoint = point;