天天看點

SDK之--TreeView 分享

樹型控件是一系列分層項目的視窗

每個項目由一個标簽和一幅可選的位圖組成

每個項目可以有一個子項目清單,單擊一個項目,可以展開或折疊其子項目

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)

{

    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//删除位元組點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,

        )

       )

      )

     )

    );

        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;     

}