shuren88 发表于 2012-3-21 22:32:50

难题:在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

zch11230 发表于 2012-3-21 23:02:38

$TVN_SELCHANGEDA, $TVN_SELCHANGEDW这两个是什么样的通知我不清楚但改成$NM_RCLICK就是右键了

shuren88 发表于 2012-3-21 23:12:37

直接改为$NM_RCLICK,我先就已经试验了,不行。我右键单击了某项,比如Other,它始终显示原先选中的项目General,见下图。也就是说,右键单击了某项不能选择项目,更不能显示选择的项目名称,这真是个难题。

netegg 发表于 2012-3-21 23:21:34

回复 3# shuren88
_GUICtrlTreeView_GetFocused/_GUICtrlTreeView_GetSelected/_GUICtrlTreeView_GetSelection
_GUICtrlTreeView_GetText

shuren88 发表于 2012-3-21 23:30:47

本帖最后由 shuren88 于 2012-3-21 23:33 编辑

回复 4# netegg

老大,这几个函数的前提都是需要事先知道要选中项目的信息,再进行设置。我希望解决的问题是右键选中项目并得到项目信息。这几个函数我都试验过,不能解决右键选中项目的问题。

netegg 发表于 2012-3-21 23:51:36

本帖最后由 netegg 于 2012-3-21 23:53 编辑

回复 5# shuren88

上面那三个函数用来枚举指定条件的项,获取项索引或者句柄,然后就出来了
如果觉得这样麻烦,就用消息,获取点击消息,然后获取文本
不过最终还是要获取到项目句柄或索引

shuren88 发表于 2012-3-22 00:06:39

回复 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:10:56

本帖最后由 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)
不太对,脑子有点木,明天好好想吧,不麻烦

shuren88 发表于 2012-3-22 00:27:15

回复 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

user3000 发表于 2012-3-22 08:57:02

我觉得 这是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

马甲 发表于 2012-3-22 09:09:35

#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

shuren88 发表于 2012-3-22 10:11:20

非常感谢老大们的热情帮助!

shuren88 发表于 2012-3-22 11:02:48

非常感谢老大们的热情帮助!
经过测试,这种方式最优:
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]
查看完整版本: 难题:在TreeView中能否实现右键单击某项便可显示点击项目的名称?[已解决]