?? lion-tut-c19.htm
字號:
<BR><B> mov
DragMode,FALSE</B> <BR><B> .endif</B>
<BR><B> .elseif uMsg==WM_NOTIFY</B>
<BR><B> mov edi,lParam</B>
<BR><B> assume edi:ptr NM_TREEVIEW</B>
<BR><B> .if
[edi].hdr.code==TVN_BEGINDRAG</B>
<BR><B> invoke
SendMessage,hwndTreeView,TVM_CREATEDRAGIMAGE,0,[edi].itemNew.hItem</B>
<BR><B> mov
hDragImageList,eax</B>
<BR><B> invoke
ImageList_BeginDrag,hDragImageList,0,0,0</B>
<BR><B> invoke
ImageList_DragEnter,hwndTreeView,[edi].ptDrag.x,[edi].ptDrag.y</B>
<BR><B> invoke
SetCapture,hWnd</B>
<BR><B> mov
DragMode,TRUE</B> <BR><B> .endif</B>
<BR><B> assume edi:nothing</B>
<BR><B> .elseif uMsg==WM_DESTROY</B>
<BR><B> invoke
PostQuitMessage,NULL</B> <BR><B> .else</B>
<BR><B> invoke
DefWindowProc,hWnd,uMsg,wParam,lParam</B>
<BR><B> ret</B>
<BR><B> .endif</B> <BR><B> xor eax,eax</B>
<BR><B> ret</B> <BR><B>WndProc endp</B> <BR><B>end start</B>
<H3><FONT color=#ff0000>分析:</FONT></H3>在處理消息WM_CREATE的代碼中,您可以創(chuàng)建樹型視圖控件。
<UL><B> invoke
CreateWindowEx,NULL,ADDR TreeViewClass,NULL,\</B>
<BR><B>
WS_CHILD+WS_VISIBLE+TVS_HASLINES+TVS_HASBUTTONS+TVS_LINESATROOT,0,\</B>
<BR><B>
0,200,400,hWnd,NULL,\</B>
<BR><B>
hInstance,NULL</B> </UL>注意: TVS_xxxx 是樹型視圖所特有的風格。
<UL><B> invoke
ImageList_Create,16,16,ILC_COLOR16,2,10</B>
<BR><B> mov hImageList,eax</B>
<BR><B> invoke
LoadBitmap,hInstance,IDB_TREE</B>
<BR><B> mov hBitmap,eax</B>
<BR><B> invoke
ImageList_Add,hImageList,hBitmap,NULL</B>
<BR><B> invoke
DeleteObject,hBitmap</B> <BR><B>
invoke SendMessage,hwndTreeView,TVM_SETIMAGELIST,0,hImageList</B>
</UL>接下來,您可以創(chuàng)建一個空的圖像列表,該圖像列表容納的是以像素為單位16x16大小和16位深度的圖像,該圖像列表初始包含兩幅圖像,最大可以容納10幅。然后我們從資源中加載圖像,并把它們放到圖像列表中去。隨后我們刪除掉圖像的句柄,因為我們不需要再用到它。設置好圖像列表后,我們通過發(fā)送消息TVM_SETIMAGELIST把它和樹型視圖控件聯(lián)系起來。
<UL><B> mov
tvinsert.hParent,NULL</B> <BR><B>
mov tvinsert.hInsertAfter,TVI_ROOT</B>
<BR><B> mov
tvinsert.u.item.imask,TVIF_TEXT+TVIF_IMAGE+TVIF_SELECTEDIMAGE</B>
<BR><B> mov
tvinsert.u.item.pszText,offset Parent</B>
<BR><B> mov
tvinsert.u.item.iImage,0</B> <BR><B>
mov tvinsert.u.item.iSelectedImage,1</B>
<BR><B> invoke
SendMessage,hwndTreeView,TVM_INSERTITEM,0,addr tvinsert</B>
</UL>現(xiàn)在把項目插入到樹型視圖控件中去,首先我們從根項目開始。因為是根項目,所以成員變量hParent是NULL,hInsertAfter是TVI_ROOT。imask指定TV_ITEM結構體變量中的pszText,iImage和iSelectedImage三個成員變量的值是有效的。我們應該給這三個成員變量賦上正確的值。其中pszText顯示項目的名稱,iImage是圖像列表中圖像的索引號,該圖像顯示在未選中的項目名稱的左邊,iSelectedImage是選中的項目的圖像索引號。設置好了這些值后,我們發(fā)送TVM_INSERTITEM消息給樹型視圖控件來把根項目加入到樹型視圖控件中去。
<UL><B> mov hParent,eax</B>
<BR><B> mov tvinsert.hParent,eax</B>
<BR><B> mov
tvinsert.hInsertAfter,TVI_LAST</B>
<BR><B> mov
tvinsert.u.item.pszText,offset Child1</B>
<BR><B> invoke
SendMessage,hwndTreeView,TVM_INSERTITEM,0,addr tvinsert</B>
<BR><B> mov
tvinsert.u.item.pszText,offset Child2</B>
<BR><B> invoke
SendMessage,hwndTreeView,TVM_INSERTITEM,0,addr tvinsert</B>
</UL>加入完根項目后,我們再加入子項目。這時的成員變量hParent是其父項目的句柄,hInsertAfter的值是TVI_LAST。至于選中和非選中時用的圖像是一樣的,所以我們無需更改其它變量的值。
<UL><B> .elseif uMsg==WM_NOTIFY</B>
<BR><B> mov edi,lParam</B>
<BR><B> assume edi:ptr
NM_TREEVIEW</B> <BR><B> .if
[edi].hdr.code==TVN_BEGINDRAG</B>
<BR><B>
invoke SendMessage,hwndTreeView,TVM_CREATEDRAGIMAGE,0,[edi].itemNew.hItem</B>
<BR><B> mov
hDragImageList,eax</B>
<BR><B>
invoke ImageList_BeginDrag,hDragImageList,0,0,0</B>
<BR><B>
invoke ImageList_DragEnter,hwndTreeView,[edi].ptDrag.x,[edi].ptDrag.y</B>
<BR><B>
invoke SetCapture,hWnd</B>
<BR><B> mov
DragMode,TRUE</B> <BR><B> .endif</B>
<BR><B> assume edi:nothing</B>
</UL>當用戶拖動項目時,樹型視圖控件將發(fā)送WM_NOTIFY消息給它的父窗口,子消息號是TVN_BEGINDRAG。在lPAram中是指向結構體NM_TREEVIEW
的指針,該結構體包含了一些附加信息。我們把lParam的值放到edi寄存器中,這樣就可以把edi作為一個指針來使用。“assume edi:ptr
NM_TREEVIEW ”語句用來告訴編譯器MASM把edi作為指向NM_TREEVIEW
的結構體的變量使用。我們通過發(fā)送消息TVM_CREATEDRAGIMAGE來創(chuàng)建一個拖動的圖像。它將返回一個新創(chuàng)建的圖像列表的句柄,該圖像列表中包含拖動中的圖像。我們調用ImageList_BeginDrag函數(shù)設置拖動圖像的熱點。調用ImageList_DragEnter函數(shù)進入操作。該函數(shù)會在特定位置顯示拖動中的圖像。起初顯示的位置我們設在結構體NM_TREEVIEW中的成員變量ptDrag所指的位置。我們鎖定鼠標的輸入,并設置標志變量,表示我們進入了拖拉操作。
<UL><B> .elseif uMsg==WM_MOUSEMOVE</B>
<BR><B> .if DragMode==TRUE</B>
<BR><B> mov
eax,lParam</B>
<BR><B> and
eax,0ffffh</B>
<BR><B> mov
ecx,lParam</B>
<BR><B> shr
ecx,16</B>
<BR><B> mov
tvhit.pt.x,eax</B>
<BR><B> mov
tvhit.pt.y,ecx</B>
<BR><B>
invoke ImageList_DragMove,eax,ecx</B>
<BR><B>
invoke ImageList_DragShowNolock,FALSE</B>
<BR><B>
invoke SendMessage,hwndTreeView,TVM_HITTEST,NULL,addr tvhit</B>
<BR><B> .if
eax!=NULL</B>
<BR><B>
invoke SendMessage,hwndTreeView,TVM_SELECTITEM,TVGN_DROPHILITE,eax</B>
<BR><B>
.endif</B>
<BR><B>
invoke ImageList_DragShowNolock,TRUE</B>
<BR><B> .endif</B>
</UL>現(xiàn)在我們來看看WM_MOUSEMOVE消息的處理過程。當用戶拖動圖像時,我們的父窗口將接收到WM_MOUSEMOVE。為了響應這些消息,我們調用ImageList_DragMove來更新更新圖像的位置。然后我們發(fā)送消息TVM_HITTEST給列表視圖控件看看拖拉中的圖像是否正好經過某些項目的上面,當然還要附帶傳遞坐標位置等信息。如果經過的話,我們發(fā)送消息TVM_SELECTITEM并附帶TVGN_DROPHILITE標志給樹型視圖控件,后者將會高亮度顯示正被經過的項目。在高亮度顯示的過程中,我們隱藏掉拖動中的圖像免得顯示的圖像難看。
<UL><B> .elseif uMsg==WM_LBUTTONUP</B>
<BR><B> .if DragMode==TRUE</B>
<BR><B>
invoke ImageList_DragLeave,hwndTreeView</B>
<BR><B>
invoke ImageList_EndDrag</B>
<BR><B>
invoke ImageList_Destroy,hDragImageList</B>
<BR><B>
invoke SendMessage,hwndTreeView,TVM_GETNEXTITEM,TVGN_DROPHILITE,0</B>
<BR><B>
invoke SendMessage,hwndTreeView,TVM_SELECTITEM,TVGN_CARET,eax</B>
<BR><B>
invoke SendMessage,hwndTreeView,TVM_SELECTITEM,TVGN_DROPHILITE,0</B>
<BR><B>
invoke ReleaseCapture</B>
<BR><B> mov
DragMode,FALSE</B> <BR><B>
.endif</B>
</UL>當用戶釋放鼠標左鍵后,拖拉操作就可以結束了。我們調用ImageList_DragLeave,ImageList_EndDrag和ImageList_Destroy來結束拖拉操作模式。為了使得樹形視圖控件好看,我們檢查最后高亮度顯示的項目,并且選中它。我們還必須使得其不高亮度顯示,否則其它的項目被選中時就不能高亮度顯示了。最后我們釋放對鼠標輸入事件的捕獲。<BR>
<HR SIZE=1>
<DIV align=center>
<SCRIPT language=JavaScript1.1 src="../lion-tut-c13.files/textclick"></SCRIPT>
<BR></DIV><!-- 10:1 文本廣告交換 -->
<DIV align=center>
<SCRIPT language=JavaScript1.1 src="../lion-tut-c13.files/c21.htm"></SCRIPT>
<!-- 10:1 文本廣告交換 --></DIV>
<HR SIZE=1>
<DIV align=center>翻譯:Lxx.阿龍,校對:LuoYunBin's Win32 ASM Page, <A
href="http://asm.yeah.net/">http://asm.yeah.net/</A></DIV></BODY></HTML>
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -