imutraveler 发表于 2016-8-29 19:33:21

TreeView子项目上创建右键菜单问题?求助!(已解决)

本帖最后由 imutraveler 于 2016-9-21 21:27 编辑

TreeViewItem是读access数据库,通过数组创建的。

想要实现的功能:

右键点击每个TreeViewItem,都能弹出菜单,“编辑分组”和“删除分组”,
点击“编辑分组”,弹出小窗口,可以编辑分组名称,
点击“删除分组”,从数据库中删除分组!

我现在的问题是,只有点击最后一个TreeViewItem才能正常执行

求帮忙!谢谢了!

macran 发表于 2016-8-29 21:40:25

大概看了一下。没有深入,似乎你这边的思路和我想的不一样。右键菜单为什么不用GUICtrlCreateContextMenu
然后再结合 WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)

而你现在的问题,明细测试分组1-9 ,都在CAse 第二种情况中响应了,即: Case $GroupItem To $GroupItem ;TreeView列表点击事件
而没有在第3种情况下响应。所以达不到你的要求。

macran 发表于 2016-8-29 21:46:28

wm_notify 的功能是依据哪个控件发生了什么消息分别要怎么处理,一般是Switch (控件分类)嵌套Switch(消息),这是 GUIGetMsg()无法实现的。明白这个,你的问题就解决了。

imutraveler 发表于 2016-8-29 23:35:23

回复 3# macran


    想过wm_notify ,,, 只是因为,后续要在listview中使用wm_notify , 来定义一些单击,双击,右键的操作,,不确定一个程序中能否同时使用2个 wm_notify   ,

macran 发表于 2016-8-30 10:05:13

你还是没理解我的意思。wm_notify是对不同的控件不同的消息都处理,一般会用到嵌套。格式大概是:
swtich 控件
CASE :Treeview
    SWITCH消息
      case :编辑
      。。。。。
      case:删除
      。。。。。。
case:listview
    switch消息
   case:A消息
    。。。。。。。
   case:B消息
endswitch
endswitch
   
所以不存在需要2个wm_notify的问题。

nmgwddj 发表于 2016-8-30 10:10:16

1、菜单只创建一份,哪里需要哪里 Show 出来就可以了,不要给每个数据创建一份菜单。
2、消息响应用 WM_NOTIFY 消息,消息中可以根据不同控件做出不同响应,并不需要创建两份 WM_NOTIFY 响应函数。

http://www.autoitx.com/forum.php?mod=viewthread&tid=39801&highlight=%D3%D2%BC%FC%2B%B2%CB%B5%A5

http://www.autoitx.com/forum.php?mod=viewthread&tid=45113&highlight=TreeView

论坛还有很多例子,自己多搜索看看。

imutraveler 发表于 2016-8-30 14:07:12

回复 5# macran


    嗯,明白了,谢谢你!

imutraveler 发表于 2016-8-30 14:07:44

回复 6# nmgwddj


    好的,思路懂了,我自己再研究一下!

chzj589 发表于 2016-8-30 16:57:09

本帖最后由 chzj589 于 2016-9-2 08:34 编辑

回复 8# imutraveler
测试了一下,用WM_NOTIFY与WM_COMMAND可行




imutraveler 发表于 2016-8-30 20:20:23

本帖最后由 imutraveler 于 2016-8-30 20:24 编辑

回复 9# chzj589


    你好 ,能否发下具体修改的代码部分呢?wm_notify这里改了一下,,现在,右键菜单的2个按钮执行还是有问题 ,,nmsg总是得到0#NoTrayIcon
#Region ;**** 由 AccAu3Wrapper_GUI 创建指令 ****
#AccAu3Wrapper_OutFile=Console.exe
#AccAu3Wrapper_UseUpx=Y
#AccAu3Wrapper_UseX64=n
#AccAu3Wrapper_Res_Comment=Traveler.
#AccAu3Wrapper_Res_Description=远程集中管理
#AccAu3Wrapper_Res_Fileversion=1.0
#AccAu3Wrapper_Res_LegalCopyright=Traveler.
#AccAu3Wrapper_Res_Language=2052
#AccAu3Wrapper_Res_requestedExecutionLevel=None
#EndRegion ;**** 由 AccAu3Wrapper_GUI 创建指令 ****

#include <ButtonConstants.au3>
#include <EditConstants.au3>
#include <GUIConstantsEx.au3>
#include <GuiStatusBar.au3>
#include <WindowsConstants.au3>
#include <StaticConstants.au3>

