找回密码
 加入
搜索
查看: 6555|回复: 12

[GUI管理] [已解决]老话题:Listview就地编辑,请看完

  [复制链接]
发表于 2012-11-22 15:31:03 | 显示全部楼层 |阅读模式
本帖最后由 qinylj 于 2012-11-23 08:46 编辑

看了以前的各位写的ListView就地编辑,一般就是两种情况:
1.用Windows消息创建一个编辑框(由_GUICtrlEdit_Create创建),但是这种方法有个缺点:字体,Win7的话字体默认是雅黑,但是这个控件是宋体,不知道有没有方法可以改为系统字体?
2.直接在窗体的循环中创建一个Input框,这种方法的优点是几乎和原来的Listview看起来一样,字体也可以更改,缺点是单击修改。
但是上面两种都有点缺点,不知道是否能够用GUICtrlCreateListView创建然后由Windows消息创建一个几乎一样的框并且双击修改(包括字体)

在蛋蛋大大的帮助之下,搞定了,以下是一段我比较满意的代码,效果如下
#include <GuiListView.au3>
#include <Editconstants.au3>
#include <WindowsConstants.au3>
#include <GUIConstantsEx.au3>
;2011.11.09 by bbs.wglm.net 小A  修改至:yhxhappy  2012.11.22由qinylj修改
;[修改] 删掉了原来的Enter键,仅仅换成Input输入,但是这是目前我比较满意的一个Listview原地编辑例子,字体正常,支持右键复制粘贴
Global $ListView_HitItem, $Listview_HitItemIndex, $Listview_HitItemSubItem, $ListView_HitItemInput;定义全局变量
$Form = GUICreate("LIST原位编辑支持子项 by 小A&修改by qinylj,感谢蛋蛋大大的帮助", 1166, 709)
GUISetFont(9, 400, 0, "微软雅黑")
$ListView = GUICtrlCreateListView("1|2|3|4|5|6|7", 8, 8, 1153, 697)
GUICtrlSendMsg($ListView, $LVM_SETEXTENDEDLISTVIEWSTYLE, $LVS_EX_GRIDLINES, $LVS_EX_GRIDLINES);扩展风格
$label = GUICtrlCreateLabel("", -100, -100, 1, 1)
GUISetState(@SW_SHOW)
For $i = 0 To 9
        GUICtrlSendMsg($ListView, $LVM_SETCOLUMNWIDTH, $i, 150)
Next
For $i = 0 To 120
        GUICtrlCreateListViewItem("Au3中文" & $i & "|论坛" & $i & "|感谢蛋蛋大大netegg" & $i & "|BY" & $i & "|小A" & $i & "|修改By" & $i & "|Qinylj" & $i, $ListView)
Next
GUIRegisterMsg($WM_NOTIFY, "_WM_NOTIFY")
GUIRegisterMsg($WM_COMMAND, "_WM_COMMAND")

While 1
        $nMsg = GUIGetMsg()
        Switch $nMsg
                Case $GUI_EVENT_CLOSE
                        Exit
        EndSwitch
WEnd

Func _WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
        #forceref $hWnd, $iMsg, $iwParam, $ilParam
        Local $tNMHDR, $hWndFrom, $iCode
        $tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
        $hWndFrom = DllStructGetData($tNMHDR, 'hWndFrom')
        $iCode = DllStructGetData($tNMHDR, 'Code')

        Switch $hWndFrom
                Case GUICtrlGetHandle($ListView)
                        Switch $iCode
                                Case $NM_DBLCLK;双击消息
                                        $ListView_HitItem = _GUICtrlListView_SubItemHitTest(GUICtrlGetHandle($ListView));确定哪些项目或子项目在控件的给定位置,参见帮助文件
                                        $Listview_HitItemIndex = $ListView_HitItem[0];获取点击项目的0基索引
                                        $Listview_HitItemSubItem = $ListView_HitItem[1];获取点击项目的子项索引
                                        If $Listview_HitItemIndex = -1 Then Return
                                        $ListView_HitItemPos = ControlGetPos($Form, "", $ListView);获取Listview坐标
                                        $ListView_HitItemRect = _GUICtrlListView_GetSubItemRect($ListView, $ListView_HitItem[0], $ListView_HitItem[1]);获取点击项的边界矩形
                                        $ListView_HitItemText = _GUICtrlListView_GetItemText($ListView, $ListView_HitItem[0], $ListView_HitItem[1]) ;读取所点击单元格的文本
                                        $ListView_HitItemInput = GUICtrlCreateInput($ListView_HitItemText, _ ;创建一个与单元格差不多大小的输入框 ;$ListView_HitItemText为在Input控件中显示的文本
                                                        $ListView_HitItemRect[0] + $ListView_HitItemPos[0] + 4, _;Input控件距离左侧的值,即X坐标,由点击项目的X坐标加上Listview的X坐标再加上4(4为微调值,保证X坐标吻合)
                                                        $ListView_HitItemRect[1] + $ListView_HitItemPos[1] + 2, _;Input控件距离上方的值,即Y坐标,由点击项目的Y坐标加上Listview的Y坐标再加上2(2为微调值,保证Y坐标吻合)
                                                        _GUICtrlListView_GetColumnWidth($ListView, $ListView_HitItem[1]) - 2, _;Input控件的宽度
                                                        $ListView_HitItemRect[3] - $ListView_HitItemRect[1]);Input控件的高度
                                        GUICtrlSetState(-1, $GUI_ONTOP + $GUI_FOCUS) ;使输入框具有焦点及置顶
                        EndSwitch
        EndSwitch
        Return $GUI_RUNDEFMSG
