找回密码
 加入
搜索
查看: 2645|回复: 10

[AU3基础] 【已解决】Treeview树形列表通过事件判断点击项目会响应上一个项目

[复制链接]
发表于 2020-3-2 14:58:19 | 显示全部楼层 |阅读模式
本帖最后由 sh1536 于 2020-3-2 18:07 编辑

请教问什么通过WM_NOTIFY来捕获点击了哪个项目时,不是响应点击的这个,而是响应的上一个被选中的项目?

如图,我点击了项目二,但是响应的是点击了项目一



#include <TreeViewConstants.au3>
#include <GUIConstants.au3>
#include <GuiTreeView.au3>
#Region
$Form1 = GUICreate("Form1", 600, 400, -1, -1)
$TreeView = GUICtrlCreateTreeView(6, 6, 150, 386, BitOR($TVS_HASBUTTONS, $TVS_HASLINES, $TVS_LINESATROOT, $TVS_DISABLEDRAGDROP, $TVS_SHOWSELALWAYS, 0x8000)) ;去掉横向滑块
$TreeViewItem1 = GUICtrlCreateTreeViewItem("项目1", $TreeView)
$TreeViewItem2 = GUICtrlCreateTreeViewItem("项目2", $TreeView)
$TreeViewItem3 = GUICtrlCreateTreeViewItem("项目3", $TreeView)

GUISetState(@SW_SHOW)
GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY") ;捕捉窗口控件交互时事件
#EndRegion

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

Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam) ;捕捉窗口控件交互时事件
        Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR
        $tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
        $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
        $iIDFrom = DllStructGetData($tNMHDR, "IDFrom")
        $iCode = DllStructGetData($tNMHDR, "Code")
        Switch $hWnd
                Case $Form1
                        _Form1_NOTIFY($hWnd, $iIDFrom, $iCode, $ilParam)
        EndSwitch
        Return $GUI_RUNDEFMSG
EndFunc

Func _Form1_NOTIFY($hWnd, $iControl, $iMsg, $ilParam) ;捕捉窗口事件
        Local $Index
        Switch $iControl
                Case $TreeView
                        Switch $iMsg
                                Case $NM_CLICK ;左键单击
                                        ;If _GUICtrlTreeView_GetSelected($TreeView, $TreeViewItem0) Then
                                        MsgBox(0, 0, "单击了" & GUICtrlRead($TreeView, 1), 0, $Form1)
                                        ;EndIf
                                Case $NM_RCLICK ;右键单击事件

                        EndSwitch
        EndSwitch
EndFunc
我想实现分别点击项目执行不同功能,请教解决方法。

本帖子中包含更多资源

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

×
发表于 2020-3-2 17:32:14 | 显示全部楼层
是这样子吗?

#include <TreeViewConstants.au3>
#include <GUIConstants.au3>
#include <GuiTreeView.au3>
#Region
$Form1 = GUICreate("Form1", 600, 400, -1, -1)
$TreeView = GUICtrlCreateTreeView(6, 6, 150, 386, BitOR($TVS_HASBUTTONS, $TVS_HASLINES, $TVS_LINESATROOT, $TVS_DISABLEDRAGDROP, $TVS_SHOWSELALWAYS, 0x8000)) ;去掉横向滑块
$TreeViewItem1 = GUICtrlCreateTreeViewItem("项目1", $TreeView)
$TreeViewItem2 = GUICtrlCreateTreeViewItem("项目2", $TreeView)
$TreeViewItem3 = GUICtrlCreateTreeViewItem("项目3", $TreeView)
GUISetState(@SW_SHOW)
GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY") ;捕捉窗口控件交互时事件
#EndRegion
While 1
        $nMsg = GUIGetMsg()
        Switch $nMsg
                Case $GUI_EVENT_CLOSE
                        Exit
        EndSwitch
WEnd
Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam) ;捕捉窗口控件交互时事件
        #forceref $hWnd, $iMsg, $iwParam
        Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $hWndListView, $tInfo
        Local $hWndTreeView = $TreeView
        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 ; 鼠标左键单击
                                        Local $mPos = _WinAPI_GetMousePos(True, $hWndTreeView)
                                        Local $mText = _GUICtrlTreeView_HitTestItem($hWndTreeView, DllStructGetData($mPos, "X"), DllStructGetData($mPos, "Y"))
                                        Local $iPos = _GUICtrlTreeView_HitTest($hWndTreeView, DllStructGetData($mPos, "X"), DllStructGetData($mPos, "Y"))
                                        Local $cText = _GUICtrlTreeView_GetText($hWndTreeView, $mText) ;获得当前坐标项目文本
                                        MsgBox(0, 0, "单击了" & $cText)
                        EndSwitch
        EndSwitch
        Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY

评分

参与人数 1金钱 +10 收起 理由
sh1536 + 10 感谢帮忙!

