CHEARV 发表于 2013-10-11 16:46:28

[已解决]请教,如何让为两个LISTVIEW控件创建同一个右键菜单?

本帖最后由 CHEARV 于 2013-10-12 09:40 编辑

如题,我创建了两个LISTVIEW控件,如果要为每个控件创建一个右键菜单,这个容易实现。我现在想的是,能不能给两个控件创建同一个右键菜单呢?

如果能,那后面的代码又是如何区分是哪个控件触发的事件呢?
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GuiListView.au3>
Opt("GUIOnEventMode", 1)

$Form1 = GUICreate("Test", 800, 600, 203, 80, BitOR($GUI_SS_DEFAULT_GUI, $WS_MAXIMIZEBOX, $WS_SIZEBOX, $WS_THICKFRAME, $WS_TABSTOP))
GUISetOnEvent($GUI_EVENT_CLOSE, "Form1Click")
$ListView1 = GUICtrlCreateListView("1|2|3|4", 40, 80, 640, 228, -1, $LVS_EX_GRIDLINES + $LVS_EX_FULLROWSELECT )
GUICtrlSetOnEvent($ListView1, "ListView1Click")
$ListViewA = GUICtrlCreateListView("A|B|C|D", 40, 336, 640, 236, -1, $LVS_EX_GRIDLINES + $LVS_EX_FULLROWSELECT)
GUICtrlSetOnEvent($ListViewA, "ListView1Click")
$ContextMenu = GUICtrlCreateContextMenu($ListView1)
;$ContextMenu = GUICtrlCreateContextMenu($ListViewA)
$ContextMenu1 = GUICtrlCreateMenuItem("菜单一", $ContextMenu)
GUICtrlSetOnEvent(-1, "ContextMenuClick")
$ContextMenu2 = GUICtrlCreateMenuItem("菜单二", $ContextMenu)
GUICtrlSetOnEvent(-1, "ContextMenuClick")
GUISetState(@SW_SHOW)

While 1
        Sleep(100)
WEnd

Func Form1Click()
        Exit
EndFunc
Func ListView1Click()
EndFunc       
Func ContextMenuClick()
        Switch @GUI_CtrlId
                Case $ListView1
                        Exit
                Case $ListViewA
        EndSwitch               
ENDFunc 最近参考了几个注册消息的代码,能实现上面的功能了,但不能获取产生事件的控制,哪位高手能再指点一下,我对那个注册消息的几个参数根本不懂,代码是照抄过来的。
#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GuiListView.au3>
#include<GuiMenu.au3>
Opt("GUIOnEventMode", 1)
Global Enum $id1 = 1000, $id2, $id3


$Form1 = GUICreate("Test", 800, 600, 203, 80, BitOR($GUI_SS_DEFAULT_GUI, $WS_MAXIMIZEBOX, $WS_SIZEBOX, $WS_THICKFRAME, $WS_TABSTOP))
GUISetOnEvent($GUI_EVENT_CLOSE, "Form1Click")
$ListView1 = GUICtrlCreateListView("1|2|3|4", 40, 80, 640, 228, -1, $LVS_EX_GRIDLINES + $LVS_EX_FULLROWSELECT)
$ListViewA = GUICtrlCreateListView("A|B|C|D", 40, 336, 640, 236, -1, $LVS_EX_GRIDLINES + $LVS_EX_FULLROWSELECT)

GUISetState(@SW_SHOW)
GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")
GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")

While 1
        Sleep(100)
WEnd

Func Form1Click()
        Exit
EndFunc   ;==>Form1Click


