树型控件是一系列分层项目的窗口
每个项目由一个标签和一幅可选的位图组成
每个项目可以有一个子项目列表,单击一个项目,可以展开或折叠其子项目
1.创建树型控件:hwndTreeView=CreateWindow
("SysTreeView32",NULL,WS_CHILD|WS_VISIBLE|TVS_HASLINES|TVS_HASBUTTONS|TVS_LINESATROOT,0,0,200,400,hWnd,NULL,g_hInstance,NULL);
2.创建完控件后,通过SendMessage(),来增加、删除、安排各个项目
每个消息都有一个或多个相应的宏来代替直接发送消息
3.Tree View的样式:创建窗口时直接设置,或者通过SetWindowLong或GetWindowLong来设置和获得样式
TVS_CHECKBOXES Version 4.70 允许复选框作为树项控件的项目 设置这个样式后,创建图象列表使用DrawFrameControl
For more information, see Working with state image indexes
控件创建后,这个样式不能被删除,如果一定要删除,删除整个控件,在原来的位置重新创建一个没有该样式的树型控件
TVS_DISABLEDRAGDROP 阻止发送TVN_BEGINDRAG通知消息。
TVS_EDITLABELS:允许用户编辑项目的标签。
TVS_FULLROWSELECT:单击项目所在行的任何位置,都可以选择该项目,并高量显示整行,不能跟TVS_HASLINES样式合用 Version 4.71
TVS_HASBUTTONS:在根项目旁边显示+ -按钮,用户单击,展开或折叠其子项目,TVS_LINESATROOT样式也设置才生效
TVS_HASLINES:显示分层项目时使用线条
TVS_INFOTIP:Version 4.71 树型控件将发送TVN_GETINFOTIP通知来取得tooltip信息
TVS_LINESATROOT:用线条将根项目连接起来,必须同时设置TVS_HASLINES才能生效
TVS_NONEVENHEIGHT:Version 4.71 发送TVM_SETITEMHEIGHT消息设置项目的高度为一个even value将失效
TVS_NOSCROLL:Version 4.71 始终没有水平或垂直滚动条
TVS_NOTOOLTIPS Version 4.70 不支持tooltip
TVS_RTLREADING Version 4.70. 文本右到左的顺序显示on Hebrew or Arabic systems.
TVS_SHOWSELALWAYS:树型控件失去焦点后,被选择的项目仍保持选择
TVS_SINGLEEXPAND:Version 4.71 选择的项目自动展开,没有选择的项目自动折叠 原来项目是折叠的,单击展开,原来项目是展开的,单击折叠
TVS_TRACKSELECT:Version 4.70 鼠标移到项目上变成手形 Enables hot tracking in a tree view control.
4.树型控件消息:
TVM_GETINDENT:wParam = 0;lParam = 0;//Returns the amount of indentation,等同于宏 TreeView_GetIndent
TVM_SETINDENT:wParam = (WPARAM) indent;lParam = 0;//设置缩进,等同于宏 TreeView_SetIndent
TVM_GETBKCOLOR:wParam = 0;lParam = 0;//返回当前整个控件的背景色COLORREF,等同于宏 TreeView_GetBkColor
TVM_SETBKCOLOR:wParam = 0;lParam = (LPARAM)(COLORREF)clrBk;//设置背景颜色,返回先前的背景色 ,等同于宏 TreeView_SetBkColor
TVM_GETITEMHEIGHT:wParam = 0;lParam = 0;//返回一个项目的高度,等同于宏TreeView_GetItemHight
TVM_SETITEMHEIGHT:wParam = (WPARAM)(SHORT) cyItem;lParam = 0;//设置项目的高度,单位像素,为偶数,例如设置成33,自动转换成32
如果这个值小于位图的高度,则设置为位图的高度(MSDN说法,实际上不是)
TVM_GETTEXTCOLOR:wParam = 0;lParam = 0;//返回当前树型控件的文本颜色COLORREF
TVM_SETTEXTCOLOR:wParam = 0;lParam = (LPARAM)(COLORREF) clrText;//设置文本的颜色
TVM_INSERTITEM:wParam = 0;lParam = (LPARAM) (LPTVINSERTSTRUCT) lpis;//为树型控件增加一个项目,等同于宏 TreeView_InsertItem
TVM_DELETEITEM:lParam = (LPARAM) (HTREEITEM) hitem;//删除一个指定的项目,等同于宏 TreeView_DeleteItem
TVM_GETIMAGELIST:wParam = (WPARAM) iImage; lParam = 0;//返回树型控件的image list(normal或者state)的句柄,等同于宏 TreeView_GetImageList
TVM_SETIMAGELIST:wParam = (WPARAM) iImage;lParam = (LPARAM) (HIMAGELIST) himl;//设置图象列表(normal或state),等同于宏 TreeView_SetImageList
如果himl为NULL,则移除原来的图象列表
TVM_GETTOOLTIPSP:wParam = 0;lParam = 0;//Retrieves the handle to the child tooltip control,等同于宏TreeView_GetToolTips
TVM_SETTOOLTIPS:wParam = (WPARAM)(HWND) hwndTooltip;lParam = 0;//设置工具提示栏
TVM_EDITLABEL:lParam = (LPARAM) (HTREEITEM) hitem;//开始指定的项目标签替换 等同于宏TreeView_EditLabel
TVM_ENDEDITLABELNOW:wParam = (WPARAM) (BOOL) fCancel; //终止项目的标签编辑 等同于宏TreeView_EndEditLabelNow
TVM_CREATEDRAGIMAGE:lParam = (LPARAM) (HTREEITEM) hitem;//为指定的项目创建一个拖动位图,同时为该为图创建an image list,并将该位图加入到the image list,程序
使用image list的函数来在拖动项目时显示该位图,等同于宏TreeView_CreateDragImage
TVM_GETUNICODEFORMAT:wParam = 0;lParam = 0;//控件使用UNICODE字符返回非零,等同于宏 TreeView_GetUnicodeFormat
TVM_SETUNICODEFORMAT:wParam = (WPARAM)(BOOL)fUnicode;lParam = 0;//设置控件接收UNICODE还是ANSI字符
TVM_GETSCROLLTIME:wParam = 0;lParam = 0;//返回树型控件的最大滚动时间/次数?等同于宏TreeView_GetScrollTime
TVM_SETSCROLLTIME:wParam = (WPARAM)(UINT)uScrollTime;lParam = 0;//设置树型控件最大滚动次数
TVM_SETINSERTMARK:wParam = (WPARAM)(BOOL) fAfter;lParam = (LPARAM)(HTREEITEM) htiInsert;等同于宏 TreeView_SetInsertMark
fAfter为非零,则the insertion mark放在item之后,如果为零,则放在the insertion mark之前
TVM_GETINSERTMARKCOLOR:wParam = 0;lParam = 0;//返回绘制the insertion mark的颜色,等同于宏 TreeView_GetInsertMarkColor
TVM_SETINSERTMARKCOLOR:wParam = 0;lParam = (LPARAM)(COLORREF)clrInsertMark;//设置the insertion mark的颜色,等同于宏 TreeView_SetInsertMarkColor
TVM_GETITEM:wParam = 0;lParam = (LPARAM) (LPTVITEM) pitem;//获得一个项目的属性,hItem成员标识了要接收信息的项目;mask成员指定了要接收的属性
如果mask成员==TVIF_TEXT,pszText成员必须设置一个buffer来接收项目的文本 cchTextMax设置成buffer的大小
如果mask成员==TVIF_STATE,stateMask成员must specify the item state bits to retrieve. On output,state成员包含the values of the specified state bits.
等同于宏TreeView_GetItem
TVM_SETITEM:wParam = 0;lParam = (LPARAM) (const LPTVITEM) pitem;//设置项目的属性,等同于宏 TreeView_SetItem
TVM_SORTCHILDREN:wParam = (WPARAM)(BOOL) fRecurse;lParam = (LPARAM)(HTREEITEM) hitem;//指定父项目的子项目进行排序
TVM_SORTCHILDRENCB:wParam = (WPARAM)(BOOL) fRecurse;lParam = (LPARAM) (LPTVSORTCB) psort;//指定父项目的子项目通过自定义的回调函数进行排序进行排序
TVM_GETCOUNT:wParam = 0;lParam = 0;//返当前整个控件的项目数,等同于宏 TreeView_GetCount
TVM_GETVISIBLECOUNT:wParam = 0;lParam = 0;//获得可见项目的数目,等同于宏TreeView_GetVisibleCount
TVGN_ROOT返回根项目,根项目指项目列表中排第一位的项目,等同于宏TreeView_GetRoot
TVM_GETNEXTITEM:wParam = (WPARAM) (UINT) flag;lParam = (LPARAM) (HTREEITEM) hitem;//返回跟hitem有某种关系的item的句柄,等同于宏TreeView_GetNextItem
flag可以是下列值之一:
TVGN_CARET:返回当前被选择的项目 等同于宏TreeView_GetSelection。
TVGN_CHILD:返回指定项目第一个子项目 等同于宏TreeView_GetChild。
TVGN_DROPHILITE:返回拖放操作的目标项目 等同于宏TreeView_GetDropHilight
TVGN_FIRSTVISIBLE:返回树型控件的第一个可见的项目 等同于宏TreeView_GetFirstVisible
TVGN_LASTVISIBLE:Version 4.71 ,返回树型控件的最后一个展开的项目 等同于宏TreeView_GetLastVisible
TVGN_NEXT:返回指定项目的下一个兄弟项目 等同于宏TreeView_GetNextSibling
TVGN_NEXTVISIBLE:返回指定项目的下一个可见的项目,指定的项目必须也是可见的,等同于宏TreeView_GetNextVisible
TVGN_PARENT:返回指定项目的父项目 等同于宏TreeView_GetParent
TVGN_PREVIOUS:返回指定项目的前一个兄弟项目 等同于宏TreeView_GetPrevSibling
TVGN_PREVIOUSVISIBLE返回指定项目的前一个可见的项目,指定的项目必须也是可见的,等同于宏TreeView_GetPrevVisible
TVM_ENSUREVISIBLE:lParam = (LPARAM) (HTREEITEM) hitem;//确保指定项目是可见的,通过展开父项目或滚动树型控件窗口,等同于宏TreeView_EnsureVisible,如果通过展开
父项目使 指定项目可见,则返回0,否则返回非零。
TVM_EXPAND:wParam = (WPARAM) (UINT) flag;lParam = (LPARAM) (HTREEITEM) hItem;//展开或折叠指定的项目,等同于宏TreeView_Expand,
flag可以是一个或多个值的组合:
TVE_COLLAPSE:折叠
TVE_COLLAPSERESET:折叠并删除其子项目,必须与TVE_COLLAPSE联用
TVE_EXPAND:展开
TVE_EXPANDPARTIAL:部分展开,必须与TVE_EXPAND联用,Version 4.70
TVE_TOGGLE:折叠的就展开,展开的就折叠
TVM_GETEDITCONTROL:wParam = 0;lParam = 0;//返回用来编辑树型控件项目的标签的single-line编辑控件的句柄,等同于宏 TreeView_GetEditControl
TVM_GETISEARCHSTRING:wParam = 0;lParam = (LPARAM) (LPSTR) lpsz;//获得搜索字符串,等同于宏 TreeView_GetISearchString
TVM_GETITEMRECT:wParam = (WPARAM) (BOOL) fItemRect;lParam = (LPARAM) (LPRECT) prc;//返回指定项目的矩形
fItemRect如果为TRUE,返回的仅仅是项目文本的矩形,如果为FALSE,返回的是项目所占据的整行的矩形
发送时将HTREEITEM放入lpRECT中传递(强制转换),消息返回后,lpRECT储存了项目的矩形 等同于宏TreeView_GetItemRect
★TVM_SELECTITEM:wParam = (WPARAM) flag;lParam = (LPARAM) (HTREEITEM) hitem;//
TVM_HITTEST:wParam = 0;lParam = (LPARAM) (LPTVHITTESTINFO) lpht;//等同于宏 TreeView_HitTest
lpht是结构体TVHITTESTINFO的地址,消息发送时,pt成员指定了要测试的点的坐标
消息返回后, hItem成员保存了该坐标的项目的句柄,如果该坐标没有项目则为NULL
同时, flags成员保存了这次测试的结果,flags的值可以是以下一个或多个的组合:
TVHT_ABOVE:测试的点位于客户区上
TVHT_BELOW:位于客户区下
TVHT_NOWHERE:位于客户区内,但在最后项目之下
TVHT_ONITEM:在位图或标签上
TVHT_ONITEMBUTTON:在+ -号按钮上
TVHT_ONITEMICON:在位图上
TVHT_ONITEMINDENT In the indentation associated with an item.
TVHT_ONITEMLABEL:在标签上
TVHT_ONITEMRIGHT:在项目右边的区域内
TVHT_ONITEMSTATEICON On the state icon for a tree view item that is in a user-defined state.
TVHT_TOLEFT:位于客户区的左边
TVHT_TORIGHT:位于客户区的右边
5.通知消息(事件发生)
This section contains information about the notification messages that are sent by tree view controls.
NM_CLICK (tree view)
NM_CUSTOMDRAW (tree view)
NM_DBLCLK (tree view)
NM_KILLFOCUS (tree view)
NM_RCLICK (tree view)
NM_RDBLCLK (tree view)
NM_RETURN (tree view)
NM_SETCURSOR (tree view)
NM_SETFOCUS (tree view)
TVN_BEGINDRAG
TVN_BEGINLABELEDIT
TVN_BEGINRDRAG
TVN_DELETEITEM
TVN_ENDLABELEDIT
TVN_GETDISPINFO
TVN_GETINFOTIP
TVN_ITEMEXPANDED
TVN_ITEMEXPANDING
TVN_KEYDOWN
TVN_SELCHANGED
TVN_SELCHANGING
TVN_SETDISPINFO
TVN_SINGLEEXPAND
TVN_ITEMEXPANDING
TVN_ITEMEXPANDED
6.结构体
typedef struct tagTVINSERTSTRUCT{//包含用于给树型控件增加一个新的节点的信息
HTREEITEM hParent;//父项目的句柄
HTREEITEM hInsertAfter;//TVI_ROOT(根,项目列表的第一个) TVI_FIRST(插入项目放在同一个父项目下的最前面)TVI_LAST(放在同一个父项目下的最后面)
TVI_SORT(按字母排序)
#if (_WIN32_IE >= 0x0400)
union
{
TVITEMEX itemex;
TVITEM item;
} DUMMYUNIONNAME;
#else
TVITEM item;
#endif
}TVINSERTSTRUCT, FAR *LPTVINSERTSTRUCT;
typedef struct tagTVITEM{//一个树型控件节点的属性
UINT mask;//一个标志,表明这个结构体其他成员哪些是有效的
HTREEITEM hItem;//项目的句柄
UINT state;
UINT stateMask;
LPTSTR pszText;//文本
int cchTextMax;//文本的最大长度
int iImage;//项目非选取状态下,要使用的image在图象列表中的索引
int iSelectedImage;//项目选取状态下,要使用的image在图象列表中的索引
int cChildren;//
LPARAM lParam;
} TVITEM, FAR *LPTVITEM;
mask可以是以下值的组合:
TVIF_CHILDREN:cChildren成员有效
TVIF_HANDLE:hItem成员有效
TVIF_IMAGE:iImage成员有效
TVIF_PARAM:lParam成员有效
TVIF_SELECTEDIMAGE:iSelectedImage成员有效
TVIF_STATE:state和stateMask成员有效
TVIF_TEXT:pszText和cchTextMax成员有效
state成员:
TVIS_BOLD The item is bold.
TVIS_CUT The item is selected as part of a cut-and-paste operation.
TVIS_DROPHILITED The item is selected as a drag-and-drop target.
TVIS_EXPANDED The item's list of child items is currently expanded; that is, the child items are visible. This value applies only to parent items.
TVIS_EXPANDEDONCE The item's list of child items has been expanded at least once. The TVN_ITEMEXPANDING and TVN_ITEMEXPANDED notification messages are not
generated for parent items that have this state set in response to a TVM_EXPAND message. Using TVE_COLLAPSE and TVE_COLLAPSERESET with TVM_EXPAND will cause
this state to be reset. This value applies only to parent items.
TVIS_EXPANDPARTIAL Version 4.70. A partially expanded tree view item. In this state, some, but not all, of the child items are visible and the parent item's
plus symbol is displayed.
TVIS_SELECTED The item is selected. Its appearance depends on whether it has the focus. The item will be drawn using the system colors for selection.
When you set or retrieve an item's overlay image index or state image index, you must specify the following masks in the stateMask member of the TVITEM
structure. These values can also be used to mask off the state bits that are not of interest. TVIS_OVERLAYMASK Mask for the bits used to specify the item's
overlay image index.
TVIS_STATEIMAGEMASK Mask for the bits used to specify the item's state image index.
TVIS_USERMASK Same as TVIS_STATEIMAGEMASK
cChildren成员:
zero:该项目没有子项目
one:该项目有一个或多个子项目
I_CHILDRENCALLBACK:he parent window keeps track of whether the item has child items. In this case, when the tree view control needs to display the item, the
control sends the parent a TVN_GETDISPINFO notification message to determine whether the item has child items.
If the tree view control has the TVS_HASBUTTONS style, it uses this member to determine whether to display the button indicating the presence of child
items. You can use this member to force the control to display the button even though the item does not have any child items inserted. This allows you to
display the button while minimizing the control's memory usage by inserting child items only when the item is visible or expanded
typedef struct tagNMTREEVIEW {
NMHDR hdr;
UINT action;
TVITEM itemOld;
TVITEM itemNew;
POINT ptDrag;
} NMTREEVIEW, FAR *LPNMTREEVIEW;
typedef struct tagTVHITTESTINFO {
POINT pt;
UINT flags;
HTREEITEM hItem;
} TVHITTESTINFO, FAR *LPTVHITTESTINFO;
typedef struct tagNMTVCUSTOMDRAW {
NMCUSTOMDRAW nmcd;
COLORREF clrText;
COLORREF clrTextBk;
#if (_WIN32_IE >= 0x0400)
int iLevel;
#endif
} NMTVCUSTOMDRAW, *LPNMTVCUSTOMDRAW;
7.下面是个实例:
//树型控件 类名:SysTreeView32
#include <Windows.h>
#include <tchar.h>
#include "resource.h"
#include <commctrl.h>
#pragma comment(lib,"comctl32.lib")
TCHAR ClassName[]=_T("TreeViewWinClass");
TCHAR AppName[]=_T("Tree View Demo");
TCHAR TreeViewClass[]=_T("SysTreeView32");
BOOL DragMode=FALSE;
HINSTANCE g_hInstance;
HWND hwndTreeView;
HTREEITEM hParent;
HIMAGELIST hImageList;
HIMAGELIST hDragImageList;
BOOL CALLBACK About(HWND hDlg, UINT message,WPARAM wParam, LPARAM lParam);
INT_PTR CALLBACK ProcWinMain(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam)
{
/*
typedef struct tagTVINSERTSTRUCT{//包含用于给树型控件增加一个新的节点的信息
HTREEITEM hParent;
HTREEITEM hInsertAfter;
#if (_WIN32_IE >= 0x0400)
union
{
TVITEMEX itemex;
TVITEM item;
} DUMMYUNIONNAME;
#else
TVITEM item;
#endif
}TVINSERTSTRUCT, FAR *LPTVINSERTSTRUCT;
typedef struct tagTVITEM{//定义或接收一个树型控件节点的属性
UINT mask;
HTREEITEM hItem;
UINT state;
UINT stateMask;
LPTSTR pszText;
int cchTextMax;
int iImage;
int iSelectedImage;
int cChildren;
LPARAM lParam;
} TVITEM, FAR *LPTVITEM;
typedef struct tagTVHITTESTINFO{//包含用于决定某一点与树型控件的位置关系的信息
POINT pt;
UINT flags;
HTREEITEM hItem;
}TVHITTESTINFO, FAR *LPTVHITTESTINFO;
*/
HBITMAP hBitmap;
TV_INSERTSTRUCT tvinsert;
TV_HITTESTINFO tvhit;
switch(Msg)
{
case WM_CREATE:
//a hierarchical(分层的) list of items. Each item consists of a label and an optional bitmap
hwndTreeView=CreateWindow
("SysTreeView32",NULL,WS_CHILD|WS_VISIBLE|TVS_HASLINES|TVS_LINESATROOT|TVS_HASBUTTONS|TVS_SINGLEEXPAND,30,100,200,80,hWnd,(HMENU)157,hInst,NULL);
//创建一个空的图像列表,该图像列表容纳的是以像素为单位16x16大小和16位的图像,该图像列表初始包含2幅图像,最大可以容纳10 幅
hImageList=ImageList_Create(16,16,ILC_COLOR16,2,10);
hBitmap=LoadBitmap(hInst,MAKEINTRESOURCE(IDB_BITMAP));
ImageList_Add(hImageList,hBitmap,NULL);//给image列表增加一幅位图
DeleteObject(hBitmap);
//给树型控件发送TVM_SETIMAGELIST消息,设置图象
SendMessage(hwndTreeView,TVM_SETIMAGELIST,TVSIL_NORMAL,(LPARAM)hImageList);
//设置和获取整个控件背景颜色
SendMessage(hwndTreeView,TVM_SETBKCOLOR,0,RGB(200,230,150));
color=SendMessage(hwndTreeView,TVM_GETBKCOLOR,0,0);
sprintf(str,"Red:%d;Green:%d;Blue:%d",GetRValue(color),GetGValue(color),GetBValue(color));
// SetWindowText(hBuddy,str);
//设置和获取缩进
SendMessage(hwndTreeView,TVM_SETINDENT,30,0);
sprintf(str,"%d",SendMessage(hwndTreeView,TVM_GETINDENT,0,0));
// SetWindowText(hBuddy,str);
//设置和获取项目的高度
SendMessage(hwndTreeView,TVM_SETITEMHEIGHT,33,0);
sprintf(str,"%d",SendMessage(hwndTreeView,TVM_GETITEMHEIGHT,0,0));
// SetWindowText(hBuddy,str);
//设置和获取文本颜色
SendMessage(hwndTreeView,TVM_SETTEXTCOLOR,0,RGB(0,150,100));
color=SendMessage(hwndTreeView,TVM_GETTEXTCOLOR,0,0);
sprintf(str,"Red:%d;Green:%d;Blue:%d",GetRValue(color),GetGValue(color),GetBValue(color));
SetWindowText(hBuddy,str);
//创建父Node
tvinsert.item.mask=TVIF_TEXT|TCIF_IMAGE|TVIF_SELECTEDIMAGE;//pszText和cchTextMax、iImage、iSelectedImage成员有效
tvinsert.item.iImage=0;//没被选择时的位图索引,因为image列表现在只有一幅位图,所以索引是0
tvinsert.item.iSelectedImage=0;//被选择时的位图索引
tvinsert.item.pszText="父节点1";
tvinsert.hParent=NULL;
tvinsert.hInsertAfter=TVI_ROOT;//根节点,所以hParent是NULL,hInsertAfter是 TVI_ROOT
hParent=(HTREEITEM)SendMessage(hwndTreeView,TVM_INSERTITEM,0,(LPARAM)&tvinsert);
tvinsert.hParent=hParent;
tvinsert.hInsertAfter=TVI_LAST;//TVI_LAST表示节点添加在最后
tvinsert.item.pszText="子节点11";
SendMessage(hwndTreeView,TVM_INSERTITEM,0,(LPARAM)&tvinsert);
tvinsert.hParent=NULL;
tvinsert.hInsertAfter=TVI_ROOT;
tvinsert.item.pszText="父节点2";
//返回值为父节点
hParent=(HTREEITEM)SendMessage(hwndTreeView,TVM_INSERTITEM,0,(LPARAM)&tvinsert);
//创建子Node,hParent=父节点
tvinsert.hParent=hParent;
tvinsert.hInsertAfter=TVI_LAST;//TVI_LAST表示节点添加在同一父项目下的最后面
tvinsert.item.pszText="子节点21";
SendMessage(hwndTreeView,TVM_INSERTITEM,0 ,(LPARAM)&tvinsert);
tvinsert.item.pszText="子节点22";
SendMessage(hwndTreeView,TVM_INSERTITEM,0,(LPARAM)&tvinsert);
tvinsert.item.pszText="子节点23";
SendMessage(hwndTreeView,TVM_INSERTITEM,0,(LPARAM)&tvinsert);
/*
SendMessage
(
hwndTreeView,TVM_DELETEITEM,0,
SendMessage//获得根项目,即项目列表的第一个项目
(
hwndTreeView,TVM_GETNEXTITEM,(WPARAM)TVGN_ROOT,
0
)
);
*/
//下面的练习,看起来像不像函数呢?通过发送消息来获得节点的句柄
SendMessage//删除字节点23
(
hwndTreeView,TVM_DELETEITEM,0,
SendMessage////获得子节点22的下一个兄弟项目,即子节点23
(
hwndTreeView,TVM_GETNEXTITEM,(WPARAM)TVGN_NEXT,
SendMessage//获得子节点21的下一个兄弟项目,即子节点22
(
hwndTreeView,TVM_GETNEXTITEM,(WPARAM)TVGN_NEXT,
SendMessage//获得父节点2的第一个子项目,即子节点21
(
hwndTreeView,TVM_GETNEXTITEM,(WPARAM)TVGN_CHILD,
SendMessage//获得最后一个可见项目,即父节点2
(
hwndTreeView,TVM_GETNEXTITEM,(WPARAM)TVGN_LASTVISIBLE,
0
)
)
)
)
);
/*
SendMessage
(
hwndTreeView,TVM_DELETEITEM,0,
SendMessage
(
hwndTreeView,TVM_GETNEXTITEM,(WPARAM)TVGN_NEXT,
SendMessage
(
hwndTreeView,TVM_GETNEXTITEM,(WPARAM)TVGN_NEXT,
SendMessage
(
hwndTreeView,TVM_GETNEXTITEM,(WPARAM)TVGN_CHILD,
(LPARAM)hParent
)
)
)
);
*/
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
case WM_MOUSEMOVE:
if(DragMode)
{
//储存鼠标的坐标,相对于hWnd窗口
tvhit.pt.x=LOWORD(lParam);
tvhit.pt.y=HIWORD(lParam);
//将坐标转换成相对于树型控件的坐标
ClientToScreen(hWnd,&tvhit.pt);
ScreenToClient(hwndTreeView,&tvhit.pt);
//设置拖动图像和鼠标的偏移量
tvhit.pt.x+=5;
tvhit.pt.y+=5;
//ImageList_DragMove来更新拖动图像的位置
ImageList_DragMove(tvhit.pt.x,tvhit.pt.y);
ImageList_DragShowNolock(FALSE);
//发送消息TVM_HITTEST给列表视图控件看看鼠标是否正好经过某些节点
HTREEITEM hTmp=(HTREEITEM)SendMessage(hwndTreeView,TVM_HITTEST,NULL,(LPARAM)&tvhit);
if(hTmp!= NULL)//鼠标正好经过某个节点
{
SendMessage(hwndTreeView,TVM_SELECTITEM,TVGN_DROPHILITE,(LPARAM)hTmp);
}
ImageList_DragShowNolock(TRUE);//show the image
}
break;
case WM_LBUTTONUP:
if(DragMode)
{
ImageList_DragLeave(hwndTreeView);
ImageList_EndDrag();
ImageList_Destroy(hDragImageList);
HTREEITEM hTmp=(HTREEITEM)SendMessage(hwndTreeView,TVM_GETNEXTITEM,TVGN_DROPHILITE,0);
SendMessage(hwndTreeView,TVM_SELECTITEM,TVGN_CARET,(LPARAM)hTmp);
SendMessage(hwndTreeView,TVM_SELECTITEM,TVGN_DROPHILITE,0);
ReleaseCapture();
DragMode=FALSE;
}
break;
//树型视图控件将发送WM_NOTIFY消息给它的父窗口
case WM_NOTIFY:
phdr=(NMHDR*)lParam;
switch(phdr->code)
{
case NM_RELEASEDCAPTURE:
SendMessage(hwndTrack,TBM_SETPOS,TRUE,40);
sprintf(str,"%d",SendMessage(hwndTrack,TBM_GETPOS,0,0));
SetWindowText((HWND)SendMessage(hwndTrack,TBM_GETBUDDY,FALSE,0),str);
break;
case TVN_BEGINDRAG://当用户拖动项目时
pTree=(NM_TREEVIEW *)lParam;
{
//发送消息TVM_CREATEDRAGIMAGE来创建一个拖动的图像
hDragImageList=(HIMAGELIST)SendMessage(hwndTreeView,TVM_CREATEDRAGIMAGE,0,(LPARAM)(pTree->itemNew.hItem));
ImageList_BeginDrag(hDragImageList,0,0,0);
ImageList_DragEnter(hwndTreeView,pTree->ptDrag.x,pTree->ptDrag.y);
SetCapture(hWnd);//捕获所有窗口的鼠标消息
DragMode=TRUE;
}
break;
case NM_CUSTOMDRAW:
switch(wParam)//判断哪个控件发送的
{
case 157://TREEVIEW的ID
ptvcd=(NMTVCUSTOMDRAW*)lParam;
switch(ptvcd->nmcd.dwDrawStage)//绘制阶段
{
case CDDS_PREPAINT://Before the painting cycle begins
return CDRF_NOTIFYITEMDRAW;//send NM_CUSTOMDRAW notification messages to the parent,before and after drawing items
case CDDS_ITEMPREPAINT://Before an item is drawn
// newfont=(HFONT)GetStockObject(ANSI_FIXED_FONT);
// SelectObject(ptvcd->nmcd.hdc,newfont);
// ptvcd->clrText=RGB(255,0,0);
// ptvcd->clrTextBk=RGB(200,0,0);//设置项目的背景色
return CDRF_NEWFONT;
default:
break;
}
break;
default:
break;
}
break;
default:
break;
}
default:
return DefWindowProc(hWnd,Msg,wParam,lParam);
}
return 0;
}
int WINAPI WinMain( HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow
)
{
WNDCLASSEX wc;
MSG msg;
HWND hWnd;
g_hInstance=hInstance;
wc.cbSize=sizeof(WNDCLASSEX);
wc.style=CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc=ProcWinMain;
wc.cbClsExtra=NULL;
wc.cbWndExtra=NULL;
wc.hInstance=hInstance;
wc.hbrBackground=(HBRUSH)(COLOR_APPWORKSPACE);
wc.lpszMenuName=NULL;
wc.lpszClassName=ClassName;
wc.hIcon=wc.hIconSm=LoadIcon(NULL,IDI_APPLICATION);
wc.hCursor=LoadCursor(NULL,IDC_ARROW);
RegisterClassEx(&wc);
hWnd=CreateWindowEx(WS_EX_CLIENTEDGE,ClassName,AppName,WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,CW_USEDEFAULT,400,600,NULL,NULL,hInstance,NULL);
ShowWindow(hWnd,SW_SHOWNORMAL);
UpdateWindow(hWnd);
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
InitCommonControls();//Registers and initializes the common control window classes. This function is obsolete. New applications should use the
InitCommonControlsEx function.
}
BOOL CALLBACK About(HWND hDlg, UINT message,WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG:
case WM_COMMAND:
switch (LOWORD (wParam))
{
case IDOK:
case IDCANCEL:
EndDialog (hDlg,0);
return true;
}
break;
}
return false;
}