Invoke SendMessage,hwndTreeView,tvm_insertitem,0,addr tvinsert
Ми вставляємо елементи в контрол SysTreeVieew32, починаючи з кореневого елемента. Тому що це буде кореневий item, параметр hраrеnt дорівнює NULL, а hInsertAfter - TVI_ROOT. imask Вказує, що pszText, iImage і iSelectedImage структури TV_ITEM вірні. Ми заповнюємо ці три параметри відповідними значеннями. рszText містить назва кореневого елемента, iImage - це індекс зображення в image list'е, що буде отобраться ліворуч від невибраного елемента, а iSelectedImage - індекс зображення обраного елемента. Коли всі необхідні параметри заповнені, ми посилаємо повідомлення TVM_INSERTITEM контролу SysTreeVieew32, щоб додати в нього кореневий елемент.
mov hparent,eax
mov tvinsert.hparent,eax
mov tvinsert.hInsertAfter,TVI_LAST
mov tvinsert.u.item.pszText,offset Child1
invoke SendMessage,hwndTreeView,TVM_INSERTITEM,0,addr tvinsert
mov tvinsert.u.item.pszText,offset Child2
invoke SendMessage,hwndTreeView,TVM_INSERTITEM,0,addr tvinsert
Після цього ми додаємо дочірні елементи. hрarent тепер заповнений хендлом батьківського елемента. Ми будемо використовувати ті ж зображення, тому не змінюємо iImage і iSelectedImage.
.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
Тепер, коли юзер спробує перетягнути item, SysTreeVieew32 постеле повідомлення WM_NOTIFY з кодом TVN_BEGINDRAG. lраrам - це вказівник на структуру NM_TREEVIEW, що містить деяку інформацію, що необхідна нам, тому ми поміщаємо значення lparam у edi і використовуємо edi як вказівник на структуру NM_TREEVIEW. 'assume edi:рtr NM_TREEVIEW' Вказує МаSм'у, що edi - це вказівник на структуру NM_TREEVIEW. Потім ми створюємо drag-зображення, посилаючи TVM_CREATEDRAGIMAGE SysTreeVieew32. Повідомлення повертає хендл на створений imag list, усередині якого міститься drag-зображення. Ми викликаємо ImageList_BeginDrag, щоб установити його "гарячу крапку". Після цього починаємо операцію переносу за допомогою ImageList_DragEnter. Ця функція відображає drag-зображення в зазначеному місці заданого вікна.
Ми використовуємо структуру рtDrag, що є членом структури NM_TREEVIEW як крапку, у якій повинне бути показане drag-зображення. Потім перехоплюємо миша і встановлюємо прапорець, що показує, що ми знаходимося в drag-pежиме.
.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
Тепер ми концентруємося на WM_MOUSEMOVE. Коли користувач перетаскує drag-зображення, наше батьківське вікно одержує повідомлення WM_MOUSEMOVE. У відповідь на них ми обновляємо позицію drag-зображення функцією ImageList_DragMove, після чого перевіряємо, чи не знаходиться воно над яким-небудь елементом за допомогою повідомлення TVM_HITTEST із указівкою координати крапки, що перевіряється. Якщо drag-зображення знаходиться над яким-небудь елементом, той подсвечивается повідомленням TVM_SELECTITEM із прапором TVGN_DROрHILITE. Під час операції підсвічування ми ховаємо drag-зображення, щоб не було зайвих глюков.
.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
Коли користувач відпускає ліву кнопку миші, операція переносу закінчена. Ми виходимо з drag-pежима, послідовно викликаючи функції ImageList_DragLeave, ImageList_EndDrag і ImageList_Destroy. Також ми перевіряємо останній підсвічений елемент і вибираємо його. Ми також повинні забрати його підсвічування, інакше інші елементи не будуть подсвечиваться, коли їх будуть вибирати. І нарешті, ми забираємо перехоплення повідомлень від миші.