#include <GuiListView.au3>
#include <ListViewConstants.au3>
#include <GuiTreeView.au3>
#include <TreeViewConstants.au3>
#include <GuiImageList.au3>
#include <GuiButton.au3>
#include <String.au3>
#include <WinAPI.au3>
;~ #include <Array.au3>
#include <Constants.au3> ; 托盘事件$TRAY_EVENT_PRIMARYDOUBLE

Opt("GUICloseOnESC",0) ;禁用 Esc 键退出程序
Opt("TrayMenuMode", 3) ;不显示默认托盘菜单项“脚本暂停/退出”
Opt("TrayOnEventMode", 1) ;响应托盘事件
Opt("TrayIconHide",1) ;隐藏脚本自身托盘图标
Opt("WinDetectHiddenText",1) ;检测隐藏窗口的文本或窗口的隐藏文本
Opt("WinTitleMatchMode",4) ;窗口的匹配模式

; 定义变量
Global $DbPath, $DbPass, $TableGroup, $TableServer, $TableUsers, $Conn
Global $GroupItem, $iS = 0
Global $TreeContext, $TreeEdit, $TreeDelete, $SelectedItemIndex
Local $Title = "远程集中管理 (控制台) " ,$OemInfo

$OemInfo = ""

; 设置主程序窗口标题
If $OemInfo <> "" Then $Title &= " -- " & $OemInfo

;======================== ;;; 开始:创建程序主窗口 ;;; ========================
$Form1 = GUICreate($Title, 960, 615)

; 创建 工具栏
$MenuItem1 = GUICtrlCreateMenu("参数设置")
$MenuItem101 = GUICtrlCreateMenuItem("Mstsc 默认选项", $MenuItem1)
$MenuItem102 = GUICtrlCreateMenuItem("功能02", $MenuItem1)
$MenuItem2 = GUICtrlCreateMenu("管理功能")
$MenuItem103 = GUICtrlCreateMenuItem("用户管理", $MenuItem2)
$MenuItem104 = GUICtrlCreateMenuItem("OEM信息", $MenuItem2)
$MenuItem3 = GUICtrlCreateMenu("关于程序")

; 创建 组框:"搜索"
$SearchGroup = GUICtrlCreateGroup("", 10, 2, 235, 44)
$SearchText = GUICtrlCreateInput("", 21, 14, 130, 25) ;创建搜索文本框
GUICtrlSetFont(-1, 10, 400, 0, "微软雅黑")
$SearchBtn = GUICtrlCreateButton("查找", 155, 13, 80, 27) ;创建查找按钮
GUICtrlSetFont(-1, 10, 400, 0, "微软雅黑")

; 创建 组框:"连接按钮"
$BtnGroup = GUICtrlCreateGroup("", 250, 2, 700, 44)
$AddHostBtn = GUICtrlCreateButton("添加主机", 260, 13, 100, 27) ;"添加主机"按钮
GUICtrlSetFont(-1, 10, 400, 0, "微软雅黑")
$AddGroupBtn = GUICtrlCreateButton("添加分组", 370, 13, 100, 27) ;"添加分组"按钮
GUICtrlSetFont(-1, 10, 400, 0, "微软雅黑")
$EditHostBtn = GUICtrlCreateButton("修改主机", 480, 13, 100, 27) ;"修改主机"按钮
GUICtrlSetState(-1, $GUI_DISABLE)
GUICtrlSetFont(-1, 10, 400, 0, "微软雅黑")
$DelHostBtn = GUICtrlCreateButton("删除主机", 590, 13, 100, 27) ;"删除主机"按钮
GUICtrlSetState(-1, $GUI_DISABLE)
GUICtrlSetFont(-1, 10, 400, 0, "微软雅黑")

; 创建 TreeView
$TreeView = GUICtrlCreateTreeView(10, 50, 235, 508, BitOR($TVS_HASBUTTONS, $TVS_HASLINES, $TVS_LINESATROOT, $TVS_DISABLEDRAGDROP, $TVS_SHOWSELALWAYS), $WS_EX_CLIENTEDGE)
$Group = GUICtrlCreateTreeViewItem("已分组服务器列表", $TreeView) ;创建TreeView项目
GUICtrlSetColor(-1, 0xff0000)
GUICtrlSetState(-1, BitOR($GUI_EXPAND, $GUI_DEFBUTTON)) ;设置TreeView样式
;~ _GUICtrlTreeView_SetLineColor($TreeView, 0xff0000)

