【已解决】Treeview树形列表通过事件判断点击项目会响应上一个项目
本帖最后由 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
我想实现分别点击项目执行不同功能,请教解决方法。
是这样子吗?
#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
chzj589 发表于 2020-3-2 17:32
是这样子吗?
感谢回复!!通过坐标来判断还没用过,又学习到了,非常感谢。
另外我在你的基础上修改了下,用树视图项目(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
本帖最后由 floor6ggg 于 2020-3-4 07:28 编辑
http://www.autoitx.com/thread-15253-2-1.html
解法2:可以参考pusofalse大的$TVN_SELCHANGEDW 的方法 测试是可以准确显示出点击的项目名称的
#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 TVN_SELCHANGED:当所选项目已经改变时,才发送此通知,截取TVN_SELCHANGED是正确的。 本帖最后由 floor6ggg 于 2020-3-4 07:28 编辑
解法3:
Melba23大神在官网的论述,我也看不懂,好在现在的翻译软件很发达…………
https://www.autoitscript.com/for ... ents#comment-676043 #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 巧妙的通过$fClicked返回的while循环里面,此时的_GUICtrlTreeView_GetText是准确的…………这种解法也挺赞 本帖最后由 floor6ggg 于 2020-3-4 07:29 编辑
解法4567………………等待高人后续补充………… floor6ggg 发表于 2020-3-3 23:54
测试是可以准确显示出点击的项目名称的
都试了下,个人感觉解法二最赞,准确且代码简单
其中这条可以不需要:
_TreeView_GetText($hTreeView)
解法三很巧妙,但是需要额外代码来辅助,没有解法二简单粗暴
感谢帮忙
页:
[1]