#include "listview.h" // for some helper routines and border metrics #define __IOleControl_INTERFACE_DEFINED__ // There is a conflich with the IOleControl's def of CONTROLINFO #include "shlobj.h" // // Definitions missing from commctrl.h // typedef const TVITEMEX *LPCTVITEMEX; // // Private definitions // #define MAGIC_MININDENT 5 #define MAGIC_INDENT 3 #define MAGIC_HORZLINE 5 // flags for TV_DrawItem #define TVDI_NOIMAGE 0x0001 // don't draw image #define TVDI_NOTREE 0x0002 // don't draw indent, lines, +/- #define TVDI_TRANSTEXT 0x0004 // draw text transparently in black #define TVDI_ERASE 0x0008 // erase while drawing #define TVDI_GRAYTEXT 0x0010 // text is gray (disabled item) #define TVDI_GRAYCTL 0x0020 // text and background is gray (disabled control) #define TVDI_FORCEIMAGE 0x0040 // Always draw image #define TVDI_NOBK 0x0080 // Internal flags for TV_SelectItem #define TVC_INTERNAL 0x1000 typedef struct _TREE { CCONTROLINFO ci; // Flags BITBOOL fHorz:1; // horizontal scrollbar present BITBOOL fVert:1; // vertical scrollbar present BITBOOL fFocus:1; // currently has focus BITBOOL fNameEditPending:1; // Is a name edit pending? BITBOOL fRedraw:1; // should redraw? BITBOOL fScrollWait:1; // are we waiting for a dblclk to not scroll? BITBOOL fCreatedFont:1; // we created our font BITBOOL fNoDismissEdit:1; // don't dismiss in-place edit control BITBOOL fIndentSet:1; // is the parent managing the indent size? BITBOOL fTrackSet:1; // have we set a track event? BITBOOL fPlaceTooltip:1; // should we do the placement of tooltip over the text? BITBOOL fCyItemSet:1; // the the parent set our item height? BITBOOL fInsertAfter:1; // insert mark should be after htiInsert instead of before BITBOOL fRestoreOldDrop:1; // hOldDrop needs to be restored to hDropTarget // Handles HTREEITEM hRoot; // tree root item HTREEITEM hCaret; // item with focus caret HTREEITEM hDropTarget; // item which is the drop target HTREEITEM hOldDrop; // item which used to be the drop target HTREEITEM htiEdit; // The item that is being edited. HTREEITEM hHot; // the currently hottracked item HTREEITEM hToolTip; // the current item set in tooltips HTREEITEM htiInsert; // item that is relative to the insert mark HTREEITEM htiSearch; // item active in most recent incremental search HTREEITEM htiDrag; // item that's being dragged. HDPA hdpaWatch; // array of PTVWATCHEDITEMs - items being watched HIMAGELIST hImageList; // image list HIMAGELIST himlState; // state image list HCURSOR hCurHot; // the cursor when we're over a hot item int iPuntChar; // number of wm_char's to punt int cxState; int cyState; HBRUSH hbrBk; // background brush HFONT hFont; // tree font HFONT hFontHot; // underlined for hot tracking HFONT hFontBold; // bold tree font HFONT hFontBoldHot; // underlined for hot tracking HBITMAP hStartBmp; // initial DC mono bitmap HBITMAP hBmp; // indent bitmaps in hdcBits HDC hdcBits; // HDC for drawing indent bitmaps HTREEITEM hItemPainting; // the guy we are currently painting HANDLE hheap; // heap for allocs for win32 HBRUSH hbrLine; HBRUSH hbrText; POINT ptCapture; // Point where the mouse was capture COLORREF clrText; COLORREF clrBk; COLORREF clrim; // insert mark color. COLORREF clrLine; // line color COLORREF clrBkNonTheme; // Saved when not themed COLORREF clrLineNonTheme; // Saved when not themed // Dimensions SHORT cxImage; // image width SHORT cyImage; // image height SHORT cxNativeImage; // image width (no scaling) SHORT cyNativeImage; // image height (no scaling) SHORT cyText; // text height SHORT cyItem; // item height SHORT cxBorder; // horizontal item border SHORT cyBorder; // vert item border SHORT cxIndent; // indent width SHORT cxWnd; // window width SHORT cyWnd; // window height // Scroll Positioners WORD cxMax; // width of longest item WORD cFullVisible; // number of items that CAN fully fit in window SHORT xPos; // horizontal scrolled position UINT cShowing; // number of showing (non-collapsed) items UINT cItems; // total number of items HTREEITEM hTop; // first visible item (i.e., at top of client rect) UINT uMaxScrollTime; // the maximum smooth scroll timing // stuff for edit in place HWND hwndEdit; // Edit window for name editing. WNDPROC pfnEditWndProc; // edit field subclass proc //tooltip stuff HWND hwndToolTips; LPTSTR pszTip; // store current tooltip/infotip string. LPSTR pszTipA; // store current ANSI tooltip/infotip string. //incremental search stuff ISEARCHINFO is; HTHEME hTheme; DWORD dwLastAccId; DWORD dwExStyle; #ifdef DEBUG BOOL fInTextCallback; #endif } TREE, *PTREE; #define TV_StateIndex(pitem) ((int)(((DWORD)((pitem)->state) >> 12) & 0xF)) #define KIDS_COMPUTE 0 // use hKids to determine if a node has children #define KIDS_FORCE_YES 1 // force a node to have kids (ignore hKids) #define KIDS_FORCE_NO 2 // force a node to not have kids (ignore hKids) #define KIDS_CALLBACK 3 // callback to see if a node has kids #define KIDS_INVALID 4 // all values this and above are bogus #define MAXLABELTEXT MAX_PATH // // Note that there are multiple senses of "visible" going on. // // TREE.hTop tracks visibility in the sense of "will it be painted?" // // TREEITEM.iShownIndex tracks visibility in the sense of "not collapsed". // You can be off the screen but as long as your parent is expanded // you get an iShownIndex. // // typedef struct _TREEITEM { HTREEITEM hParent; // allows us to walk back out of the tree HTREEITEM hNext; // next sibling HTREEITEM hKids; // first child LPTSTR lpstr; // item text, can be LPSTR_TEXTCALLBACK LPARAM lParam; // item data DWORD dwAccId; WORD state; // TVIS_ state flags WORD iImage; // normal state image at iImage WORD iSelectedImage; // selected state image WORD iWidth; // cached: width of text area (for hit test, drawing) WORD iShownIndex; // cached: -1 if not visible, otherwise nth visible item // invisible = parent is invisible or collapsed BYTE iLevel; // cached: level of item (indent) BYTE fKids; // KIDS_ values WORD iIntegral; // integral height // for parameter validation, put at end of struct // ****************************** WORD wSignature; // ****************************** } TREEITEM; // // The signature is intentionally not ASCII characters, so it's // harder to run into by mistake. I choose a value greater than // 0x8000 so it can't be the high word of a pointer. // #define TV_SIG 0xABCD #define TV_MarkAsDead(hti) ((hti)->wSignature = 0) #define ITEM_VISIBLE(hti) ((hti)->iShownIndex != (WORD)-1) // get the parent, avoiding the hidden root node #define VISIBLE_PARENT(hItem) (!(hItem)->iLevel ? NULL : (hItem)->hParent) // REVIEW: make this a function if the optimizer doesn't do well with this #define FULL_WIDTH(pTree, hItem) (ITEM_OFFSET(pTree,hItem) + hItem->iWidth) int ITEM_OFFSET(PTREE pTree, HTREEITEM hItem); #define VTI_NULLOK 1 BOOL ValidateTreeItem(HTREEITEM hItem, UINT flags); #ifdef DEBUG #define DBG_ValidateTreeItem(hItem, flags) ValidateTreeItem(hItem, flags) #else #define DBG_ValidateTreeItem(hItem, flags) #endif // // TVWATCHEDITEM // // Structure that tracks items being watched. // // See TV_StartWatch for more information, and TV_DoExpandRecurse // for an example. // // The hti field is a bit odd. // // if fStale == FALSE, then hti is the item being watched. // if fStale == TRUE , then hti is the item *after* the item being watched. // // We keep this strange semantic for fStale==TRUE so that TV_NextWatchItem // can successfully step to the item after a deleted item. (Normally, // trying to do anything with a deleted item will fault.) // typedef struct TVWATCHEDITEM { HTREEITEM hti; // current item BOOL fStale; // has the original item been deleted? } TVWATCHEDITEM, *PTVWATCHEDITEM; BOOL TV_StartWatch(PTREE pTree, PTVWATCHEDITEM pwi, HTREEITEM htiStart); BOOL TV_EndWatch(PTREE pTree, PTVWATCHEDITEM pwi); #define TV_GetWatchItem(pTree, pwi) ((pwi)->hti) #define TV_RestartWatch(pTree, pwi, htiStart) \ ((pwi)->hti = (htiStart), (pwi)->fStale = FALSE) #define TV_IsWatchStale(pTree, pwi) ((pwi)->fStale) #define TV_IsWatchValid(pTree, pwi) (!(pwi)->fStale) #define TV_GetAccId(hItem) ((hItem)? (hItem)->dwAccId : CHILDID_SELF) // // TV_NextWatchItem - Enumerate the item after the watched item. // This works even if the watched item was deleted. // #define TV_NextWatchItem(pTree, pwi) \ ((pwi)->fStale || ((pwi)->hti = (pwi)->hti->hNext)), \ (pwi)->fStale = FALSE // in TVSCROLL.C BOOL TV_ScrollBarsAfterAdd (PTREE, HTREEITEM); BOOL TV_ScrollBarsAfterRemove (PTREE, HTREEITEM); BOOL TV_ScrollBarsAfterExpand (PTREE, HTREEITEM); BOOL TV_ScrollBarsAfterCollapse (PTREE, HTREEITEM); void TV_ScrollBarsAfterResize (PTREE, HTREEITEM, int, UINT); BOOL TV_ScrollBarsAfterSetWidth (PTREE, HTREEITEM); BOOL TV_HorzScroll (PTREE, UINT, UINT); BOOL TV_VertScroll (PTREE, UINT, UINT); BOOL TV_SetLeft (PTREE, int); #define TV_SetTopItem(pTree, i) TV_SmoothSetTopItem(pTree, i, 0) BOOL TV_SmoothSetTopItem (PTREE, UINT, UINT); BOOL TV_CalcScrollBars (PTREE); BOOL TV_ScrollIntoView (PTREE, HTREEITEM); BOOL TV_ScrollVertIntoView (PTREE, HTREEITEM); HTREEITEM TV_GetShownIndexItem (HTREEITEM, UINT); UINT TV_ScrollBelow (PTREE, HTREEITEM, BOOL, BOOL); BOOL TV_SortChildren(PTREE, HTREEITEM, BOOL); BOOL TV_SortChildrenCB(PTREE, LPTV_SORTCB, BOOL); void TV_ComputeItemWidth(PTREE pTree, HTREEITEM hItem, HDC hdc); // in TVPAINT.C void TV_GetBackgroundBrush (PTREE pTree, HDC hdc); void TV_UpdateTreeWindow (PTREE, BOOL); void TV_ChangeColors (PTREE); void TV_CreateIndentBmps (PTREE); void TV_Paint (PTREE, HDC); HIMAGELIST TV_CreateDragImage (PTREE pTree, HTREEITEM hItem); BOOL TV_ShouldItemDrawBlue (PTREE pTree, TVITEMEX *ti, UINT flags); LRESULT TV_GenerateDragImage (PTREE ptree, SHDRAGIMAGE* pshdi); BOOL TV_GetInsertMarkRect(PTREE pTree, LPRECT prc); // in TVMEM.C #define TVDI_NORMAL 0x0000 // TV_DeleteItem flags #define TVDI_NONOTIFY 0x0001 #define TVDI_CHILDRENONLY 0x0002 #define TVDI_NOSELCHANGE 0x0004 BOOL TV_DeleteItem(PTREE, HTREEITEM, UINT); HTREEITEM TV_InsertItem(PTREE pTree, LPTV_INSERTSTRUCT lpis); void TV_DestroyTree(PTREE); LRESULT TV_OnCreate(HWND, LPCREATESTRUCT); HTREEITEM TV_InsertItemA(PTREE pTree, LPTV_INSERTSTRUCTA lpis); // in TREEVIEW.C BOOL TV_GetItemRect(PTREE, HTREEITEM, LPRECT, BOOL); BOOL TV_Expand(PTREE pTree, WPARAM wCode, TREEITEM * hItem, BOOL fNotify); HTREEITEM TV_GetNextItem(PTREE, HTREEITEM, WPARAM); void TV_GetItem(PTREE pTree, HTREEITEM hItem, UINT mask, LPTVITEMEX lpItem); void TV_PopBubble(PTREE pTree); // Flags for TV_SelectItem #define TVSIFI_NOTIFY 0x0001 #define TVSIFI_UPDATENOW 0x0002 #define TVSIFI_NOSINGLEEXPAND 0x0004 BOOL TV_SelectItem(PTREE, WPARAM, HTREEITEM, UINT, UINT); BOOL TV_SendChange(PTREE, HTREEITEM, int, UINT, UINT, UINT, int, int); HTREEITEM TV_GetNextVisItem(HTREEITEM); HTREEITEM TV_GetPrevItem(HTREEITEM); HTREEITEM TV_GetPrevVisItem(HTREEITEM); void TV_CalcShownItems(PTREE, HTREEITEM hItem); void TV_OnSetFont(PTREE, HFONT, BOOL); BOOL TV_SizeWnd(PTREE, UINT, UINT); void TV_InvalidateItem(PTREE, HTREEITEM, UINT uFlags); VOID TV_CreateBoldFont(PTREE pTree); BOOL TV_SetInsertMark(PTREE pTree, HTREEITEM hItem, BOOL fAfter); LRESULT CALLBACK _export TV_EditWndProc(HWND, UINT, WPARAM, LPARAM); LRESULT CALLBACK _export TV_WndProc(HWND, UINT, WPARAM, LPARAM); BOOL TV_Init(HINSTANCE hinst); void TV_Terminate(BOOL fSystemExit); LRESULT TV_Timer (PTREE pTree, UINT uTimerId); HWND TV_OnEditLabel (PTREE pTree, HTREEITEM hItem); void TV_SetEditSize (PTREE pTree); BOOL TV_DismissEdit (PTREE pTree, BOOL fCancel); void TV_CancelPendingEdit (PTREE pTree); int TV_UpdateShownIndexes (PTREE pTree, HTREEITEM hWalk); void TV_UnsubclassToolTips(PTREE pTree); LRESULT WINAPI TV_SubClassWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); void TV_SubclassToolTips(PTREE pTree); BOOL TV_UpdateToolTip(PTREE pTree); BOOL TV_SetToolTipTarget(PTREE pTree, HTREEITEM hItem); void TV_OnSetBkColor(PTREE pTree, COLORREF clr); void TV_InitCheckBoxes(PTREE pTree); void TV_InitThemeMetrics(PTREE pTree, HTHEME hTheme); #define TVMP_CALCSCROLLBARS (TV_FIRST + 0x1000) // Fake customdraw. See comment block in tvscroll.c typedef struct TVFAKEDRAW { NMTVCUSTOMDRAW nmcd; PTREE pTree; HFONT hfontPrev; DWORD dwCustomPrev; DWORD dwCustomItem; } TVFAKEDRAW, *PTVFAKEDRAW; void TreeView_BeginFakeCustomDraw(PTREE pTree, PTVFAKEDRAW ptvfd); DWORD TreeView_BeginFakeItemDraw(PTVFAKEDRAW plvfd, HTREEITEM hitem); void TreeView_EndFakeItemDraw(PTVFAKEDRAW ptvfd); void TreeView_EndFakeCustomDraw(PTVFAKEDRAW ptvfd);