第十九课 树型视图控件
TVM_INSERTITEM 
wParam = 0; 
lParam = 
  指向结构体TV_INSERTSTRUCT的指针; 
您应当知道一些关于树型视图中的项目之间关系的一些术语。 一个项目可能是一个父亲、儿子或两者都是。父项目下含有子项目,而该父项目又有可能是其它项目的子项目。一个没有父项目的项目叫根项目。在树型视图中可能有多个根项目。现在我们来看看TV_INSERTSTRUCT结构体:
该结构体根据消息类型,用来发送或接收关于一个树型视图的项目的有关信息。譬如:对于消息TVM_INSERTITEM,它用来指定插入树型视图控件的项目的属性。而对于消息TVM_GETITEM,该结构体用来填充关于选定项目的信息。
imask 
用来指定TV_ITEM的那些成员变量有效。譬如,如果指定了TVIF_TEXT,这意味着pszText成员变量是有效的。您可以同时指定几个标志位。
hItem 
是树型视图项目的句柄。每一个项目都有它自己的句柄,就像窗口一样。如果您想要操作一个项目,就必须选择它的句柄。
pszText 
是一个字符串指针。它是项目的标签名。
cchTextMax仅在查询项目的名称时使用。由于在pszText中指定了指针,WINDOWS还要知道该缓冲去的大小。所以您必须给出该值。
iImage 
和 
iSelectedImage用来指定图象列表以及一个索引号。这样就知道当项目被选中或没被选中时用哪个图象来表示该项目。像资源管理器中左边窗口中的文件夹等小图表就是有这两个参数来决定的。 
为了在树型视图中插入一个项目,您必须至少设定hParent, hInsertAfter,另外您还要设定imask和pszText值。 
如果创建成功的话,该函数返回一个空的图象列表的句柄。
cx == 以像素为单位的图象的宽度。
cy == 
以像素为单位的图象的高度。图象列表中的每一幅的高度都必须相同。否则WINDOWS会对您的图象进行裁剪,如果过大的话就可能裁剪成几小块。所以您必须指定相同大小的图象。
flags 
== 指定图象列表的图象的颜色深度。详细情况请参考WIN32 API 指南。
cInitial == 
指定包含的图象的数目。WINDWOS将依此来分配合适的内存。
cGrow == 在增加新图象是一次增加的数目。
图象列表不是窗口。仅仅是保存在那给其它的窗口使用的一种资源。 在图象列表产生后,您可以调用ImageList_Add来向其中加入图象。
TVM_GETITEM 
wParam = 0 
lParam 
  =指向结构体TV_ITEM的指针。该结构体将用来得到相关的信息。
在发送该消息前必须设置成员变量imask的值,以便WINDOWS能告诉相关的信息。当然,最重要的是,您必须传递您想得到信息的项目的句柄。这就引起了一个问题,您如何得到项目的句柄?要保存所有项目的句柄吗?
答案是很简单的:没有必要。您可以发送消息TVM_GETNEXTITEM到树型视图以检索您想要得到其属性的项目的句柄。譬如:您可以查询第一个子项目的句柄、根目录的句柄、选中的项目的句柄等等。
WinMain PROTO :DWORD,:DWORD,:DWORD,:DWORD 
.const 
IDB_TREE equ 
4006                
; ID of the bitmap resource 
.data 
ClassName  db 
"TreeViewWinClass",0 
AppName    db "Tree View 
Demo",0 
TreeViewClass  db "SysTreeView32",0 
Parent  db "Parent Item",0 
Child1  db "child1",0 
Child2  db "child2",0 
DragMode  dd 
FALSE                
; a flag to determine if we are in drag mode 
.data? 
hInstance  HINSTANCE ? 
hwndTreeView dd 
?            ; handle of 
the tree view control 
hParent  dd 
?                        
; handle of the root tree view item 
hImageList dd 
?                    
; handle of the image list used in the tree view control 
hDragImageList  dd ?        ; 
handle of the image list used to store the drag image 
.code 
start: 
    invoke 
GetModuleHandle, NULL 
    mov    
hInstance,eax 
    invoke WinMain, hInstance,NULL,NULL, 
SW_SHOWDEFAULT 
    invoke ExitProcess,eax 
    invoke InitCommonControls 
WinMain proc 
hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD 
    LOCAL wc:WNDCLASSEX 
    
LOCAL msg:MSG 
    LOCAL hwnd:HWND 
    mov   wc.cbSize,SIZEOF WNDCLASSEX 
    mov   wc.style, CS_HREDRAW or CS_VREDRAW 
    mov   wc.lpfnWndProc, OFFSET WndProc 
    mov   wc.cbClsExtra,NULL 
    mov   wc.cbWndExtra,NULL 
    push  hInst 
    
pop   wc.hInstance 
    mov   
wc.hbrBackground,COLOR_APPWORKSPACE 
    
mov   wc.lpszMenuName,NULL 
    
mov   wc.lpszClassName,OFFSET ClassName 
    
invoke LoadIcon,NULL,IDI_APPLICATION 
    
mov   wc.hIcon,eax 
    mov   
wc.hIconSm,eax 
    invoke 
LoadCursor,NULL,IDC_ARROW 
    mov   
wc.hCursor,eax 
    invoke RegisterClassEx, addr wc 
    invoke CreateWindowEx,WS_EX_CLIENTEDGE,ADDR 
