'Listview drag and drop autodefine "off" Declare import,ClientToScreen(hWnd:uint,POINT:pointer) Declare import,GetClassNameA(hWnd:uint,lpClassName:uint,nMaxCount:int),int Declare import,GetCursorPos(POINT:pointer),int Declare import,GetDesktopWindow(),uint Declare import,GetDlgItem(hWnd:uint,ControlID:int),uint Declare import,GetParent(hWnd:uint),uint Declare import,IsWindow(hWnd:uint),int Declare import,LoadCursorA(hInstance:uint,lpCursorName:uint),uint Declare import,ReleaseCapture(),int Declare import,ScreenToClient(hWnd:uint,xy:pointer),int Declare import,SendMessageA(hWnd:uint,message:uint,wParam:int,lparam:uint),uint Declare import,SetCapture(hWnd:uint),int Declare import,_SetCursor alias SetCursor(hCur:uint),uint Declare import,WindowFromPoint(xPoint:int,yPoint:int),uint TYPE IMAGEINFO UINT hbmImage UINT hbmMask UINT Unused1 UINT Unused2 WINRECT rcImage ENDTYPE IMAGEINFO imf TYPE LVHITTESTINFO POINT pt UINT flags INT iItem INT iSubItem ENDTYPE LVHITTESTINFO lvhi TYPE LVITEM UINT mask INT iItem INT iSubItem UINT state UINT stateMask POINTER pszText INT cchTextMax INT iImage UINT lParam INT iIndent INT iGroupId UINT cColumns UINT puColumns ENDTYPE LVITEM lvi TYPE NMLISTVIEW UINT hWndFrom INT idFrom INT code INT iItem INT iSubItem UINT uNewState UINT uOldState UINT uChanged POINT ptAction INT lParam ENDTYPE DIALOG d1 UINT hDragImageList,DragFromWindow,LVhWndFrom,LVhWndTo,Cursor_Drag,Cursor_Normal,Cursor_No INT DragTable[256],DragCount,bDragging POINT pt const IDC_ARROW=32512 const IDC_NO=32648 const LVIF_TEXT=1 const LVM_HITTEST = 4114 Const LVHT_NOWHERE = 0x1 Const LVM_SETEXTENDEDLISTVIEWSTYLE = 0x1000 + 54 const LVM_INSERTITEM = 4103 const LVM_GETITEM = 4101 const LVM_DELETEITEM = 4104 Const LVS_EX_FULLROWSELECT=0x20 Const LVN_BEGINDRAG = -109 Const LVNI_SELECTED = 2 Const LVM_GETNEXTITEM = 4108 const LVM_GETITEMCOUNT = 4100 Const LVM_CREATEDRAGIMAGE = 4129 MEMORY Cursor_data 'cursor from code _asm mov eax,Cursor_3_cur mov [$Cursor_data],eax _endasm CreateDragCursor() Cursor_Normal = LoadCursorA(0, IDC_ARROW) Cursor_No = LoadCursorA(0, IDC_NO) Cursor_Drag = LoadImage("Cursor_3.cur", @imgcursor) CREATEDIALOG d1,0,0,386,386,0x80C80080,0,"Drag item(s)",&handler CONTROL d1,@LISTVIEW,"",0,3,192,384,0x50800001|@LVSSORTASCENDING,1 CONTROL d1,@LISTVIEW,"",193,3,192,384,0x50800001|@LVSSORTASCENDING,2 Domodal d1 END Sub handler(),INT Select @message Case @idinitdialog SendMessage d1,LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_FULLROWSELECT, 1 SendMessage d1,LVM_SETEXTENDEDLISTVIEWSTYLE, 0, LVS_EX_FULLROWSELECT, 2 Centerwindow d1 AddSomeItems() Case @idmousemove IF bDragging GetCursorPos(pt) ImageList_DragMove(pt.x, pt.y) IF TestDragPosition(pt.x)<0 'dummy variable. is changed!! _SetCursor(Cursor_No) Else _SetCursor(Cursor_Drag) Endif Endif Case @idlbuttonup IF bDragging Then StopDragLVhandler() Case @idcontrol Select @controlid Case 1 Select @notifycode Case LVN_BEGINDRAG BeginDragLVhandler(d1.hWnd, 1, *@LPARAM) EndSelect Case 2 Select @notifycode Case LVN_BEGINDRAG BeginDragLVhandler(d1.hWnd, 2, *@LPARAM) EndSelect EndSelect EndSelect Return 0 EndSub Sub BeginDragLVhandler(parent:uint, controlID:int, nmlv:NMLISTVIEW) UINT hOneImageList, hTempImageList INT iHeight, iPos, bFirst DragCount = 0 LVhWndFrom = GetDlgItem(parent, controlID) DragFromWindow = parent pt.x = 8 pt.y = 8 bFirst = TRUE iPos = SendMessageA(LVhWndFrom, LVM_GETNEXTITEM, -1, LVNI_SELECTED) While (iPos <> -1) and (DragCount < 256) IF bFirst ' For the first selected item hDragImageList = SendMessageA(LVhWndFrom, LVM_CREATEDRAGIMAGE, iPos, &pt) ImageList_GetImageInfo(hDragImageList, 0, &imf) iHeight = imf.rcImage.bottom : bFirst = FALSE ' add item index to memory DragTable[0] = iPos : DragCount++ Else ' For the rest selected items we create a single-line drag image, then append it to the bottom of the complete drag image hOneImageList = SendMessageA(LVhWndFrom, LVM_CREATEDRAGIMAGE, iPos, &pt) hTempImageList = ImageList_Merge(hDragImageList, 0, hOneImageList, 0, 0, iHeight) ImageList_Destroy(hDragImageList) : ImageList_Destroy(hOneImageList) hDragImageList = hTempImageList ImageList_GetImageInfo(hDragImageList, 0, &imf) iHeight = imf.rcImage.bottom ' add item index to memory DragTable[DragCount] = iPos DragCount++ Endif iPos = SendMessageA(LVhWndFrom, LVM_GETNEXTITEM, iPos, LVNI_SELECTED) Wend ImageList_BeginDrag(hDragImageList, 0, 0, 0) pt = nmlv.ptAction ClientToScreen(LVhWndFrom, &pt) ImageList_DragEnter(GetDesktopWindow(), pt.x, pt.y) bDragging = TRUE SetCapture(parent) EndSub Sub StopDragLVhandler() POINTER P UINT LVhWnd INT a, StartItem SetCaption d1, "Drag item(s)" ' change the cursor _SetCursor(Cursor_Normal) bDragging = FALSE ImageList_DragLeave(LVhWnd) ImageList_EndDrag() ImageList_Destroy(hDragImageList) ReleaseCapture() ' DragFromWindow - start-drag ListView owner ' DragTable[] - index of dragged items ' DragCount - items count ' LVhWndFrom - handle to the start-drag ListView ' LVhWndTo - handle to the stop-drag ListView StartItem = TestDragPosition(LVhWndTo) IF StartItem <> -1 ' move the dragged items to new position in (other?) ListView, first move the dragged items to memory P = new(STRING, DragCount) lvi.mask = LVIF_TEXT lvi.iSubItem = 0 lvi.cchTextMax = 254 For a = DragCount-1 To 0 Step -1 lvi.iItem = DragTable[a] lvi.pszText = #P[a, 0] SendMessageA(LVhWndFrom, LVM_GETITEM, 0, &lvi) SendMessageA(LVhWndFrom, LVM_DELETEITEM, DragTable[a], 0) Next a ' then move the items from memory to current listview For a = 0 To DragCount-1 lvi.iItem = StartItem+a lvi.pszText = #P[a, 0] SendMessageA(LVhWndTo, LVM_INSERTITEM, 0, &lvi) Next a Delete P Endif EndSub ' returns the ListView item from current cursor position and the current ListView handle Sub TestDragPosition(hWnd:uint byref),int ISTRING xclass[31] INT item GetCursorPos(pt) hWnd = WindowFromPoint(pt.x, pt.y) IF IsWindow(hWnd) IF GetParent(hWnd) = DragFromWindow ' only within starting window GetClassNameA(hWnd, &xclass, 30) IF xclass = "SysListView32" ' only ListView ScreenToClient(hWnd, pt) lvhi.pt = pt lvhi.flags = LVHT_NOWHERE item = SendMessageA(hWnd, LVM_HITTEST, 0, &lvhi) IF item < 0 Then item = SendMessageA(hWnd, LVM_GETITEMCOUNT, 0, 0) setcaption d1, using("hWnd:# x:# y:# item:# dragging # item(s)", hWnd, pt.x, pt.y, item, DragCount) return item Endif Endif Endif Return -1 EndSub Sub AddSomeItems() INT a ControlCmd d1, 1, @lvinsertcolumn, 0, "ListView 1" ControlCmd d1, 1, @lvsetcolwidth, 0, 190 ControlCmd d1, 2, @lvinsertcolumn, 0, "ListView 2" ControlCmd d1, 2, @lvsetcolwidth, 0, 190 For a = 0 to 20 ControlCmd d1, 1, @lvinsertitem, a, using("Item A #", a) IF a<15 Then ControlCmd d1, 2, @lvinsertitem, a, using("Item B #", a) Next a EndSub Sub CreateDragCursor() BFILE F OpenFile F, GetStartPath+"Cursor_3.cur", "w" __write F, Cursor_data, 326 CloseFile F EndSub _asm ;----------------------------- segment .data use32 ;----------------------------- Cursor_3_cur: dd 0x00020000,0x20200001,0x00000000,0x01300000,0x00160000 dd 0x00280000,0x00200000,0x00400000,0x00010000,0x00000001 dd 0x00800000,0x00000000,0x00000000,0x00000000,0x00000000 dd 0x00000000,0xFFFF0000,0x000000FF,0x00000000,0x00000000 dd 0x00000000,0x00000000,0x00000000,0x00000000,0xFC070000 dd 0xFC070000,0xFC070000,0xFC070000,0xFC070000,0x3C070000 dd 0xDC060000,0xDC060000,0xBC050000,0xBC050000,0x7C030000 dd 0x00430000,0x00660000,0x00760000,0x007E0000,0xC07F0000 dd 0x807F0000,0x007F0000,0x007E0000,0x007C0000,0x00780000 dd 0x00700000,0x00600000,0x00400000,0x00000000,0xFFFF0000 dd 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF dd 0x01F0FFFF,0x01F0FFFF,0x01F0FFFF,0x01F0FFFF,0x01F0FFFF dd 0x01F0FFFF,0x01F0FFFF,0x01F0FFFF,0x01F0FFFF,0x01F0FFFF dd 0x0170FFFF,0x0130FFFF,0x0110FFFF,0xFF00FFFF,0xFF00FFFF dd 0x0F00FFFF,0x1F00FFFF,0x3F00FFFF,0x7F00FFFF,0xFF00FFFF dd 0xFF01FFFF,0xFF03FFFF,0xFF07FFFF,0xFF0FFFFF,0xFF1FFFFF dd 0xFF3FFFFF db 0xFF,0xFF _endasm