找回密码
 加入
搜索
查看: 5426|回复: 7

[GUI管理] 关于ListView编辑的问题

  [复制链接]
发表于 2011-4-10 09:51:10 | 显示全部楼层 |阅读模式
关于ListView的$LVN_ENDLABELEDITW消息,怎么得到编辑框里的内容呢?$tagNMLVDISPINFO这个结构中倒是有个Text属性,但是只能得到第一个字符,而且中文会乱码数据结构我不是很懂,求大虾点拨。
下面是一种变通的解决办法,但是不只一个列表控件的话就没辙了
#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
发表于 2011-4-10 11:05:34 | 显示全部楼层
占个沙发,等待高手指教
发表于 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[0], $aHit[1])
                        Local $aPos = ControlGetPos($hWnd, '', $hListview)
                        Local $text = _GUICtrlListView_GetItemText($hListview, $aHit[0], $aHit[1])
                        Local $iStyle = BitOR($WS_CHILD, $WS_VISIBLE, $ES_AUTOHSCROLL, $ES_LEFT)
 
                        $hEdit = _GUICtrlEdit_Create($hWnd, $text, $aPos[0] + $aRect[0], $aPos[1] + $aRect[1], _GUICtrlListView_GetColumnWidth($hListview, $aHit[1]), 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[1]))
                        DllStructSetData($stRect, 4, 17)
                        _WinAPI_FrameRect($hDC, DllStructGetPtr($stRect), $hBrush)
                Case $NM_CLICK
                        $aHit1 = _GUICtrlListView_SubItemHitTest($hListview)
                        IF $aHit1[0]<>-1 Then
                        Local $aRect1 = _GUICtrlListView_GetSubItemRect($hListview, $aHit1[0], $aHit1[1])
                        Local $aPos1 = ControlGetPos($hWnd, '', $hListview)
                        Local $text1 = _GUICtrlListView_GetItemText($hListview, $aHit1[0], $aHit1[1])
                        Local $iStyle1 = BitOR($WS_CHILD, $WS_VISIBLE, $ES_AUTOHSCROLL, $ES_LEFT)
                        GUICtrlSetState($lable,$GUI_SHOW)
                        GUICtrlSetData($lable,$text1)
                        GUICtrlSetPos($lable,$aPos1[0] + $aRect1[0], $aPos1[1] + $aRect1[1], _GUICtrlListView_GetColumnWidth($hListview, $aHit1[1]),$aRect1[3]-$aRect1[1])                      
                        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[0], $iText, $aHit[1])
                                        _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
发表于 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'上

评分

参与人数 1金钱 +10 收起 理由
iamwonvy + 10 谢谢你 我的问题解决了

查看全部评分

 楼主| 发表于 2011-4-10 21:15:29 | 显示全部楼层
回复 4# netegg

蛋蛋一直追着3mile兄说明这点,精神可嘉啊
发表于 2011-4-10 21:44:48 | 显示全部楼层
回复  3mile
这两个操作其实可以合起来,没必要多写一个case,建议而已
netegg 发表于 2011-4-10 20:34

对啊,有道理.
呵呵,只是想让LISTVIEW象EXCEL的单元格一样可以单击,所以走入误区了
发表于 2011-4-11 00:37:35 | 显示全部楼层
回复 7# 3mile
客气,交流而已
您需要登录后才可以回帖 登录 | 加入

本版积分规则

QQ|手机版|小黑屋|AUTOIT CN ( 鲁ICP备19019924号-1 )谷歌 百度

GMT+8, 2024-12-23 17:16 , Processed in 0.082074 second(s), 24 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表