; 创建 ListView
$ListView = GUICtrlCreateListView("", 250, 50, 700, 310)
_GUICtrlListView_AddColumn($ListView, "名称", 140) ;创建列
_GUICtrlListView_AddColumn($ListView, "隶属分组", 120) ;创建列
_GUICtrlListView_AddColumn($ListView, "IP", 110) ;创建列
_GUICtrlListView_AddColumn($ListView, "端口", 60) ;创建列
_GUICtrlListView_AddColumn($ListView, "备注", 240) ;创建列
_GUICtrlListView_SetExtendedListViewStyle($ListView, BitOR($LVS_EX_FULLROWSELECT, $LVS_EX_GRIDLINES)) ;设置ListView样式
;~ GUICtrlSetColor($ListView , 0xff7f24)

; 创建 组框:"手动运行"
$SoftGroup = GUICtrlCreateGroup(" 手动运行 ", 250, 365, 345, 194)
GUICtrlSetFont(-1, 10, 400, 0, "微软雅黑")
; 创建 组框:"Mstsc 选项"
$MstscGroup = GUICtrlCreateGroup(" Mstsc 选项 ", 600, 365, 350, 97)
GUICtrlSetFont(-1, 10, 400, 0, "微软雅黑")
; 创建 组框:"Radmin 中转"
$RadminGroup = GUICtrlCreateGroup(" Radmin 中转 ", 600, 462, 350, 97)
GUICtrlSetFont(-1, 10, 400, 0, "微软雅黑")

; 创建 状态栏
$StatusBar = _GUICtrlStatusBar_Create($Form1)
Dim $StatusBar_PartsWidth =
_GUICtrlStatusBar_SetParts($StatusBar, $StatusBar_PartsWidth)
_GUICtrlStatusBar_SetText($StatusBar, "总计分组:         组", 0)
$GroupCountLabel = GUICtrlCreateLabel("8888", 70, 574, 28, 16, $SS_RIGHT)
GUICtrlSetFont(-1, 9, 400, 0, "微软雅黑")
GUICtrlSetColor(-1, 0x1c86ee)
_GUICtrlStatusBar_SetText($StatusBar, "主机数量:         台", 1)
$HostCountLabel = GUICtrlCreateLabel("8888", 210, 574, 28, 16, $SS_RIGHT)
GUICtrlSetFont(-1, 9, 400, 0, "微软雅黑")
GUICtrlSetColor(-1, 0x1c86ee)
_GUICtrlStatusBar_SetText($StatusBar, "当前用户:", 2)
$CurrentUserLabel = GUICtrlCreateLabel("wangzhongheng123", 350, 574, 120, 16)
GUICtrlSetFont(-1, 9, 400, 0, "微软雅黑")
GUICtrlSetColor(-1, 0x1c86ee)
_GUICtrlStatusBar_SetText($StatusBar, ""& $OemInfo, 3)
_GUICtrlStatusBar_SetText($StatusBar, "By XXX.      版本:V1.0", 4)
_GUICtrlStatusBar_SetMinHeight($StatusBar, 25)
GUISetState(@SW_SHOW)
;======================== ;;; 结束:创建程序主窗口 ;;; ========================

;======================== ;;; 开始:创建托盘菜单、注册托盘事件 ;;; ========================
; 创建 托盘菜单
$TrayAbout = TrayCreateItem("关于程序")
TrayCreateItem("") ;菜单分隔条
$TrayView = TrayCreateItem("显示主窗口")
TrayCreateItem("") ;菜单分隔条
$TrayExit = TrayCreateItem("退出")

; 注册 托盘菜单事件
TraySetOnEvent($TRAY_EVENT_PRIMARYDOUBLE, "TrayEvent") ; 注册托盘图标双击事件
TrayItemSetOnEvent($TrayAbout, "TrayEvent") ; 注册托盘菜单"关于程序"事件
TrayItemSetOnEvent($TrayView, "TrayEvent") ; 注册托盘菜单"显示界面"事件
TrayItemSetOnEvent($TrayExit, "TrayEvent") ; 注册托盘菜单"退出"事件
TraySetState(1) ; 显示托盘图标
TraySetClick(16) ; 释放鼠标右键(显示托盘菜单)
TraySetToolTip("远程集中管理") ; 设置托盘图标的提示文本
;======================== ;;; 结束:创建托盘菜单、注册托盘事件 ;;; ========================

GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY") ;注册鼠标事件
Call(ConnectDB)

; 读取 分组列表
$RS = ObjCreate("ADODB.Recordset")
$RS.ActiveConnection = $Conn
$RS.Open("Select * From " & $TableGroup & " Order By GroupName")

While Not $RS.eof And Not $RS.bof
        If @error = 1 Then ExitLoop
        ReDim $GroupItem[$iS + 1] ;数组大小 +1
        $GroupItem[$iS] = GUICtrlCreateTreeViewItem($RS.Fields(1).value, $Group)
;~         GUICtrlSetColor(-1 , 0x006400)
        $iS += 1
        $RS.movenext
WEnd

GUICtrlSetData($GroupCountLabel, UBound($GroupItem)) ;设置总计分组label
_GUICtrlTreeView_Expand($TreeView, $Group)
_GUICtrlTreeView_SelectItemByIndex($TreeView, $Group, 0)

While 1
        $nMsg = GUIGetMsg()
        Switch $nMsg
                Case $GUI_EVENT_CLOSE
                        $RS.close
                        $Conn.Close
                        Exit
;~                Case $GroupItem To $GroupItem ;TreeView列表点击事件
                       
                Case $TreeEdit
                        If$TreeEdit <> 0 Then
                                MsgBox(0, "", "点击了<编辑分组>按钮")
                        Else
                                MsgBox(0, "", $nMsg)
                        EndIf
                Case $TreeDelete
                        MsgBox(0, "", "点击了<删除分组>按钮")
        EndSwitch
WEnd

;=============== 函数 - 定义 ===============
Func ConnectDB()   ;连接数据库
        $DbPath = @ScriptDir & "\" & "Data.mdb"
        ;~ $mdbpass = "traveler@)!^"
        $DbPass = "123"
        $TableGroup = "TB_Group"
        $TableServer = "TB_Server"
        $TableUsers = "TB_Users"
        $Conn = ObjCreate("ADODB.Connection")
        $Conn.Open("Provider=Microsoft.Jet.OLEDB.4.0; Data Source=" & $DbPath & "; Jet OLEDB:Database Password=" & $DbPass)
EndFunc   ;==>ConnectDB

Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
        #forceref $hWnd, $iMsg, $iwParam
        Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $hWndListView, $tInfo
        $hWndListView = $ListView
        $hWndTreeView = $TreeView
        If Not IsHWnd($ListView) Then $hWndListView = GUICtrlGetHandle($ListView)
        If Not IsHWnd($TreeView) Then $hWndTreeView = GUICtrlGetHandle($TreeView)

        $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_CLICK ; 鼠标左键单击项目时由控件发送
                                        $rPos = _WinAPI_GetMousePos(True, $hWndTreeView)
                                        $rSel = _GUICtrlTreeView_HitTestItem($hWndTreeview, DllStructGetData($rPos, "X"), DllStructGetData($rPos, "Y"))
                                        If $rSel = 0 Then
                                                Return $GUI_RUNDEFMSG
                                        Else
                                                _GUICtrlListView_DeleteAllItems($ListView)
                                        EndIf
                                        _GUICtrlTreeView_SelectItem($hWndTreeview, $rSel)
                                        $SelectedItemIndex = _GUICtrlTreeView_Index($hWndTreeview, $rSel)
                                       
                                        $RS = ObjCreate("ADODB.Recordset")
                                        $RS.ActiveConnection = $Conn
                                        $RS.Open("Select * From " & $TableServer & " Where Groups='" & _GUICtrlTreeView_GetText($TreeView, $GroupItem[$SelectedItemIndex]) & "'")

                                        While Not $RS.eof And Not $RS.bof
                                                If @error = 1 Then ExitLoop
                                                GUICtrlCreateListViewItem($RS.Fields(1).value & "|" & $RS.Fields(7).value & "|" & $RS.Fields(2).value & "|" & $RS.Fields(3).value & "|" & $RS.Fields(9).value, $ListView )
                                                $RS.movenext
                                        WEnd
                               
                                        GUICtrlSetData($HostCountLabel, _GUICtrlListView_GetItemCount($ListView)) ;设置总计主机label
                                Case $NM_DBLCLK ; 鼠标左键双击项目时由控件发送
                                        MsgBox(0, "", "双击了<左键>")
                                Case $NM_RCLICK ; 鼠标右键单击项目时由控件发送
                                        $rPos = _WinAPI_GetMousePos(True, $hWndTreeView)
                                        $rSel = _GUICtrlTreeView_HitTestItem($hWndTreeview, DllStructGetData($rPos, "X"), DllStructGetData($rPos, "Y"))
                                        If $rSel = 0 Then Return $GUI_RUNDEFMSG
                                        _GUICtrlTreeView_SelectItem($hWndTreeview, $rSel)
                                        $SelectedItemIndex = _GUICtrlTreeView_Index($hWndTreeview, $rSel)
                                       
                                        $TreeContext = GUICtrlCreateContextMenu($GroupItem[$SelectedItemIndex])
                                        $TreeEdit = GUICtrlCreateMenuItem("编辑分组", $TreeContext)
                                        GUICtrlCreateMenuItem("", $TreeContext) ; 分割线
                                        $TreeDelete = GUICtrlCreateMenuItem("删除分组", $TreeContext)
                                        $a = $TreeEdit
                        EndSwitch
                Case $hWndListView
                        Switch $iCode
                                Case $NM_CLICK ; 鼠标左键单击项目时由控件发送
                                        $index = _GUICtrlListView_GetSelectedIndices($ListView)
                                        If $index <> "" Then
