- Offizieller Beitrag
Hi,
in einem Listview lassen sich mit dem Style $LVS_EDITLABELS Einträge on-the-fly editieren. Dies gilt aber nur für die Einträge in Spalte 0.
Mit der folgenden Methode lassen sich alle SubItem sofort editieren. In der zuständigen Funktion verwende ich OnEventMode. Ich habe es aber so geschrieben, dass nur für die Ausführung der Funktion in den OnEventMode geschaltet wird, anschließend wird wieder in den vorherigen Modus zurückgeschaltet (Für all jene, die sich noch immer mit GUIGetMsg rumplagen möchten ).
Das Bsp. habe ich daher auch mal im GetMsgMode erstellt.
Um den Editiermodus nutzen zu können, darf $LVS_EDITLABELS hier nicht gesetzt sein.
- mit Doppelklick öffnet sich genau über der angeklickten Spalte ein Editfenster mit dem Inhalt des SubItem
- der untere Rand des Editfensters liegt an der Mauszeigerspitze
- das Eingabefeld paßt sich der Breite der zugehörigen Spalte an
- ist das Fenster so verschoben, dass eine Spalte nach links/rechts über den Desktop hinausragt, wird das Editfenster am Bildschirmrand, statt mittig über der Spalte positioniert
- der geänderte Inhalt des Fensters wird mit ENTER übernommen und in das SubItem geschrieben
- findet keine Änderung statt muß das Fenster mit ESC geschlossen werden
- während des Editierens werden im Fenstertitel Zeilennummer und Spaltenname des editierten SubItem angezeigt
Bsp. Edit SubItems
#include<StaticConstants.au3>
#include<GUIConstantsEx.au3>
#include<ListViewConstants.au3>
#include<StructureConstants.au3>
#include<WindowsConstants.au3>
#include <GUIListView.au3>
Global $currentItem[2], $title, $currentOpt[2] = ["none"]
[/autoit] [autoit][/autoit] [autoit]$GUI = GUICreate('test')
$hListView = GUICtrlCreateListView('Spalte1|Spalte2|Spalte3', 10, 10, 300, 200, $LVS_REPORT)
_GUICtrlListView_SetColumnWidth($hListView, 0, 70)
_GUICtrlListView_SetColumnWidth($hListView, 1, 60)
_GUICtrlListView_SetColumnWidth($hListView, 2, $LVSCW_AUTOSIZE_USEHEADER )
For $i = 1 To 9
GUICtrlCreateListViewItem('Z. ' & $i & ' - Sp. 1|Z. ' & $i & ' - Sp. 2|Z. ' & $i & ' - Sp. 3', $hListView)
Next
$EditBox = GUICreate('', 200, 30, -1, -1, BitOR($WS_POPUP,$WS_BORDER), $WS_EX_TOPMOST)
$hEdit = GUICtrlCreateInput('', 5, 5, 190, 20, $SS_CENTER)
HotKeySet('{ESC}', '_EscEdit')
GUISetState(@SW_SHOW, $GUI)
GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
While True
$msg = GUIGetMsg()
If $msg = $GUI_EVENT_CLOSE Then Exit
WEnd
Func _LeftDblClick($Info)
If $Info[3] = -1 Then Return
If $currentOpt[0] = "none" Then
$currentOpt[0] = Opt('GUICoordMode', 1)
$currentOpt[1] = Opt("GUIOnEventMode", 1)
EndIf
GUICtrlSetOnEvent($hEdit, '_EditEnter')
_GUICtrlListView_SetSelectedColumn($Info[1], $Info[4])
$title = WinGetTitle($GUI)
Local $mouse = MouseGetPos(), $posEdit = WinGetPos($EditBox)
Local $posGUI = WinGetPos($GUI), $posLV = ControlGetPos($GUI, '', $hListView)
Local $colInfo = _GUICtrlListView_GetColumn($Info[1], $Info[4]), $sumWidth = 0, $tmp
WinSetTitle($GUI, '', 'Editiere: Zeile ' & $Info[3]+1 & ', ' & $colInfo[5])
For $i = 0 To $Info[4]
$tmp = _GUICtrlListView_GetColumn($Info[1], $i)
$sumWidth += $tmp[4]
Next
$sumWidth -= $colInfo[4]
Local $xPos = $posGUI[0]+$posLV[0]+$sumWidth
If $xPos+$colInfo[4]+10 > @DesktopWidth Then $xPos = @DesktopWidth - ($colInfo[4] + 10)
If $xPos < 0 Then $xPos = 0
WinMove($EditBox, '', $xPos, $mouse[1]-$posEdit[3], $colInfo[4]+10)
GUICtrlSetData($hEdit, _GUICtrlListView_GetItemText($Info[1], $Info[3], $Info[4]))
$currentItem[0] = $Info[3]
$currentItem[1] = $Info[4]
GUISetState(@SW_SHOW, $EditBox)
EndFunc
Func _EscEdit()
WinSetTitle($GUI, '', $title)
Opt('GUICoordMode', $currentOpt[0])
Opt("GUIOnEventMode", $currentOpt[1])
$currentOpt[0] = "none"
GUISetState(@SW_HIDE, $EditBox)
EndFunc
Func _EditEnter()
WinSetTitle($GUI, '', $title)
Opt('GUICoordMode', $currentOpt[0])
Opt("GUIOnEventMode", $currentOpt[1])
$currentOpt[0] = "none"
_GUICtrlListView_SetItemText($hListView, $currentItem[0], GUICtrlRead($hEdit), $currentItem[1])
GUISetState(@SW_HIDE, $EditBox)
EndFunc
Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $hWndListView
$hWndListView = $hListView ; ID des LV
If Not IsHWnd($hListView) Then $hWndListView = GUICtrlGetHandle($hListView) ; ID des LV
$tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
$hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
$iIDFrom = DllStructGetData($tNMHDR, "IDFrom")
$iCode = DllStructGetData($tNMHDR, "Code")
Switch $hWndFrom
Case $hWndListView
Switch $iCode
Case $NM_DBLCLK
Local $tInfo = DllStructCreate($tagNMITEMACTIVATE, $ilParam)
Local $aInfo[5] = [$hWndFrom, $iIDFrom, $iCode, DllStructGetData($tInfo, "Index"), _
DllStructGetData($tInfo, "SubItem")]
_LeftDblClick($aInfo)
EndSwitch
EndSwitch
Return $GUI_RUNDEFMSG
EndFunc ;==>WM_NOTIFY
Hier mal eine alternative Variante, die EditBox kann bei nichtgeändertem Inhalt jetzt auch mit ENTER verlassen werden.
Spoiler anzeigen
#include<StaticConstants.au3>
#include<GUIConstantsEx.au3>
#include<ListViewConstants.au3>
#include<StructureConstants.au3>
#include<WindowsConstants.au3>
#include <GUIListView.au3>
Global $currentItem[2], $title, $currentOpt[2] = ["none"]
[/autoit] [autoit][/autoit] [autoit]$GUI = GUICreate('test')
$hListView = GUICtrlCreateListView('Spalte1|Spalte2|Spalte3', 10, 10, 300, 200, $LVS_REPORT)
_GUICtrlListView_SetColumnWidth($hListView, 0, 70)
_GUICtrlListView_SetColumnWidth($hListView, 1, 60)
_GUICtrlListView_SetColumnWidth($hListView, 2, $LVSCW_AUTOSIZE_USEHEADER )
For $i = 1 To 9
GUICtrlCreateListViewItem('Z. ' & $i & ' - Sp. 1|Z. ' & $i & ' - Sp. 2|Z. ' & $i & ' - Sp. 3', $hListView)
Next
$EditBox = GUICreate('', 200, 30, -1, -1, BitOR($WS_POPUP,$WS_BORDER), $WS_EX_TOPMOST)
$dummy = GUICtrlCreateDummy()
$hEdit = GUICtrlCreateInput('', 5, 5, 190, 20, $SS_CENTER)
HotKeySet('{ESC}', '_EscEdit')
Global $AccelKeys[1][2]=[["{ENTER}", $dummy]]
GUICtrlSetOnEvent($dummy, "_EditEnter")
GUISetAccelerators($AccelKeys)
GUISetState(@SW_SHOW, $GUI)
GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
While True
$msg = GUIGetMsg()
If $msg = $GUI_EVENT_CLOSE Then Exit
WEnd
Func _LeftDblClick($Info)
If $Info[3] = -1 Then Return
If $currentOpt[0] = "none" Then
$currentOpt[0] = Opt('GUICoordMode', 1)
$currentOpt[1] = Opt("GUIOnEventMode", 1)
EndIf
GUICtrlSetOnEvent($hEdit, '_EditEnter')
_GUICtrlListView_SetSelectedColumn($Info[1], $Info[4])
$title = WinGetTitle($GUI)
Local $mouse = MouseGetPos(), $posEdit = WinGetPos($EditBox)
Local $posGUI = WinGetPos($GUI), $posLV = ControlGetPos($GUI, '', $hListView)
Local $colInfo = _GUICtrlListView_GetColumn($Info[1], $Info[4]), $sumWidth = 0, $tmp
WinSetTitle($GUI, '', 'Editiere: Zeile ' & $Info[3]+1 & ', ' & $colInfo[5])
For $i = 0 To $Info[4]
$tmp = _GUICtrlListView_GetColumn($Info[1], $i)
$sumWidth += $tmp[4]
Next
$sumWidth -= $colInfo[4]
Local $xPos = $posGUI[0]+$posLV[0]+$sumWidth
If $xPos+$colInfo[4]+10 > @DesktopWidth Then $xPos = @DesktopWidth - ($colInfo[4] + 10)
If $xPos < 0 Then $xPos = 0
WinMove($EditBox, '', $xPos, $mouse[1]-$posEdit[3], $colInfo[4]+10)
GUICtrlSetData($hEdit, _GUICtrlListView_GetItemText($Info[1], $Info[3], $Info[4]))
$currentItem[0] = $Info[3]
$currentItem[1] = $Info[4]
GUISetState(@SW_SHOW, $EditBox)
EndFunc
Func _EscEdit()
WinSetTitle($GUI, '', $title)
Opt('GUICoordMode', $currentOpt[0])
Opt("GUIOnEventMode", $currentOpt[1])
$currentOpt[0] = "none"
GUISetState(@SW_HIDE, $EditBox)
EndFunc
Func _EditEnter()
WinSetTitle($GUI, '', $title)
Opt('GUICoordMode', $currentOpt[0])
Opt("GUIOnEventMode", $currentOpt[1])
$currentOpt[0] = "none"
_GUICtrlListView_SetItemText($hListView, $currentItem[0], GUICtrlRead($hEdit), $currentItem[1])
GUISetState(@SW_HIDE, $EditBox)
EndFunc
Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $hWndListView
$hWndListView = $hListView ; ID des LV
If Not IsHWnd($hListView) Then $hWndListView = GUICtrlGetHandle($hListView) ; ID des LV
$tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
$hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
$iIDFrom = DllStructGetData($tNMHDR, "IDFrom")
$iCode = DllStructGetData($tNMHDR, "Code")
Switch $hWndFrom
Case $hWndListView
Switch $iCode
Case $NM_DBLCLK
Local $tInfo = DllStructCreate($tagNMITEMACTIVATE, $ilParam)
Local $aInfo[5] = [$hWndFrom, $iIDFrom, $iCode, DllStructGetData($tInfo, "Index"), _
DllStructGetData($tInfo, "SubItem")]
_LeftDblClick($aInfo)
EndSwitch
EndSwitch
Return $GUI_RUNDEFMSG
EndFunc ;==>WM_NOTIFY