Что нового

Реализовать сложный Drag&Drop

w3d

Чайник
Сообщения
84
Репутация
3
Есть форма (1), которая формируется средствами AutoIT с ListBox с перечнем значений.
Есть другая форма (2) стороннего приложения с текстовыми полями.
Можно ли сделать такой трюк:
- берется значение с (1) и бросается мышкой на поле в (2), при этом определяется hwnd поля на (2).
 

amel27

Продвинутый
Сообщения
146
Репутация
55
w3d сказал(а):
Есть форма (1), которая формируется средствами AutoIT с ListBox с перечнем значений.
Есть другая форма (2) стороннего приложения с текстовыми полями.
Можно ли сделать такой трюк:
- берется значение с (1) и бросается мышкой на поле в (2), при этом определяется hwnd поля на (2).
думаю где-то так:

1. Фиксируем начало Drag&Drop (сообщение LVN_BEGINDRAG);
2. Включаем хук на отжатие левой кнопки мышки;
3. При отжатии проверяем контрол под курсором, отменяем Drag&Drop при необходимости;
4. Отключаем хук
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8 159
Репутация
2 329
w3d « Создано: Сегодня в 13:52:41 »
Можно ли сделать такой трюк
В принципе можно попробовать:

Код:
#include <GUIConstants.au3>
#include <GUIListBox.au3>
#include <WindowsConstants.au3>
#include <Misc.au3>
;

Global $Begin_Drag = False

$hGUI = GUICreate("Drag List Item", 300, 200, 200)

$ListBox = GUICtrlCreateList("", 10, 20, 280, 150)
$hListBox = GUICtrlGetHandle(-1)
GUICtrlSetData($ListBox, "Item 1|Item 2")

GUIRegisterMsg($WM_COMMAND, "WM_CAMMAND")
GUISetState(@SW_SHOW)

_External_Form()

While 1
	$nMsg = GUIGetMsg()
	
	Switch $nMsg
		Case $GUI_EVENT_CLOSE
			Exit
		Case Else
			If $Begin_Drag Then
				$Begin_Drag = False
				
				Local $sSelText = _GUICtrlListBox_GetText($ListBox, _GUICtrlListBox_GetCurSel($ListBox))
				
				While _IsPressed("01")
					Sleep(10)
				WEnd
				
				$hWnd = _WinGetHoveredHandle()
				
				If $sSelText <> "" And $hWnd <> $hListBox And $hWnd <> $hGUI Then
					ToolTip("Dropped Dest hWnd: " & $hWnd)
					ControlSetText($hWnd, "", $hWnd, $sSelText)
				EndIf
			EndIf
	EndSwitch
WEnd

Func _External_Form()
	GUICreate("External Tets Form", 200, 150, 600)
	GUICtrlCreateEdit("", 10, 20, 180, 100)
	GUISetState()
EndFunc

Func _WinGetHoveredHandle()
	Local $iOld_Opt_MCM = Opt("MouseCoordMode", 1)
	Local $Ret = DllCall("user32.dll", "int", "WindowFromPoint", "long", MouseGetPos(0), "long", MouseGetPos(1))
	
	Opt("MouseCoordMode", $iOld_Opt_MCM)
	
	Return HWnd($Ret[0])
EndFunc

Func WM_CAMMAND($hWndGUI, $MsgID, $wParam, $lParam)
	Local $hWndFrom, $iIDFrom, $iCode, $hWndListBox
	If Not IsHWnd($ListBox) Then $hWndListBox = GUICtrlGetHandle($ListBox)
	
	$hWndFrom = $lParam
	$iIDFrom = BitAND($wParam, 0xFFFF) ; Low Word
	$iCode = BitShift($wParam, 16) ; Hi Word
	
	Switch $iIDFrom
		Case $ListBox
			If $iCode = 1 Then $Begin_Drag = True
	EndSwitch
	
	Return $GUI_RUNDEFMSG
EndFunc
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8 159
Репутация
2 329

amel27

Продвинутый
Сообщения
146
Репутация
55
CreatoR сказал(а):
Насколько я понял речь про ListBox, где LVN_BEGINDRAG будет бесполезен :(
угу, по ходу ListBox не поддерживает штатно Drag&Drop, остается только ручное программирование... зато, можно замутить хоть правой кнопкой... :smile: Кстати, для фиксации "Drag" недостаточно одного нажатия на элементе - требуется последующее перемещение с нажатой кнопкой... ;)

