[已解决]TreeView双击项目事件、右击菜单事件等问题
本帖最后由 雪栀 于 2014-8-28 09:48 编辑解决方案见2楼和4楼,在官网发现一个鼠标事件相关的UDF,我可能会改一下、整合一些功能发上来。
===============================================================================
提问之前我翻了帮助和论坛的帖子,找了一堆相关的例子,包括ListView的双击、右击问题(是的我没写错,大多数是ListView的例子。。。),已经用GUIRegisterMsg的方式解决了双击TreeView项目激发事件的问题,但是现在有如下几个问题:
1、右击某项目可弹出菜单,但点击菜单无效;
2、点击退出按钮无效
下面这个问题无所谓了,只是探讨一下:
备注:运行时请选择x86,否则双击没反映,可能是某些函数对x64的支持有缺陷
把菜单和按钮产生的消息用GUIGetMsg获取,写到While 1……WEnd这一段里,是可以生效的,我是想问能不能用注册消息的方式实现,最近在了解GUIRegisterMsg,注册不同的消息模拟多线程
代码只是示例……写的有点乱……#include <GuiConstants.au3>
#include <GuiTreeView.au3>
#NoTrayIcon
Dim $inifile_path = "playlist.ini"
If Not FileExists($inifile_path) Then
FileInstall("playlist.ini", $inifile_path)
EndIf
Dim $csname = "List", $hClass = 0
$Manage = GUICreate("选择", 300, 300, (@DesktopWidth - 215) / 2, (@DesktopHeight - 100) / 2)
$treeview = GUICtrlCreateTreeView(0, 0, 200, 300, -1, $WS_EX_CLIENTEDGE)
readinfo($inifile_path, $treeview) ;加载ini
;右键菜单
$Menu = GUICtrlCreateContextMenu($treeview)
$rclk = GUICtrlCreateMenuItem("萌萌的菜单", $Menu)
;备用按钮
$exit = GUICtrlCreateButton("退出", 216, 180, 67, 25)
GUISetState(@SW_SHOW, $Manage)
GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
While 1
Local $msg = GUIGetMsg()
Select
Case $msg = -3
Exit
EndSelect
WEnd
Func readinfo($ini, $htv, $csname = "List", $hClass = 0);加载ini
If Not $hClass Then $hClass = $htv
$aSec = IniReadSection($ini, $csname)
If @error Then Return False
For $i = 1 To $aSec
$child = IniReadSection($ini, $aSec[$i])
If @error Then;类
$hItem = GUICtrlCreateTreeViewItem($aSec[$i], $hClass)
Else;子类
$hClass1 = GUICtrlCreateTreeViewItem($aSec[$i], $hClass)
readinfo($ini, $hClass, $aSec[$i], $hClass1)
EndIf
Next
Return True
EndFunc ;==>readinfo
Func WM_NOTIFY($hWndGUI, $MsgID, $WParam, $LParam) ;注册消息,待修改
Local $tagNMHDR, $Event, $hWndFrom, $IDFrom
$tagNMHDR = DllStructCreate("int;int;int", $LParam)
If @error Then Return $GUI_RUNDEFMSG
$IDFrom = DllStructGetData($tagNMHDR, 2)
$Event = DllStructGetData($tagNMHDR, 3)
$tagNMHDR = 0
Switch $IDFrom ;选择产生事件的控件
Case $treeview
Switch $Event ;选择产生的事件
Case $NM_CLICK ; 左击
Case $NM_DBLCLK ; 双击
$Index = _GUICtrlTreeView_GetSelection($treeview)
If Not $Index Then Return; 这里用以判断是否选定了TreeViewItem
MsgBox(0,0,"双击了" & GUICtrlRead($treeview, 1))
Case $NM_RCLICK ; 右击
;MsgBox(0,"","右击!") ;调试
EndSwitch
Case $rclk
Switch $Event ;选择产生的事件
Case $NM_CLICK ; 左击
MsgBox(0,0,"菜单:" & GUICtrlRead($treeview, 1))
EndSwitch
Case $exit
Switch $Event ;选择产生的事件
Case $NM_CLICK ; 左击
Exit
EndSwitch
EndSwitch
Return $GUI_RUNDEFMSG
EndFunc ;==>WM_NOTIFYplaylist.ini文件:
List1=List1
List2=List2
1=0001
2=0010
3=0011
类似问题也在激烈讨论中http://www.autoitx.com/forum.php?mod=viewthread&tid=45019,我在22楼的回答(http://www.autoitx.com/forum.php?mod=viewthread&tid=45019&page=2&extra=#pid592224)又换了一种写法,问题依然没有解决。希望这类单击、双击、右击控件的问题解决后,大家可以整合一下别的什么GUICtrlOnHover之类的,写个强大的鼠标事件UDF{:face (125):} 将就着看一下吧,仅供参考
#include <GuiConstants.au3>
#include <GuiTreeView.au3>
#NoTrayIcon
Dim $inifile_path = "playlist.ini"
If Not FileExists($inifile_path) Then
FileInstall("playlist.ini", $inifile_path)
EndIf
Dim $csname = "List", $hClass = 0
$Manage = GUICreate("选择", 300, 300, (@DesktopWidth - 215) / 2, (@DesktopHeight - 100) / 2)
$treeview = GUICtrlCreateTreeView(0, 0, 200, 300, -1, $WS_EX_CLIENTEDGE)
readinfo($inifile_path, $treeview) ;加载ini
;右键菜单
$Menu = GUICtrlCreateContextMenu($treeview)
$rclk = GUICtrlCreateMenuItem("萌萌的菜单", $Menu)
;备用按钮
$exit = GUICtrlCreateButton("退出", 216, 180, 67, 25)
GUISetState(@SW_SHOW, $Manage)
GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")
While 1
Local $msg = GUIGetMsg()
Select
Case $msg = -3
Exit
EndSelect
WEnd
Func readinfo($ini, $htv, $csname = "List", $hClass = 0) ;加载ini
If Not $hClass Then $hClass = $htv
$aSec = IniReadSection($ini, $csname)
If @error Then Return False
For $i = 1 To $aSec
$child = IniReadSection($ini, $aSec[$i])
If @error Then;类
$hItem = GUICtrlCreateTreeViewItem($aSec[$i], $hClass)
Else;子类
$hClass1 = GUICtrlCreateTreeViewItem($aSec[$i], $hClass)
readinfo($ini, $hClass, $aSec[$i], $hClass1)
EndIf
Next
Return True
EndFunc ;==>readinfo
Func WM_NOTIFY($hWndGUI, $MsgID, $WParam, $LParam) ;注册消息,待修改
Local $tagNMHDR, $Event, $hWndFrom, $IDFrom
$tagNMHDR = DllStructCreate("int;int;int", $LParam)
If @error Then Return $GUI_RUNDEFMSG
$IDFrom = DllStructGetData($tagNMHDR, 2)
$Event = DllStructGetData($tagNMHDR, 3)
$tagNMHDR = 0
ConsoleWrite($IDFrom & @CRLF)
Switch $IDFrom ;选择产生事件的控件
Case $treeview
Switch $Event ;选择产生的事件
Case $NM_CLICK ; 左击
Case $NM_DBLCLK ; 双击
$Index = _GUICtrlTreeView_GetSelection($treeview)
If Not $Index Then Return; 这里用以判断是否选定了TreeViewItem
MsgBox(0, 0, "双击了" & GUICtrlRead($treeview, 1))
Case $NM_RCLICK ; 右击
;MsgBox(0,"","右击!") ;调试
EndSwitch
Case $rclk
Switch $Event ;选择产生的事件
Case $NM_CLICK ; 左击
MsgBox(0, 0, "菜单:" & GUICtrlRead($treeview, 1))
EndSwitch
EndSwitch
Return $GUI_RUNDEFMSG
EndFunc ;==>WM_NOTIFY
Func WM_COMMAND($hWnd, $msg, $wParam, $lParam)
#forceref $hWnd, $Msg
Local $nNotifyCode = BitShift($wParam, 16)
Local $nID = BitAND($wParam, 0x0000FFFF)
Local $hCtrl = $lParam
Switch $nID
Case $exit
Switch $nNotifyCode
Case 0
Exit
EndSwitch
Case $rclk
Switch $nNotifyCode
Case 0
MsgBox(0, "", "不要点我!")
EndSwitch
EndSwitch
Return $GUI_RUNDEFMSG
EndFunc ;==>WM_COMMAND 回复 2# gto250
非常感谢。但可否解释一下WM_NOTIFY、WM_COMMAND这两个消息有什么不同,为什么针对有的控件有效、有的控件无效呢?
另外您给出的代码的第97行,我想判断一下右击的位置可以吗?但是右击貌似不会改变当前选中项目。比如第97行改成MsgBox(0, 0, "右击菜单:" & GUICtrlRead($treeview, 1)),运行,默认选中的是List1,此时右击List2点菜单,MsgBox却提示右击了List1 回复 3# 雪栀
在你的右键响应函数里加上 GUIGetCursorInfo这个来判断鼠标的坐标, 再根据具体的坐标执行相应的操作. 回复 4# lanfengc
感谢提醒,我知道了!
页:
[1]