查看全部评分

 楼主| 发表于 2020-3-2 18:05:29 | 显示全部楼层

感谢回复!!通过坐标来判断还没用过,又学习到了,非常感谢。



另外我在你的基础上修改了下,用树视图项目(TreeViewItem)控件创建时的控件ID来判断点击了哪一个项目,用文本来判断我感觉不利于后续程序迭代。修改后的源码在下面:
#include <TreeViewConstants.au3>
#include <GUIConstants.au3>
#include <GuiTreeView.au3>
#Region
$Form1 = GUICreate("Form1", 600, 400, -1, -1)
$TreeView = GUICtrlCreateTreeView(6, 6, 150, 386, BitOR($TVS_HASBUTTONS, $TVS_HASLINES, $TVS_LINESATROOT, $TVS_DISABLEDRAGDROP, $TVS_SHOWSELALWAYS, 0x8000)) ;去掉横向滑块
$TreeViewItem1 = GUICtrlCreateTreeViewItem("项目1", $TreeView)
$TreeViewItem2 = GUICtrlCreateTreeViewItem("项目2", $TreeView)
$TreeViewItem3 = GUICtrlCreateTreeViewItem("项目3", $TreeView)
GUISetState(@SW_SHOW)
GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY") ;捕捉窗口控件交互时事件
#EndRegion
While 1
        $nMsg = GUIGetMsg()
        Switch $nMsg
                Case $GUI_EVENT_CLOSE
                        Exit
        EndSwitch
WEnd
Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam) ;捕捉窗口控件交互时事件
        #forceref $hWnd, $iMsg, $iwParam
        Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $hWndListView, $tInfo
        Local $hWndTreeView = $TreeView
        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 ; 鼠标左键单击
                                        Local $mPos = _WinAPI_GetMousePos(True, $hWndTreeView)
                                        Local $mText = _GUICtrlTreeView_HitTestItem($hWndTreeView, DllStructGetData($mPos, "X"), DllStructGetData($mPos, "Y"))
                                        ;Local $iPos = _GUICtrlTreeView_HitTest($hWndTreeView, DllStructGetData($mPos, "X"), DllStructGetData($mPos, "Y"))
                                        ;Local $cText = _GUICtrlTreeView_GetText($hWndTreeView, $mText) ;获得当前坐标项目文本
                                        ;MsgBox(0, 0, "单击了" & $cText)

                                        Switch $mText
                                                Case _GUICtrlTreeView_GetItemHandle($TreeView, $TreeViewItem1)
                                                        MsgBox(0, 0, "单击了项目一")
                                                Case _GUICtrlTreeView_GetItemHandle($TreeView, $TreeViewItem2)
                                                        MsgBox(0, 0, "单击了项目二")
                                                Case _GUICtrlTreeView_GetItemHandle($TreeView, $TreeViewItem3)
                                                        MsgBox(0, 0, "单击了项目三")
                                        EndSwitch
                        EndSwitch
        EndSwitch
        Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY
发表于 2020-3-3 23:48:59 | 显示全部楼层
本帖最后由 floor6ggg 于 2020-3-4 07:28 编辑

http://www.autoitx.com/thread-15253-2-1.html
解法2:可以参考pusofalse大的  $TVN_SELCHANGEDW 的方法
发表于 2020-3-3 23:54:26 | 显示全部楼层
测试是可以准确显示出点击的项目名称的
#include <GuiConstantsEx.au3>
#include <GuiTreeView.au3>
#include <GuiImageList.au3>
#include <WindowsConstants.au3>
Global $fClicked = False

#region ### START Koda GUI section ### Form=C:\Documents and Settings\Administrator\Desktop\Linkget\Linkget.kxf
$GUI = GUICreate("", 676, 378, 203, 289)
$hTreeView = _GUICtrlTreeView_Create($GUI, 2, 2, 161, 227)

_GUICtrlTreeView_BeginUpdate($hTreeView)
For $x = 1 To Random(2, 10, 1)
    $hItem = _GUICtrlTreeView_Add($hTreeView, 0, StringFormat("[%02d] New Item", $x))
Next
_GUICtrlTreeView_EndUpdate($hTreeView)

GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
GUISetState(@SW_SHOW)
#endregion ### START Koda GUI section ### Form=C:\Documents and Settings\Administrator\Desktop\Linkget\Linkget.kxf


Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
    #forceref $hWnd, $iMsg, $iwParam
    Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $hWndTreeview
    $hWndTreeview = $hTreeView
    If Not IsHWnd($hTreeView) Then $hWndTreeview = GUICtrlGetHandle($hTreeView)

    $tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
    $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
    $iIDFrom = DllStructGetData($tNMHDR, "IDFrom")
    $iCode = DllStructGetData($tNMHDR, "Code")
    Switch $hWndFrom
        Case $hWndTreeview
            Switch $iCode
                                Case $TVN_SELCHANGEDW
                                                ConsoleWrite(@ScriptLineNumber&"WM_NOTIFY:-->$TVN_SELCHANGEDW: " &_GUICtrlTreeView_GetText($hWndTreeview, _GUICtrlTreeView_GetSelection($hWndTreeview))& @LF)
                                        Return 0 ; zero to allow the default processing
            EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit
        Case Else
            If $fClicked = True Then
                _TreeView_GetText($hTreeView)
                $fClicked = False
            EndIf
    EndSwitch
