rexx Posted March 5, 2010 Posted March 5, 2010 http://www.autoitscript.com/forum/index.php?showtopic=56411 It works fine in x86, but in x64, I got some problem in DLL calls. First, in the WM_NOTIFY function, Local $tNMHDR = DllStructCreate("hwnd hTree;int_ptr;int_ptr code", $lParam) Local $code = DllStructGetData($tNMHDR, "code") I use int_ptr in the struct to get the correct 64-bit int, but it becomes unsigned int. The help file says that int_ptr is signed int. Is that a bug or I'm doing something wrong? I convert both $code and the $TVN_ constants to HEX to make it work, but I think it's not a good solution. And the second problem, in the SysEvents() function. Case $GUI_EVENT_MOUSEMOVE If $bTreeDrag = False Then ContinueCase $aHwnd = DllCall("user32.dll", "hwnd", "WindowFromPoint", "uint", MouseGetPos(0), "uint", MouseGetPos(1)) ;cancel drag in progress and cleanup if moved outside treeview: If ($aHwnd[0] <> $hTree) Then $bTreeDrag = False _WinAPI_InvalidateRect($hTree) _GUIImageList_Destroy($hTreeDragImage) ;delete drag image _SendMessage($hTree, $TVM_SELECTITEM, $TVGN_DROPHILITE, 0) ;remove DropTarget _SendMessage($hTree, $TVM_SETINSERTMARK, 0, 0) ;remove InsertMark ContinueCase EndIf The $aHwnd[0] is always a strange number, so it always stop dragging here. I've tried use "uint_ptr" for mouse position, but not works. Anyone helps? Thanks in advance. Here's the full code. expandcollapse popup#include <GuiTreeView.au3> #Include <WindowsConstants.au3> #Include <GUIConstantsEx.au3> ;Opt("GUICloseOnESC", 0) Opt("GUIOnEventMode", 1) $sTitle = "Treeview Drag & Drop Editing" ;Required global constants: Global $bTreeDrag = False, $bTreeEdit = False, $hDragItem, $hTreeDragImage, $fWhere $hGui = GUICreate($sTitle, 400, 300, -1, -1, -1, -1) $label = GUICtrlCreateLabel("Drag and drop separate items or branches to move them." & _ @LF & "To start edit selected item, LMB on item or press Enter." & _ @LF & "To end editing, LMB outside item (apply) or Esc (cancel) / Enter (apply)." & _ @LF & "To insert new item press Insert, to delete existing item press Delete.", 30, 10, 340, 60) $cTree = GUICtrlCreateTreeView(50,75,300,200,$TVS_HASBUTTONS+$TVS_HASLINES+$TVS_LINESATROOT+$TVS_EDITLABELS+$TVS_CHECKBOXES) GUICtrlSetState(-1, $GUI_DROPACCEPTED) $cTreeItemsStart = GUICtrlCreateDummy() $cTreeItem_1 = GUICtrlCreateTreeViewItem("item 1", $cTree) $cTreeItem_1a = GUICtrlCreateTreeViewItem("item 1a", $cTreeItem_1) $cTreeItem_1b = GUICtrlCreateTreeViewItem("item 1b", $cTreeItem_1) $cTreeItem_2 = GUICtrlCreateTreeViewItem("item 2", $cTree) $cTreeItem_2a = GUICtrlCreateTreeViewItem("item 2a", $cTreeItem_2) $cTreeItem_3 = GUICtrlCreateTreeViewItem("item 3", $cTree) $cTreeItem_3a = GUICtrlCreateTreeViewItem("item 3a", $cTreeItem_3) $cTreeItem_3a1 = GUICtrlCreateTreeViewItem("item 3a1", $cTreeItem_3a) $cTreeItem_4 = GUICtrlCreateTreeViewItem("item 4", $cTree) $cTreeItemsEnd = GUICtrlCreateDummy() ;Treeview with images test: ;~ $hImgList = _GUIImageList_Create (16, 16) ;~ For $ii = 1 To $cTreeItemsEnd-$cTreeItemsStart ;~ _GUIImageList_AddIcon ($hImgList, "shell32.dll", 60+$ii*2) ;~ Next ;~ _GUICtrlTreeView_SetNormalImageList(GUICtrlGetHandle($cTree), $hImgList) ;~ $a = 0 ;~ For $i = $cTreeItemsStart+1 To $cTreeItemsEnd-1 ;~ _GUICtrlTreeView_SetImageIndex($cTree, _GUICtrlTreeView_GetItemHandle($cTree, $i), $a) ;~ _GUICtrlTreeView_SetSelectedImageIndex($cTree, _GUICtrlTreeView_GetItemHandle($cTree, $i), $a) ;~ $a += 1 ;~ Next $label2 = GUICtrlCreateLabel("", 50, 280, 300, 15) GUISetOnEvent($GUI_EVENT_CLOSE, "SysEvents") GUISetOnEvent($GUI_EVENT_MOUSEMOVE, "SysEvents") GUISetOnEvent($GUI_EVENT_PRIMARYUP, "SysEvents") GUIRegisterMsg($WM_NOTIFY, "On_WM_NOTIFY") GUISetState() While 1 Sleep(200) ;add Enter, Esc, Delete and Insert key functionality to treeview edit: ; TreeKeyboardFunc($cTree) WEnd Func SysEvents() Local $hTree = GUICtrlGetHandle($cTree) Switch @GUI_CtrlId Case $GUI_EVENT_CLOSE Exit Case $GUI_EVENT_PRIMARYUP If $bTreeDrag Then _WinAPI_InvalidateRect($hTree) $bTreeDrag = False _GUIImageList_Destroy($hTreeDragImage) ;delete drag image _SendMessage($hTree, $TVM_SELECTITEM, $TVGN_DROPHILITE, 0) ;remove DropTarget _SendMessage($hTree, $TVM_SETINSERTMARK, 0, 0) ;remove InsertMark If (TreeItemFromPoint($hTree) = $hDragItem) Then ContinueCase ;move item: $hItem = TreeItemCopy($hTree, $hDragItem, TreeItemFromPoint($hTree), $fWhere) If $hItem <> 0 Then _GUICtrlTreeView_SelectItem($hTree, $hItem) _GUICtrlTreeView_Delete($hTree, $hDragItem) EndIf EndIf Case $GUI_EVENT_MOUSEMOVE If $bTreeDrag = False Then ContinueCase $aHwnd = DllCall("user32.dll", "hwnd", "WindowFromPoint", "uint", MouseGetPos(0), "uint", MouseGetPos(1)) ;cancel drag in progress and cleanup if moved outside treeview: If ($aHwnd[0] <> $hTree) Then $bTreeDrag = False _WinAPI_InvalidateRect($hTree) _GUIImageList_Destroy($hTreeDragImage) ;delete drag image _SendMessage($hTree, $TVM_SELECTITEM, $TVGN_DROPHILITE, 0) ;remove DropTarget _SendMessage($hTree, $TVM_SETINSERTMARK, 0, 0) ;remove InsertMark ContinueCase EndIf $hItemHover = TreeItemFromPoint($hTree) If $hItemHover = 0 Then ;meh Else $aRect = _GUICtrlTreeView_DisplayRect($hTree, $hItemHover) $iTreeY = _WinAPI_GetMousePosY(True, $hTree) Switch $iTreeY Case $aRect[1] To $aRect[1]+Int(($aRect[3]-$aRect[1])/4) _SendMessage($hTree, $TVM_SELECTITEM, $TVGN_DROPHILITE, 0) ;remove DropTarget _SendMessage($hTree, $TVM_SETINSERTMARK, 0, $hItemHover) ;add InsertMark before item $fWhere = -1 Case 1+$aRect[1]+Int(($aRect[3]-$aRect[1])/3) To $aRect[1]+Int(($aRect[3]-$aRect[1])*2/3) _SendMessage($hTree, $TVM_SETINSERTMARK, 0, 0) ;remove InsertMark _SendMessage($hTree, $TVM_SELECTITEM, $TVGN_DROPHILITE, $hItemHover) ;add DropTarget $fWhere = 0 Case 1+$aRect[1]+Int(($aRect[3]-$aRect[1])*2/3) To $aRect[3] _SendMessage($hTree, $TVM_SELECTITEM, $TVGN_DROPHILITE, 0) ;remove DropTarget _SendMessage($hTree, $TVM_SETINSERTMARK, 1, $hItemHover) ;add InsertMark after item $fWhere = 1 EndSwitch EndIf DrawDragImage($hTree, $hTreeDragImage) EndSwitch EndFunc ; TreeItemFromPoint() ; Returns handle of tree item under mouse: Func TreeItemFromPoint($hWnd) Local $tMPos = _WinAPI_GetMousePos(True, $hWnd) Return _GUICtrlTreeView_HitTestItem($hWnd, DllStructGetData($tMPos, 1), DllStructGetData($tMPos, 2)) EndFunc ; TreeItemCopy() ; Copies tree item $hItemSource and all its children to an item $hItemTarget, depending on $fDirection ; $fDirection: ; -1 = before $hItemTarget ; 0 = inside $hItemTarget ; 1 = after $hItemTarget Func TreeItemCopy($hWnd, $hItemSource, $hItemTarget, $fDirection) ;making sure parent can't be dropped onto one of its descendants: $hTest = $hItemTarget Do $hTest = _GUICtrlTreeView_GetParentHandle($hWnd, $hTest) If $hTest = $hItemSource Then Return 0 Until $hTest = 0 ;create new item at determined position $sText = _GUICtrlTreeView_GetText($hWnd, $hItemSource) $hParent = _GUICtrlTreeView_GetParentHandle($hWnd, $hItemTarget) Switch $fDirection Case -1 $hPrev = _GUICtrlTreeView_GetPrevSibling($hWnd, $hItemTarget) If $hPrev = 0 Then $hNew = _GUICtrlTreeView_AddFirst($hWnd, $hItemTarget, $sText) Else $hNew = _GUICtrlTreeView_InsertItem($hWnd, $sText, $hParent, $hPrev) EndIf Case 0 $hNew = _GUICtrlTreeView_InsertItem($hWnd, $sText, $hItemTarget) Case 1 $hNew = _GUICtrlTreeView_InsertItem($hWnd, $sText, $hParent, $hItemTarget) Case Else Return 0 EndSwitch ;save item state and checkbox image if there is such _GUICtrlTreeView_SetState($hWnd, $hNew, _GUICtrlTreeView_GetState($hWnd, $hItemSource)) If _GUICtrlTreeView_GetStateImageList($hWnd) <> 0 Then _GUICtrlTreeView_SetStateImageIndex($hWnd, $hNew, _GUICtrlTreeView_GetStateImageIndex($hWnd, $hItemSource)) EndIf ;save icon/selected image indexes If _GUICtrlTreeView_GetNormalImageList($hWnd) <> 0 Then _GUICtrlTreeView_SetImageIndex($hWnd, $hNew, _GUICtrlTreeView_GetImageIndex($hWnd, $hItemSource)) _GUICtrlTreeView_SetSelectedImageIndex($hWnd, $hNew, _GUICtrlTreeView_GetSelectedImageIndex($hWnd, $hItemSource)) EndIf ;recurse through descendants: $iChildCount = _GUICtrlTreeView_GetChildCount($hWnd, $hItemSource) If $iChildCount > 0 Then For $i = 0 To $iChildCount-1 $hRecSource = _GUICtrlTreeView_GetItemByIndex($hWnd, $hItemSource, $i) TreeItemCopy($hWnd, $hRecSource, $hNew, 0) Next EndIf Return $hNew EndFunc Func On_WM_NOTIFY($hWnd, $Msg, $wParam, $lParam) ;wparam = cid, lparam = pnmh If $wParam = $cTree Then Local $tNMHDR = DllStructCreate("hwnd hTree;int_ptr;int_ptr code", $lParam) Local $code = DllStructGetData($tNMHDR, "code") Local $hTree = HWnd(DllStructGetData($tNMHDR, "hTree")) ; tooltip($code) Switch Hex($code) Case Hex($TVN_BEGINDRAGA), Hex($TVN_BEGINDRAGW) ; msgbox(0,0,"Begin Drag",0) $bTreeDrag = True $hDragItem = TreeItemFromPoint($hTree) ;~ _GUICtrlTreeView_SelectItem($hTree, $hDragItem) _GUICtrlTreeView_SetSelected($hTree, _GUICtrlTreeView_GetSelection($hTree), False) $hTreeDragImage = TreeCreateDragImage($hTree, $hDragItem) DrawDragImage($hTree, $hTreeDragImage) Case Hex($TVN_BEGINLABELEDITA), Hex($TVN_BEGINLABELEDITW) $bTreeEdit = True ;~ $hTreeEdit = _SendMessage($hTree, $TVM_GETEDITCONTROL, 0, 0) Case Hex($TVN_ENDLABELEDITA), Hex($TVN_ENDLABELEDITW) $bTreeEdit = False Return 1 Case Hex($TVN_SELCHANGEDA), Hex($TVN_SELCHANGEDW) Local $hSel = _GUICtrlTreeView_GetSelection($hTree) ; Local $tNMTREEVIEW = DllStructCreate($tagNMTREEVIEW, $lParam) ; Local $hSel = DllStructGetData($tNMTREEVIEW, "NewhItem") Local $sTxt = "Selected: " & _GUICtrlTreeView_GetText($hTree, $hSel) & " (item handle " & $hSel & ")" GUICtrlSetData($label2, $sTxt) Case Else EndSwitch ; EndIf EndFunc Func KeyPressed($iHexKey) Local $aRet = DllCall('user32.dll', "int", "GetAsyncKeyState", "int", $iHexKey) ;~ If BitAND($aRet[0], 0x8000) Or BitAND($aRet[0], 1) Then Return 1 If BitAND($aRet[0], 1) Then Return 1 Return 0 EndFunc ;Func TreeKeyboardFunc($cID) ; Local $hWnd = GUICtrlGetHandle($cID) ; If $bTreeDrag Then Return ; If $bTreeEdit Then ; If KeyPressed(0x0d) Then _SendMessage($hWnd, $TVM_ENDEDITLABELNOW, 0, 0) ;enter ; If KeyPressed(0x1b) Then _SendMessage($hWnd, $TVM_ENDEDITLABELNOW, 1, 0) ;esc ; EndIf ; Local $aRet = DllCall('user32.dll', 'hwnd', 'GetFocus') ; If $aRet[0] = $hWnd Then ; If KeyPressed(0x2d) Then _GUICtrlTreeView_Add($hWnd, _GUICtrlTreeView_GetSelection($hWnd), "New Item") ;insert ; If KeyPressed(0x2e) Then _GUICtrlTreeView_Delete($hWnd, _GUICtrlTreeView_GetSelection($hWnd)) ;delete ; If KeyPressed(0x0d) Then _SendMessage($hWnd, $TVM_EDITLABEL, 0, _GUICtrlTreeView_GetSelection($hWnd)) ;enter ; EndIf ;EndFunc Func TreeCreateDragImage($hWnd, $hItem) ;if treeview has imagelist, use image from it If _GUICtrlTreeView_GetNormalImageList($hWnd) <> 0 Then Return _GUICtrlTreeView_CreateDragImage($hWnd, $hItem) ;if not, create a bitmap of dragitem's text rectangle and put it into imagelist. Local $aItemRect = _GUICtrlTreeView_DisplayRect($hWnd, $hItem, True) Local $iImgW = $aItemRect[2]-$aItemRect[0] Local $iImgH = $aItemRect[3]-$aItemRect[1] Local $hTreeDC = _WinAPI_GetDC($hWnd) Local $hMemDC = _WinAPI_CreateCompatibleDC($hTreeDC) Local $hMemBmp = _WinAPI_CreateCompatibleBitmap($hTreeDC, $iImgW, $iImgH) Local $hMemBmpOld = _WinAPI_SelectObject($hMemDC, $hMemBmp) _WinAPI_BitBlt($hMemDC, 0, 0, $iImgW, $iImgH, $hTreeDC, $aItemRect[0], $aItemRect[1], $SRCCOPY) _WinAPI_SelectObject($hMemDC, $hMemBmpOld) _WinAPI_ReleaseDC($hWnd, $hTreeDC) _WinAPI_DeleteDC($hMemDC) Local $hImgList = _GUIImageList_Create($iImgW, $iImgH, 6) _GUIImageList_Add($hImgList, $hMemBmp) _WinAPI_DeleteObject($hMemBmp) Return $hImgList EndFunc ; Draw drag image ; by Gary Frost (gafrost) (?) Func DrawDragImage(ByRef $hControl, ByRef $aDrag) Local $tPoint, $hDC $hDC = _WinAPI_GetWindowDC($hControl) $tPoint = _WinAPI_GetMousePos(True, $hControl) _WinAPI_InvalidateRect($hControl) _GUIImageList_Draw($aDrag, 0, $hDC, DllStructGetData($tPoint, "X")-10, DllStructGetData($tPoint, "Y")-8) _WinAPI_ReleaseDC($hControl, $hDC) EndFunc ;==>DrawDragImage
rexx Posted March 6, 2010 Author Posted March 6, 2010 I found the solution for WindowFromPoint http://www.autoitscript.com/forum/index.php?showtopic=109121 But the first problem still not solved.
rexx Posted March 6, 2010 Author Posted March 6, 2010 (edited) OK, I solved it. Just use the $tagNMHDR structure. Global Const $tagNMHDR = "hwnd hWndFrom;uint_ptr IDFrom;INT Code" "Code" is int, not int_ptr expandcollapse popup#include <GuiTreeView.au3> #Include <WindowsConstants.au3> #Include <GUIConstantsEx.au3> ;Opt("GUICloseOnESC", 0) Opt("GUIOnEventMode", 1) $sTitle = "Treeview Drag & Drop Editing" ;Required global constants: Global $bTreeDrag = False, $bTreeEdit = False, $hDragItem, $hTreeDragImage, $fWhere $hGui = GUICreate($sTitle, 400, 300, -1, -1, -1, -1) $label = GUICtrlCreateLabel("Drag and drop separate items or branches to move them." & _ @LF & "To start edit selected item, LMB on item or press Enter." & _ @LF & "To end editing, LMB outside item (apply) or Esc (cancel) / Enter (apply)." & _ @LF & "To insert new item press Insert, to delete existing item press Delete.", 30, 10, 340, 60) $cTree = GUICtrlCreateTreeView(50,75,300,200,$TVS_HASBUTTONS+$TVS_HASLINES+$TVS_LINESATROOT+$TVS_EDITLABELS+$TVS_CHECKBOXES) GUICtrlSetState(-1, $GUI_DROPACCEPTED) $cTreeItemsStart = GUICtrlCreateDummy() $cTreeItem_1 = GUICtrlCreateTreeViewItem("item 1", $cTree) $cTreeItem_1a = GUICtrlCreateTreeViewItem("item 1a", $cTreeItem_1) $cTreeItem_1b = GUICtrlCreateTreeViewItem("item 1b", $cTreeItem_1) $cTreeItem_2 = GUICtrlCreateTreeViewItem("item 2", $cTree) $cTreeItem_2a = GUICtrlCreateTreeViewItem("item 2a", $cTreeItem_2) $cTreeItem_3 = GUICtrlCreateTreeViewItem("item 3", $cTree) $cTreeItem_3a = GUICtrlCreateTreeViewItem("item 3a", $cTreeItem_3) $cTreeItem_3a1 = GUICtrlCreateTreeViewItem("item 3a1", $cTreeItem_3a) $cTreeItem_4 = GUICtrlCreateTreeViewItem("item 4", $cTree) $cTreeItemsEnd = GUICtrlCreateDummy() ;Treeview with images test: ;~ $hImgList = _GUIImageList_Create (16, 16) ;~ For $ii = 1 To $cTreeItemsEnd-$cTreeItemsStart ;~ _GUIImageList_AddIcon ($hImgList, "shell32.dll", 60+$ii*2) ;~ Next ;~ _GUICtrlTreeView_SetNormalImageList(GUICtrlGetHandle($cTree), $hImgList) ;~ $a = 0 ;~ For $i = $cTreeItemsStart+1 To $cTreeItemsEnd-1 ;~ _GUICtrlTreeView_SetImageIndex($cTree, _GUICtrlTreeView_GetItemHandle($cTree, $i), $a) ;~ _GUICtrlTreeView_SetSelectedImageIndex($cTree, _GUICtrlTreeView_GetItemHandle($cTree, $i), $a) ;~ $a += 1 ;~ Next $label2 = GUICtrlCreateLabel("", 50, 280, 300, 15) GUISetOnEvent($GUI_EVENT_CLOSE, "SysEvents") GUISetOnEvent($GUI_EVENT_MOUSEMOVE, "SysEvents") GUISetOnEvent($GUI_EVENT_PRIMARYUP, "SysEvents") GUIRegisterMsg($WM_NOTIFY, "On_WM_NOTIFY") GUISetState() While 1 Sleep(200) ;add Enter, Esc, Delete and Insert key functionality to treeview edit: ; TreeKeyboardFunc($cTree) WEnd Func SysEvents() Local $hTree = GUICtrlGetHandle($cTree) Switch @GUI_CtrlId Case $GUI_EVENT_CLOSE Exit Case $GUI_EVENT_PRIMARYUP If $bTreeDrag Then _WinAPI_InvalidateRect($hTree) $bTreeDrag = False _GUIImageList_Destroy($hTreeDragImage) ;delete drag image _SendMessage($hTree, $TVM_SELECTITEM, $TVGN_DROPHILITE, 0) ;remove DropTarget _SendMessage($hTree, $TVM_SETINSERTMARK, 0, 0) ;remove InsertMark If (TreeItemFromPoint($hTree) = $hDragItem) Then ContinueCase ;move item: $hItem = TreeItemCopy($hTree, $hDragItem, TreeItemFromPoint($hTree), $fWhere) If $hItem <> 0 Then _GUICtrlTreeView_SelectItem($hTree, $hItem) _GUICtrlTreeView_Delete($hTree, $hDragItem) EndIf EndIf Case $GUI_EVENT_MOUSEMOVE If $bTreeDrag = False Then ContinueCase Local $tPoint = DllStructCreate("int;int") DllStructSetData($tPoint, 1, MouseGetPos(0)) DllStructSetData($tPoint, 2, MouseGetPos(1)) Local $hWndPoint = _WinAPI_WindowFromPoint($tPoint) ;cancel drag in progress and cleanup if moved outside treeview: if $hWndPoint <> $hTree then $bTreeDrag = False _WinAPI_InvalidateRect($hTree) _GUIImageList_Destroy($hTreeDragImage) ;delete drag image _SendMessage($hTree, $TVM_SELECTITEM, $TVGN_DROPHILITE, 0) ;remove DropTarget _SendMessage($hTree, $TVM_SETINSERTMARK, 0, 0) ;remove InsertMark ContinueCase EndIf $hItemHover = TreeItemFromPoint($hTree) If $hItemHover = 0 Then ;meh Else $aRect = _GUICtrlTreeView_DisplayRect($hTree, $hItemHover) $iTreeY = _WinAPI_GetMousePosY(True, $hTree) Switch $iTreeY Case $aRect[1] To $aRect[1]+Int(($aRect[3]-$aRect[1])/4) _SendMessage($hTree, $TVM_SELECTITEM, $TVGN_DROPHILITE, 0) ;remove DropTarget _SendMessage($hTree, $TVM_SETINSERTMARK, 0, $hItemHover) ;add InsertMark before item $fWhere = -1 Case 1+$aRect[1]+Int(($aRect[3]-$aRect[1])/3) To $aRect[1]+Int(($aRect[3]-$aRect[1])*2/3) _SendMessage($hTree, $TVM_SETINSERTMARK, 0, 0) ;remove InsertMark _SendMessage($hTree, $TVM_SELECTITEM, $TVGN_DROPHILITE, $hItemHover) ;add DropTarget $fWhere = 0 Case 1+$aRect[1]+Int(($aRect[3]-$aRect[1])*2/3) To $aRect[3] _SendMessage($hTree, $TVM_SELECTITEM, $TVGN_DROPHILITE, 0) ;remove DropTarget _SendMessage($hTree, $TVM_SETINSERTMARK, 1, $hItemHover) ;add InsertMark after item $fWhere = 1 EndSwitch EndIf DrawDragImage($hTree, $hTreeDragImage) EndSwitch EndFunc ; TreeItemFromPoint() ; Returns handle of tree item under mouse: Func TreeItemFromPoint($hWnd) Local $tMPos = _WinAPI_GetMousePos(True, $hWnd) Return _GUICtrlTreeView_HitTestItem($hWnd, DllStructGetData($tMPos, 1), DllStructGetData($tMPos, 2)) EndFunc ; TreeItemCopy() ; Copies tree item $hItemSource and all its children to an item $hItemTarget, depending on $fDirection ; $fDirection: ; -1 = before $hItemTarget ; 0 = inside $hItemTarget ; 1 = after $hItemTarget Func TreeItemCopy($hWnd, $hItemSource, $hItemTarget, $fDirection) ;making sure parent can't be dropped onto one of its descendants: $hTest = $hItemTarget Do $hTest = _GUICtrlTreeView_GetParentHandle($hWnd, $hTest) If $hTest = $hItemSource Then Return 0 Until $hTest = 0 ;create new item at determined position $sText = _GUICtrlTreeView_GetText($hWnd, $hItemSource) $hParent = _GUICtrlTreeView_GetParentHandle($hWnd, $hItemTarget) Switch $fDirection Case -1 $hPrev = _GUICtrlTreeView_GetPrevSibling($hWnd, $hItemTarget) If $hPrev = 0 Then $hNew = _GUICtrlTreeView_AddFirst($hWnd, $hItemTarget, $sText) Else $hNew = _GUICtrlTreeView_InsertItem($hWnd, $sText, $hParent, $hPrev) EndIf Case 0 $hNew = _GUICtrlTreeView_InsertItem($hWnd, $sText, $hItemTarget) Case 1 $hNew = _GUICtrlTreeView_InsertItem($hWnd, $sText, $hParent, $hItemTarget) Case Else Return 0 EndSwitch ;save item state and checkbox image if there is such _GUICtrlTreeView_SetState($hWnd, $hNew, _GUICtrlTreeView_GetState($hWnd, $hItemSource)) If _GUICtrlTreeView_GetStateImageList($hWnd) <> 0 Then _GUICtrlTreeView_SetStateImageIndex($hWnd, $hNew, _GUICtrlTreeView_GetStateImageIndex($hWnd, $hItemSource)) EndIf ;save icon/selected image indexes If _GUICtrlTreeView_GetNormalImageList($hWnd) <> 0 Then _GUICtrlTreeView_SetImageIndex($hWnd, $hNew, _GUICtrlTreeView_GetImageIndex($hWnd, $hItemSource)) _GUICtrlTreeView_SetSelectedImageIndex($hWnd, $hNew, _GUICtrlTreeView_GetSelectedImageIndex($hWnd, $hItemSource)) EndIf ;recurse through descendants: $iChildCount = _GUICtrlTreeView_GetChildCount($hWnd, $hItemSource) If $iChildCount > 0 Then For $i = 0 To $iChildCount-1 $hRecSource = _GUICtrlTreeView_GetItemByIndex($hWnd, $hItemSource, $i) TreeItemCopy($hWnd, $hRecSource, $hNew, 0) Next EndIf Return $hNew EndFunc Func On_WM_NOTIFY($hWnd, $Msg, $wParam, $lParam) ;wparam = cid, lparam = pnmh If $wParam = $cTree Then Local $tNMHDR = DllStructCreate("hwnd hTree;int_ptr;int code", $lParam) Local $code = DllStructGetData($tNMHDR, "code") Local $hTree = HWnd(DllStructGetData($tNMHDR, "hTree")) Switch $code Case $TVN_BEGINDRAGA, $TVN_BEGINDRAGW $bTreeDrag = True $hDragItem = TreeItemFromPoint($hTree) ;~ _GUICtrlTreeView_SelectItem($hTree, $hDragItem) _GUICtrlTreeView_SetSelected($hTree, _GUICtrlTreeView_GetSelection($hTree), False) $hTreeDragImage = TreeCreateDragImage($hTree, $hDragItem) DrawDragImage($hTree, $hTreeDragImage) Case $TVN_BEGINLABELEDITA, $TVN_BEGINLABELEDITW $bTreeEdit = True ;~ $hTreeEdit = _SendMessage($hTree, $TVM_GETEDITCONTROL, 0, 0) Case $TVN_ENDLABELEDITA, $TVN_ENDLABELEDITW $bTreeEdit = False Return 1 Case $TVN_SELCHANGEDA, $TVN_SELCHANGEDW Local $hSel = _GUICtrlTreeView_GetSelection($hTree) ; Local $tNMTREEVIEW = DllStructCreate($tagNMTREEVIEW, $lParam) ; Local $hSel = DllStructGetData($tNMTREEVIEW, "NewhItem") Local $sTxt = "Selected: " & _GUICtrlTreeView_GetText($hTree, $hSel) & " (item handle " & $hSel & ")" GUICtrlSetData($label2, $sTxt) Case Else EndSwitch ; EndIf EndFunc Func KeyPressed($iHexKey) Local $aRet = DllCall('user32.dll', "int", "GetAsyncKeyState", "int", $iHexKey) ;~ If BitAND($aRet[0], 0x8000) Or BitAND($aRet[0], 1) Then Return 1 If BitAND($aRet[0], 1) Then Return 1 Return 0 EndFunc ;Func TreeKeyboardFunc($cID) ; Local $hWnd = GUICtrlGetHandle($cID) ; If $bTreeDrag Then Return ; If $bTreeEdit Then ; If KeyPressed(0x0d) Then _SendMessage($hWnd, $TVM_ENDEDITLABELNOW, 0, 0) ;enter ; If KeyPressed(0x1b) Then _SendMessage($hWnd, $TVM_ENDEDITLABELNOW, 1, 0) ;esc ; EndIf ; Local $aRet = DllCall('user32.dll', 'hwnd', 'GetFocus') ; If $aRet[0] = $hWnd Then ; If KeyPressed(0x2d) Then _GUICtrlTreeView_Add($hWnd, _GUICtrlTreeView_GetSelection($hWnd), "New Item") ;insert ; If KeyPressed(0x2e) Then _GUICtrlTreeView_Delete($hWnd, _GUICtrlTreeView_GetSelection($hWnd)) ;delete ; If KeyPressed(0x0d) Then _SendMessage($hWnd, $TVM_EDITLABEL, 0, _GUICtrlTreeView_GetSelection($hWnd)) ;enter ; EndIf ;EndFunc Func TreeCreateDragImage($hWnd, $hItem) ;if treeview has imagelist, use image from it If _GUICtrlTreeView_GetNormalImageList($hWnd) <> 0 Then Return _GUICtrlTreeView_CreateDragImage($hWnd, $hItem) ;if not, create a bitmap of dragitem's text rectangle and put it into imagelist. Local $aItemRect = _GUICtrlTreeView_DisplayRect($hWnd, $hItem, True) Local $iImgW = $aItemRect[2]-$aItemRect[0] Local $iImgH = $aItemRect[3]-$aItemRect[1] Local $hTreeDC = _WinAPI_GetDC($hWnd) Local $hMemDC = _WinAPI_CreateCompatibleDC($hTreeDC) Local $hMemBmp = _WinAPI_CreateCompatibleBitmap($hTreeDC, $iImgW, $iImgH) Local $hMemBmpOld = _WinAPI_SelectObject($hMemDC, $hMemBmp) _WinAPI_BitBlt($hMemDC, 0, 0, $iImgW, $iImgH, $hTreeDC, $aItemRect[0], $aItemRect[1], $SRCCOPY) _WinAPI_SelectObject($hMemDC, $hMemBmpOld) _WinAPI_ReleaseDC($hWnd, $hTreeDC) _WinAPI_DeleteDC($hMemDC) Local $hImgList = _GUIImageList_Create($iImgW, $iImgH, 6) _GUIImageList_Add($hImgList, $hMemBmp) _WinAPI_DeleteObject($hMemBmp) Return $hImgList EndFunc ; Draw drag image ; by Gary Frost (gafrost) (?) Func DrawDragImage(ByRef $hControl, ByRef $aDrag) Local $tPoint, $hDC $hDC = _WinAPI_GetWindowDC($hControl) $tPoint = _WinAPI_GetMousePos(True, $hControl) _WinAPI_InvalidateRect($hControl) _GUIImageList_Draw($aDrag, 0, $hDC, DllStructGetData($tPoint, "X")-10, DllStructGetData($tPoint, "Y")-8) _WinAPI_ReleaseDC($hControl, $hDC) EndFunc ;==>DrawDragImage Edited March 6, 2010 by rexx
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now