EndFunc   ;==>_WM_NOTIFY

Func _WM_COMMAND($hWnd, $iMsg, $iwParam, $ilParam)
        #forceref $hWnd, $iMsg, $iwParam, $ilParam
        Local $hWndFrom, $iIDFrom, $iCode
        $hWndFrom = $ilParam
        $iCode = BitShift($iwParam, 16);获取高位
        $iIDFrom = BitAND($iwParam, 0x0000FFFF);获取低位
        
        Switch $hWndFrom
                Case GUICtrlGetHandle($ListView_HitItemInput)
                        Switch $iCode
                                Case $EN_KILLFOCUS ; 控件丢失键盘焦点时发送
                                        _GUICtrlListView_SetItemText($ListView, $Listview_HitItemIndex, GUICtrlRead($ListView_HitItemInput), $Listview_HitItemSubItem) ;更改子项文本,$Listview_HitItemIndex项目索引,$Listview_HitItemSubItem子项的索引
                                        GUICtrlDelete($ListView_HitItemInput);删除Input控件
                        EndSwitch
        EndSwitch
        Return $GUI_RUNDEFMSG
EndFunc   ;==>_WM_COMMAND

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?加入

×
发表于 2012-11-22 16:14:07 | 显示全部楼层
win7的默认字体是雅黑?这个不太清楚,如果是的话,设置下edit的字体不就行了
 楼主| 发表于 2012-11-22 16:16:18 | 显示全部楼层
回复 2# netegg


    就是设置不了啊?
 楼主| 发表于 2012-11-22 16:16:39 | 显示全部楼层
回复 2# netegg


    不知道是不是我的方法有问题
发表于 2012-11-22 16:24:03 | 显示全部楼层
回复 4# qinylj
不对,知道了,edit没法设置字体,可能要用richedit
 楼主| 发表于 2012-11-22 16:28:49 | 显示全部楼层
回复 5# netegg


  能否直接用Input控件?
 楼主| 发表于 2012-11-22 16:36:29 | 显示全部楼层
回复 5# netegg


    如果用Input的话就涉及到Input的消息,但是Input的失去焦点的消息是哪个呢?貌似也没看到Input的消息?
发表于 2012-11-22 16:41:58 | 显示全部楼层
回复 7# qinylj
input其实就是个edit的特例,用edit的消息试试看
 楼主| 发表于 2012-11-22 17:31:05 | 显示全部楼层
回复 8# netegg


    试了,没效果
发表于 2012-11-22 19:43:42 | 显示全部楼层
回复 9# qinylj
input没消息?
发表于 2012-11-22 19:48:22 | 显示全部楼层
[au3]#AutoIt3Wrapper_au3check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6
#include <GuiEdit.au3>
#include <WinAPI.au3> ; used for Lo/Hi word
#include <WindowsConstants.au3>
#include <GuiConstantsEx.au3>

Opt('MustDeclareVars', 1)

$Debug_Ed = False ; 查看传递给函数的类名, 设置为真并使用另一控件的句柄观察其工作

Global $hEdit,$iMemo

_Example1()

