kxing 发表于 2010-3-18 21:55:22

关于上下文菜单的问题

请问下高手们怎样触发不同的上下文菜单呢
如下面这段代码,上下文菜单中有多条项目,但是触发事件都一样的。
主要是看不懂这个函数,不然也不来麻烦大家了。
#include <GUIMenu.au3>
#include <GuiConstantsEx.au3>
#include <GuiTreeView.au3>
#include <WindowsConstants.au3>

GUICreate("test", 400, 300)
$iTree = GUICtrlCreateTreeView(5, 5, 390, 290)
$hTree = GUICtrlGetHandle($iTree)

$iContext = GUICtrlCreateContextMenu(GUICtrlCreateDummy())
$hContext = GUICtrlGetHandle($iContext)
$iMenuItem1 = GUICtrlCreateMenuItem("About", $iContext)
$iMenuItem2 = GUICtrlCreateMenuItem("Open", $iContext)

Local $aArray
For $i = 0 To 99
      $aArray[$i] = $i
      $Treeitem=GUICtrlCreateTreeViewItem("Item " & ($i + 1), $iTree)
      Assign("." & GUICtrlGetHandle(-1), $i+1)
Next
GUISetState()
GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")

While GUIGetMsg() <> -3
WEnd


Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
      Local $tNMTV, $iCode, $hItem

      $tNMTV = DllStructCreate($tagNMTVDISPINFO, $ilParam)
      $iCode = DllStructGetData($tNMTV, "Code")

      If ($iCode = $NM_DBLCLK) Then
                $hItem = _GUICtrlTreeView_GetSelection($iTree)
                Msgbox(0, $hItem, Eval("." & $hItem))
      ElseIf ($iCode = $NM_RCLICK) Then
                Local $iX, $iY, $aXY, $tXY, $iTest, $iMenuID

                ; Converts screen coordinate to client coordinate.
                $aXY = MouseGetPos()
                $tXY = DllStructCreate("long X;long Y")
                DllStructSetData($tXY, "X", $aXY)
                DllStructSetData($tXY, "Y", $aXY)
                _WinAPI_ScreenToClient($hTree, $tXY)
                $iX = DllStructGetData($tXY, "X")
                $iY = DllStructGetData($tXY, "Y")

                $iTest = _GUICtrlTreeView_HitTest($hTree, $iX, $iY)
                If ($iTest <> 4) Then Return ; The mouse point is not hovering on an item.
                $hItem = _GUICtrlTreeView_HitTestItem($hTree, $iX, $iY)
                _GUICtrlTreeView_SelectItem($hTree, $hItem)

                $iIndex = Eval("." & $hItem)
                $iMenuId = _GUICtrlMenu_TrackPopupMenu($hContext, $hTree, -1, -1, 1, 1, 2)
                If ($iMenuId <> 0) Then Msgbox(48, "msg","Msg" & $iIndex)
                $tXY = 0

      EndIf
EndFunc   ;==>WM_NOTIFY
怎样能点item1显示信息,点item2打开文件呢?
多谢回答!!

lynfr8 发表于 2010-3-18 23:20:48

回复 1# kxing #include <GUIMenu.au3>
#include <GuiConstantsEx.au3>
#include <GuiTreeView.au3>
#include <WindowsConstants.au3>

GUICreate("test", 400, 300)
$iTree = GUICtrlCreateTreeView(5, 5, 390, 290)
$hTree = GUICtrlGetHandle($iTree)

$iContext = GUICtrlCreateContextMenu(GUICtrlCreateDummy())
$hContext = GUICtrlGetHandle($iContext)
$iMenuItem1 = GUICtrlCreateMenuItem("About", $iContext)
$iMenuItem2 = GUICtrlCreateMenuItem("Open", $iContext)

Local $aArray
For $i = 0 To 1
      $aArray[$i] = $i
      $Treeitem=GUICtrlCreateTreeViewItem("Item " & ($i + 1), $iTree)
      Assign("." & GUICtrlGetHandle(-1), $i+1)
Next
GUISetState()
GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")

