蜘蛛抱蛋 发表于 2011-4-10 09:51:10

关于ListView编辑的问题

关于ListView的$LVN_ENDLABELEDITW消息,怎么得到编辑框里的内容呢?$tagNMLVDISPINFO这个结构中倒是有个Text属性,但是只能得到第一个字符,而且中文会乱码{:face (396):}数据结构我不是很懂,求大虾点拨。
下面是一种变通的解决办法,但是不只一个列表控件的话就没辙了{:face (394):}
#include <GuiConstantsEx.au3>
#include <GuiListView.au3>
#include <GuiImageList.au3>
#include <WindowsConstants.au3>

Global $ord_name, $Changed = -1
$GUI = GUICreate("(UDF Created) ListView Create", 400, 300)
$hListView = _GUICtrlListView_Create($GUI, "1|2|3", 2, 2, 394, 268, BitOR($LVS_EDITLABELS, $LVS_REPORT))
_GUICtrlListView_SetExtendedListViewStyle($hListView, BitOR($LVS_EX_GRIDLINES, $LVS_EX_FULLROWSELECT, $LVS_EX_SUBITEMIMAGES))
GUISetState()
GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
_GUICtrlListView_AddItem($hListView, "Row 1: Col 1", 0)
_GUICtrlListView_AddSubItem($hListView, 0, "Row 1: Col 2", 1)
_GUICtrlListView_AddSubItem($hListView, 0, "Row 1: Col 3", 2)
_GUICtrlListView_AddItem($hListView, "Row 2: Col 1", 1)
_GUICtrlListView_AddSubItem($hListView, 1, "Row 2: Col 2", 1)
_GUICtrlListView_AddItem($hListView, "Row 3: Col 1", 2)
    Do
      If $Changed <> -1 Then   ;这儿判断是否结束编辑,并且获取改变后的子项
      Local $pre_name = _GUICtrlListView_GetItemText($hListView, $Changed)
      If $pre_name = $ord_name Then
            $Changed = -1
            ContinueLoop
      EndIf
      MsgBox(0,$ord_name, $pre_name)
      $Changed = -1
      EndIf
      Sleep(100)
    Until GUIGetMsg() = $GUI_EVENT_CLOSE
    GUIDelete()
   
Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
    #forceref $hWnd, $iMsg, $iwParam
    Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $hWndListView, $tInfo
;~Local $tBuffer
    $hWndListView = $hListView
    If Not IsHWnd($hListView) Then $hWndListView = GUICtrlGetHandle($hListView)

    $tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
    $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
    $iIDFrom = DllStructGetData($tNMHDR, "IDFrom")
    $iCode = DllStructGetData($tNMHDR, "Code")
    Switch $hWndFrom
      Case $hWndListView
            Switch $iCode
            Case $LVN_BEGINLABELEDITW ; Start of label editing for an item
                  Return False
             Case $LVN_ENDLABELEDITW ; The end of label editing for an item
                  Local $tInfo = DllStructCreate($tagNMLVDISPINFO, $ilParam)
                  Local $tBuffer = DllStructCreate("char Text[" & DllStructGetData($tInfo, "TextMax") & "]", _
                            DllStructGetData($tInfo, "Text"))
                  Local $sNewText = DllStructGetData($tBuffer, "Text")   ;这里得到的修改内容不完整
                  $Changed = DllStructGetData($tInfo, "Item")
                  $ord_name = _GUICtrlListView_GetItemText($hWndListView, $Changed)
                  If StringLen($sNewText) Then Return True
            EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY

kadingxiaodi 发表于 2011-4-10 11:05:34

占个沙发,等待高手指教

3mile 发表于 2011-4-10 16:27:01

#include <GUIEdit.au3>
#include <GuiListView.au3>
#include <Editconstants.au3>
#include <WindowsConstants.au3>
#include <GUIConstantsEx.au3>


Global $msg, $hWnd, $hListview, $hEdit, $aHit, $aPos, $hDC, $hBrush,$lable

$hWnd = GUICreate('Listview edit all subitem')

