难题:在TreeView中能否实现右键单击某项便可显示点击项目的名称?[已解决]
本帖最后由 shuren88 于 2012-3-22 10:15 编辑以下代码可以在TreeView中实现鼠标左键单击某项,便可以显示点击项目的名称。
能否实现鼠标右键单击某项,便可以显示点击项目的名称?这是否是Autoit的TreeView中的难题?
搜索了很久没有任何蛛丝马迹,恳请大侠们不吝赐教,先谢了!#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <TreeViewConstants.au3>
#include <GuiTreeView.au3>
Local $treeview, $generalitem, $displayitem, $aboutitem, $compitem
Local $useritem, $resitem, $otheritem, $startlabel, $aboutlabel, $compinfo
Local $togglebutton, $infobutton, $statebutton, $cancelbutton
Local $msg, $item, $hItem, $text
GUICreate("My GUI with treeview", 350, 215)
$treeview = GUICtrlCreateTreeView(6, 6, 200, 180, BitOR($TVS_HASBUTTONS, $TVS_HASLINES, $TVS_LINESATROOT, $TVS_DISABLEDRAGDROP, $TVS_SHOWSELALWAYS), $WS_EX_CLIENTEDGE)
$generalitem = GUICtrlCreateTreeViewItem("General", $treeview)
GUICtrlSetColor(-1, 0x0000C0)
$displayitem = GUICtrlCreateTreeViewItem("Display", $treeview)
GUICtrlSetColor(-1, 0x0000C0)
$aboutitem = GUICtrlCreateTreeViewItem("About", $generalitem)
$compitem = GUICtrlCreateTreeViewItem("Computer", $generalitem)
$useritem = GUICtrlCreateTreeViewItem("User", $generalitem)
$resitem = GUICtrlCreateTreeViewItem("Resolution", $displayitem)
$otheritem = GUICtrlCreateTreeViewItem("Other", $displayitem)
GUICtrlSetState($generalitem, BitOR($GUI_EXPAND, $GUI_DEFBUTTON)) ; Expand the "General"-item and paint in bold
GUICtrlSetState($displayitem, BitOR($GUI_EXPAND, $GUI_DEFBUTTON)) ; Expand the "Display"-item and paint in bold
GUIRegisterMsg($WM_NOTIFY, 'MY_WM')
GUISetState()
While 1
$msg = GUIGetMsg()
Select
Case $msg = $GUI_EVENT_CLOSE
ExitLoop
EndSelect
WEnd
GUIDelete()
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 = $TreeView Then
Switch $iCode
Case $TVN_SELCHANGEDA, $TVN_SELCHANGEDW
If GUICtrlRead($TreeView) > 0 Then _
MsgBox(0, 0, 'ID: ' & GUICtrlRead($TreeView) & @CRLF & 'Text: ' & GUICtrlRead($TreeView, 1))
EndSwitch
EndIf
Return $GUI_RUNDEFMSG
EndFunc ;==>_OnNotify $TVN_SELCHANGEDA, $TVN_SELCHANGEDW这两个是什么样的通知我不清楚但改成$NM_RCLICK就是右键了 直接改为$NM_RCLICK,我先就已经试验了,不行。我右键单击了某项,比如Other,它始终显示原先选中的项目General,见下图。也就是说,右键单击了某项不能选择项目,更不能显示选择的项目名称,这真是个难题。
回复 3# shuren88
_GUICtrlTreeView_GetFocused/_GUICtrlTreeView_GetSelected/_GUICtrlTreeView_GetSelection
_GUICtrlTreeView_GetText 本帖最后由 shuren88 于 2012-3-21 23:33 编辑
回复 4# netegg
老大,这几个函数的前提都是需要事先知道要选中项目的信息,再进行设置。我希望解决的问题是右键选中项目并得到项目信息。这几个函数我都试验过,不能解决右键选中项目的问题。 本帖最后由 netegg 于 2012-3-21 23:53 编辑
回复 5# shuren88
上面那三个函数用来枚举指定条件的项,获取项索引或者句柄,然后就出来了
如果觉得这样麻烦,就用消息,获取点击消息,然后获取文本
不过最终还是要获取到项目句柄或索引 回复 6# netegg
老大,按你的思路试了一下,还是老问题,右击某项还是无法改变原来选中的项目。可以显示,但显示的任然是原来选中的项目,而非右击的项目。代码如下:#AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6
#include <GuiConstantsEx.au3>
#include <GuiTreeView.au3>
#include <WindowsConstants.au3>
Opt('MustDeclareVars', 1)
$Debug_TV = False ; Check ClassName being passed to functions, set to True and use a handle to another control to see it work
Global $hTreeView, $hItem
_Main()
Func _Main()
Local $GUI
Local $iStyle = BitOR($TVS_EDITLABELS, $TVS_HASBUTTONS, $TVS_HASLINES, $TVS_LINESATROOT, $TVS_DISABLEDRAGDROP, $TVS_SHOWSELALWAYS, $TVS_CHECKBOXES)
$GUI = GUICreate("(UDF Created) TreeView Create", 400, 300)
$hTreeView = _GUICtrlTreeView_Create($GUI, 2, 2, 396, 268, $iStyle, $WS_EX_CLIENTEDGE)
GUISetState()
GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
_GUICtrlTreeView_BeginUpdate($hTreeView)
For $x = 1 To Random(2, 10, 1)
$hItem[$x] = _GUICtrlTreeView_Add($hTreeView, 0, StringFormat("[%02d] New Item", $x))
Next
_GUICtrlTreeView_EndUpdate($hTreeView)
; Loop until user exits
Do
Until GUIGetMsg() = $GUI_EVENT_CLOSE
GUIDelete()
EndFunc ;==>_Main
Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
#forceref $hWnd, $iMsg, $iwParam
Local $hWndFrom, $iCode, $tNMHDR, $hWndTreeview;, $iIDFrom
$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
Case $NM_RCLICK
For $x = 1 To 10
If _GUICtrlTreeView_GetSelected($hTreeView, $hItem[$x]) Then
If _GUICtrlTreeView_GetChecked($hTreeView, $hItem[$x]) Then
_GUICtrlTreeView_SetChecked($hTreeView, $hItem[$x], False)
Else
_GUICtrlTreeView_SetChecked($hTreeView, $hItem[$x])
EndIf
EndIf
Next
EndSwitch
EndSwitch
Return $GUI_RUNDEFMSG
EndFunc ;==>WM_NOTIFY
Func _DebugPrint($s_text, $line = @ScriptLineNumber)
ConsoleWrite( _
"!===========================================================" & @LF & _
"+======================================================" & @LF & _
"-->Line(" & StringFormat("%04d", $line) & "):" & @TAB & $s_text & @LF & _
"+======================================================" & @LF)
EndFunc ;==>_DebugPrint 本帖最后由 netegg 于 2012-3-22 00:19 编辑
Case $NM_RCLICK ; The user has clicked the right mouse button within the control
Local $handle = _GUICtrlTreeView_GetSelection($hWndFrom)
memowrite(_GUICtrlTreeView_GetText($hWndFrom, $handle) & @CRLF)
不太对,脑子有点木,明天好好想吧,不麻烦 回复 8# netegg
老大,按你的思路试了一下,还是老问题,右击某项还是无法改变原来选中的项目。可以显示,但显示的任然是原来选中的项目,而非右击的项目。代码和图片如下:
#AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6
#include <GuiConstantsEx.au3>
#include <GuiTreeView.au3>
#include <WindowsConstants.au3>
#include <WinAPI.au3>
Opt('MustDeclareVars', 1)
$Debug_TV = False ; Check ClassName being passed to functions, set to True and use a handle to another control to see it work
Global $hTreeView, $hItem
_Main()
Func _Main()
Local $GUI
Local $iStyle = BitOR($TVS_EDITLABELS, $TVS_HASBUTTONS, $TVS_HASLINES, $TVS_LINESATROOT, $TVS_DISABLEDRAGDROP, $TVS_SHOWSELALWAYS, $TVS_CHECKBOXES)
$GUI = GUICreate("(UDF Created) TreeView Create", 400, 300)
$hTreeView = _GUICtrlTreeView_Create($GUI, 2, 2, 396, 268, $iStyle, $WS_EX_CLIENTEDGE)
GUISetState()
GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
_GUICtrlTreeView_BeginUpdate($hTreeView)
For $x = 1 To Random(2, 10, 1)
$hItem[$x] = _GUICtrlTreeView_Add($hTreeView, 0, StringFormat("[%02d] New Item", $x))
Next
_GUICtrlTreeView_EndUpdate($hTreeView)
; Loop until user exits
Do
Until GUIGetMsg() = $GUI_EVENT_CLOSE
GUIDelete()
EndFunc ;==>_Main
Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
#forceref $hWnd, $iMsg, $iwParam
Local $hWndFrom, $iCode, $tNMHDR, $hWndTreeview;, $iIDFrom
$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
;Case $NM_RCLICK
Case $NM_RCLICK ; The user has clicked the right mouse button within the control
Local $handle = _GUICtrlTreeView_GetSelection($hWndFrom)
MsgBox(0, "", _GUICtrlTreeView_GetText($hWndFrom, $handle))
For $x = 1 To 10
If _GUICtrlTreeView_GetSelected($hTreeView, $hItem[$x]) Then
If _GUICtrlTreeView_GetChecked($hTreeView, $hItem[$x]) Then
_GUICtrlTreeView_SetChecked($hTreeView, $hItem[$x], False)
Else
_GUICtrlTreeView_SetChecked($hTreeView, $hItem[$x])
EndIf
EndIf
Next
EndSwitch
EndSwitch
Return $GUI_RUNDEFMSG
EndFunc ;==>WM_NOTIFY
Func _DebugPrint($s_text, $line = @ScriptLineNumber)
ConsoleWrite( _
"!===========================================================" & @LF & _
"+======================================================" & @LF & _
"-->Line(" & StringFormat("%04d", $line) & "):" & @TAB & $s_text & @LF & _
"+======================================================" & @LF)
EndFunc ;==>_DebugPrint
Func MemoWrite($sMessage = "")
GUICtrlSetData($iMemo, $sMessage & @CRLF, 1)
EndFunc ;==>MemoWrite
我觉得 这是TreeView特性吧, 一定要用鼠标左键才可选中项目.
所以我认为稍稍变通一下吧, 点击右键时模拟点击下左键
执行效果还行.Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
#forceref $hWnd, $iMsg, $iwParam
Local $hWndFrom, $iCode, $tNMHDR, $hWndTreeview;, $iIDFrom
$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
;Case $NM_RCLICK
Case $NM_RCLICK ; The user has clicked the right mouse button within the control
Local $m, $tText, $handle
For $x = 1 To 10
_GUICtrlTreeView_SetChecked($hWndTreeview, $hItem[$x], False)
_GUICtrlTreeView_SetSelected($hWndTreeview, $hItem[$x], False)
Next
$m = MouseGetPos()
MouseClick('left', $m, $m, 1, 0)
Sleep(50)
$handle = _GUICtrlTreeView_GetSelection($hWndFrom)
$tText = _GUICtrlTreeView_GetText($hWndFrom, $handle)
_GUICtrlTreeView_SetChecked($hWndTreeview, $handle, True)
_GUICtrlTreeView_SetSelected($hWndTreeview, $handle, True)
MsgBox(0, '当前选中项', $tText)
EndSwitch
EndSwitch
Return $GUI_RUNDEFMSG
EndFunc ;==>WM_NOTIFY #AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6
#include <GuiConstantsEx.au3>
#include <GuiTreeView.au3>
#include <WindowsConstants.au3>
#include <WinAPIEx.au3>
Opt('MustDeclareVars', 1)
$Debug_TV = False ; Check ClassName being passed to functions, set to True and use a handle to another control to see it work
Global $hTreeView, $hItem,$GUI,$rPos,$rSel
_Main()
Func _Main()
;Local $GUI
Local $iStyle = BitOR($TVS_EDITLABELS, $TVS_HASBUTTONS, $TVS_HASLINES, $TVS_LINESATROOT, $TVS_DISABLEDRAGDROP, $TVS_SHOWSELALWAYS, $TVS_CHECKBOXES)
$GUI = GUICreate("(UDF Created) TreeView Create", 400, 300)
$hTreeView = _GUICtrlTreeView_Create($GUI, 2, 2, 396, 268, $iStyle, $WS_EX_CLIENTEDGE)
GUISetState()
GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
_GUICtrlTreeView_BeginUpdate($hTreeView)
For $x = 1 To Random(2, 10, 1)
$hItem[$x] = _GUICtrlTreeView_Add($hTreeView, 0, StringFormat("[%02d] New Item", $x))
Next
_GUICtrlTreeView_EndUpdate($hTreeView)
; Loop until user exits
Do
Until GUIGetMsg() = $GUI_EVENT_CLOSE
GUIDelete()
EndFunc ;==>_Main
Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
#forceref $hWnd, $iMsg, $iwParam
Local $hWndFrom, $iCode, $tNMHDR, $hWndTreeview;, $iIDFrom
$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
Case $NM_RCLICK
$rPos = _WinAPI_GetMousePos(True, $GUI)
$rSel = _GUICtrlTreeView_HitTestItem($hTreeView, DllStructGetData($rPos, "X"), DllStructGetData($rPos, "Y"))
If $rSel = 0 Then Return $GUI_RUNDEFMSG
_GUICtrlTreeView_SelectItem($hTreeView, $rSel)
EndSwitch
EndSwitch
Return $GUI_RUNDEFMSG
EndFunc ;==>WM_NOTIFY
Func _DebugPrint($s_text, $line = @ScriptLineNumber)
ConsoleWrite( _
"!===========================================================" & @LF & _
"+======================================================" & @LF & _
"-->Line(" & StringFormat("%04d", $line) & "):" & @TAB & $s_text & @LF & _
"+======================================================" & @LF)
EndFunc ;==>_DebugPrint
非常感谢老大们的热情帮助! 非常感谢老大们的热情帮助!
经过测试,这种方式最优:
Case $NM_RCLICK ;鼠标右击
$rPos = _WinAPI_GetMousePos(True, $hWndGUIFrom)
$rSel = _GUICtrlTreeView_HitTestItem($hWndTreeview, DllStructGetData($rPos, "X"), DllStructGetData($rPos, "Y"))
If $rSel = 0 Then Return $GUI_RUNDEFMSG
_GUICtrlTreeView_SelectItem($hWndTreeview, $rSel)
;Case $NM_CLICK
Case $TVN_SELCHANGEDA, $TVN_SELCHANGEDW ;鼠标左击
页:
[1]