WEnd

评分

参与人数 1金钱 +10 收起 理由
sh1536 + 10 赞一个!

查看全部评分

发表于 2020-3-3 23:55:52 | 显示全部楼层
TVN_SELCHANGED:当所选项目已经改变时,才发送此通知,截取TVN_SELCHANGED是正确的。
发表于 2020-3-4 00:00:40 | 显示全部楼层
本帖最后由 floor6ggg 于 2020-3-4 07:28 编辑

解法3:
Melba23大神在官网的论述,我也看不懂,好在现在的翻译软件很发达…………
https://www.autoitscript.com/for ... ents#comment-676043
发表于 2020-3-4 00:01:43 | 显示全部楼层
#include <GuiConstantsEx.au3>
#include <GuiTreeView.au3>
#include <GuiImageList.au3>
#include <WindowsConstants.au3>
;~ #include <Array.au3>
Global $fClicked = False

#region ### START Koda GUI section ### Form=C:\Documents and Settings\Administrator\Desktop\Linkget\Linkget.kxf
$GUI = GUICreate("", 676, 378, 203, 289)
$hTreeView = _GUICtrlTreeView_Create($GUI, 2, 2, 161, 227)

_GUICtrlTreeView_BeginUpdate($hTreeView)
For $x = 1 To Random(2, 10, 1)
    $hItem = _GUICtrlTreeView_Add($hTreeView, 0, StringFormat("[%02d] New Item", $x))
Next
_GUICtrlTreeView_EndUpdate($hTreeView)

;~  _ArrayDisplay($hItem,'')

GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
GUISetState(@SW_SHOW)
#endregion ### START Koda GUI section ### Form=C:\Documents and Settings\Administrator\Desktop\Linkget\Linkget.kxf

Func _TreeView_GetText(ByRef $hWndTreeview)
    ConsoleWrite(@ScriptLineNumber&"_TreeView_GetText:-->Selection Text: " & _GUICtrlTreeView_GetText($hWndTreeview, _GUICtrlTreeView_GetSelection($hWndTreeview))& @LF)
EndFunc   ;==>_TreeView_GetText

Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
    #forceref $hWnd, $iMsg, $iwParam
    Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $hWndTreeview
    $hWndTreeview = $hTreeView
    If Not IsHWnd($hTreeView) Then $hWndTreeview = GUICtrlGetHandle($hTreeView)

    $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 ; The user has clicked the left mouse button within the control

                    ConsoleWrite("$NM_CLICK" & @LF & "--> hWndFrom:" & @TAB & $hWndFrom & @LF & _
                            "-->IDFrom:" & @TAB & $iIDFrom & @LF & _
                            "-->Code:" & @TAB & $iCode & @LF)
                                                        ConsoleWrite(@ScriptLineNumber&"WM_NOTIFY:-->Selection Text: " & _GUICtrlTreeView_GetText($hWndTreeview, _GUICtrlTreeView_GetSelection($hWndTreeview))& @LF)
                    $fClicked = True
                    Return 0 ; zero to allow the default processing
            EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY

While 1
    $nMsg = GUIGetMsg()
    Switch $nMsg
        Case $GUI_EVENT_CLOSE
            Exit
        Case Else
            If $fClicked = True Then
                _TreeView_GetText($hTreeView)
                $fClicked = False
            EndIf
    EndSwitch
WEnd
发表于 2020-3-4 00:10:45 | 显示全部楼层
巧妙的通过$fClicked返回的while循环里面,此时的_GUICtrlTreeView_GetText是准确的…………这种解法也挺赞
发表于 2020-3-4 00:11:17 | 显示全部楼层
本帖最后由 floor6ggg 于 2020-3-4 07:29 编辑

解法4567………………等待高人后续补充…………
 楼主| 发表于 2020-3-28 16:05:49 | 显示全部楼层
floor6ggg 发表于 2020-3-3 23:54
测试是可以准确显示出点击的项目名称的

都试了下,个人感觉解法二最赞,准确且代码简单
其中这条可以不需要:
 _TreeView_GetText($hTreeView)
解法三很巧妙,但是需要额外代码来辅助,没有解法二简单粗暴
感谢帮忙
您需要登录后才可以回帖 登录 | 加入

本版积分规则

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

GMT+8, 2024-4-26 12:38 , Processed in 0.079573 second(s), 21 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

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