[已解决]TreeView就地编辑(如何保存)
本帖最后由 dhlhmgc 于 2016-1-5 11:03 编辑得到 水木子 和 Afan 的帮助,TreeView的操作已有一定基础,
为方便使用,项目节点功能,已经能实现如下操作
1、鼠标点击进入编辑状态(需要间隔点)
2、选中节点项目,按F2键进入编辑状态
3、用鼠标右键菜单选择修改
4、新建子节点、删除本级节点等
请帮忙,解决以下问题:
1、编辑后如何保存节点,鼠标移出或者回车,都能保存节点(对于修改节点给出提示,是否要将“旧名称”更改为新名称,但新建节点不需要提示)
2、如何添加本级节点,新建操作(新建时也直接进入编辑状态)
代码如下:
#include <WindowsConstants.au3>
#include <GUIConstants.au3>
#include <GuiTreeView.au3>
#include <GuiMenu.au3>
#include <Misc.au3>
Global $hTreeCurValue
Local $Form1 = GUICreate('Form1', 640, 450)
Local $iStyle = BitOR($TVS_EDITLABELS, $TVS_HASBUTTONS, $TVS_HASLINES, $TVS_LINESATROOT, $TVS_DISABLEDRAGDROP, $TVS_SHOWSELALWAYS, $TVS_CHECKBOXES)
Local $TreeView1 = GUICtrlCreateTreeView(16, 24, 297, 329, $iStyle, $WS_EX_CLIENTEDGE)
Local $hTreeView = GUICtrlGetHandle(-1)
$Input1 = GUICtrlCreateInput('Input1', 16, 376, 585, 21)
$Label1 = GUICtrlCreateLabel('Label1', 16, 408, 588, 17)
$Button1 = GUICtrlCreateButton('Button1', 368, 24, 75, 25)
$Button2 = GUICtrlCreateButton('Button2', 368, 58, 75, 25)
$Button3 = GUICtrlCreateButton('Button3', 368, 91, 75, 25)
$Button4 = GUICtrlCreateButton('Button4', 368, 125, 75, 25)
$Button5 = GUICtrlCreateButton('Button5', 368, 158, 75, 25)
$Button6 = GUICtrlCreateButton('Button6', 368, 192, 75, 25)
#cs
Local Enum $MenuAdd = 1000, $MenuEdit, $MenuDel
Local $Menu1 = _GUICtrlMenu_CreatePopup()
_GUICtrlMenu_InsertMenuItem($Menu1, 0, ' 添加数据 ', $MenuAdd)
_GUICtrlMenu_InsertMenuItem($Menu1, 1, ' 修改数据 ', $MenuEdit)
_GUICtrlMenu_InsertMenuItem($Menu1, 2, ' 删除数据 ', $MenuDel)
#ce
Global $aMenu = StringSplit(" 添加本级节点 | 删除此节点 | 修改节点名称 || 添加子节点 | 删除所有子节点", "|",1)
$iMenu = GUICtrlCreateContextMenu(GUICtrlCreateDummy())
$hMenu = GUICtrlGetHandle($iMenu) ;GUICtrlGetHandle ( 控件ID )
For $i = 1 to $aMenu
$aMenu[$i] = GUICtrlCreateMenuItem($aMenu[$i], $iMenu)
;Assign("iMenuItem" & $i, GUICtrlCreateMenuItem($aMenu[$i], $iMenu), 2 )
;msgbox(48,0, Eval("iMenuItem" & $i),0,$Form1)
next
GUIRegisterMsg($WM_NOTIFY, '_MY_WM') ;注册事件
GUISetState()
$hImage = _GUIImageList_Create(16, 16, 5, 3)
_GUIImageList_AddIcon($hImage, 'shell32.dll', 110)
_GUIImageList_AddIcon($hImage, 'shell32.dll', 131)
_GUIImageList_AddIcon($hImage, 'shell32.dll', 165)
_GUIImageList_AddIcon($hImage, 'shell32.dll', 168)
_GUIImageList_AddIcon($hImage, 'shell32.dll', 137)
_GUIImageList_AddIcon($hImage, 'shell32.dll', 146)
_GUICtrlTreeView_SetNormalImageList($hTreeView, $hImage)
;Local $hItem
Global $hItem = StringSplit(" 北京市 | 天津市 | 上海市 | 贵州省 | 云南省 | 四川省 ", "|",2)
For $x = 0 To Ubound($hItem)-1 ;_GUIImageList_GetImageCount($hImage) - 1
;$hItem[$x] = _GUICtrlTreeView_Add($TreeView1, 0, StringFormat('[%02d] New Item', $x + 1), $x, $x)
$hItem[$x] = _GUICtrlTreeView_Add($TreeView1, 0, $hItem[$x], $x, $x)
Next
While 1
$nMsg = GUIGetMsg()
Switch $nMsg
Case $GUI_EVENT_CLOSE
Exit
Case $Button1
EndSwitch
WEnd
Func _MY_WM($hWnd, $Msg, $wParam, $lParam)
Local $tNMHdr = DllStructCreate($tagNMHDR, $lParam), $tNM_TREEVIEW
Local $hWndFrom = DllStructGetData($tNMHdr, 'hWndFrom')
Local $iIDFrom= DllStructGetData($tNMHdr, 'IDFrom')
Local $iCode = DllStructGetData($tNMHdr, 'Code')
If $iIDFrom = $TreeView1 Then
Switch $iCode ;根据事件ID处理
Case $TVN_SELCHANGINGA, $TVN_SELCHANGINGW ;//某个项目正在发生变化
GUICtrlSetData( $Label1,"项目正在变化!" & $hTreeCurValue)
Case $TVN_SELCHANGEDA, $TVN_SELCHANGEDW ;//某个项已经发生变化
$Index = _GUICtrlTreeView_GetSelection($iIDFrom)
$hTreeCurValue = _GUICtrlTreeView_GetText($hTreeView , $Index)
GUICtrlSetData( $Input1,"项目变化!" & $hTreeCurValue)
Case $TVN_KEYDOWN
if Not _GUICtrlTreeView_GetEditControl($hTreeView) = 0 Then
;如果正在编辑,则退出
Return $GUI_RUNDEFMSG
Endif
;取按键值
$tInfo = DllStructCreate($tagNMLVKEYDOWN, $LParam) ;$ilParam)
$psx = DllStructGetData($tInfo, "VKey")
Switch $psx
Case 113 ;F2键 - 开始编辑
;GUICtrlSetData( $Input1,"按键" & $psx)
$Index = _GUICtrlTreeView_GetSelection($iIDFrom)
_GUICtrlTreeView_EditText($hTreeView, $Index)
Case 13
GUICtrlSetData( $Input1,"按键" & $psx)
Case Else
EndSwitch
;_GUICtrlTreeView_EndEdit($hTreeView)
;Endif
Case $TVN_ENDLABELEDITA, $TVN_ENDLABELEDITW ; 文本编辑结束
;GUICtrlSendMsg($TreeView, $TVM_ENDEDITLABELNOW, 0, 0) ;与下行作用相同, 终止编辑
_GUICtrlTreeView_EndEdit($hTreeView, False)
$Index = _GUICtrlTreeView_GetSelection($iIDFrom)
$hNewValue = _GUICtrlTreeView_GetText($hTreeView , $Index)
;$new_Name = ControlGetText($hTreeView, '', $hEditControl)
GUICtrlSetData( $Input1,StringFormat("编辑结束,将[%s]改为[%s]",$hTreeCurValue,$hNewValue) )
Case $TVN_BEGINLABELEDITA, $TVN_BEGINLABELEDITW ; 开始文本编辑
;$hItem = _GUICtrlTreeView_GetEditControl($hTreeView)
;$hIndex = _GUICtrlTreeView_Index($hTreeView, $hItem)
;$hText = _GUICtrlTreeView_GetText($hTreeView , $hIndex)
GUICtrlSetData( $Input1,"编辑开始了[" & $hTreeCurValue & "]" )
;$dll = DllOpen("user32.dll")
;While 1
; Sleep ( 250 )
; If _IsPressed("0D", $dll) Then ;检测是否回车键
; _GUICtrlTreeView_EndEdit($hTreeView, True)
; ;MsgBox(0,"检查按键", "点击 End 键")
; ExitLoop
; EndIf
;WEnd
;DllClose($dll)
Case $NM_CLICK ; 左击
;单击时记录值
;$Index = _GUICtrlTreeView_GetSelection($iIDFrom)
;$hTreeCurValue = _GUICtrlTreeView_GetText($hTreeView , $Index)
Case $NM_DBLCLK ; 双击
Case $NM_RCLICK ; 右击
;//这里用以判断是否选定了TreeViewItem
$Index = _GUICtrlTreeView_GetSelection($iIDFrom)
If Not $Index Then Return $GUI_RUNDEFMSG
#cs
;//MouseGetPos()返回鼠标坐标的2元素一维数组array: $array = X 坐标 (横向), $array = Y 坐标 (垂直)
Local $aPos = MouseGetPos()
;//C/C++ 样式的数据结构供 DllCall 使用.
Local $tag = DllStructCreate("long X;long Y")
DllStructSetData($tag, 'X', $aPos)
DllStructSetData($tag, 'Y', $aPos)
;//转换屏幕指定点坐标到客户端屏幕坐标
_WinAPI_ScreenToClient($hTreeView, $tag)
Local $iX = DllStructGetData($tag, 'X')
Local $iY = DllStructGetData($tag, 'Y')
$tag = 0 ;//
Local $iX = _WinAPI_GetMousePosX(True, $hTreeView)
Local $iY = _WinAPI_GetMousePosY(True, $hTreeView)
#ce
;//$tagPOINT = "struct; long X;long Y; endstruct"
Local $tag = _WinAPI_GetMousePos(True, $hTreeView)
Local $iX = DllStructGetData($tag, 'X')
Local $iY = DllStructGetData($tag, 'Y')
;StringFormat('鼠标: [左键:%u 右键:%u] 控件[%u = %u]', $a, $a, $a, $a, $a, $iIDFrom)
;//检索测试点位置相对于控件的信息,返回结果代码.
Local $iPos = _GUICtrlTreeView_HitTest($hTreeView, $iX, $iY)
If ($iPos <> 2) And ($iPos <> 4) And ($iPos <> 64) Then Return $GUI_RUNDEFMSG
;1 - 在客户区末项的下面.
;8 - 位于项目缩进
;16 - 位于项目按钮
;32 - 位于项目右边
;2 - 位于项目位图 -通过
;4 - 位于项目文本 -通过
;64 - 位于项目用户自定义状态图标 -通过
;128- 位于客户区上方
;256- 位于客户区下方
;512- 位于客户区左边
;1024 - 位于客户区右边
;//检索指定坐标的项目,如果不是当前选定的项目,则退出
Local $hItem = _GUICtrlTreeView_HitTestItem($hTreeView, $iX, $iY)
if $Index <> $hItem Then Return $GUI_RUNDEFMSG
;//选定项目,弹出菜单
;_GUICtrlTreeView_SelectItem($hTreeView, $hItem)
Local $iMenuId = _GUICtrlMenu_TrackPopupMenu($hMenu, $hWndFrom, -1, -1, 1, 1, 2)
Switch $iMenuId
Case 0 ;没有选择或错误
Case $aMenu ;//添加本级节点
Case $aMenu ;//删除此节点
_GUICtrlTreeView_Delete($hTreeView, $hItem)
Case $aMenu ;//修改节点
_GUICtrlTreeView_EditText($hTreeView, $hItem)
Case $aMenu ;//添加子节点
$jb = _GUICtrlTreeView_Level($hTreeView, $hItem)
if $jb< 2 Then
if Not _GUICtrlTreeView_GetChildren($hTreeView, $hItem) Then
_GUICtrlTreeView_SetChildren($hTreeView, $hItem , True)
Endif
$subitem = _GUICtrlTreeView_AddChild($hTreeView, $hItem, "新建节点")
;_GUICtrlTreeView_Expand($hTreeView, $hItem, True)
_GUICtrlTreeView_SelectItem($hTreeView, $subitem , $TVGN_CARET)
_GUICtrlTreeView_EditText($hTreeView, $subitem)
Endif
Case $aMenu ;//删除所有子节点
_GUICtrlTreeView_DeleteChildren($hTreeView, $hItem)
_GUICtrlTreeView_SetChildren($hTreeView, $hItem , False)
Case Else ;其他
MsgBox( 48, $iMenuId , _GUICtrlMenu_GetItemText($hMenu,$iMenuId, False), 0, $Form1 )
EndSwitch
#cs
Switch _GUICtrlMenu_TrackPopupMenu($Menu1, $hWndFrom, -1, -1, 1, 1, 2)
Case $MenuAdd
MsgBox(48, '', '您点击了添加', 0, $hWndFrom)
Case $MenuEdit
$hTreeCurValue = _GUICtrlTreeView_GetText($hTreeView , $Index)
GUICtrlSetData( $Input1,"编辑开始了[" & $hTreeCurValue & "]" )
_GUICtrlTreeView_EditText($hTreeView, $hItem) ;
;MsgBox(48, '', '您点击了编辑', 0, $hWndFrom)
Case $MenuDel
MsgBox(48, '', '您点击了删除', 0, $hWndFrom)
EndSwitch
#ce
EndSwitch
EndIf
Return $GUI_RUNDEFMSG
EndFunc ;==>_MY_WM 引用afan前辈的话,先整理好代码再提问,看来对LZ来说确实很难啊! 确实,我也头昏了,对于WINDOWS 的事件消息码一大堆
翻看了TreeView_Constants的常量定义,也没有相应事件的说明
百度到了一些,但一般的事件码都有两个
$TVN_BEGINLABELEDITA = $TVN_FIRST - 10
$TVN_BEGINLABELEDITW = $TVN_FIRST - 59
用鼠标点击(间隔点)到是可以引发(开始编辑的事件)
在F2键编辑 或 菜单右键编辑时,使用
_GUICtrlTreeView_EditText($hTreeView, $subitem)
进行编辑时,尽然不会触发(开始编辑的事件)
想在F2键和右键修改的地方把
_GUICtrlTreeView_EditText($hTreeView, $subitem)
换成
GUICtrlSendMsg($hTreeView,$TVN_BEGINLABELEDITW, 0, 0) 想让它
触发事件也没有成功
参照了
就地编辑(重命名,改名)TreeView项目, 快捷实现树分支的勾选操作或反选操作
这个代码,设置输入新值后,检查按回车键,获取新值,到是可以了,
修改节点内容时,输入新值,不按回车,还是获取不到新值,没有办法
郁闷啊。。。 本帖最后由 水木子 于 2015-12-4 23:08 编辑
回复 3# dhlhmgc
整理下代码,真的就这么难?
你先看看,剩下的自己改吧!
另外我觉得你可以低调点嘛!毕竟这些东西都是别人帮你完成的,怎么可以在这里借别人的东西去别处炫耀呢!你说是吧!
#include <GUIMenu.au3>
#include <GuiTreeView.au3>
#include <GuiConstantsEx.au3>
#include <WindowsConstants.au3>
HotKeySet('{F2}', 'EditText')
$MyGui = GUICreate('', 400, 300)
$iStyle = BitOR($TVS_EDITLABELS, $TVS_HASBUTTONS, $TVS_HASLINES, $TVS_LINESATROOT, $TVS_DISABLEDRAGDROP, $TVS_SHOWSELALWAYS, $TVS_CHECKBOXES)
$TreeView1 = GUICtrlCreateTreeView(5, 5, 390, 280, $iStyle, $WS_EX_CLIENTEDGE)
$hTreeView = GUICtrlGetHandle(-1)
$TreeViewItem1 = GUICtrlCreateTreeViewItem('TreeViewItem1', $TreeView1)
GUICtrlCreateTreeViewItem('TreeViewItem1-1', $TreeViewItem1)
GUICtrlCreateTreeViewItem('TreeViewItem1-2', $TreeViewItem1)
GUICtrlCreateTreeViewItem('TreeViewItem1-3', $TreeViewItem1)
$TreeViewItem2 = GUICtrlCreateTreeViewItem('TreeViewItem2', $TreeView1)
GUICtrlCreateTreeViewItem('TreeViewItem2-1', $TreeViewItem2)
GUICtrlCreateTreeViewItem('TreeViewItem2-2', $TreeViewItem2)
GUICtrlCreateTreeViewItem('TreeViewItem2-3', $TreeViewItem2)
$TreeViewItem3 = GUICtrlCreateTreeViewItem('TreeViewItem3', $TreeView1)
GUICtrlCreateTreeViewItem('TreeViewItem3-1', $TreeViewItem3)
GUICtrlCreateTreeViewItem('TreeViewItem3-2', $TreeViewItem3)
GUICtrlCreateTreeViewItem('TreeViewItem3-3', $TreeViewItem3)
GUICtrlSetState($TreeViewItem1, $GUI_EXPAND)
GUICtrlSetState($TreeViewItem2, $GUI_EXPAND)
;~ GUICtrlSetState($TreeViewItem3, $GUI_EXPAND)
Global $aMenuItemText = ['修改项目文本', 'MenuItem - 2', 'MenuItem - 3', 'MenuItem - 4', 'MenuItem - 5']
$iMenu = GUICtrlCreateContextMenu(GUICtrlCreateDummy())
$hMenu = GUICtrlGetHandle(-1)
$iMenuItem1 = GUICtrlCreateMenuItem($aMenuItemText, $iMenu)
$iMenuItem2 = GUICtrlCreateMenuItem($aMenuItemText, $iMenu)
$iMenuItem3 = GUICtrlCreateMenuItem($aMenuItemText, $iMenu)
$iMenuItem4 = GUICtrlCreateMenuItem($aMenuItemText, $iMenu)
$iMenuItem5 = GUICtrlCreateMenuItem($aMenuItemText, $iMenu)
GUISetState()
GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")
Do
Until GUIGetMsg() = -3
Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $hWndTreeview
$hWndTreeview = $TreeView1
If Not IsHWnd($TreeView1) Then $hWndTreeview = GUICtrlGetHandle($TreeView1)
$tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
$hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
$iIDFrom = DllStructGetData($tNMHDR, "IDFrom")
$iCode = DllStructGetData($tNMHDR, "Code")
Switch $hWndFrom
Case $hWndTreeview
Switch $iCode
Case $NM_RCLICK
MouseDown('left')
$iItemID = GUICtrlRead($TreeView1)
$hItemID = GUICtrlGetHandle($iItemID)
$aCursor = GUIGetCursorInfo()
$aRect = _GUICtrlTreeView_DisplayRect($TreeView1, $hItemID, True)
$aPos = ControlGetPos($MyGui, '', $TreeView1)
$aCursor = $aCursor - $aPos
$aCursor = $aCursor - $aPos
If $aCursor > $aRect And $aCursor < $aRect And $aCursor > $aRect And $aCursor < $aRect Then
$hMenu = GUICtrlGetHandle($iMenu)
Local $iMenuId = _GUICtrlMenu_TrackPopupMenu($hMenu, $MyGui, -1, -1, 1, 1, 2)
Switch $iMenuId
Case $iMenuItem1
EditText()
Case $iMenuItem2
MsgBox(0, 0, 'MenuItem - 2')
Case $iMenuItem3
MsgBox(0, 0, 'MenuItem - 3')
Case $iMenuItem4
MsgBox(0, 0, 'MenuItem - 4')
Case $iMenuItem5
MsgBox(0, 0, 'MenuItem - 5')
EndSwitch
EndIf
Case $TVN_ENDLABELEDITA, $TVN_ENDLABELEDITW
Local $tInfo = DllStructCreate($tagNMHDR & ";" & $tagTVITEMEX, $ilParam)
If DllStructGetData($tInfo, "Text") <> 0 Then
Local $tBuffer = DllStructCreate("WCHAR Text[" & DllStructGetData($tInfo, "TextMax") & "]", DllStructGetData($tInfo, "Text"))
_GUICtrlTreeView_SetText($hTreeView, _GUICtrlTreeView_GetSelection($hTreeView), DllStructGetData($tBuffer, "Text"))
EndIf
EndSwitch
EndSwitch
Return $GUI_RUNDEFMSG
EndFunc ;==>WM_NOTIFY
Func WM_COMMAND($hWnd, $iMsg, $iwParam, $ilParam)
Local $hWndFrom, $iIDFrom, $iCode, $hWndEdit
$hWndFrom = $ilParam
$iIDFrom = _WinAPI_LoWord($iwParam)
$iCode = _WinAPI_HiWord($iwParam)
If $iCode = 0 Then _GUICtrlTreeView_EndEdit($hTreeView)
Return $GUI_RUNDEFMSG
EndFunc ;==>WM_COMMAND
Func EditText()
$iSelectItem = _GUICtrlTreeView_GetSelection($hTreeView)
If $iSelectItem <> 0 Then
_GUICtrlTreeView_EditText($hTreeView, $iSelectItem)
_GUICtrlTreeView_SetSelected($TreeView1, $iSelectItem, False)
EndIf
EndFunc ;==>EditText
难啊,我也不是炫耀
我就是怕人说,才注明是靠什么人帮助,引用了哪些代码的。
照实写出来也不怕,主要目的
一是解决自己遇到的问题,必竟AU3的GUI设计和处理,及WIN消息代码,不像VB、VBA哪么傻瓜式(都是封装好的),我是从VBA转过来的,对于GUI确实不太适应
提出问题时,我发的代码,包括其中的一些注解都没有去掉,其实也可以看出来(,自己也做了很多偿试。
二是能让大伙也能看到,共同学习进步(相信有好多像我这样的吧)
另外论坛的目的,确实就是让大家共同进步的嘛!!
水木子老师,非常感谢您的帮助,每次解决一个问题,我都差不多要去翻看帮助,
看看老师么,解决问题实现的代码,做标记注解(不理解的只有先死记下来)也不容易啊
再次感谢!! 好东西啊,找的就是这个。
页:
[1]