ClassName,ADDR 
AppName,\           
WS_OVERLAPPED+WS_CAPTION+WS_SYSMENU+WS_MINIMIZEBOX+WS_MAXIMIZEBOX+WS_VISIBLE,CW_USEDEFAULT,\ 
           
CW_USEDEFAULT,200,400,NULL,NULL,\ 
           
hInst,NULL 
    mov   hwnd,eax 
    .while TRUE 
        invoke GetMessage, ADDR 
msg,NULL,0,0 
        .BREAK .IF 
(!eax) 
        invoke 
TranslateMessage, ADDR msg 
        
invoke DispatchMessage, ADDR msg 
    .endw 
    mov eax,msg.wParam 
    
ret 
WinMain endp 
WndProc proc uses edi hWnd:HWND, uMsg:UINT, wParam:WPARAM, 
lParam:LPARAM 
    LOCAL tvinsert:TV_INSERTSTRUCT 
    LOCAL hBitmap:DWORD 
    
LOCAL tvhit:TV_HITTESTINFO 
    .if uMsg==WM_CREATE 
        invoke 
CreateWindowEx,NULL,ADDR TreeViewClass,NULL,\ 
            
WS_CHILD+WS_VISIBLE+TVS_HASLINES+TVS_HASBUTTONS+TVS_LINESATROOT,0,\ 
            
0,200,400,hWnd,NULL,\ 
            
hInstance,NULL            
; Create the tree view control 
        mov hwndTreeView,eax 
        invoke 
ImageList_Create,16,16,ILC_COLOR16,2,10    ; create the 
associated image list 
        mov 
hImageList,eax 
        invoke 
LoadBitmap,hInstance,IDB_TREE        ; load 
the bitmap from the resource 
        mov hBitmap,eax 
        invoke 
ImageList_Add,hImageList,hBitmap,NULL    ; Add the bitmap into 
the image list 
        invoke 
DeleteObject,hBitmap    ; always delete the bitmap resource 
        invoke 
SendMessage,hwndTreeView,TVM_SETIMAGELIST,0,hImageList 
        mov tvinsert.hParent,NULL 
        mov 
tvinsert.hInsertAfter,TVI_ROOT 
        mov 
tvinsert.item.imask,TVIF_TEXT+TVIF_IMAGE+TVIF_SELECTEDIMAGE 
        mov 
tvinsert.item.pszText,offset Parent 
        mov tvinsert.item.iImage,0 
        mov 
tvinsert.item.iSelectedImage,1 
        invoke 
SendMessage,hwndTreeView,TVM_INSERTITEM,0,addr tvinsert 
        mov hParent,eax 
        mov tvinsert.hParent,eax 
        mov 
tvinsert.hInsertAfter,TVI_LAST 
        mov 
tvinsert.item.pszText,offset Child1 
        invoke 
SendMessage,hwndTreeView,TVM_INSERTITEM,0,addr tvinsert 
        mov 
tvinsert.item.pszText,offset Child2 
        invoke 
SendMessage,hwndTreeView,TVM_INSERTITEM,0,addr tvinsert 
    .elseif uMsg==WM_MOUSEMOVE 
        .if DragMode==TRUE 
            mov 
eax,lParam 
            and 
eax,0ffffh 
            mov 
ecx,lParam 
            shr 
ecx,16 
            mov 
tvhit.pt.x,eax 
            mov 
tvhit.pt.y,ecx 
            invoke 
ImageList_DragMove,eax,ecx 
            invoke 
ImageList_DragShowNolock,FALSE 
            invoke 
SendMessage,hwndTreeView,TVM_HITTEST,NULL,addr tvhit 
            .if 
eax!=NULL 
                
invoke SendMessage,hwndTreeView,TVM_SELECTITEM,TVGN_DROPHILITE,eax 
            
.endif 
            invoke 
ImageList_DragShowNolock,TRUE 
        .endif 
    .elseif uMsg==WM_LBUTTONUP 
        .if DragMode==TRUE 
            invoke 
ImageList_DragLeave,hwndTreeView 
            invoke 
ImageList_EndDrag 
            invoke 
ImageList_Destroy,hDragImageList 
            invoke 
SendMessage,hwndTreeView,TVM_GETNEXTITEM,TVGN_DROPHILITE,0 
            invoke 
SendMessage,hwndTreeView,TVM_SELECTITEM,TVGN_CARET,eax 
            invoke 
SendMessage,hwndTreeView,TVM_SELECTITEM,TVGN_DROPHILITE,0 
            invoke 
ReleaseCapture 
            mov 
DragMode,FALSE 
        .endif 
    .elseif uMsg==WM_NOTIFY 
        mov edi,lParam 
        assume edi:ptr NM_TREEVIEW 
        .if 
[edi].hdr.code==TVN_BEGINDRAG 
            invoke 
SendMessage,hwndTreeView,TVM_CREATEDRAGIMAGE,0,[edi].itemNew.hItem 
            mov 
hDragImageList,eax 
            invoke 
ImageList_BeginDrag,hDragImageList,0,0,0 
            invoke 
ImageList_DragEnter,hwndTreeView,[edi].ptDrag.x,[edi].ptDrag.y 
            invoke 
SetCapture,hWnd 
            mov 
DragMode,TRUE 
        .endif 
        assume edi:nothing 
    .elseif uMsg==WM_DESTROY 
        invoke 
PostQuitMessage,NULL 
    .else 
        invoke 
DefWindowProc,hWnd,uMsg,wParam,lParam 
        ret 
    .endif 
    xor eax,eax 
    ret 
WndProc endp 
end start