While GUIGetMsg() <> -3
WEnd


Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
      Local $tNMTV, $iCode, $hItem

      $tNMTV = DllStructCreate($tagNMTVDISPINFO, $ilParam)
      $iCode = DllStructGetData($tNMTV, "Code")

      If ($iCode = $NM_DBLCLK) Then
                $hItem = _GUICtrlTreeView_GetSelection($iTree);修改这几句即可 by lynfr8
                                If Eval("." & $hItem) = 1 Then
                Msgbox(0, $hItem, '标题为点击item的句柄,而你点击的是第'&Eval("." & $hItem)&' 个item');点击第一个
                        ElseIf Eval("." & $hItem) = 2Then
                                ShellExecute("Notepad.exe");点击第二个,打开程序
                        EndIf
                       
      ElseIf ($iCode = $NM_RCLICK) Then
                Local $iX, $iY, $aXY, $tXY, $iTest, $iMenuID
                $aXY = MouseGetPos()
                $tXY = DllStructCreate("long X;long Y")
                DllStructSetData($tXY, "X", $aXY)
                DllStructSetData($tXY, "Y", $aXY)
                _WinAPI_ScreenToClient($hTree, $tXY)
                $iX = DllStructGetData($tXY, "X")
                $iY = DllStructGetData($tXY, "Y")

                $iTest = _GUICtrlTreeView_HitTest($hTree, $iX, $iY)
                If ($iTest <> 4) Then Return
                $hItem = _GUICtrlTreeView_HitTestItem($hTree, $iX, $iY)
                _GUICtrlTreeView_SelectItem($hTree, $hItem)

                $iIndex = Eval("." & $hItem)
                $iMenuId = _GUICtrlMenu_TrackPopupMenu($hContext, $hTree, -1, -1, 1, 1, 2)
                If ($iMenuId <> 0) Then Msgbox(48, "msg","Msg" & $iIndex)
                $tXY = 0

      EndIf
EndFunc   ;==>WM_NOTIFY

kxing 发表于 2010-3-19 00:00:07

楼上的朋友误会我意思了.
我要的是点击菜单触发事件,不是双击.
也就是ContextMenu,点第一个菜单显示about信息,点第二个打开记事本。

afan 发表于 2010-3-19 00:06:08

#include <GUIMenu.au3>
#include <GuiConstantsEx.au3>
#include <GuiTreeView.au3>
#include <WindowsConstants.au3>

GUICreate("test", 400, 300)
$iTree = GUICtrlCreateTreeView(5, 5, 390, 290)
$hTree = GUICtrlGetHandle($iTree)

$iContext = GUICtrlCreateContextMenu(GUICtrlCreateDummy())
$hContext = GUICtrlGetHandle($iContext)
$iMenuItem1 = GUICtrlCreateMenuItem("About", $iContext)
$iMenuItem2 = GUICtrlCreateMenuItem("Open", $iContext)

Local $aArray
For $i = 0 To 99
        $aArray[$i] = $i
        $Treeitem = GUICtrlCreateTreeViewItem("Item " & ($i + 1), $iTree)
        Assign("." & GUICtrlGetHandle(-1), $i + 1)
Next
GUISetState()
GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")

While GUIGetMsg() <> -3
WEnd


Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
        Local $tNMTV, $iCode, $hItem

        $tNMTV = DllStructCreate($tagNMTVDISPINFO, $ilParam)
        $iCode = DllStructGetData($tNMTV, "Code")

        If ($iCode = $NM_DBLCLK) Then
                $hItem = _GUICtrlTreeView_GetSelection($iTree)
                MsgBox(0, $hItem, Eval("." & $hItem))
        ElseIf ($iCode = $NM_RCLICK) Then
                Local $iX, $iY, $aXY, $tXY, $iTest, $iMenuID

                ; Converts screen coordinate to client coordinate.
                $aXY = MouseGetPos()
                $tXY = DllStructCreate("long X;long Y")
                DllStructSetData($tXY, "X", $aXY)
                DllStructSetData($tXY, "Y", $aXY)
                _WinAPI_ScreenToClient($hTree, $tXY)
                $iX = DllStructGetData($tXY, "X")
                $iY = DllStructGetData($tXY, "Y")

                $iTest = _GUICtrlTreeView_HitTest($hTree, $iX, $iY)
                If ($iTest <> 4) Then Return ; The mouse point is not hovering on an item.
                $hItem = _GUICtrlTreeView_HitTestItem($hTree, $iX, $iY)
                _GUICtrlTreeView_SelectItem($hTree, $hItem)

                $iIndex = Eval("." & $hItem)
                $iMenuID = _GUICtrlMenu_TrackPopupMenu($hContext, $hTree, -1, -1, 1, 1, 2)
                If $iMenuID = $iMenuItem1 Then MsgBox(0, "Item " & $iIndex, "About " & $iIndex)
                If $iMenuID = $iMenuItem2 Then MsgBox(0, "Item " & $iIndex, "Open " & $iIndex)
                $tXY = 0

        EndIf
EndFunc   ;==>WM_NOTIFY

kxing 发表于 2010-3-19 00:15:27

嗯嗯,刚刚解决了.

原来只是这里:
                $iMenuId = _GUICtrlMenu_TrackPopupMenu($hContext, $hTree, -1, -1, 1, 1, 2)
                If ($iMenuId = $iMenuItem1) Then Msgbox(48, "msg","第一个菜单")
                If ($iMenuId = $iMenuItem2) Then Msgbox(48, "msg","第二个菜单")

感谢上面的朋友回答,多谢!

lynfr8 发表于 2010-3-19 00:27:22

呵呵,没细看楼主的要求
这样修改亦可,原理和afan差不多

#include <GUIMenu.au3>
#include <GuiConstantsEx.au3>
#include <GuiTreeView.au3>
#include <WindowsConstants.au3>

GUICreate("test", 400, 300)
$iTree = GUICtrlCreateTreeView(5, 5, 390, 290)
$hTree = GUICtrlGetHandle($iTree)

$iContext = GUICtrlCreateContextMenu(GUICtrlCreateDummy())
$hContext = GUICtrlGetHandle($iContext)
$iMenuItem1 = GUICtrlCreateMenuItem("About", $iContext)
$iMenuItem2 = GUICtrlCreateMenuItem("Open", $iContext)

Local $aArray
For $i = 0 To 1
$aArray[$i] = $i
$Treeitem=GUICtrlCreateTreeViewItem("Item " & ($i + 1), $iTree)
Assign("." & GUICtrlGetHandle(-1), $i+1)
Next
GUISetState()
GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")

While GUIGetMsg() <> -3
WEnd


Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
Local $tNMTV, $iCode, $hItem

$tNMTV = DllStructCreate($tagNMTVDISPINFO, $ilParam)
$iCode = DllStructGetData($tNMTV, "Code")

If ($iCode = $NM_DBLCLK) Then
$hItem = _GUICtrlTreeView_GetSelection($iTree);修改这几句即可 by lynfr8
If Eval("." & $hItem) = 1 Then
Msgbox(0, $hItem, '标题为点击item的句柄,而你点击的是第'&Eval("." & $hItem)&' 个item');点击第一个
ElseIf Eval("." & $hItem) = 2 Then
ShellExecute("Notepad.exe");点击第二个,打开程序
EndIf

ElseIf ($iCode = $NM_RCLICK) Then
Local $iX, $iY, $aXY, $tXY, $iTest, $iMenuID
$aXY = MouseGetPos()
$tXY = DllStructCreate("long X;long Y")
DllStructSetData($tXY, "X", $aXY)
DllStructSetData($tXY, "Y", $aXY)
_WinAPI_ScreenToClient($hTree, $tXY)
$iX = DllStructGetData($tXY, "X")
$iY = DllStructGetData($tXY, "Y")

$iTest = _GUICtrlTreeView_HitTest($hTree, $iX, $iY)
If ($iTest <> 4) Then Return
$hItem = _GUICtrlTreeView_HitTestItem($hTree, $iX, $iY)
_GUICtrlTreeView_SelectItem($hTree, $hItem)

$iIndex = Eval("." & $hItem)
$iMenuId = _GUICtrlMenu_TrackPopupMenu($hContext, $hTree, -1, -1, 1, 1, 2)
If ($iMenuId=6 ) Then Msgbox(0, "显示about信息","ContextMenu,点第一个菜单显示about信息");修改这里即可
If ($iMenuId=7 ) Then ShellExecute("Notepad.exe");");修改这里即可
$tXY = 0

EndIf
EndFunc ;==>WM_NOTIFY

kxing 发表于 2010-3-19 00:27:58

在问下afan老大,怎么键盘上的application不能弹出菜单呢
按道理来说这个application也是右键啊!需要怎么做才能相当于鼠标的右键弹出菜单呢

lynfr8 发表于 2010-3-19 00:58:26

A4 左 MENU(菜单) 键
A5 右 MENU(菜单) 键
...
ElseIf ($iCode = $NM_RCLICK) Or _IsPressed( 'A5')Then
...没成功

貌似A5无法检测,不知道是否个人键盘问题还是bug
各位可以试试:
#include <Misc.au3>
$dll = DllOpen("user32.dll")
While 1
    Sleep ( 250 )
    If _IsPressed("A5", $dll) Then
      MsgBox(0,"_IsPressed", "End Key Pressed")
      ExitLoop
    EndIf
WEnd
DllClose($dll)

l5mygirl 发表于 2010-3-19 09:28:59

路过,顺便学习下......

kxing 发表于 2010-3-19 10:38:54

嘿嘿感谢了,马上去看看.

kxing 发表于 2010-3-19 10:43:09

测试了,a5确实不行。
a4我键盘没有,哈哈!!!!
有其他方法实现这样的激活菜单吗?

kxing 发表于 2010-3-19 19:10:38

楼上的朋友你误会了.
我要的是ctrl旁边的那个application菜单键。
不是左右都有的那个alt,我还说呢,怎么有两个application。
这个alt我测试了,左右都正常,不过我希望要的是application。
麻烦楼上的朋友看看有没相关的资料,多谢!!!

menfan 发表于 2010-3-20 11:30:55

呵呵,学习一下。。

jonyzhr 发表于 2010-5-2 20:09:16

还是不明白,哎,努力学
页: [1]
查看完整版本: 关于上下文菜单的问题