Func _Example1()

  ; 创建界面
  GUICreate("Edit Create", 400, 532)
  $hEdit = GUICtrlCreateinput("This is a test" & @CRLF & "Another Line", 2, 2, 394, 268)
  $iMemo = GUICtrlCreateEdit("", 2, 272, 394, 258, BitOR($WS_VSCROLL, $ES_AUTOVSCROLL, $ES_READONLY))
  GUISetState()

  GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")

  _GUICtrlEdit_AppendText($hEdit, @CRLF & "Append to the end?")

  ; 循环至用户退出
  Do
  Until GUIGetMsg() = $GUI_EVENT_CLOSE
  GUIDelete()
EndFunc   ;==>_Example1


Func WM_COMMAND($hWnd, $iMsg, $iwParam, $ilParam)
  #forceref $hWnd, $iMsg
  Local $hWndFrom, $iIDFrom, $iCode, $hWndEdit
  If Not IsHWnd($hEdit) Then $hWndEdit = GUICtrlGetHandle($hEdit)
  $hWndFrom = $ilParam
  $iIDFrom = _WinAPI_LoWord($iwParam)
  $iCode = _WinAPI_HiWord($iwParam)
  Switch $hWndFrom
    Case $hEdit, $hWndEdit
      Switch $iCode
        Case $EN_ALIGN_LTR_EC ; 将编辑控件方向改为从左到右时发送
          memowrite("$EN_ALIGN_LTR_EC" & @LF)
          memowrite("-->hWndFrom:" & @TAB & $hWndFrom & @LF)
          memowrite("-->IDFrom:" & @TAB & $iIDFrom & @LF)
          memowrite("-->Code:" & @TAB & $iCode & @LF)
          ; 无返回值
        Case $EN_ALIGN_RTL_EC ; 将编辑控件方向改为从右到左时发送
          memowrite("$EN_ALIGN_RTL_EC" & @LF)
          memowrite("-->hWndFrom:" & @TAB & $hWndFrom & @LF)
          memowrite("-->IDFrom:" & @TAB & $iIDFrom & @LF)
          memowrite("-->Code:" & @TAB & $iCode & @LF)
          ; 无返回值
        Case $EN_CHANGE ; 改变控件中的文本时发送
          memowrite("$EN_CHANGE" & @LF)
          memowrite("-->hWndFrom:" & @TAB & $hWndFrom & @LF)
          memowrite("-->IDFrom:" & @TAB & $iIDFrom & @LF)
          memowrite("-->Code:" & @TAB & $iCode & @LF)
          ; 无返回值
        Case $EN_ERRSPACE ; 控件无法分配足够内存用于指定请求时发送
          memowrite("$EN_ERRSPACE" & @LF)
          memowrite("-->hWndFrom:" & @TAB & $hWndFrom & @LF)
          memowrite("-->IDFrom:" & @TAB & $iIDFrom & @LF)
          memowrite("-->Code:" & @TAB & $iCode & @LF)
          ; 无返回值
        Case $EN_HSCROLL ; 点击控件水平滚动条时发送
          memowrite("$EN_HSCROLL" & @LF)
          memowrite("-->hWndFrom:" & @TAB & $hWndFrom & @LF)
          memowrite("-->IDFrom:" & @TAB & $iIDFrom & @LF)
          memowrite("-->Code:" & @TAB & $iCode & @LF)
          ; 无返回值
        Case $EN_KILLFOCUS ; 控件丢失键盘焦点时发送
          memowrite("$EN_KILLFOCUS" & @LF)
          memowrite("-->hWndFrom:" & @TAB & $hWndFrom & @LF)
          memowrite("-->IDFrom:" & @TAB & $iIDFrom & @LF)
          memowrite("-->Code:" & @TAB & $iCode & @LF)
          ; 无返回值
        Case $EN_MAXTEXT ; 当前文本插入已超过编辑框字符的指定数量时发送
          memowrite("$EN_MAXTEXT" & @LF)
          memowrite("-->hWndFrom:" & @TAB & $hWndFrom & @LF)
          memowrite("-->IDFrom:" & @TAB & $iIDFrom & @LF)
          memowrite("-->Code:" & @TAB & $iCode & @LF)
          ; 当编辑控件不具有$ES_AUTOHSCROLL样式且将插入的字符的数量超过编辑控件宽度时会发送该消息.
          ; 当编辑控件不具有$ES_AUTOVSCROLL样式且插入的文本行数加原文本行数总行数超过控件高度时也会发送该消息

          ; 无返回值
        Case $EN_SETFOCUS ; 控件收到键盘焦点时发送
          memowrite("$EN_SETFOCUS" & @LF)
          memowrite("-->hWndFrom:" & @TAB & $hWndFrom & @LF)
          memowrite("-->IDFrom:" & @TAB & $iIDFrom & @LF)
          memowrite("-->Code:" & @TAB & $iCode & @LF)
          ; 无返回值
        Case $EN_UPDATE ; 编辑控件将重绘时发送
          memowrite("$EN_UPDATE" & @LF)
          memowrite("-->hWndFrom:" & @TAB & $hWndFrom & @LF)
          memowrite("-->IDFrom:" & @TAB & $iIDFrom & @LF)
          memowrite("-->Code:" & @TAB & $iCode & @LF)
          ; 无返回值
        Case $EN_VSCROLL ; 点击编辑控件垂直滚动条或在控件上转动鼠标滚轮时发送
          memowrite("$EN_VSCROLL" & @LF)
          memowrite("-->hWndFrom:" & @TAB & $hWndFrom & @LF)
          memowrite("-->IDFrom:" & @TAB & $iIDFrom & @LF)
          memowrite("-->Code:" & @TAB & $iCode & @LF)
          ; 无返回值
      EndSwitch
  EndSwitch
  Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_COMMAND