P.S. я не силен в GUI, поэтому мне внапряг переводить "1" в "$LBS_NOTIFY"... :-[
 
Автор
W

w3d

Чайник
Сообщения
84
Репутация
3
А если использовать не ListBox, а другой контрол? Например Label? Будет проще?
 
Автор
W

w3d

Чайник
Сообщения
84
Репутация
3
Еще вопрос - можно при перетаскивании сменить курсор (чтобы был стандартно - с плюсиком)?
 
Автор
W

w3d

Чайник
Сообщения
84
Репутация
3
Нашел :smile:
Код:
#include <GUIConstants.au3>
#include <Constants.au3>
#include <WindowsConstants.au3>
#include <WinAPI.au3>
;

$hGUI = GUICreate("Set Cursor Test GUI", 300, 200)
GUISetState()

$hCursor = _WinAPI_LoadImage(0, @WindowsDir & "\Cursors\3dgarro.cur", $IMAGE_CURSOR, 0, 0, BitOR($LR_LOADFROMFILE, $LR_DEFAULTSIZE))

GUIRegisterMsg($WM_MOUSEMOVE, "WM_SETCURSOR")
GUIRegisterMsg($WM_SETCURSOR, "WM_SETCURSOR")

While GUIGetMsg() <> $GUI_EVENT_CLOSE
WEnd

Func WM_SETCURSOR($hWnd, $iMsg, $iwParam, $ilParam)
    _WinAPI_SetCursor($hCursor)
EndFunc
 
Автор
W

w3d

Чайник
Сообщения
84
Репутация
3
CreatoR сказал(а):
w3d « Создано: Сегодня в 13:52:41 »
Можно ли сделать такой трюк
В принципе можно попробовать:
Попробовал заменить на ListView, но не работает :(

Код:
#include <GUIConstants.au3>
    #include <GUIListBox.au3>
    #include <WindowsConstants.au3>
    #include <Misc.au3>
	#include <GuiConstantsEx.au3>
	#include <GuiListView.au3>



	Global $Begin_Drag = False

	Dim $fields [2][2]
	$fields [0][0] = "item1"
	$fields [1][0] = "item2"
	$fields [0][1] = "status1"
	$fields [1][1] = "status2"

	Local $hListBox

	; Create GUI
	$hGUI = GUICreate("Test", 400, 300)
	$ListBox = GUICtrlCreateListView("", 2, 2, 394, 268)
	$hListBox = GUICtrlGetHandle(-1)
	_GUICtrlListView_SetUnicodeFormat($hListBox, False)
	GUISetState()
	; Add columns
	_GUICtrlListView_AddColumn($hListBox, "Item", 100)
	_GUICtrlListView_AddColumn($hListBox, "Status", 100)
	_GUICtrlListView_SetItemCount($hListBox, 30)
	_GUICtrlListView_AddArray($hListBox, $fields)


    GUIRegisterMsg($WM_COMMAND, "WM_CAMMAND")
    GUISetState(@SW_SHOW)

    _External_Form()

    While 1
    	$nMsg = GUIGetMsg()

    	Switch $nMsg
    		Case $GUI_EVENT_CLOSE
    			Exit
    		Case Else
    			If $Begin_Drag Then
    				$Begin_Drag = False
    				Local $sSelText = _GUICtrlListBox_GetText($ListBox, _GUICtrlListBox_GetCurSel($ListBox))
    				While _IsPressed("01")
    					Sleep(10)
    				WEnd
    				$hWnd = _WinGetHoveredHandle()
    				If $sSelText <> "" And $hWnd <> $hListBox And $hWnd <> $hGUI Then
    					ToolTip("Dropped Dest hWnd: " & $hWnd)
    					ControlSetText($hWnd, "", $hWnd, $sSelText)
    				EndIf
    			EndIf
    	EndSwitch
    WEnd

    Func _External_Form()
    	GUICreate("External Tets Form", 200, 150, 600)
    	GUICtrlCreateEdit("", 10, 20, 180, 100)
    	GUISetState()
    EndFunc

    Func _WinGetHoveredHandle()
    	Local $iOld_Opt_MCM = Opt("MouseCoordMode", 1)
    	Local $Ret = DllCall("user32.dll", "int", "WindowFromPoint", "long", MouseGetPos(0), "long", MouseGetPos(1))

    	Opt("MouseCoordMode", $iOld_Opt_MCM)

    	Return HWnd($Ret[0])
    EndFunc

    Func WM_CAMMAND($hWndGUI, $MsgID, $wParam, $lParam)
    	Local $hWndFrom, $iIDFrom, $iCode, $hWndListBox
    	If Not IsHWnd($ListBox) Then $hWndListBox = GUICtrlGetHandle($ListBox)

    	$hWndFrom = $lParam
    	$iIDFrom = BitAND($wParam, 0xFFFF) ; Low Word
    	$iCode = BitShift($wParam, 16) ; Hi Word

    	Switch $iIDFrom
    		Case $ListBox
    			If $iCode = 1 Then $Begin_Drag = True
    	EndSwitch

    	Return $GUI_RUNDEFMSG
    EndFunc
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8 159
Репутация
2 329
w3d [?]
Попробовал заменить на ListView
Код:
#include <GUIConstantsEx.au3>
#include <Constants.au3>
#include <GUIListView.au3>
#include <WindowsConstants.au3>
#include <WinAPI.au3>
#include <Misc.au3>
;

Global $Begin_Drag = False

$hCursor = _WinAPI_LoadImage(0, @WindowsDir & "\Cursors\3dgarro.cur", $IMAGE_CURSOR, 0, 0, BitOR($LR_LOADFROMFILE, $LR_DEFAULTSIZE))

Dim $aFields[2][2]
$aFields[0][0] = "item1"
$aFields[1][0] = "item2"
$aFields[0][1] = "status1"
$aFields[1][1] = "status2"

; Create GUI
$hGUI = GUICreate("Test", 400, 300)
$ListView = GUICtrlCreateListView("", 2, 2, 394, 268)
$hListView = GUICtrlGetHandle(-1)
_GUICtrlListView_SetUnicodeFormat($hListView, False)

; Add columns
_GUICtrlListView_AddColumn($hListView, "Item", 100)
_GUICtrlListView_AddColumn($hListView, "Status", 100)
_GUICtrlListView_SetItemCount($hListView, 30)
_GUICtrlListView_AddArray($hListView, $aFields)

GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
GUIRegisterMsg($WM_LBUTTONUP, "WM_LBUTTONUP")

GUISetState(@SW_SHOW)

_External_Form()

While 1
	$nMsg = GUIGetMsg()
	
	Switch $nMsg
		Case $GUI_EVENT_CLOSE
			Exit
	EndSwitch
WEnd

Func _External_Form()
	GUICreate("External Tets Form", 200, 150, 600)
	GUICtrlCreateEdit("", 10, 20, 180, 100)
	GUISetState()
EndFunc

Func _WinGetHoveredHandle()
	Local $iOld_Opt_MCM = Opt("MouseCoordMode", 1)
	Local $Ret = DllCall("user32.dll", "int", "WindowFromPoint", "long", MouseGetPos(0), "long", MouseGetPos(1))

	Opt("MouseCoordMode", $iOld_Opt_MCM)

	Return HWnd($Ret[0])
EndFunc

Func WM_LBUTTONUP($hWndGUI, $MsgID, $wParam, $lParam)
	If Not $Begin_Drag Then Return $GUI_RUNDEFMSG
	$Begin_Drag = False
	
	Local $sSelText = _GUICtrlListView_GetItemText($ListView, Number(_GUICtrlListView_GetSelectedIndices($ListView)))
	
	Local $hWnd = _WinGetHoveredHandle()
	Local $hAncestor = _WinAPI_GetAncestor($hWnd, $GA_ROOTOWNER)
	
	If $sSelText <> "" And $hAncestor <> $hGUI Then
		ToolTip("Dropped Dest hWnd: " & $hWnd)
		ControlSetText($hAncestor, "", $hWnd, $sSelText)
	EndIf
	
	Return $GUI_RUNDEFMSG
EndFunc

Func WM_NOTIFY($hWndGUI, $MsgID, $wParam, $lParam)
	Local $tagNMHDR, $iEvent, $hwndFrom, $iCode, $iItem
	
	$tagNMHDR = DllStructCreate("int;int;int;int", $lParam) ;NMHDR (hwndFrom, idFrom, code, Item)
	If @error Then Return $GUI_RUNDEFMSG
	
	$iCode = DllStructGetData($tagNMHDR, 3)
	$iItem = DllStructGetData($tagNMHDR, 4)
	
	Switch $wParam
		Case $ListView
			Switch $iCode
				Case $LVN_BEGINDRAG
					_WinAPI_SetCursor($hCursor)
					$Begin_Drag = True
			EndSwitch
	EndSwitch
	
	Return $GUI_RUNDEFMSG
EndFunc
 
Автор
W

w3d

Чайник
Сообщения
84
Репутация
3
CreatoR
Круто!
Теперь буду разбираться как оно работает )
 
Автор
W

w3d

Чайник
Сообщения
84
Репутация
3
Запихал данный код в функцию, и обнаружил что после его отработки перестает реагировать трей на события (
Как можно побороть?
Код:
#include <GUIConstantsEx.au3>
#include <Constants.au3>
#include <GUIListView.au3>
#include <WindowsConstants.au3>
#include <WinAPI.au3>
#include <Misc.au3>
#include <GuiConstants.au3>
#include <EditConstants.au3>
#Include <Array.au3>


Opt("TrayMenuMode", 1 + 2)
Opt("TrayOnEventMode", 1)
Opt("TrayAutoPause", 0)

Global $Begin_Drag = False
Global $hGUI, $ListView, $hCursor

; настройка меню в трее
$fielditem  = TrayCreateItem("Set")
TrayItemSetOnEvent(-1, "_TrayEvent")
$exit = TrayCreateItem("Exit")
TrayItemSetOnEvent(-1, "_TrayEvent")

While 1
WEnd

Func _TrayEvent()
    Switch @TRAY_ID
		Case $fielditem
			_Set()
        Case $exit
            Exit
    EndSwitch
EndFunc

Func _Set()
    $hCursor = _WinAPI_LoadImage(0, @WindowsDir & "\Cursors\3dgarro.cur", $IMAGE_CURSOR, 0, 0, BitOR($LR_LOADFROMFILE, $LR_DEFAULTSIZE))
    Dim $aFields[2][2]
    $aFields[0][0] = "item1"
    $aFields[1][0] = "item2"
    $aFields[0][1] = "status1"
    $aFields[1][1] = "status2"
    ; Create GUI
    $hGUI = GUICreate("Test", 400, 300)
    $ListView = GUICtrlCreateListView("", 2, 2, 394, 268)
    $hListView = GUICtrlGetHandle(-1)
    _GUICtrlListView_SetUnicodeFormat($hListView, False)
    ; Add columns
    _GUICtrlListView_AddColumn($hListView, "Item", 100)
    _GUICtrlListView_AddColumn($hListView, "Status", 100)
    _GUICtrlListView_SetItemCount($hListView, 30)
    _GUICtrlListView_AddArray($hListView, $aFields)
    GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
    GUIRegisterMsg($WM_LBUTTONUP, "WM_LBUTTONUP")
    GUISetState(@SW_SHOW)
    ;_External_Form()
    While 1
    	$nMsg = GUIGetMsg()
    	Switch $nMsg
    		Case $GUI_EVENT_CLOSE
    			;Exit
				GUIDelete($hGUI)
    	EndSwitch
    WEnd
EndFunc

    Func _External_Form()
    	GUICreate("External Tets Form", 200, 150, 600)
    	GUICtrlCreateEdit("", 10, 20, 180, 100)
    	GUISetState()
    EndFunc

    Func _WinGetHoveredHandle()
    	Local $iOld_Opt_MCM = Opt("MouseCoordMode", 1)
    	Local $Ret = DllCall("user32.dll", "int", "WindowFromPoint", "long", MouseGetPos(0), "long", MouseGetPos(1))
    	Opt("MouseCoordMode", $iOld_Opt_MCM)
    	Return HWnd($Ret[0])
    EndFunc

    Func WM_LBUTTONUP($hWndGUI, $MsgID, $wParam, $lParam)
    	If Not $Begin_Drag Then Return $GUI_RUNDEFMSG
    	$Begin_Drag = False
    	Local $sSelText = _GUICtrlListView_GetItemText($ListView, Number(_GUICtrlListView_GetSelectedIndices($ListView)))
    	Local $hWnd = _WinGetHoveredHandle()
    	Local $hAncestor = _WinAPI_GetAncestor($hWnd, $GA_ROOTOWNER)
    	If $sSelText <> "" And $hAncestor <> $hGUI Then
    		ToolTip("Dropped Dest hWnd: " & $hWnd)
    		ControlSetText($hAncestor, "", $hWnd, $sSelText)
    	EndIf
    	Return $GUI_RUNDEFMSG
    EndFunc

    Func WM_NOTIFY($hWndGUI, $MsgID, $wParam, $lParam)
    	Local $tagNMHDR, $iEvent, $hwndFrom, $iCode, $iItem
    	$tagNMHDR = DllStructCreate("int;int;int;int", $lParam) ;NMHDR (hwndFrom, idFrom, code, Item)
    	If @error Then Return $GUI_RUNDEFMSG
    	$iCode = DllStructGetData($tagNMHDR, 3)
    	$iItem = DllStructGetData($tagNMHDR, 4)
    	Switch $wParam
    		Case $ListView
    			Switch $iCode
    				Case $LVN_BEGINDRAG
    					_WinAPI_SetCursor($hCursor)
    					$Begin_Drag = True
    			EndSwitch
    	EndSwitch
    	Return $GUI_RUNDEFMSG
    EndFunc
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8 159
Репутация
2 329
w3d [?]
обнаружил что после его отработки перестает реагировать трей на события
А как он будет реагировать, если опрос делается по событию, а после создания GUI создаётся второй неприрывающийся цикл, который задерживает выполнения первого события? Нужно тогда и GUI обрабатывать по событию:

Код:
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <EditConstants.au3>
#include <Constants.au3>
#include <GUIListView.au3>
#include <WinAPI.au3>
#include <Misc.au3>
#include <Array.au3>
;

Opt("TrayMenuMode", 1 + 2)
Opt("TrayOnEventMode", 1)
Opt("TrayAutoPause", 0)

Opt("GUIOnEventMode", 1)

Global $iDebug = True

Global $Begin_Drag = False
Global $hGUI, $hExt_GUI, $nListView, $hCursor

; настройка меню в трее
$nField_TrayItem = TrayCreateItem("Set")
TrayItemSetOnEvent(-1, "_TrayEvents")
$nExit_TrayItem = TrayCreateItem("Exit")
TrayItemSetOnEvent(-1, "_TrayEvents")

_GUICreate_Proc()
If $iDebug Then _Create_ExternalForm_Proc()

While 1
	Sleep(100)
WEnd

Func _TrayEvents()
	Switch @TRAY_ID
		Case $nField_TrayItem
			GUISetState(@SW_SHOW, $hGUI)
			If $iDebug Then GUISetState(@SW_SHOW, $hExt_GUI)
		Case $nExit_TrayItem
			Exit
	EndSwitch
EndFunc

Func _GUIEvents()
	Switch @GUI_CtrlId
		Case $GUI_EVENT_CLOSE
			GUISetState(@SW_HIDE, $hGUI)
			If $iDebug Then GUISetState(@SW_HIDE, $hExt_GUI)
	EndSwitch
EndFunc

Func _GUICreate_Proc()
	$hCursor = _WinAPI_LoadImage(0, @WindowsDir & "\Cursors\3dgarro.cur", $IMAGE_CURSOR, 0, 0, _
		BitOR($LR_LOADFROMFILE, $LR_DEFAULTSIZE))
	
	Dim $aFields[2][2]
	$aFields[0][0] = "item1"
	$aFields[1][0] = "item2"
	$aFields[0][1] = "status1"
	$aFields[1][1] = "status2"
	
	; Create GUI
	$hGUI = GUICreate("Test", 400, 300)
	
	$nListView = GUICtrlCreateListView("", 2, 2, 394, 268)
	$hListView = GUICtrlGetHandle(-1)
	_GUICtrlListView_SetUnicodeFormat($hListView, False)
	
	; Add columns
	_GUICtrlListView_AddColumn($hListView, "Item", 100)
	_GUICtrlListView_AddColumn($hListView, "Status", 100)
	_GUICtrlListView_SetItemCount($hListView, 30)
	_GUICtrlListView_AddArray($hListView, $aFields)
	
	GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
	GUIRegisterMsg($WM_LBUTTONUP, "WM_LBUTTONUP")
	
	GUISetOnEvent($GUI_EVENT_CLOSE, "_GUIEvents")
EndFunc

Func _Create_ExternalForm_Proc()
	$hExt_GUI = GUICreate("External Tets Form", 200, 150, 600)
	GUICtrlCreateEdit("", 10, 20, 180, 100)
EndFunc

Func _WinAPI_GetHoveredHandle()
	Local $iOld_Opt_MCM = Opt("MouseCoordMode", 1)
	Local $Ret = DllCall("user32.dll", "int", "WindowFromPoint", "long", MouseGetPos(0), "long", MouseGetPos(1))
	Opt("MouseCoordMode", $iOld_Opt_MCM)
	Return HWnd($Ret[0])
EndFunc

Func WM_LBUTTONUP($hWndGUI, $MsgID, $wParam, $lParam)
	If Not $Begin_Drag Then Return $GUI_RUNDEFMSG
	$Begin_Drag = False
	
	Local $iIndex = Number(_GUICtrlListView_GetSelectedIndices($nListView))
	Local $sSelText = _GUICtrlListView_GetItemText($nListView, $iIndex)
	Local $hWnd = _WinAPI_GetHoveredHandle()
	Local $hAncestor = _WinAPI_GetAncestor($hWnd, $GA_ROOTOWNER)
	
	If $sSelText <> "" And $hAncestor <> $hGUI Then
		ToolTip("Dropped Dest hWnd: " & $hWnd)
		ControlSetText($hAncestor, "", $hWnd, $sSelText)
	EndIf
	
	Return $GUI_RUNDEFMSG
EndFunc

Func WM_NOTIFY($hWndGUI, $MsgID, $wParam, $lParam)
	Local $tagNMHDR, $iEvent, $hwndFrom, $iCode, $iItem
	$tagNMHDR = DllStructCreate("int;int;int;int", $lParam) ;NMHDR (hwndFrom, idFrom, code, Item)
	If @error Then Return $GUI_RUNDEFMSG
	
	$iCode = DllStructGetData($tagNMHDR, 3)
	$iItem = DllStructGetData($tagNMHDR, 4)
	
	Switch $wParam
		Case $nListView
			Switch $iCode
				Case $LVN_BEGINDRAG
					_WinAPI_SetCursor($hCursor)
					$Begin_Drag = True
			EndSwitch
	EndSwitch
	
	Return $GUI_RUNDEFMSG
EndFunc
 
Автор
W

w3d

Чайник
Сообщения
84
Репутация
3
Т.е. листвью создается сразу, а потом просто показывается когда нужно...
Интересный подход, совсем позабыл я про такой ход конем.
 

XpycT

Скриптер
Сообщения
380
Репутация
132
Подскажите а как реализовать Drag & Drop но из одного ListView в другой ListView. Попытался сделать на основе приведеннго выше примера, ничего не получаеться :'(.
Код:
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <EditConstants.au3>
#include <Constants.au3>
#include <GUIListView.au3>
#include <WinAPI.au3>
#include <Misc.au3>
#include <Array.au3>
;

Opt("TrayMenuMode", 1 + 2)
Opt("TrayOnEventMode", 1)
Opt("TrayAutoPause", 0)

Opt("GUIOnEventMode", 1)

Global $iDebug = False

Global $Begin_Drag = False
Global $hGUI, $hExt_GUI, $nListView1, $nListView2, $hCursor

; настройка меню в трее
$nField_TrayItem = TrayCreateItem("Set")
TrayItemSetOnEvent(-1, "_TrayEvents")
$nExit_TrayItem = TrayCreateItem("Exit")
TrayItemSetOnEvent(-1, "_TrayEvents")

_GUICreate_Proc()
If $iDebug Then _Create_ExternalForm_Proc()

While 1
	Sleep(100)
WEnd

Func _TrayEvents()
	Switch @TRAY_ID
		Case $nField_TrayItem
			GUISetState(@SW_SHOW, $hGUI)
			If $iDebug Then GUISetState(@SW_SHOW, $hExt_GUI)
		Case $nExit_TrayItem
			Exit
	EndSwitch
EndFunc

Func _GUIEvents()
	Switch @GUI_CtrlId
		Case $GUI_EVENT_CLOSE
			GUISetState(@SW_HIDE, $hGUI)
			If $iDebug Then GUISetState(@SW_HIDE, $hExt_GUI)
	EndSwitch
EndFunc

Func _GUICreate_Proc()
	$hCursor = _WinAPI_LoadImage(0, @WindowsDir & "\Cursors\3dgarro.cur", $IMAGE_CURSOR, 0, 0, _
		BitOR($LR_LOADFROMFILE, $LR_DEFAULTSIZE))

	Dim $aFields[2][2]
	$aFields[0][0] = "item1"
	$aFields[1][0] = "item2"
	$aFields[0][1] = "status1"
	$aFields[1][1] = "status2"

	; Create GUI
	$hGUI = GUICreate("Test", 800, 300)

	$nListView1 = GUICtrlCreateListView("", 2, 2, 394, 268)
	$hListView1 = GUICtrlGetHandle(-1)
	_GUICtrlListView_SetUnicodeFormat($hListView1, False)

	; Add columns
	_GUICtrlListView_AddColumn($hListView1, "Item", 100)
	_GUICtrlListView_AddColumn($hListView1, "Status", 100)
	_GUICtrlListView_SetItemCount($hListView1, 30)
	_GUICtrlListView_AddArray($hListView1, $aFields)

	$nListView2 = GUICtrlCreateListView("", 396, 2, 394, 268)
	$hListView2 = GUICtrlGetHandle(-1)
	_GUICtrlListView_SetUnicodeFormat($hListView2, False)

	; Add columns
	_GUICtrlListView_AddColumn($hListView2, "Item", 100)
	_GUICtrlListView_AddColumn($hListView2, "Status", 100)
	_GUICtrlListView_SetItemCount($hListView2, 30)
; 	_GUICtrlListView_AddArray($hListView2, $aFields)

	GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
	GUIRegisterMsg($WM_LBUTTONUP, "WM_LBUTTONUP")

	GUISetOnEvent($GUI_EVENT_CLOSE, "_GUIEvents")
EndFunc

Func _Create_ExternalForm_Proc()
	$hExt_GUI = GUICreate("External Tets Form", 200, 150, 600)
	GUICtrlCreateEdit("", 10, 20, 180, 100)
EndFunc

Func _WinAPI_GetHoveredHandle()
	Local $iOld_Opt_MCM = Opt("MouseCoordMode", 1)
	Local $Ret = DllCall("user32.dll", "int", "WindowFromPoint", "long", MouseGetPos(0), "long", MouseGetPos(1))
	Opt("MouseCoordMode", $iOld_Opt_MCM)
	Return HWnd($Ret[0])
EndFunc

Func WM_LBUTTONUP($hWndGUI, $MsgID, $wParam, $lParam)
	If Not $Begin_Drag Then Return $GUI_RUNDEFMSG
	$Begin_Drag = False

	Local $iIndex = Number(_GUICtrlListView_GetSelectedIndices($nListView1))
	Local $sSelText = _GUICtrlListView_GetItemText($nListView1, $iIndex)
	Local $hWnd = _WinAPI_GetHoveredHandle()
	Local $hAncestor = _WinAPI_GetAncestor($hWnd, $GA_ROOTOWNER)

	If $sSelText <> "" And $hAncestor <> $hGUI Then
		ToolTip("Dropped Dest hWnd: " & $hWnd)
		ControlSetText($hAncestor, "", $hWnd, $sSelText)
	EndIf

	Return $GUI_RUNDEFMSG
EndFunc

Func WM_NOTIFY($hWndGUI, $MsgID, $wParam, $lParam)
	Local $tagNMHDR, $iEvent, $hwndFrom, $iCode, $iItem
	$tagNMHDR = DllStructCreate("int;int;int;int", $lParam) ;NMHDR (hwndFrom, idFrom, code, Item)
	If @error Then Return $GUI_RUNDEFMSG

	$iCode = DllStructGetData($tagNMHDR, 3)
	$iItem = DllStructGetData($tagNMHDR, 4)

	Switch $wParam
		Case $nListView1
			Switch $iCode
				Case $LVN_BEGINDRAG
					_WinAPI_SetCursor($hCursor)
					$Begin_Drag = True
			EndSwitch
		Case $nListView2
			Switch $iCode
				Case $LVN_BEGINDRAG
					_WinAPI_SetCursor($hCursor)
					$Begin_Drag = True
			EndSwitch
	EndSwitch

	Return $GUI_RUNDEFMSG
EndFunc
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8 159
Репутация
2 329
XpycT [?]
Попытался сделать на основе приведеннго выше примера
Не самый лучший шаблон:

Код:
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <EditConstants.au3>
#include <Constants.au3>
#include <GUIListView.au3>
#include <WinAPI.au3>
#include <Misc.au3>
#include <Array.au3>
;

Opt("TrayMenuMode", 1 + 2)
Opt("TrayOnEventMode", 1)
Opt("TrayAutoPause", 0)

Opt("GUIOnEventMode", 1)

Global $iDebug = False

Global $Begin_Drag = False
Global $hGUI, $hExt_GUI, $nListView1, $nListView2, $hCursor

; настройка меню в трее
$nField_TrayItem = TrayCreateItem("Set")
TrayItemSetOnEvent(-1, "_TrayEvents")
$nExit_TrayItem = TrayCreateItem("Exit")
TrayItemSetOnEvent(-1, "_TrayEvents")

_GUICreate_Proc()
If $iDebug Then _Create_ExternalForm_Proc()

While 1
	Sleep(100)
WEnd

Func _TrayEvents()
	Switch @TRAY_ID
		Case $nField_TrayItem
			GUISetState(@SW_SHOW, $hGUI)
			If $iDebug Then GUISetState(@SW_SHOW, $hExt_GUI)
		Case $nExit_TrayItem
			Exit
	EndSwitch
EndFunc

Func _GUIEvents()
	Switch @GUI_CtrlId
		Case $GUI_EVENT_CLOSE
			GUISetState(@SW_HIDE, $hGUI)
			If $iDebug Then GUISetState(@SW_HIDE, $hExt_GUI)
	EndSwitch
EndFunc

Func _GUICreate_Proc()
	$hCursor = _WinAPI_LoadImage(0, @WindowsDir & "\Cursors\3dgarro.cur", $IMAGE_CURSOR, 0, 0, _
			BitOR($LR_LOADFROMFILE, $LR_DEFAULTSIZE))

	Dim $aFields[2][2]
	$aFields[0][0] = "item1"
	$aFields[1][0] = "item2"
	$aFields[0][1] = "status1"
	$aFields[1][1] = "status2"

	; Create GUI
	$hGUI = GUICreate("Test", 800, 300)

	$nListView1 = GUICtrlCreateListView("", 2, 2, 394, 268)
	$hListView1 = GUICtrlGetHandle(-1)
	_GUICtrlListView_SetUnicodeFormat($hListView1, False)

	; Add columns
	_GUICtrlListView_AddColumn($hListView1, "Item", 100)
	_GUICtrlListView_AddColumn($hListView1, "Status", 100)
	_GUICtrlListView_SetItemCount($hListView1, 30)
	_GUICtrlListView_AddArray($hListView1, $aFields)

	$nListView2 = GUICtrlCreateListView("", 396, 2, 394, 268)
	$hListView2 = GUICtrlGetHandle(-1)
	_GUICtrlListView_SetUnicodeFormat($hListView2, False)

	; Add columns
	_GUICtrlListView_AddColumn($hListView2, "Item", 100)
	_GUICtrlListView_AddColumn($hListView2, "Status", 100)
	_GUICtrlListView_SetItemCount($hListView2, 30)
	; 	_GUICtrlListView_AddArray($hListView2, $aFields)

	GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
	GUIRegisterMsg($WM_LBUTTONUP, "WM_LBUTTONUP")

	GUISetOnEvent($GUI_EVENT_CLOSE, "_GUIEvents")
EndFunc

Func _Create_ExternalForm_Proc()
	$hExt_GUI = GUICreate("External Tets Form", 200, 150, 600)
	GUICtrlCreateEdit("", 10, 20, 180, 100)
EndFunc

Func _WinAPI_GetHoveredHandle()
	Local $iOld_Opt_MCM = Opt("MouseCoordMode", 1)
	Local $Ret = DllCall("user32.dll", "int", "WindowFromPoint", "long", MouseGetPos(0), "long", MouseGetPos(1))
	Opt("MouseCoordMode", $iOld_Opt_MCM)
	Return HWnd($Ret[0])
EndFunc

Func WM_LBUTTONUP($hWndGUI, $MsgID, $wParam, $lParam)
	If Not $Begin_Drag Then Return $GUI_RUNDEFMSG
	$Begin_Drag = False

	Local $iIndex = Number(_GUICtrlListView_GetSelectedIndices($nListView1))
	Local $sSelText = _GUICtrlListView_GetItemText($nListView1, $iIndex)
	Local $hWnd = _WinAPI_GetHoveredHandle()
	Local $hAncestor = _WinAPI_GetAncestor($hWnd, $GA_ROOTOWNER)

	If $sSelText <> "" Then ; And $hAncestor <> $hGUI Then
		ToolTip("Dropped Dest hWnd: " & $hWnd)
		_GUICtrlListView_AddItem($hWnd, $sSelText)
		;ControlSetText($hAncestor, "", $hWnd, $sSelText)
	EndIf

	Return $GUI_RUNDEFMSG
EndFunc

Func WM_NOTIFY($hWndGUI, $MsgID, $wParam, $lParam)
	Local $tagNMHDR, $iEvent, $hwndFrom, $iCode, $iItem
	$tagNMHDR = DllStructCreate("int;int;int;int", $lParam) ;NMHDR (hwndFrom, idFrom, code, Item)
	If @error Then Return $GUI_RUNDEFMSG

	$iCode = DllStructGetData($tagNMHDR, 3)
	$iItem = DllStructGetData($tagNMHDR, 4)

	Switch $wParam
		Case $nListView1
			Switch $iCode
				Case $LVN_BEGINDRAG
					_WinAPI_SetCursor($hCursor)
					$Begin_Drag = True
			EndSwitch
		Case $nListView2
			Switch $iCode
				Case $LVN_BEGINDRAG
					_WinAPI_SetCursor($hCursor)
					$Begin_Drag = True
			EndSwitch
	EndSwitch

	Return $GUI_RUNDEFMSG
EndFunc
 

XpycT

Скриптер
Сообщения
380
Репутация
132
CreatoR
Спасибо буду разбираться

Как перенести значение всех колонок разобрался, а вот как удалить тот элемент который был перенесен никак понять не могу функция
Код:
_GUICtrlListView_DeleteItem($nListView1, $iIndex)
постоянно возвращает False

Вот скрипт (переделал под себя)
Код:
#Region Includes
#include <Constants.au3>
#include <StructureConstants.au3>
#include <WinAPI.au3>
#include <WindowsConstants.au3>
#include <GuiListView.au3>
#include <ListViewConstants.au3>
#include <GUIConstantsEx.au3>
#EndRegion Includes

Opt("GUIOnEventMode", 1)
#NoTrayIcon

Global $Begin_Drag = False
Global $hGUI, $hExt_GUI, $nListView1, $nListView2, $hCursor

$hCursor = _WinAPI_LoadImage(0, @WindowsDir & "\Cursors\3dgarro.cur", $IMAGE_CURSOR, 0, 0, BitOR($LR_LOADFROMFILE, $LR_DEFAULTSIZE))

Dim $aFields[2][2]
$aFields[0][0] = "item1"
$aFields[1][0] = "item2"
$aFields[0][1] = "status1"
$aFields[1][1] = "status2"

; Create GUI
$hGUI = GUICreate("Test", 800, 300)

$nListView1 = GUICtrlCreateListView("", 2, 2, 394, 268)
$hListView1 = GUICtrlGetHandle(-1)
_GUICtrlListView_SetUnicodeFormat($hListView1, False)

; Add columns
_GUICtrlListView_AddColumn($hListView1, "Item", 100)
_GUICtrlListView_AddColumn($hListView1, "Status", 100)
_GUICtrlListView_SetItemCount($hListView1, 30)
_GUICtrlListView_AddArray($hListView1, $aFields)

$nListView2 = GUICtrlCreateListView("", 396, 2, 394, 268)
$hListView2 = GUICtrlGetHandle(-1)
_GUICtrlListView_SetUnicodeFormat($hListView2, False)

; Add columns
_GUICtrlListView_AddColumn($hListView2, "Item", 100)
_GUICtrlListView_AddColumn($hListView2, "Status", 100)
_GUICtrlListView_SetItemCount($hListView2, 30)
; _GUICtrlListView_AddArray($hListView2, $aFields)

GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
GUIRegisterMsg($WM_LBUTTONUP, "WM_LBUTTONUP")

GUISetOnEvent($GUI_EVENT_CLOSE, "_GUIEvents")

GUISetState(@SW_SHOW, $hGUI)

While 1
	Sleep(100)
WEnd

Func _GUIEvents()
	Switch @GUI_CtrlId
		Case $GUI_EVENT_CLOSE
			Exit
	EndSwitch
EndFunc

Func _WinAPI_GetHoveredHandle()
	Local $iOld_Opt_MCM = Opt("MouseCoordMode", 1)
	Local $Ret = DllCall("user32.dll", "int", "WindowFromPoint", "long", MouseGetPos(0), "long", MouseGetPos(1))
	Opt("MouseCoordMode", $iOld_Opt_MCM)
	Return HWnd($Ret[0])
EndFunc

Func WM_LBUTTONUP($hWndGUI, $MsgID, $wParam, $lParam)
	If Not $Begin_Drag Then Return $GUI_RUNDEFMSG
	$Begin_Drag = False

	Local $iIndex = Number(_GUICtrlListView_GetSelectedIndices($nListView1))
	Local $sSelText0 = _GUICtrlListView_GetItemText($nListView1, $iIndex, 0)
	Local $sSelText1 = _GUICtrlListView_GetItemText($nListView1, $iIndex, 1)
	Local $hWnd = _WinAPI_GetHoveredHandle()
	Local $hAncestor = _WinAPI_GetAncestor($hWnd, $GA_ROOTOWNER)

	If $sSelText0 <> "" And $sSelText1 <> "" Then ; And $hAncestor <> $hGUI Then
		ConsoleWrite($iIndex & " | " & $sSelText0 & " | " & $sSelText1 & @CR)
; 		ToolTip("Dropped Dest hWnd: " & $hWnd)
		GUICtrlCreateListViewItem($sSelText0 & " | " & $sSelText1, $nListView2)
		_GUICtrlListView_DeleteItem($nListView1, $iIndex)
; 		ControlSetText($hAncestor, "", $hWnd, $sSelText)
EndIf

	Return $GUI_RUNDEFMSG
EndFunc

Func WM_NOTIFY($hWndGUI, $MsgID, $wParam, $lParam)
	Local $tagNMHDR, $iEvent, $hwndFrom, $iCode, $iItem
	$tagNMHDR = DllStructCreate("int;int;int;int", $lParam) ;NMHDR (hwndFrom, idFrom, code, Item)
	If @error Then Return $GUI_RUNDEFMSG

	$iCode = DllStructGetData($tagNMHDR, 3)
	$iItem = DllStructGetData($tagNMHDR, 4)

	Switch $wParam
		Case $nListView1
			Switch $iCode
				Case $LVN_BEGINDRAG
					_WinAPI_SetCursor($hCursor)
					$Begin_Drag = True
			EndSwitch
		Case $nListView2
			Switch $iCode
				Case $LVN_BEGINDRAG
					_WinAPI_SetCursor($hCursor)
					$Begin_Drag = True
			EndSwitch
	EndSwitch

	Return $GUI_RUNDEFMSG
EndFunc
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8 159
Репутация
2 329
XpycT [?]
Как перенести значение всех колонок разобрался, а вот как удалить тот элемент который был перенесен никак понять не могу
Раз уж такое дело, то подходить к этой задаче нужно с другой стороны, многое за нас уже сделано в UDF и даже нативно:

Код:
#NoTrayIcon
#Region Includes
#include <Constants.au3>
#include <StructureConstants.au3>
#include <WinAPI.au3>
#include <WindowsConstants.au3>
#include <GuiListView.au3>
#include <ListViewConstants.au3>
#include <GUIConstantsEx.au3>
#EndRegion Includes
;

Opt("GUIOnEventMode", 1)

Global $Begin_Drag = False
Global $hGUI, $hExt_GUI, $nListView1, $nListView2, $hCursor

$hCursor = _WinAPI_LoadImage(0, @WindowsDir & "\Cursors\3dgarro.cur", $IMAGE_CURSOR, 0, 0, BitOR($LR_LOADFROMFILE, $LR_DEFAULTSIZE))

Global $aFields[2][2]
$aFields[0][0] = "item1"
$aFields[1][0] = "item2"
$aFields[0][1] = "status1"
$aFields[1][1] = "status2"

; Create GUI
$hGUI = GUICreate("Test", 800, 300)

$nListView1 = GUICtrlCreateListView("", 2, 2, 394, 268, $LVS_SHOWSELALWAYS)
$hListView1 = GUICtrlGetHandle(-1)
GUICtrlSetState(-1, $GUI_DROPACCEPTED)
_GUICtrlListView_SetUnicodeFormat($hListView1, False)

; Add columns
_GUICtrlListView_AddColumn($hListView1, "Item", 100)
_GUICtrlListView_AddColumn($hListView1, "Status", 100)
_GUICtrlListView_SetItemCount($hListView1, 30)
_GUICtrlListView_AddArray($hListView1, $aFields)

$nListView2 = GUICtrlCreateListView("", 396, 2, 394, 268, $LVS_SHOWSELALWAYS)
$hListView2 = GUICtrlGetHandle(-1)
GUICtrlSetState(-1, $GUI_DROPACCEPTED)
_GUICtrlListView_SetUnicodeFormat($hListView2, False)

; Add columns
_GUICtrlListView_AddColumn($hListView2, "Item", 100)
_GUICtrlListView_AddColumn($hListView2, "Status", 100)
_GUICtrlListView_SetItemCount($hListView2, 30)
; _GUICtrlListView_AddArray($hListView2, $aFields)

GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")

GUISetOnEvent($GUI_EVENT_CLOSE, "_GUIEvents")
GUISetOnEvent($GUI_EVENT_DROPPED, "_GUIEvents")

GUISetState(@SW_SHOW, $hGUI)

While 1
	Sleep(100)
WEnd

Func _GUIEvents()
	Switch @GUI_CtrlId
		Case $GUI_EVENT_CLOSE
			Exit
		Case $GUI_EVENT_DROPPED
			Local $hWnd_Source = GUICtrlGetHandle(@GUI_DragId)
			Local $hWnd_Dest = GUICtrlGetHandle(@GUI_DropId)
			
			_GUICtrlListView_CopyItems($hWnd_Source, $hWnd_Dest, True)
	EndSwitch
EndFunc

Func WM_NOTIFY($hWndGUI, $MsgID, $wParam, $lParam)
	Local $tagNMHDR, $iEvent, $hwndFrom, $iCode, $iItem
	$tagNMHDR = DllStructCreate("int;int;int;int", $lParam) ;NMHDR (hwndFrom, idFrom, code, Item)
	If @error Then Return $GUI_RUNDEFMSG
	
	$iCode = DllStructGetData($tagNMHDR, 3)
	$iItem = DllStructGetData($tagNMHDR, 4)
	
	Switch $wParam
		Case $nListView1, $nListView2
			Switch $iCode
				Case $LVN_BEGINDRAG
					_WinAPI_SetCursor($hCursor)
			EndSwitch
	EndSwitch
	
	Return $GUI_RUNDEFMSG
EndFunc
 

XpycT

Скриптер
Сообщения
380
Репутация
132
CreatoR сказал(а):
Раз уж такое дело, то подходить к этой задаче нужно с другой стороны, многое за нас уже сделано в UDF и даже нативно:
Моя извеняется :-[ Надо было сразу написать что требовалось от скрипта.

Спасибо за решение.
 
Верх