$hListview = _GUICtrlListView_Create($hWnd, '', 6, 6, 708, 370, BitOR($LVS_EDITLABELS, $LVS_REPORT))
_GUICtrlListView_SetExtendedListViewStyle($hListview, $LVS_EX_GRIDLINES)
$lable=GUICtrlCreateLabel("",10,10,10,10)
GUICtrlSetState(-1,$gui_HIDE)

For $i = 0 To 4
      _GUICtrlListView_InsertColumn($hListview, 0, 'row' & 4 - $i, 98)
Next

For $i = 0 To 4
      _GUICtrlListView_AddItem($hListview, 'item' & $i, $i)
      For $j = 1 To 4
                _GUICtrlListView_AddSubItem($hListview, $i, 'subitem' & $j, $j)
      Next
Next

GUIRegisterMsg($WM_NOTIFY, 'WM_NOTIFY')
GUIRegisterMsg($WM_COMMAND, 'WM_COMMAND')

GUISetState(@SW_SHOW)

Do
Until GUIGetMsg() = -3

Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
      Local $tNMHDR, $hWndFrom, $iCode

      $tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
      $hWndFrom = DllStructGetData($tNMHDR, 'hWndFrom')
      $iCode = DllStructGetData($tNMHDR, 'Code')

      Switch $iCode
                Case $NM_DBLCLK
                        GUICtrlSetState($lable,$gui_HIDE)
                        $aHit = _GUICtrlListView_SubItemHitTest($hListview)
                        Local $aRect = _GUICtrlListView_GetSubItemRect($hListview, $aHit, $aHit)
                        Local $aPos = ControlGetPos($hWnd, '', $hListview)
                        Local $text = _GUICtrlListView_GetItemText($hListview, $aHit, $aHit)
                        Local $iStyle = BitOR($WS_CHILD, $WS_VISIBLE, $ES_AUTOHSCROLL, $ES_LEFT)

                        $hEdit = _GUICtrlEdit_Create($hWnd, $text, $aPos + $aRect, $aPos + $aRect, _GUICtrlListView_GetColumnWidth($hListview, $aHit), 17, $iStyle)
                        _GUICtrlEdit_SetSel($hEdit, 0, -1)
                        _WinAPI_SetFocus($hEdit)
                        $hDC = _WinAPI_GetWindowDC($hEdit)
                        $hBrush = _WinAPI_CreateSolidBrush(0x0000FF)
                        
                        Local $stRect = DllStructCreate('int;int;int;int')
                        DllStructSetData($stRect, 1, 0)
                        DllStructSetData($stRect, 2, 0)
                        DllStructSetData($stRect, 3, _GUICtrlListView_GetColumnWidth($hListview, $aHit))
                        DllStructSetData($stRect, 4, 17)
                        _WinAPI_FrameRect($hDC, DllStructGetPtr($stRect), $hBrush)
                Case $NM_CLICK
                        $aHit1 = _GUICtrlListView_SubItemHitTest($hListview)
                        IF $aHit1<>-1 Then
                        Local $aRect1 = _GUICtrlListView_GetSubItemRect($hListview, $aHit1, $aHit1)
                        Local $aPos1 = ControlGetPos($hWnd, '', $hListview)
                        Local $text1 = _GUICtrlListView_GetItemText($hListview, $aHit1, $aHit1)
                        Local $iStyle1 = BitOR($WS_CHILD, $WS_VISIBLE, $ES_AUTOHSCROLL, $ES_LEFT)
                        GUICtrlSetState($lable,$GUI_SHOW)
                        GUICtrlSetData($lable,$text1)
                        GUICtrlSetPos($lable,$aPos1 + $aRect1, $aPos1 + $aRect1, _GUICtrlListView_GetColumnWidth($hListview, $aHit1),$aRect1-$aRect1)                     
                        GUICtrlSetBkColor($lable,0x2468a2)
                        EndIf
      EndSwitch
EndFunc   ;==>WM_NOTIFY

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($hListview, $aHit, $iText, $aHit)
                                        _WinAPI_DeleteObject($hBrush)
                                        _WinAPI_ReleaseDC($hEdit, $hDC)
                                        _WinAPI_DestroyWindow($hEdit)
                                        _GUICtrlEdit_Destroy($hEdit)
                                        $Item = -1
                                        $SubItem = 0
                        EndSwitch
      EndSwitch
      Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_COMMAND