;~                                                 MsgBox(0, "", "单击了<左键>")
                                                GUICtrlSetState($EditHostBtn, $GUI_ENABLE)
                                                GUICtrlSetState($DelHostBtn, $GUI_ENABLE)
                                        Else
                                                GUICtrlSetState($EditHostBtn, $GUI_DISABLE)
                                                GUICtrlSetState($DelHostBtn, $GUI_DISABLE)
                                        EndIf
                                Case $NM_DBLCLK ; 鼠标左键双击项目时由控件发送
                                        MsgBox(0, "", "双击了<左键>")
                                Case $NM_RCLICK ; 鼠标右键单击项目时由控件发送
                                        MsgBox(0, "", _GUICtrlListView_GetSelectedIndices($ListView))
                        EndSwitch
        EndSwitch
        Return $GUI_RUNDEFMSG
EndFunc;==>WM_NOTIFY

Func TrayEvent() ;托盘事件
        Switch @TRAY_ID
                Case $TrayAbout
                        Call("About")
                Case $TrayView, $TRAY_EVENT_PRIMARYDOUBLE
                        GUISetState(@SW_SHOW, $Form1)
                        GUISetState(@SW_RESTORE, $Form1)
                Case $TrayExit
                        Exit
        EndSwitch
EndFunc

Func About()
        GUISetState(@SW_RESTORE, $Form1)
        GUISetState(@SW_DISABLE ,$Form1)
        Msgbox(64, "关于程序","远程集中管理(控制台)   V1.0 ", 0)
        GUISetState(@SW_ENABLE ,$Form1)
        GUISetState(@SW_RESTORE, $Form1)
EndFunc

chzj589 发表于 2016-8-30 21:04:48

回复 10# imutraveler
我用事件模式

imutraveler 发表于 2016-8-30 23:45:32

回复 11# chzj589


    说实话,看得我是一脸懵逼,只是略懂一点,之前自己写过小工具,非常简单那种,也改过别人代码。
第一次自己从头开始写,真是困难重重啊,每一个功能都是一个要学习的难点,哎!

nmgwddj 发表于 2016-8-31 08:24:39

这样自己进步才会很快,加油。

chzj589 发表于 2016-8-31 09:13:25

回复 12# imutraveler
不会吧,我只是加了GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY") 和
GUIRegisterMsg($WM_COMMAND, "WM_COMMAND"),
修改了:
        ;右键菜单
        $Menu = GUICtrlCreateContextMenu($TreeView)
        $rclk = GUICtrlCreateMenuItem("编辑分组", $Menu)
        GUICtrlCreateMenuItem("", $Menu) ; 分割线
        $rclka = GUICtrlCreateMenuItem("删除分组", $Menu)
把循环模式改为事件模式。
因事件模式要再添加窗口,增加功能比较好操作。个人认为。

imutraveler 发表于 2016-8-31 17:10:50

回复 14# chzj589


    嗯,看到了,只是我还是希望右键菜单是创建在Item上的,就是右键点击“以分组服务器”应该没有反映。
页: [1] 2 3
查看完整版本: TreeView子项目上创建右键菜单问题?求助!(已解决)