Jump to content
Sign in to follow this  
gobsor

Kill ListView SubItem-Edit on ENTER?

Recommended Posts

gobsor

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

Share this post


Link to post
Share on other sites
PsaltyDS

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

Share this post


Link to post
Share on other sites
gobsor

Ah! Exactly what I was looking for!

Thanks man!

Share this post


Link to post
Share on other sites
gobsor

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

Share this post


Link to post
Share on other sites
PsaltyDS

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

Share this post


Link to post
Share on other sites
gobsor

Ah, now I see! Changed it and all columns use that self-drawn rect now :]

thanks

Share this post


Link to post
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
Sign in to follow this  

×

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.