netegg 发表于 2011-4-10 20:34:44

回复 3# 3mile
这两个操作其实可以合起来,没必要多写一个case,建议而已

蜘蛛抱蛋 发表于 2011-4-10 21:13:57

回复 3# 3mile

非常感谢3mile兄,自定义编辑框确实是不错的主意。刚刚在路上走的时候我想通了,只是一个小小的问题。直接上代码
#include <GuiConstantsEx.au3>
#include <GuiListView.au3>
#include <GuiImageList.au3>
#include <WindowsConstants.au3>

Global $ord_name
$GUI = GUICreate("(UDF Created) ListView Create", 400, 300)
$hListView = _GUICtrlListView_Create($GUI, "1|2|3", 2, 2, 394, 268, BitOR($LVS_EDITLABELS, $LVS_REPORT))
_GUICtrlListView_SetExtendedListViewStyle($hListView, BitOR($LVS_EX_GRIDLINES, $LVS_EX_FULLROWSELECT, $LVS_EX_SUBITEMIMAGES))
_GUICtrlListView_SetUnicodeFormat($hListView, True)    ;这里好像不加也可
GUISetState()
GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
_GUICtrlListView_AddItem($hListView, "Row 1: Col 1", 0)
_GUICtrlListView_AddSubItem($hListView, 0, "Row 1: Col 2", 1)
_GUICtrlListView_AddSubItem($hListView, 0, "Row 1: Col 3", 2)
_GUICtrlListView_AddItem($hListView, "Row 2: Col 1", 1)
_GUICtrlListView_AddSubItem($hListView, 1, "Row 2: Col 2", 1)
_GUICtrlListView_AddItem($hListView, "Row 3: Col 1", 2)
    Do
      Sleep(100)
    Until GUIGetMsg() = $GUI_EVENT_CLOSE
    GUIDelete()
   
Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
    #forceref $hWnd, $iMsg, $iwParam
    Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $hWndListView, $tInfo
;~Local $tBuffer
    $hWndListView = $hListView
    If Not IsHWnd($hListView) Then $hWndListView = GUICtrlGetHandle($hListView)

    $tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
    $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
    $iIDFrom = DllStructGetData($tNMHDR, "IDFrom")
    $iCode = DllStructGetData($tNMHDR, "Code")
    Switch $hWndFrom
      Case $hWndListView
            Switch $iCode
            Case $LVN_BEGINLABELEDITW
                  Return False
             Case $LVN_ENDLABELEDITW
                  Local $tInfo = DllStructCreate($tagNMLVDISPINFO, $ilParam)
                  Local $tBuffer = DllStructCreate("wchar Text[" & DllStructGetData($tInfo, "TextMax") & "]", _         ;这儿有个细微改动
                            DllStructGetData($tInfo, "Text"))
                  Local $sNewText = DllStructGetData($tBuffer, "Text")
                  $ord_name = _GUICtrlListView_GetItemText($hWndListView, DllStructGetData($tInfo, "Item"))
                                        ConsoleWrite($sNewText&'|'& $ord_name&@LF)    ;看这里的显示结果
                  If StringLen($sNewText) Then Return True
            EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY
问题就在'$LVN_ENDLABELEDITW'的'W'上

蜘蛛抱蛋 发表于 2011-4-10 21:15:29

回复 4# netegg

蛋蛋一直追着3mile兄说明这点,精神可嘉啊

3mile 发表于 2011-4-10 21:44:48

回复3mile
这两个操作其实可以合起来,没必要多写一个case,建议而已
netegg 发表于 2011-4-10 20:34 http://www.autoitx.com/images/common/back.gif
对啊,有道理.
呵呵,只是想让LISTVIEW象EXCEL的单元格一样可以单击,所以走入误区了

netegg 发表于 2011-4-11 00:37:35

回复 7# 3mile
客气,交流而已{:face (396):}
页: [1]
查看完整版本: 关于ListView编辑的问题