2025-05-13 19:45:22 +03:00

803 lines
18 KiB
C

#ifndef _PH_TREENEWP_H
#define _PH_TREENEWP_H
// Important notes about pointers:
//
// All memory allocation for nodes and strings is handled by the user. This usually means there is a
// very limited time during which they can be safely accessed.
//
// Node pointers are valid through the duration of message processing, and also up to the next
// restructure operation, either user- or control- initiated. This means that state such as the
// focused node, hot node and mark node must be carefully preserved through restructuring. If
// restructuring is suspended by a set-redraw call, all nodes must be considered invalid and no user
// input can be handled.
//
// Strings are valid only through the duration of message processing.
typedef struct _PH_TREENEW_CONTEXT
{
HWND Handle;
PVOID InstanceHandle;
HWND FixedHeaderHandle;
HWND HeaderHandle;
HWND VScrollHandle;
HWND HScrollHandle;
HWND FillerBoxHandle;
HWND TooltipsHandle;
union
{
struct
{
ULONG FontOwned : 1;
ULONG Tracking : 1; // tracking for fixed divider
ULONG VScrollVisible : 1;
ULONG HScrollVisible : 1;
ULONG FixedColumnVisible : 1;
ULONG FixedDividerVisible : 1;
ULONG AnimateDivider : 1;
ULONG AnimateDividerFadingIn : 1;
ULONG AnimateDividerFadingOut : 1;
ULONG CanAnyExpand : 1;
ULONG TriState : 1;
ULONG HasFocus : 1;
ULONG ThemeInitialized : 1; // delay load theme data
ULONG ThemeActive : 1;
ULONG ThemeHasItemBackground : 1;
ULONG ThemeHasGlyph : 1;
ULONG ThemeHasHotGlyph : 1;
ULONG FocusNodeFound : 1; // used to preserve the focused node across restructuring
ULONG SearchFailed : 1; // used to prevent multiple beeps
ULONG SearchSingleCharMode : 1; // LV style single-character search
ULONG TooltipUnfolding : 1; // whether the current tooltip is unfolding
ULONG DoubleBuffered : 1;
ULONG SuspendUpdateStructure : 1;
ULONG SuspendUpdateLayout : 1;
ULONG SuspendUpdateMoveMouse : 1;
ULONG DragSelectionActive : 1;
ULONG SelectionRectangleAlpha : 1; // use alpha blending for the selection rectangle
ULONG CustomRowHeight : 1;
ULONG Spare : 4;
};
ULONG Flags;
};
ULONG Style;
ULONG ExtendedStyle;
ULONG ExtendedFlags;
HFONT Font;
HCURSOR Cursor;
HCURSOR DividerCursor;
RECT ClientRect;
LONG HeaderHeight;
LONG RowHeight;
ULONG VScrollWidth;
ULONG HScrollHeight;
LONG VScrollPosition;
LONG HScrollPosition;
LONG FixedWidth; // width of the fixed part of the tree list
LONG FixedWidthMinimum;
LONG NormalLeft; // FixedWidth + 1 if there is a fixed column, otherwise 0
PPH_TREENEW_NODE FocusNode;
ULONG HotNodeIndex;
ULONG MarkNodeIndex; // selection mark
ULONG MouseDownLast;
POINT MouseDownLocation;
PPH_TREENEW_CALLBACK Callback;
PVOID CallbackContext;
PPH_TREENEW_COLUMN *Columns; // columns, indexed by ID
ULONG NextId;
ULONG AllocatedColumns;
ULONG NumberOfColumns; // just a statistic; do not use for actual logic
PPH_TREENEW_COLUMN *ColumnsByDisplay; // columns, indexed by display order (excluding the fixed column)
ULONG AllocatedColumnsByDisplay;
ULONG NumberOfColumnsByDisplay; // the number of visible columns (excluding the fixed column)
LONG TotalViewX; // total width of normal columns
PPH_TREENEW_COLUMN FixedColumn;
PPH_TREENEW_COLUMN FirstColumn; // first column, by display order (including the fixed column)
PPH_TREENEW_COLUMN LastColumn; // last column, by display order (including the fixed column)
PPH_TREENEW_COLUMN ResizingColumn;
LONG OldColumnWidth;
LONG TrackStartX;
LONG TrackOldFixedWidth;
ULONG DividerHot; // 0 for un-hot, 100 for completely hot
PPH_LIST FlatList;
ULONG SortColumn; // ID of the column to sort by
PH_SORT_ORDER SortOrder;
FLOAT VScrollRemainder;
FLOAT HScrollRemainder;
LONG SearchMessageTime;
PWSTR SearchString;
ULONG SearchStringCount;
ULONG AllocatedSearchString;
ULONG TooltipIndex;
ULONG TooltipId;
PPH_STRING TooltipText;
RECT TooltipRect; // text rectangle of an unfolding tooltip
HFONT TooltipFont;
HFONT NewTooltipFont;
ULONG TooltipColumnId;
WNDPROC FixedHeaderOldWndProc;
WNDPROC HeaderOldWndProc;
TEXTMETRIC TextMetrics;
HTHEME ThemeData;
LONG SystemBorderX;
LONG SystemBorderY;
LONG SystemEdgeX;
LONG SystemEdgeY;
HDC BufferedContext;
HBITMAP BufferedOldBitmap;
HBITMAP BufferedBitmap;
RECT BufferedContextRect;
LONG SystemDragX;
LONG SystemDragY;
RECT DragRect;
LONG EnableRedraw;
HRGN SuspendUpdateRegion;
PH_STRINGREF EmptyText;
} PH_TREENEW_CONTEXT, *PPH_TREENEW_CONTEXT;
LRESULT CALLBACK PhTnpWndProc(
_In_ HWND hwnd,
_In_ UINT uMsg,
_In_ WPARAM wParam,
_In_ LPARAM lParam
);
BOOLEAN NTAPI PhTnpNullCallback(
_In_ HWND hwnd,
_In_ PH_TREENEW_MESSAGE Message,
_In_opt_ PVOID Parameter1,
_In_opt_ PVOID Parameter2,
_In_opt_ PVOID Context
);
VOID PhTnpCreateTreeNewContext(
_Out_ PPH_TREENEW_CONTEXT *Context
);
VOID PhTnpDestroyTreeNewContext(
_In_ PPH_TREENEW_CONTEXT Context
);
// Event handlers
BOOLEAN PhTnpOnCreate(
_In_ HWND hwnd,
_In_ PPH_TREENEW_CONTEXT Context,
_In_ CREATESTRUCT *CreateStruct
);
VOID PhTnpOnSize(
_In_ HWND hwnd,
_In_ PPH_TREENEW_CONTEXT Context
);
VOID PhTnpOnSetFont(
_In_ HWND hwnd,
_In_ PPH_TREENEW_CONTEXT Context,
_In_opt_ HFONT Font,
_In_ LOGICAL Redraw
);
VOID PhTnpOnStyleChanged(
_In_ HWND hwnd,
_In_ PPH_TREENEW_CONTEXT Context,
_In_ LONG Type,
_In_ STYLESTRUCT *StyleStruct
);
VOID PhTnpOnSettingChange(
_In_ HWND hwnd,
_In_ PPH_TREENEW_CONTEXT Context
);
VOID PhTnpOnThemeChanged(
_In_ HWND hwnd,
_In_ PPH_TREENEW_CONTEXT Context
);
ULONG PhTnpOnGetDlgCode(
_In_ HWND hwnd,
_In_ PPH_TREENEW_CONTEXT Context,
_In_ ULONG VirtualKey,
_In_opt_ PMSG Message
);
VOID PhTnpOnPaint(
_In_ HWND hwnd,
_In_ PPH_TREENEW_CONTEXT Context
);
VOID PhTnpOnPrintClient(
_In_ HWND hwnd,
_In_ PPH_TREENEW_CONTEXT Context,
_In_ HDC hdc,
_In_ ULONG Flags
);
BOOLEAN PhTnpOnNcPaint(
_In_ HWND hwnd,
_In_ PPH_TREENEW_CONTEXT Context,
_In_opt_ HRGN UpdateRegion
);
BOOLEAN PhTnpOnSetCursor(
_In_ HWND hwnd,
_In_ PPH_TREENEW_CONTEXT Context,
_In_ HWND CursorWindowHandle
);
VOID PhTnpOnTimer(
_In_ HWND hwnd,
_In_ PPH_TREENEW_CONTEXT Context,
_In_ ULONG Id
);
VOID PhTnpOnMouseMove(
_In_ HWND hwnd,
_In_ PPH_TREENEW_CONTEXT Context,
_In_ ULONG VirtualKeys,
_In_ LONG CursorX,
_In_ LONG CursorY
);
VOID PhTnpOnMouseLeave(
_In_ HWND hwnd,
_In_ PPH_TREENEW_CONTEXT Context
);
VOID PhTnpOnXxxButtonXxx(
_In_ HWND hwnd,
_In_ PPH_TREENEW_CONTEXT Context,
_In_ ULONG Message,
_In_ ULONG VirtualKeys,
_In_ LONG CursorX,
_In_ LONG CursorY
);
VOID PhTnpOnCaptureChanged(
_In_ HWND hwnd,
_In_ PPH_TREENEW_CONTEXT Context
);
VOID PhTnpOnKeyDown(
_In_ HWND hwnd,
_In_ PPH_TREENEW_CONTEXT Context,
_In_ ULONG VirtualKey,
_In_ ULONG Data
);
VOID PhTnpOnChar(
_In_ HWND hwnd,
_In_ PPH_TREENEW_CONTEXT Context,
_In_ ULONG Character,
_In_ ULONG Data
);
VOID PhTnpOnMouseWheel(
_In_ HWND hwnd,
_In_ PPH_TREENEW_CONTEXT Context,
_In_ LONG Distance,
_In_ ULONG VirtualKeys,
_In_ LONG CursorX,
_In_ LONG CursorY
);
VOID PhTnpOnMouseHWheel(
_In_ HWND hwnd,
_In_ PPH_TREENEW_CONTEXT Context,
_In_ LONG Distance,
_In_ ULONG VirtualKeys,
_In_ LONG CursorX,
_In_ LONG CursorY
);
VOID PhTnpOnContextMenu(
_In_ HWND hwnd,
_In_ PPH_TREENEW_CONTEXT Context,
_In_ LONG CursorScreenX,
_In_ LONG CursorScreenY
);
VOID PhTnpOnVScroll(
_In_ HWND hwnd,
_In_ PPH_TREENEW_CONTEXT Context,
_In_ ULONG Request,
_In_ USHORT Position
);
VOID PhTnpOnHScroll(
_In_ HWND hwnd,
_In_ PPH_TREENEW_CONTEXT Context,
_In_ ULONG Request,
_In_ USHORT Position
);
BOOLEAN PhTnpOnNotify(
_In_ HWND hwnd,
_In_ PPH_TREENEW_CONTEXT Context,
_In_ NMHDR *Header,
_Out_ LRESULT *Result
);
ULONG_PTR PhTnpOnUserMessage(
_In_ HWND hwnd,
_In_ PPH_TREENEW_CONTEXT Context,
_In_ ULONG Message,
_In_ ULONG_PTR WParam,
_In_ ULONG_PTR LParam
);
// Misc.
VOID PhTnpSetFont(
_In_ PPH_TREENEW_CONTEXT Context,
_In_opt_ HFONT Font,
_In_ BOOLEAN Redraw
);
VOID PhTnpUpdateSystemMetrics(
_In_ PPH_TREENEW_CONTEXT Context
);
VOID PhTnpUpdateTextMetrics(
_In_ PPH_TREENEW_CONTEXT Context
);
VOID PhTnpUpdateThemeData(
_In_ PPH_TREENEW_CONTEXT Context
);
VOID PhTnpInitializeThemeData(
_In_ PPH_TREENEW_CONTEXT Context
);
VOID PhTnpCancelTrack(
_In_ PPH_TREENEW_CONTEXT Context
);
VOID PhTnpLayout(
_In_ PPH_TREENEW_CONTEXT Context
);
VOID PhTnpLayoutHeader(
_In_ PPH_TREENEW_CONTEXT Context
);
VOID PhTnpSetFixedWidth(
_In_ PPH_TREENEW_CONTEXT Context,
_In_ ULONG FixedWidth
);
VOID PhTnpSetRedraw(
_In_ PPH_TREENEW_CONTEXT Context,
_In_ BOOLEAN Redraw
);
VOID PhTnpSendMouseEvent(
_In_ PPH_TREENEW_CONTEXT Context,
_In_ PH_TREENEW_MESSAGE Message,
_In_ LONG CursorX,
_In_ LONG CursorY,
_In_ PPH_TREENEW_NODE Node,
_In_ PPH_TREENEW_COLUMN Column,
_In_ ULONG VirtualKeys
);
// Columns
PPH_TREENEW_COLUMN PhTnpLookupColumnById(
_In_ PPH_TREENEW_CONTEXT Context,
_In_ ULONG Id
);
BOOLEAN PhTnpAddColumn(
_In_ PPH_TREENEW_CONTEXT Context,
_In_ PPH_TREENEW_COLUMN Column
);
BOOLEAN PhTnpRemoveColumn(
_In_ PPH_TREENEW_CONTEXT Context,
_In_ ULONG Id
);
BOOLEAN PhTnpCopyColumn(
_In_ PPH_TREENEW_CONTEXT Context,
_In_ ULONG Id,
_Out_ PPH_TREENEW_COLUMN Column
);
BOOLEAN PhTnpChangeColumn(
_In_ PPH_TREENEW_CONTEXT Context,
_In_ ULONG Mask,
_In_ ULONG Id,
_In_ PPH_TREENEW_COLUMN Column
);
VOID PhTnpExpandAllocatedColumns(
_In_ PPH_TREENEW_CONTEXT Context
);
VOID PhTnpUpdateColumnMaps(
_In_ PPH_TREENEW_CONTEXT Context
);
// Columns (header control)
LONG PhTnpInsertColumnHeader(
_In_ PPH_TREENEW_CONTEXT Context,
_In_ PPH_TREENEW_COLUMN Column
);
VOID PhTnpChangeColumnHeader(
_In_ PPH_TREENEW_CONTEXT Context,
_In_ ULONG Mask,
_In_ PPH_TREENEW_COLUMN Column
);
VOID PhTnpDeleteColumnHeader(
_In_ PPH_TREENEW_CONTEXT Context,
_Inout_ PPH_TREENEW_COLUMN Column
);
VOID PhTnpUpdateColumnHeaders(
_In_ PPH_TREENEW_CONTEXT Context
);
VOID PhTnpProcessResizeColumn(
_In_ PPH_TREENEW_CONTEXT Context,
_In_ PPH_TREENEW_COLUMN Column,
_In_ LONG Delta
);
VOID PhTnpProcessSortColumn(
_In_ PPH_TREENEW_CONTEXT Context,
_In_ PPH_TREENEW_COLUMN NewColumn
);
BOOLEAN PhTnpSetColumnHeaderSortIcon(
_In_ PPH_TREENEW_CONTEXT Context,
_In_opt_ PPH_TREENEW_COLUMN SortColumnPointer
);
VOID PhTnpAutoSizeColumnHeader(
_In_ PPH_TREENEW_CONTEXT Context,
_In_ HWND HeaderHandle,
_In_ PPH_TREENEW_COLUMN Column,
_In_ ULONG Flags
);
// Nodes
BOOLEAN PhTnpGetNodeChildren(
_In_ PPH_TREENEW_CONTEXT Context,
_In_opt_ PPH_TREENEW_NODE Node,
_Out_ PPH_TREENEW_NODE **Children,
_Out_ PULONG NumberOfChildren
);
BOOLEAN PhTnpIsNodeLeaf(
_In_ PPH_TREENEW_CONTEXT Context,
_In_ PPH_TREENEW_NODE Node
);
BOOLEAN PhTnpGetCellText(
_In_ PPH_TREENEW_CONTEXT Context,
_In_ PPH_TREENEW_NODE Node,
_In_ ULONG Id,
_Out_ PPH_STRINGREF Text
);
VOID PhTnpRestructureNodes(
_In_ PPH_TREENEW_CONTEXT Context
);
VOID PhTnpInsertNodeChildren(
_In_ PPH_TREENEW_CONTEXT Context,
_In_ PPH_TREENEW_NODE Node,
_In_ ULONG Level
);
VOID PhTnpSetExpandedNode(
_In_ PPH_TREENEW_CONTEXT Context,
_In_ PPH_TREENEW_NODE Node,
_In_ BOOLEAN Expanded
);
BOOLEAN PhTnpGetCellParts(
_In_ PPH_TREENEW_CONTEXT Context,
_In_ ULONG Index,
_In_opt_ PPH_TREENEW_COLUMN Column,
_In_ ULONG Flags,
_Out_ PPH_TREENEW_CELL_PARTS Parts
);
BOOLEAN PhTnpGetRowRects(
_In_ PPH_TREENEW_CONTEXT Context,
_In_ ULONG Start,
_In_ ULONG End,
_In_ BOOLEAN Clip,
_Out_ PRECT Rect
);
VOID PhTnpHitTest(
_In_ PPH_TREENEW_CONTEXT Context,
_Inout_ PPH_TREENEW_HIT_TEST HitTest
);
VOID PhTnpSelectRange(
_In_ PPH_TREENEW_CONTEXT Context,
_In_ ULONG Start,
_In_ ULONG End,
_In_ ULONG Flags,
_Out_opt_ PULONG ChangedStart,
_Out_opt_ PULONG ChangedEnd
);
VOID PhTnpSetHotNode(
_In_ PPH_TREENEW_CONTEXT Context,
_In_opt_ PPH_TREENEW_NODE NewHotNode,
_In_ BOOLEAN NewPlusMinusHot
);
VOID PhTnpProcessSelectNode(
_In_ PPH_TREENEW_CONTEXT Context,
_In_ PPH_TREENEW_NODE Node,
_In_ LOGICAL ControlKey,
_In_ LOGICAL ShiftKey,
_In_ LOGICAL RightButton
);
BOOLEAN PhTnpEnsureVisibleNode(
_In_ PPH_TREENEW_CONTEXT Context,
_In_ ULONG Index
);
// Mouse
VOID PhTnpProcessMoveMouse(
_In_ PPH_TREENEW_CONTEXT Context,
_In_ LONG CursorX,
_In_ LONG CursorY
);
VOID PhTnpProcessMouseVWheel(
_In_ PPH_TREENEW_CONTEXT Context,
_In_ LONG Distance
);
VOID PhTnpProcessMouseHWheel(
_In_ PPH_TREENEW_CONTEXT Context,
_In_ LONG Distance
);
// Keyboard
BOOLEAN PhTnpProcessFocusKey(
_In_ PPH_TREENEW_CONTEXT Context,
_In_ ULONG VirtualKey
);
BOOLEAN PhTnpProcessNodeKey(
_In_ PPH_TREENEW_CONTEXT Context,
_In_ ULONG VirtualKey
);
VOID PhTnpProcessSearchKey(
_In_ PPH_TREENEW_CONTEXT Context,
_In_ ULONG Character
);
BOOLEAN PhTnpDefaultIncrementalSearch(
_In_ PPH_TREENEW_CONTEXT Context,
_Inout_ PPH_TREENEW_SEARCH_EVENT SearchEvent,
_In_ BOOLEAN Partial,
_In_ BOOLEAN Wrap
);
// Scrolling
VOID PhTnpUpdateScrollBars(
_In_ PPH_TREENEW_CONTEXT Context
);
VOID PhTnpScroll(
_In_ PPH_TREENEW_CONTEXT Context,
_In_ LONG DeltaRows,
_In_ LONG DeltaX
);
VOID PhTnpProcessScroll(
_In_ PPH_TREENEW_CONTEXT Context,
_In_ LONG DeltaRows,
_In_ LONG DeltaX
);
BOOLEAN PhTnpCanScroll(
_In_ PPH_TREENEW_CONTEXT Context,
_In_ BOOLEAN Horizontal,
_In_ BOOLEAN Positive
);
// Drawing
VOID PhTnpPaint(
_In_ HWND hwnd,
_In_ PPH_TREENEW_CONTEXT Context,
_In_ HDC hdc,
_In_ PRECT PaintRect
);
VOID PhTnpPrepareRowForDraw(
_In_ PPH_TREENEW_CONTEXT Context,
_In_ HDC hdc,
_Inout_ PPH_TREENEW_NODE Node
);
VOID PhTnpDrawCell(
_In_ PPH_TREENEW_CONTEXT Context,
_In_ HDC hdc,
_In_ PRECT CellRect,
_In_ PPH_TREENEW_NODE Node,
_In_ PPH_TREENEW_COLUMN Column,
_In_ LONG RowIndex,
_In_ LONG ColumnIndex
);
VOID PhTnpDrawDivider(
_In_ PPH_TREENEW_CONTEXT Context,
_In_ HDC hdc
);
VOID PhTnpDrawPlusMinusGlyph(
_In_ HDC hdc,
_In_ PRECT Rect,
_In_ BOOLEAN Plus
);
VOID PhTnpDrawSelectionRectangle(
_In_ PPH_TREENEW_CONTEXT Context,
_In_ HDC hdc,
_In_ PRECT Rect
);
VOID PhTnpDrawThemedBorder(
_In_ PPH_TREENEW_CONTEXT Context,
_In_ HDC hdc
);
// Tooltips
VOID PhTnpInitializeTooltips(
_In_ PPH_TREENEW_CONTEXT Context
);
VOID PhTnpGetTooltipText(
_In_ PPH_TREENEW_CONTEXT Context,
_In_ PPOINT Point,
_Out_ PWSTR *Text
);
BOOLEAN PhTnpPrepareTooltipShow(
_In_ PPH_TREENEW_CONTEXT Context
);
VOID PhTnpPrepareTooltipPop(
_In_ PPH_TREENEW_CONTEXT Context
);
VOID PhTnpPopTooltip(
_In_ PPH_TREENEW_CONTEXT Context
);
PPH_TREENEW_COLUMN PhTnpHitTestHeader(
_In_ PPH_TREENEW_CONTEXT Context,
_In_ BOOLEAN Fixed,
_In_ PPOINT Point,
_Out_opt_ PRECT ItemRect
);
VOID PhTnpGetHeaderTooltipText(
_In_ PPH_TREENEW_CONTEXT Context,
_In_ BOOLEAN Fixed,
_In_ PPOINT Point,
_Out_ PWSTR *Text
);
PWSTR PhTnpMakeContextAtom(
VOID
);
LRESULT CALLBACK PhTnpHeaderHookWndProc(
_In_ HWND hwnd,
_In_ UINT uMsg,
_In_ WPARAM wParam,
_In_ LPARAM lParam
);
// Drag selection
BOOLEAN PhTnpDetectDrag(
_In_ PPH_TREENEW_CONTEXT Context,
_In_ LONG CursorX,
_In_ LONG CursorY,
_In_ BOOLEAN DispatchMessages,
_Out_opt_ PULONG CancelledByMessage
);
VOID PhTnpDragSelect(
_In_ PPH_TREENEW_CONTEXT Context,
_In_ LONG CursorX,
_In_ LONG CursorY
);
VOID PhTnpProcessDragSelect(
_In_ PPH_TREENEW_CONTEXT Context,
_In_ ULONG VirtualKeys,
_In_ PRECT OldRect,
_In_ PRECT NewRect,
_In_ PRECT TotalRect
);
// Double buffering
VOID PhTnpCreateBufferedContext(
_In_ PPH_TREENEW_CONTEXT Context
);
VOID PhTnpDestroyBufferedContext(
_In_ PPH_TREENEW_CONTEXT Context
);
// Support functions
VOID PhTnpGetMessagePos(
_In_ HWND hwnd,
_Out_ PPOINT ClientPoint
);
// Macros
#define HRGN_FULL ((HRGN)1) // passed by WM_NCPAINT even though it's completely undocumented
#define TNP_CELL_LEFT_MARGIN 6
#define TNP_CELL_RIGHT_MARGIN 6
#define TNP_ICON_RIGHT_PADDING 4
#define TNP_TIMER_NULL 1
#define TNP_TIMER_ANIMATE_DIVIDER 2
#define TNP_TOOLTIPS_ITEM 0
#define TNP_TOOLTIPS_FIXED_HEADER 1
#define TNP_TOOLTIPS_HEADER 2
#define TNP_TOOLTIPS_DEFAULT_MAXIMUM_WIDTH 550
#define TNP_ANIMATE_DIVIDER_INTERVAL 10
#define TNP_ANIMATE_DIVIDER_INCREMENT 17
#define TNP_ANIMATE_DIVIDER_DECREMENT 2
#define TNP_HIT_TEST_FIXED_DIVIDER(X, Context) \
((Context)->FixedDividerVisible && (X) >= (Context)->FixedWidth - 8 && (X) < (Context)->FixedWidth + 8)
#define TNP_HIT_TEST_PLUS_MINUS_GLYPH(X, NodeLevel) \
(((X) >= TNP_CELL_LEFT_MARGIN + ((LONG)(NodeLevel) * SmallIconWidth)) && ((X) < TNP_CELL_LEFT_MARGIN + ((LONG)(NodeLevel) * SmallIconWidth) + SmallIconWidth))
#endif