Func memowrite($s_text)
  GUICtrlSetData($iMemo, $s_text & @CRLF, 1)
EndFunc   ;==>memowrite[/au3]

帮助里guiedit的例子
发表于 2012-11-22 19:48:56 | 显示全部楼层
本帖最后由 netegg 于 2012-11-22 19:59 编辑

[au3]#AutoIt3Wrapper_au3check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6
#include <GuiEdit.au3>
#include <WinAPI.au3> ; used for Lo/Hi word
#include <WindowsConstants.au3>
#include <GuiConstantsEx.au3>

Opt('MustDeclareVars', 1)

$Debug_Ed = False ; 查看传递给函数的类名, 设置为真并使用另一控件的句柄观察其工作

Global $hEdit,$iMemo

_Example1()

Func _Example1()

  ; 创建界面
  GUICreate("Edit Create", 400, 532)
  $hEdit = GUICtrlCreateinput("This is a test" & @CRLF & "Another Line", 2, 2, 394, 20)
  $iMemo = GUICtrlCreateEdit("", 2, 272, 394, 258, BitOR($WS_VSCROLL, $ES_AUTOVSCROLL, $ES_READONLY))
  GUISetState()

  GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")

  _GUICtrlEdit_AppendText($hEdit, @CRLF & "Append to the end?")

  ; 循环至用户退出
  Do
  Until GUIGetMsg() = $GUI_EVENT_CLOSE
  GUIDelete()
EndFunc   ;==>_Example1


Func WM_COMMAND($hWnd, $iMsg, $iwParam, $ilParam)
  #forceref $hWnd, $iMsg
  Local $hWndFrom, $iIDFrom, $iCode, $hWndEdit
  If Not IsHWnd($hEdit) Then $hWndEdit = GUICtrlGetHandle($hEdit)
  $hWndFrom = $ilParam
  $iIDFrom = _WinAPI_LoWord($iwParam)
  $iCode = _WinAPI_HiWord($iwParam)
  Switch $hWndFrom
    Case $hEdit, $hWndEdit
      Switch $iCode
        Case $EN_KILLFOCUS ; 控件丢失键盘焦点时发送
          memowrite("$EN_KILLFOCUS" & @LF)
          memowrite("-->hWndFrom:" & @TAB & $hWndFrom & @LF)
          memowrite("-->IDFrom:" & @TAB & $iIDFrom & @LF)
          memowrite("-->Code:" & @TAB & $iCode & @LF)
          ; 无返回值
     EndSwitch
  EndSwitch
  Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_COMMAND

Func memowrite($s_text)
  GUICtrlSetData($iMemo, $s_text & @CRLF, 1)
EndFunc   ;==>memowrite[/au3]
稍微改改,点击下面的memo可以看见效果
 楼主| 发表于 2012-11-22 20:03:46 | 显示全部楼层
回复 12# netegg


    怎么我自己写的就有问题呢,郁闷,这个可以用哈,感谢蛋蛋大大
您需要登录后才可以回帖 登录 | 加入

本版积分规则

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

GMT+8, 2024-5-9 19:12 , Processed in 0.089673 second(s), 24 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

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