Func WM_NOTIFY($hWndGUI, $MsgID, $WParam, $LParam)
        Local $tagNMHDR, $Event, $hWndFrom, $IDFrom
        Local $tagNMHDR = DllStructCreate("int;int;int", $LParam)
        If @error Then Return $GUI_RUNDEFMSG
        $IDFrom = DllStructGetData($tagNMHDR, 2)
        $Event = DllStructGetData($tagNMHDR, 3)
        $tagNMHDR = 0
        Switch $Event; 选择产生的事件
                Case $NM_RCLICK ; 右击
                        $hMenu = _GUICtrlMenu_CreatePopup()
                        _GUICtrlMenu_AddMenuItem($hMenu, "菜单1", $id1)
                        _GUICtrlMenu_AddMenuItem($hMenu, "菜单2", $id2)
                        _GUICtrlMenu_AddMenuItem($hMenu, "菜单3", $id3)
                        _GUICtrlMenu_TrackPopupMenu($hMenu, $Form1)
                        _GUICtrlMenu_DestroyMenu($hMenu)
        EndSwitch
        Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY
Func WM_COMMAND($hWnd, $iMsg, $iwParam, $ilParam)
        Local $tagNMHDR, $Event, $hWndFrom, $IDFrom
        Local $tagNMHDR = DllStructCreate("int;int;int", $iLParam)
        ;If @error Then Return $GUI_RUNDEFMSG
        ;奇怪,这段代码是从上面移植过来的,但他好像获取不到选择产生事件的控件?谁能在这里帮我获得跟上面那段代码一样的$IDFrom吗?
        $IDFrom = DllStructGetData($tagNMHDR, 2)
        $Event = DllStructGetData($tagNMHDR, 3)
        $tagNMHDR = 0
        Switch $iwParam
                Case $id1
                        MyFunc1(1)
                Case $id2
                        MyFunc1(2)
                Case $id3
                        MyFunc1(3)
        EndSwitch
EndFunc   ;==>WM_COMMAND

CHEARV 发表于 2013-10-11 20:41:24

重新参加了一些代码,现在就卡在如何获得产生事件的控件。
我需要知道到到底是哪个Listview产生的右键。#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GuiListView.au3>
#include<GuiMenu.au3>
Opt("GUIOnEventMode", 1)
Global Enum $idOpen = 1000, $idSave, $idInfo


$Form1 = GUICreate("Test", 800, 600, 203, 80, BitOR($GUI_SS_DEFAULT_GUI, $WS_MAXIMIZEBOX, $WS_SIZEBOX, $WS_THICKFRAME, $WS_TABSTOP))
GUISetOnEvent($GUI_EVENT_CLOSE, "Form1Click")
$ListView1 = GUICtrlCreateListView("1|2|3|4", 40, 80, 640, 228, -1, $LVS_EX_GRIDLINES + $LVS_EX_FULLROWSELECT)
$ListViewA = GUICtrlCreateListView("A|B|C|D", 40, 336, 640, 236, -1, $LVS_EX_GRIDLINES + $LVS_EX_FULLROWSELECT)

GUISetState(@SW_SHOW)
GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")
GUIRegisterMsg($WM_CONTEXTMENU, "WM_CONTEXTMENU")


While 1
        Sleep(100)
WEnd

Func Form1Click()
        Exit
EndFunc   ;==>Form1Click

; WM_COMMAND消息的句柄
Func WM_COMMAND($hWnd, $iMsg, $iwParam, $ilParam)
        Local $hWndFrom, $iCode
        $hWndFrom = $ilParam
        $iIDFrom = BitAND($iwParam, 0xFFFF) ; Low Word
        $iCode = BitShift($iwParam, 16) ; Hi Word
        Switch $iwParam
                Case $idOpen
                        _WinAPI_ShowMsg("Open")
                Case $idSave
                        _WinAPI_ShowMsg("Save")
                Case $idInfo
                        _WinAPI_ShowMsg("Info")
        EndSwitch
EndFunc   ;==>WM_COMMAND

; WM_CONTEXTMENU消息的句柄
Func WM_CONTEXTMENU($hWnd, $iMsg, $iwParam, $ilParam)
        ;MsgBox(0,0,StringFormat("$hwnd = %i$imsg = %i $iwP =%i $ilP = %i",$hwnd,$imsg,$iwParam,$ilParam))
        Local $hMenu
        $hMenu = _GUICtrlMenu_CreatePopup()
        _GUICtrlMenu_InsertMenuItem($hMenu, 0, "Open", $idOpen)
        _GUICtrlMenu_InsertMenuItem($hMenu, 1, "Save", $idSave)
        _GUICtrlMenu_InsertMenuItem($hMenu, 3, "", 0)
        _GUICtrlMenu_InsertMenuItem($hMenu, 3, "Info", $idInfo)
        _GUICtrlMenu_TrackPopupMenu($hMenu, $hWnd)
        _GUICtrlMenu_DestroyMenu($hMenu)
        Return True
EndFunc   ;==>WM_CONTEXTMENU

afan 发表于 2013-10-11 21:06:58

用一个全局变量 $hLVW 保存当前的控件序列#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GuiListView.au3>
#include<GuiMenu.au3>
Opt("GUIOnEventMode", 1)
Global Enum $idOpen = 1000, $idSave, $idInfo

Global $hLVW, $hLVW0
$Form1 = GUICreate("Test", 800, 600, 203, 80, BitOR($GUI_SS_DEFAULT_GUI, $WS_MAXIMIZEBOX, $WS_SIZEBOX, $WS_THICKFRAME, $WS_TABSTOP))
GUISetOnEvent($GUI_EVENT_CLOSE, "Form1Click")
$ListView1 = GUICtrlCreateListView("1|2|3|4", 40, 80, 640, 228, -1, $LVS_EX_GRIDLINES + $LVS_EX_FULLROWSELECT)
$hLVW0 = GUICtrlGetHandle(-1)
$ListViewA = GUICtrlCreateListView("A|B|C|D", 40, 336, 640, 236, -1, $LVS_EX_GRIDLINES + $LVS_EX_FULLROWSELECT)
GUISetState(@SW_SHOW)
GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")
GUIRegisterMsg($WM_CONTEXTMENU, "WM_CONTEXTMENU")

While 1
        Sleep(100)
WEnd

Func Form1Click()
        Exit
EndFunc   ;==>Form1Click

; WM_COMMAND消息的句柄
Func WM_COMMAND($hWnd, $iMsg, $iwParam, $ilParam)
        Local $hWndFrom, $iCode
        $hWndFrom = $ilParam
        $iIDFrom = BitAND($iwParam, 0xFFFF) ; Low Word
        $iCode = BitShift($iwParam, 16) ; Hi Word
        Switch $iwParam
                Case $idOpen
                        _WinAPI_ShowMsg("Open : " & $hLVW)
                Case $idSave
                        _WinAPI_ShowMsg("Save : " & $hLVW)
                Case $idInfo
                        _WinAPI_ShowMsg("Info : " & $hLVW)
        EndSwitch
EndFunc   ;==>WM_COMMAND

; WM_CONTEXTMENU消息的句柄
Func WM_CONTEXTMENU($hWnd, $iMsg, $iwParam, $ilParam)
        ;MsgBox(0,0,StringFormat("$hwnd = %i$imsg = %i $iwP =%i $ilP = %i",$hwnd,$imsg,$iwParam,$ilParam))
        Local $hMenu
        $hMenu = _GUICtrlMenu_CreatePopup()
        _GUICtrlMenu_InsertMenuItem($hMenu, 0, "Open", $idOpen)
        _GUICtrlMenu_InsertMenuItem($hMenu, 1, "Save", $idSave)
        _GUICtrlMenu_InsertMenuItem($hMenu, 3, "", 0)
        _GUICtrlMenu_InsertMenuItem($hMenu, 3, "Info", $idInfo)
        _GUICtrlMenu_TrackPopupMenu($hMenu, $hWnd)
        _GUICtrlMenu_DestroyMenu($hMenu)
        $hLVW = Number($iwParam <> $hLVW0)
        Return True
EndFunc   ;==>WM_CONTEXTMENU
也可以直接注册 WM_NOTIFY 消息,在其通知中直接创建菜单

CHEARV 发表于 2013-10-11 22:26:36

回复 3# afan


    谢谢,我大概明白了。 WM_COMMAND 消息好像不会传递那个控件的句柄,但WM_CONTEXTMENU会传递,你是利用一个全局变量来保存这个参数。
按照我的理解,我改成了下面的代码,应该没有错误了吧#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <GuiListView.au3>
#include<GuiMenu.au3>
Opt("GUIOnEventMode", 1)
Global Enum $idOpen = 1000, $idSave, $idInfo

Global $hListView
$Form1 = GUICreate("Test", 800, 600, 203, 80, BitOR($GUI_SS_DEFAULT_GUI, $WS_MAXIMIZEBOX, $WS_SIZEBOX, $WS_THICKFRAME, $WS_TABSTOP))
GUISetOnEvent($GUI_EVENT_CLOSE, "Form1Click")
$ListView1 = GUICtrlCreateListView("1|2|3|4", 40, 80, 640, 228, -1, $LVS_EX_GRIDLINES + $LVS_EX_FULLROWSELECT)
$hListView1 = GUICtrlGetHandle(-1)
$ListViewA = GUICtrlCreateListView("A|B|C|D", 40, 336, 640, 236, -1, $LVS_EX_GRIDLINES + $LVS_EX_FULLROWSELECT)
$hListViewA = GUICtrlGetHandle(-1)

GUISetState(@SW_SHOW)
GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")
GUIRegisterMsg($WM_CONTEXTMENU, "WM_CONTEXTMENU")

While 1
        Sleep(100)
WEnd

Func Form1Click()
        Exit
EndFunc   ;==>Form1Click

; WM_COMMAND消息的句柄
Func WM_COMMAND($hWnd, $iMsg, $iwParam, $ilParam)
        Local $hWndFrom, $iCode
        $hWndFrom = $ilParam
        $iIDFrom = BitAND($iwParam, 0xFFFF) ; Low Word
        $iCode = BitShift($iwParam, 16) ; Hi Word
        Switch $hListView
                Case $hListView1
                        $s = '从 ListView1 点击 '
                Case $hListViewA
                        $s = '从 ListViewA 点击 '
        EndSwitch
       
        Switch $iwParam
                Case $idOpen
                        _WinAPI_ShowMsg($s & "Open : ")
                Case $idSave
                        _WinAPI_ShowMsg($s & "Save : ")
                Case $idInfo
                        _WinAPI_ShowMsg($s & "Info : ")
        EndSwitch
EndFunc   ;==>WM_COMMAND

; WM_CONTEXTMENU消息的句柄
Func WM_CONTEXTMENU($hWnd, $iMsg, $iwParam, $ilParam)
        Switch $iwParam
                Case $hListView1, $hListViewA
                        Local $hMenu
                        $hMenu = _GUICtrlMenu_CreatePopup()
                        _GUICtrlMenu_InsertMenuItem($hMenu, 0, "Open", $idOpen)
                        _GUICtrlMenu_InsertMenuItem($hMenu, 1, "Save", $idSave)
                        _GUICtrlMenu_InsertMenuItem($hMenu, 3, "", 0)
                        _GUICtrlMenu_InsertMenuItem($hMenu, 3, "Info", $idInfo)
                        _GUICtrlMenu_TrackPopupMenu($hMenu, $hWnd)
                        _GUICtrlMenu_DestroyMenu($hMenu)
                        $hListView = $iwParam
                        Return True
        EndSwitch
EndFunc   ;==>WM_CONTEXTMENU

lswallow 发表于 2013-10-15 16:40:51

不错,学习了,哈哈。

chamlien 发表于 2016-5-4 18:13:22

回复收藏先

zpmc123 发表于 2016-12-30 12:49:03

真是不错的源码 AFAN{:face (270):}

zxxputian2 发表于 2018-6-11 09:00:13

收藏,谢谢提供
页: [1]
查看完整版本: [已解决]请教,如何让为两个LISTVIEW控件创建同一个右键菜单?