Jump to content

Editable ListView is possible


CyberSlug
 Share

Recommended Posts

  • 2 months later...

Utilizing the latest beta's with GUIRegisterMsg

Found only one problem with this and it's the edit control paint isn't working correctly when using WM_NOTIFY

Enjoy!

Hi Gary-

I tried this version and double click works faster, but then the line quickly changes back to un-selected. If I use F2 it works fine, but not if I double-click...

...by the way, it's pronounced: "JIF"... Bob Berry --- inventor of the GIF format
Link to comment
Share on other sites

Hi Gary-

I tried this version and double click works faster, but then the line quickly changes back to un-selected. If I use F2 it works fine, but not if I double-click...

comment out

Case $msg = $GUI_EVENT_PRIMARYDOWN
                CancelEdit($ListView)

SciTE for AutoItDirections for Submitting Standard UDFs

 

Don't argue with an idiot; people watching may not be able to tell the difference.

 

Link to comment
Share on other sites

  • 4 months later...

Hi Gary,

I used this in my project and it worked fine until I added a combo box. If I add the combo box to yours I get the same issue.

The issue is once I edit the the item and press enter, it loops back to edit mode->enter->edit mode->enter ect.

Here the code I added:

$Property_Selection_Combobox = GUICtrlCreateCombo("New .....", 11, 704, 136, 25)

Any idea how to fix this?

4Fun

CODE

#include <GuiConstants.au3>

#include <GuiListview.au3>

Global Const $DebugIt = 1

Global Const $WM_NOTIFY = 0x004E

Global Const $NM_FIRST = 0

Global Const $NM_CLICK = ($NM_FIRST - 2)

Global Const $NM_DBLCLK = ($NM_FIRST - 3)

Global $ListView = -999

Global $Gui, $editFlag

Global $editCtrl = "Edit1";name of the Edit control that pops up when edit a listitem....

_Main()

Func _Main()

Local $dll

Local $Gui = GUICreate("Double Click Demo", 417, 356, 192, 125)

$ListView = GUICtrlCreateListView("Items", 10, 10, 300, 200, $LVS_EDITLABELS);Important Style!!!

$Property_Selection_Combobox = GUICtrlCreateCombo("New .....", 11, 704, 136, 25)

GUICtrlSendMsg($ListView, $LVM_SETEXTENDEDLISTVIEWSTYLE, $LVS_EX_GRIDLINES, $LVS_EX_GRIDLINES)

; Populate list and make it wide enough to see

For $i = 1 To 10

GUICtrlCreateListViewItem("DoubleClick or press F2, then press Enter", $ListView)

Next

GUICtrlSendMsg($ListView, 0x101E, 0, -1);$listview, LVM_SETCOLUMNWIDTH, 0, resize to widest value

GUISetState(@SW_SHOW)

;Register WM_NOTIFY events

GUIRegisterMsg($WM_NOTIFY, "WM_Notify_Events")

$dll = DllOpen("user32.dll")

While 1

$msg = GUIGetMsg()

_MonitorEditState($Gui, $editCtrl, $editFlag, $ListView, $dll)

Select

Case $msg = $GUI_EVENT_CLOSE

ExitLoop

;Case $msg = $GUI_EVENT_PRIMARYDOWN

;CancelEdit($ListView)

Case Else

;;;;;;;

EndSelect

WEnd

DllClose($dll)

EndFunc ;==>_Main

Func ListView_Click()

;----------------------------------------------------------------------------------------------

If $DebugIt Then ConsoleWrite (_DebugHeader("$NM_CLICK"))

;----------------------------------------------------------------------------------------------

If ControlCommand($Gui, "", $editCtrl, "IsVisible", "") Then

CancelEdit($ListView)

$editFlag = 0

EndIf

EndFunc ;==>ListView_Click

Func ListView_DoubleClick()

;----------------------------------------------------------------------------------------------

If $DebugIt Then ConsoleWrite (_DebugHeader("$NM_DBLCLK"))

;----------------------------------------------------------------------------------------------

Rename($ListView)

EndFunc ;==>ListView_DoubleClick

; WM_NOTIFY event handler

Func WM_Notify_Events($hWndGUI, $MsgID, $wParam, $lParam)

#forceref $hWndGUI, $MsgID, $wParam

Local $tagNMHDR, $event

$tagNMHDR = DllStructCreate("int;int;int", $lParam);NMHDR (hwndFrom, idFrom, code)

If @error Then Return

$event = DllStructGetData($tagNMHDR, 3)

Select

Case $wParam = $ListView

Select

Case $event = $NM_CLICK

ListView_Click()

Case $event = $NM_DBLCLK

ListView_DoubleClick()

EndSelect

EndSelect

$tagNMHDR = 0

$event = 0

$lParam = 0

EndFunc ;==>WM_Notify_Events

Func _DebugHeader($s_text)

Return _

"!===========================================================" & @LF & _

"+===========================================================" & @LF & _

"-->" & $s_text & @LF & _

"+===========================================================" & @LF

EndFunc ;==>_DebugHeader

Func _MonitorEditState(ByRef $h_gui, ByRef $editCtrl, ByRef $editFlag, ByRef $ListView, ByRef $dll)

Local $pressed = _IsPressedMod($dll)

If $editFlag And $pressed = 13 Then; pressed enter

Update($h_gui, $editCtrl, $ListView)

ElseIf $editFlag And $pressed = 27 Then; pressed esc

CancelEdit($ListView)

$editFlag = 0

ElseIf Not $editFlag And $pressed = 113 Then; pressed f2

Rename($ListView)

$editFlag = 1

EndIf

Sleep(50)

If ControlCommand($h_gui, "", $editCtrl, "IsVisible", "") Then

If $editFlag = 0 Then

$editFlag = 1

Rename($ListView)

EndIf

Else

$editFlag = 0

EndIf

EndFunc ;==>_MonitorEditState

Func Rename(ByRef $ListView)

Local $itemIndex = _GUICtrlListViewGetCurSel ($ListView)

GUICtrlSendMsg($ListView, $LVM_EDITLABEL, $itemIndex, 0)

HotKeySet("{Enter}", "Enter")

EndFunc ;==>Rename

Func Enter()

; just a dummy function

EndFunc ;==>Enter

Func Update(ByRef $h_gui, ByRef $editCtrl, ByRef $ListView)

Local $newText = ControlGetText($h_gui, "", $editCtrl)

Local $item = GUICtrlRead($ListView)

GUICtrlSetData($item, $newText)

HotKeySet("{Enter}")

Send("{Enter}");quit edit mode

$editFlag = 0

$update = 0

EndFunc ;==>Update

Func CancelEdit(ByRef $ListView)

GUICtrlSendMsg($ListView, $LVM_CANCELEDITLABEL, 0, 0)

EndFunc ;==>CancelEdit

Func _IsPressedMod($dll = "user32.dll")

Local $aR, $bRv, $hexKey, $i

For $i = 8 To 128

$hexKey = '0x' & Hex($i, 2)

$aR = DllCall($dll, "int", "GetAsyncKeyState", "int", $hexKey)

If $aR[0] <> 0 Then Return $i

Next

Return 0

EndFunc ;==>_IsPressedMod

Edited by 4Fun
Link to comment
Share on other sites

Hi Gary,

I used this in my project and it worked fine until I added a combo box. If I add the combo box to yours I get the same issue.

The issue is once I edit the the item and press enter, it loops back to edit mode->enter->edit mode->enter ect.

Here the code I added:

$Property_Selection_Combobox = GUICtrlCreateCombo("New .....", 11, 704, 136, 25)

Any idea how to fix this?

4Fun

Being both controls contain an Edit1, you just need to use the Advanced GuiGetMsg and make sure the listview control has the edit control being checked for.

#include <GuiConstants.au3>
#include <GuiListview.au3>

Global Const $DebugIt = 1

Global Const $WM_NOTIFY = 0x004E

Global Const $NM_FIRST = 0
Global Const $NM_CLICK = ($NM_FIRST - 2)
Global Const $NM_DBLCLK = ($NM_FIRST - 3)

Global $ListView = -999
Global $Gui, $editFlag, $msg
Global $editCtrl = "Edit1";name of the Edit control that pops up when edit a listitem....

_Main()

Func _Main()
    Local $dll
    Local $Gui = GUICreate("Double Click Demo", 417, 356, 192, 125)
    $ListView = GUICtrlCreateListView("Items", 10, 10, 300, 200, $LVS_EDITLABELS);Important Style!!!
    $Property_Selection_Combobox = GUICtrlCreateCombo("New .....", 11, 304, 136, 25)
    GUICtrlSendMsg($ListView, $LVM_SETEXTENDEDLISTVIEWSTYLE, $LVS_EX_GRIDLINES, $LVS_EX_GRIDLINES)
    ; Populate list and make it wide enough to see
    For $i = 1 To 10
        GUICtrlCreateListViewItem("DoubleClick or press F2, then press Enter", $ListView)
    Next
    GUICtrlSendMsg($ListView, 0x101E, 0, -1);$listview, LVM_SETCOLUMNWIDTH, 0, resize to widest value
    GUISetState(@SW_SHOW)
    ;Register WM_NOTIFY events
    GUIRegisterMsg($WM_NOTIFY, "WM_Notify_Events")
    $dll = DllOpen("user32.dll")
    While 1
        $msg = GUIGetMsg(1)
        _MonitorEditState($Gui, $editCtrl, $editFlag, $ListView, $dll)
        Select
            Case $msg[0] = $GUI_EVENT_CLOSE
                ExitLoop
                ;Case $msg = $GUI_EVENT_PRIMARYDOWN
                ;CancelEdit($ListView)
            Case Else
                ;;;;;;;
        EndSelect
    WEnd
    DllClose($dll)
EndFunc   ;==>_Main

Func ListView_Click()
    ;----------------------------------------------------------------------------------------------
    If $DebugIt Then ConsoleWrite(_DebugHeader("$NM_CLICK"))
    ;----------------------------------------------------------------------------------------------
    If ControlCommand($Gui, "", $editCtrl, "IsVisible", "") And $msg[0] = $listview Then
        CancelEdit($ListView)
        $editFlag = 0
    EndIf
EndFunc   ;==>ListView_Click

Func ListView_DoubleClick()
    ;----------------------------------------------------------------------------------------------
    If $DebugIt Then ConsoleWrite(_DebugHeader("$NM_DBLCLK"))
    ;----------------------------------------------------------------------------------------------
    Rename($ListView)
EndFunc   ;==>ListView_DoubleClick

; WM_NOTIFY event handler
Func WM_Notify_Events($hWndGUI, $MsgID, $wParam, $lParam)
    #forceref $hWndGUI, $MsgID, $wParam
    Local $tagNMHDR, $event
    $tagNMHDR = DllStructCreate("int;int;int", $lParam);NMHDR (hwndFrom, idFrom, code)
    If @error Then Return
    $event = DllStructGetData($tagNMHDR, 3)
    Select
        Case $wParam = $ListView
            Select
                Case $event = $NM_CLICK
                    ListView_Click()
                Case $event = $NM_DBLCLK
                    ListView_DoubleClick()
            EndSelect
    EndSelect
    $tagNMHDR = 0
    $event = 0
    $lParam = 0
EndFunc   ;==>WM_Notify_Events

Func _DebugHeader($s_text)
    Return _
            "!===========================================================" & @LF & _
            "+===========================================================" & @LF & _
            "-->" & $s_text & @LF & _
            "+===========================================================" & @LF
EndFunc   ;==>_DebugHeader

Func _MonitorEditState(ByRef $h_gui, ByRef $editCtrl, ByRef $editFlag, ByRef $ListView, ByRef $dll)

    Local $pressed = _IsPressedMod($dll)
    If $editFlag And $pressed = 13 Then; pressed enter
        Update($h_gui, $editCtrl, $ListView)
    ElseIf $editFlag And $pressed = 27 Then; pressed esc
        CancelEdit($ListView)
        $editFlag = 0
    ElseIf Not $editFlag And $pressed = 113 Then; pressed f2
        Rename($ListView)
        $editFlag = 1
    EndIf
    Sleep(50)

    If ControlCommand($h_gui, "", $editCtrl, "IsVisible", "")  And $msg[0] = $listview Then
        If $editFlag = 0 Then
            $editFlag = 1
            Rename($ListView)
        EndIf
    Else
        $editFlag = 0
    EndIf

EndFunc   ;==>_MonitorEditState

Func Rename(ByRef $ListView)
    Local $itemIndex = _GUICtrlListViewGetCurSel($ListView)
    GUICtrlSendMsg($ListView, $LVM_EDITLABEL, $itemIndex, 0)
    HotKeySet("{Enter}", "Enter")
EndFunc   ;==>Rename

Func Enter()
    ; just a dummy function
EndFunc   ;==>Enter

Func Update(ByRef $h_gui, ByRef $editCtrl, ByRef $ListView)
    Local $newText = ControlGetText($h_gui, "", $editCtrl)
    Local $item = GUICtrlRead($ListView)
    GUICtrlSetData($item, $newText)
    HotKeySet("{Enter}")
    Send("{Enter}");quit edit mode
    $editFlag = 0
    $update = 0
EndFunc   ;==>Update

Func CancelEdit(ByRef $ListView)
    GUICtrlSendMsg($ListView, $LVM_CANCELEDITLABEL, 0, 0)
EndFunc   ;==>CancelEdit

Func _IsPressedMod($dll = "user32.dll")
    Local $aR, $bRv, $hexKey, $i
    For $i = 8 To 128
        $hexKey = '0x' & Hex($i, 2)
        $aR = DllCall($dll, "int", "GetAsyncKeyState", "int", $hexKey)
        If $aR[0] <> 0 Then Return $i
    Next
    Return 0
EndFunc   ;==>_IsPressedMod

SciTE for AutoItDirections for Submitting Standard UDFs

 

Don't argue with an idiot; people watching may not be able to tell the difference.

 

Link to comment
Share on other sites

Gary,

Thanks for the help!

Is it possible to do this in OnEvent mode? If so can point me in the right direction.

Your the best,

Tim

Yep

#include <GuiConstants.au3>
#include <GuiListview.au3>
Opt("GUIOnEventMode", 1)

Global Const $DebugIt = 1

Global Const $WM_NOTIFY = 0x004E

Global Const $NM_FIRST = 0
Global Const $NM_CLICK = ($NM_FIRST - 2)
Global Const $NM_DBLCLK = ($NM_FIRST - 3)

Global $ListView = -999
Global $Gui, $editFlag
Global $editCtrl = "Edit1";name of the Edit control that pops up when edit a listitem....
Global $editCtrlHandle
Global $dll

_Main()

Func _Main()
    $Gui = GUICreate("Double Click Demo", 417, 356, 192, 125)
    GUISetOnEvent($GUI_EVENT_CLOSE, "_Terminate")
    $ListView = GUICtrlCreateListView("Items", 10, 10, 300, 200, $LVS_EDITLABELS);Important Style!!!
    $Property_Selection_Combobox = GUICtrlCreateCombo("New .....", 11, 304, 136, 25)
    GUICtrlSendMsg($ListView, $LVM_SETEXTENDEDLISTVIEWSTYLE, $LVS_EX_GRIDLINES, $LVS_EX_GRIDLINES)
    ; Populate list and make it wide enough to see
    For $i = 1 To 10
        GUICtrlCreateListViewItem("DoubleClick or press F2, then press Enter", $ListView)
    Next
    GUICtrlSendMsg($ListView, 0x101E, 0, -1);$listview, LVM_SETCOLUMNWIDTH, 0, resize to widest value
    GUISetState(@SW_SHOW)
    ;Register WM_NOTIFY events
    GUIRegisterMsg($WM_NOTIFY, "WM_Notify_Events")
    $dll = DllOpen("user32.dll")
    While 1
        Sleep(100)
        _MonitorEditState($Gui, $editCtrl, $editFlag, $ListView, $dll)
    WEnd
EndFunc   ;==>_Main

Func _Terminate()
    DllClose($dll)
    Exit
EndFunc   ;==>_Terminate

Func ListView_GetEditControl($h_ListView)
    Local $lResult = _SendMessage($h_ListView, $LVM_GETEDITCONTROL)
    If @error Then Return SetError(-1, -1, 0)
    Return $lResult
EndFunc   ;==>ListView_GetEditControl

Func ListView_Click()
    ;----------------------------------------------------------------------------------------------
    If $DebugIt Then _DebugPrint("$NM_CLICK")
    ;----------------------------------------------------------------------------------------------
    If $editCtrlHandle Then
        CancelEdit($ListView)
        $editFlag = 0
    EndIf
EndFunc   ;==>ListView_Click

Func ListView_DoubleClick()
    ;----------------------------------------------------------------------------------------------
    If $DebugIt Then _DebugPrint("$NM_DBLCLK")
    ;----------------------------------------------------------------------------------------------
    Rename($ListView)
    $editCtrlHandle = ListView_GetEditControl(ControlGetHandle($Gui, '', $ListView))
EndFunc   ;==>ListView_DoubleClick

; WM_NOTIFY event handler
Func WM_Notify_Events($hWndGUI, $MsgID, $wParam, $lParam)
    #forceref $hWndGUI, $MsgID, $wParam
    Local $tagNMHDR, $event
    $tagNMHDR = DllStructCreate("int;int;int;int;int;int;int;int;ptr;int;int;int;int", $lParam);NMHDR (hwndFrom, idFrom, code)
    If @error Then Return
    $event = DllStructGetData($tagNMHDR, 3)
    Select
        Case $wParam = $ListView
            Select
                Case $event = $NM_CLICK
                    ListView_Click()
                Case $event = $NM_DBLCLK
                    ListView_DoubleClick()
            EndSelect
    EndSelect
    $tagNMHDR = 0
    $event = 0
    $lParam = 0
    ; Proceed the default Autoit3 internal message commands.
    ; You also can complete let the line out.
    ; !!! But only 'Return' (without any value) will not proceed
    ; the default Autoit3-message in the future !!!
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_Notify_Events

Func _DebugPrint($s_text)
    $s_text = StringReplace($s_text, @LF, @LF & "-->")
    ConsoleWrite("!===========================================================" & @LF & _
            "+===========================================================" & @LF & _
            "-->" & $s_text & @LF & _
            "+===========================================================" & @LF)
EndFunc   ;==>_DebugPrint

Func _MonitorEditState(ByRef $h_gui, ByRef $editCtrl, ByRef $editFlag, ByRef $ListView, ByRef $dll)

    Local $pressed = _IsPressedMod($dll)
    If $editFlag And $pressed = 13 Then; pressed enter
        Update($h_gui, $editCtrl, $ListView)
    ElseIf $editFlag And $pressed = 27 Then; pressed esc
        CancelEdit($ListView)
        $editFlag = 0
    ElseIf Not $editFlag And $pressed = 113 Then; pressed f2
        Rename($ListView)
    EndIf
    Sleep(50)

    If $editCtrlHandle Then
        If $editFlag = 0 Then
            Rename($ListView)
        EndIf
    Else
        $editFlag = 0
    EndIf

EndFunc   ;==>_MonitorEditState

Func Rename(ByRef $ListView)
    Local $itemIndex = _GUICtrlListViewGetCurSel($ListView)
    GUICtrlSendMsg($ListView, $LVM_EDITLABEL, $itemIndex, 0)
    $editFlag = 1
    HotKeySet("{Enter}", "Enter")
EndFunc   ;==>Rename

Func Enter()
    Update($Gui, $editCtrl, $ListView)
EndFunc   ;==>Enter

Func Update(ByRef $h_gui, ByRef $editCtrl, ByRef $ListView)
    Local $newText = ControlGetText($h_gui, "", $editCtrl)
    Local $item = GUICtrlRead($ListView)
    GUICtrlSetData($item, $newText)
    HotKeySet("{Enter}")
    Send("{Enter}");quit edit mode
    $editFlag = 0
    $update = 0
    $editCtrlHandle = 0
EndFunc   ;==>Update

Func CancelEdit(ByRef $ListView)
    GUICtrlSendMsg($ListView, $LVM_CANCELEDITLABEL, 0, 0)
EndFunc   ;==>CancelEdit

Func _IsPressedMod($dll = "user32.dll")
    Local $aR, $bRv, $hexKey, $i
    For $i = 8 To 128
        $hexKey = '0x' & Hex($i, 2)
        $aR = DllCall($dll, "int", "GetAsyncKeyState", "int", $hexKey)
        If $aR[0] <> 0 Then Return $i
    Next
    Return 0
EndFunc   ;==>_IsPressedMod

SciTE for AutoItDirections for Submitting Standard UDFs

 

Don't argue with an idiot; people watching may not be able to tell the difference.

 

Link to comment
Share on other sites

  • 1 month later...
  • 1 month later...

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...