📄 lion-tutorial19.htm
字号:
<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> <br>
<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> <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> <b>Analysis:</b></h3>
Within WM_CREATE handler, you create the tree view control
<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>
Note the styles. TVS_xxxx are the tree view specific styles.
<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>
Next, you create an empty image list with will accept images of 16x16 pixels in
size, 16-bit color and initially, it will contain 2 images but can be expanded
to 10 if need arises. We then load the bitmap from the resource and add it to
the image list just created. After that, we delete the handle to the bitmap since
it will not be used anymore. When the image list is all set, we associate it with
the tree view control by sending TVM_SETIMAGELIST to the tree view control.
<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>
We insert items into the tree view control, beginning from the root item. Since
it will be root item, hParent member is NULL and hInsertAfter is TVI_ROOT. imask
member specifies that pszText, iImage and iSelectedImage members of the TV_ITEM
structure is valid. We fill those three members with appropriate value. pszText
contains the label of the root item, iImage is the index into the image in the
image list that will be displayed to the left of the unselected item, and iSelectedImage
is the index into the image in the image list that will be displayed when the
item is selected. When all appropriate members are filled in, we send TVM_INSERTITEM
message to the tree view control to add the root item to it.
<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>
After the root item is added, we can attach the child items to it. hParent member
is now filled with the handle of the parent item. And we will use identical images
in the image list so we don't change iImage and iSelectedImage member.
<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>
Now when the user tries to drag an item, the tree view control sends WM_NOTIFY
message with TVN_BEGINDRAG as the code. lParam is the pointer to an NM_TREEVIEW
structure which contains several pieces of information we need so we put its value
into edi and use edi as the pointer to NM_TREEVIEW structure. assume edi:ptr NM_TREEVIEW
is a way to tell MASM to treat edi as the pointer to NM_TREEVIEW structure. We
then create a drag image by sending TVM_CREATEDRAGIMAGE to the tree view control.
It returns the handle to the newly created image list with a drag image inside.
We call ImageList_BeginDrag to set the hotspot in the drag image. Then we enter
the drag operation by calling ImageList_DragEnter. This function displays the
drag image at the specified location in the specified window. We use ptDrag structure
that is a member of NM_TREEVIEW structure as the point where the drag image should
be initially displayed.After that, we capture the mouse input and set the flag
to indicate that we now enter drag mode.
<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>
Now we concentrate on WM_MOUSEMOVE. When the user drags the drag image along,
our parent window receives WM_MOUSEMOVE messages. In response to these messages,
we update the drag image position with ImageList_DragMove. After that, we check
if the drag image is over some item. We do that by sending TVM_HITTEST message
to the tree view control with a point for it to check. If the drag image is over
some item, we hilite that item by sending TVM_SELECTITEM message with TVGN_DROPHILITE
flag to the tree view control. During the hilite operation, we hide the drag image
so that it will not leave unsightly blots on the tree view control.
<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>
When the user releases the left mouse button, the drag operation is at the end.
We leave the drag mode by calling ImageList_DragLeave, followed by ImageList_EndDrag
and ImageList_Destroy. To make the tree view items look good, we also check the
last hilited item, and select it. We must also un-hilite it else the other items
will not get hilited when they are selected. And lastly, we release the mouse
capture. <br>
<hr size="1">
<div align="center"> This article come from Iczelion's asm page, Welcom to <a href="http://asm.yeah.net">http://asm.yeah.net</a></div>
</body>
</html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -