Jump to content

Kill ListView SubItem-Edit on ENTER?


gobsor
 Share

Recommended Posts

Hi!

Lately I read several topics about editing ListView Items/SubItems (ie. using $NM_DBLCLK). I needed some help to solve that issue and now did it like suggested in THIS THREAD.

Here is the code used to destroy the edit rectangle that is placed over the double-clicked subitem:

Func WM_COMMAND($hWnd, $Msg, $wParam, $lParam)
    Local $iCode = BitShift($wParam, 16)
    Switch $lParam
        Case $hEdit
            Switch $iCode
                Case $EN_KILLFOCUS
                    Local $iText = _GUICtrlEdit_GetText($hEdit)
                    _GUICtrlListView_SetItemText($tview, $iIndex, $iText, $iSubItem)
                    _WinAPI_DeleteObject($hBrush)
                    _WinAPI_ReleaseDC($hEdit, $hDC)
                    _WinAPI_DestroyWindow($hEdit)
                    $Item = -1
                    $SubItem = 0
                    $isPainted = false
            EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_COMMAND

All that i need now is some other case, like:

Case $EN_KILLFOCUS, $EN_RETURN

That will also execute the "delete object" stuff when Return-button is pressed whilst editing a subitem. Any idea whats the $iCode for pressed return button? Is there even any? If not, any suggestion/thoughts how to solve that?

Thanks in advance & regards

gob

Link to comment
Share on other sites

Here's the trick. When you hit ENTER in a single line EDIT control, the message sent is for clicking the default button (BUTTON with $BS_DEFPUSHBUTTON style set). The button can even be hidden, but it receives the required message:

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GuiEdit.au3>
#include <GuiListView.au3>
#include <ButtonConstants.au3>
#include <WinAPI.au3>

Global $hGUI, $hListView, $idButton
Global $hEdit, $hDC, $hBrush, $Item = -1, $SubItem = 0

$hGUI = GUICreate("ListView Subitems edit in place", 300, 300)
$hListView = _GUICtrlListView_Create($hGUI, "Items|SubItems", 2, 2, 296, 196, BitOR($LVS_EDITLABELS, $LVS_REPORT))
_GUICtrlListView_SetExtendedListViewStyle($hListView, $LVS_EX_GRIDLINES)
For $i = 1 To 10
    _GUICtrlListView_AddItem($hListView, "Item " & $i)
    _GUICtrlListView_AddSubItem($hListView, $i - 1, "SubItem " & $i, 1)
Next
$idButton = GUICtrlCreateButton("<TEST>", 100, 250, 100, 30, BitOR($GUI_SS_DEFAULT_BUTTON, $BS_DEFPUSHBUTTON))
GUICtrlSetState($idButton, $GUI_HIDE)
GUISetState(@SW_SHOW, $hGUI)

GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")

While 1
    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            Exit

        Case $idButton
            _KillItemEdit()
    EndSwitch
WEnd

Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
    Local $tNMHDR, $hWndFrom, $iCode
    $tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
    $hWndFrom = DllStructGetData($tNMHDR, "hWndFrom")
    $iCode = DllStructGetData($tNMHDR, "Code")
    Switch $hWndFrom
        Case $hListView
            Switch $iCode
                Case $NM_DBLCLK ; used for sub item edit
                    Local $aHit = _GUICtrlListView_SubItemHitTest($hListView)
                    If ($aHit[0] <> -1) And ($aHit[1] > 0) Then
                        $Item = $aHit[0]
                        $SubItem = $aHit[1]
                        Local $iSubItemText = _GUICtrlListView_GetItemText($hListView, $Item, $SubItem)
                        Local $iLen = _GUICtrlListView_GetStringWidth($hListView, $iSubItemText)
                        Local $aRect = _GUICtrlListView_GetSubItemRect($hListView, $Item, $SubItem)
                        $hEdit = _GUICtrlEdit_Create($hGUI, $iSubItemText, $aRect[0] + 6, $aRect[1], $iLen + 10, 17, BitOR($WS_CHILD, $WS_VISIBLE, $ES_AUTOHSCROLL, $ES_LEFT))
                        _GUICtrlEdit_SetSel($hEdit, 0, -1)
                        _WinAPI_SetFocus($hEdit)
                        $hDC = _WinAPI_GetWindowDC($hEdit)
                        $hBrush = _WinAPI_CreateSolidBrush(0)
                        FrameRect($hDC, 0, 0, $iLen + 10, 17, $hBrush)
                    EndIf
                Case $LVN_ENDLABELEDITA, $LVN_ENDLABELEDITW ; Used for 1st column edit
                    Local $tInfo = DllStructCreate($tagNMLVDISPINFO, $ilParam)
                    Local $tBuffer = DllStructCreate("char Text[" & DllStructGetData($tInfo, "TextMax") & "]", DllStructGetData($tInfo, "Text"))
                    If StringLen(DllStructGetData($tBuffer, "Text")) Then Return True
            EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY

Func FrameRect($hDC, $nLeft, $nTop, $nRight, $nBottom, $hBrush)
    Local $stRect = DllStructCreate("int;int;int;int")
    DllStructSetData($stRect, 1, $nLeft)
    DllStructSetData($stRect, 2, $nTop)
    DllStructSetData($stRect, 3, $nRight)
    DllStructSetData($stRect, 4, $nBottom)
    DllCall("user32.dll", "int", "FrameRect", "hwnd", $hDC, "ptr", DllStructGetPtr($stRect), "hwnd", $hBrush)
EndFunc   ;==>FrameRect

Func WM_COMMAND($hWnd, $Msg, $wParam, $lParam)
    Local $iCode = BitShift($wParam, 16)
    Switch $lParam
        Case $hEdit
            Switch $iCode
                Case $EN_KILLFOCUS
                    _KillItemEdit()
            EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_COMMAND

Func _KillItemEdit()
    Local $iText = _GUICtrlEdit_GetText($hEdit)
    _GUICtrlListView_SetItemText($hListView, $Item, $iText, $SubItem)
    _WinAPI_DeleteObject($hBrush)
    _WinAPI_ReleaseDC($hEdit, $hDC)
    _WinAPI_DestroyWindow($hEdit)
    $Item = -1
    $SubItem = 0
EndFunc   ;==>_KillItemEdit

;)

Edited by PsaltyDS
Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Link to comment
Share on other sites

Oh, I just noticed its working fine for all SubItems, since those are using that self-created EditLabel that is placed upon them. But I edit the Items themselves using

_GUICtrlListView_EDITLabel($tview, $iIndex)

It works for all columns beside column 0, you got another tip for me how to handle that?

I need some kind of 'listener', that tells me when RETURN was pressed in either the Item's or the SubItem's field, so I can execute a function once RETURN was announced.

Edited by gobsor
Link to comment
Share on other sites

The example script you linked to was designed to ignore the first column. You only have to change one line to have it work on all columns:

; If ($aHit[0] <> -1) And ($aHit[1] > 0) Then
                    If ($aHit[0] <> -1) Then

;)

Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Link to comment
Share on other sites

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...