找回密码
 加入
搜索
查看: 6584|回复: 21

[AU3基础] 如何获取菜单项目的句柄以便触发动作?

[复制链接]
发表于 2020-2-12 09:28:34 | 显示全部楼层 |阅读模式
#include <WindowsConstants.au3>
#include <GUIConstantsEx.au3>
Local $hGUI = GUICreate('', 400, 400)
Local $idSetMenu = GUICtrlCreateMenu("设置[&S]", -1, 1)
Local $idTopItem = GUICtrlCreateMenuItem("窗口置顶", $idSetMenu)
GUICtrlSetState(-1, $GUI_CHECKED)
Local $idRepeatItem = GUICtrlCreateMenuItem("结果去重", $idSetMenu)
GUICtrlSetState(-1, $GUI_CHECKED)
GUICtrlCreateMenuItem("", $idSetMenu, 2)
Local $idFunctionItem = GUICtrlCreateMenuItem("功能设置", $idSetMenu)
GUISetState(@SW_SHOW)
WinSetOnTop($hGUI, "", 1)

GUIRegisterMsg($WM_COMMAND, "WM_COMMAND") 
While 1
        $Msg = GUIGetMsg()
        Switch $Msg
                Case -3
                        Exit
                Case $idTopItem
                        If BitAND(GUICtrlRead($idTopItem), $GUI_CHECKED) = $GUI_CHECKED Then
                                GUICtrlSetState($idTopItem, $GUI_UNCHECKED)
                                WinSetOnTop($hGUI, "", 0)
                        Else
                                GUICtrlSetState($idTopItem, $GUI_CHECKED)
                                WinSetOnTop($hGUI, "", 1)
                        EndIf
                Case $idRepeatItem
                        If BitAND(GUICtrlRead($idRepeatItem), $GUI_CHECKED) = $GUI_CHECKED Then
                                GUICtrlSetState($idRepeatItem, $GUI_UNCHECKED)
                        Else
                                GUICtrlSetState($idRepeatItem, $GUI_CHECKED)
                        EndIf
        EndSwitch
WEnd

Func WM_COMMAND($hWnd, $iMsg, $wParam, $lParam)
        Switch $lParam
                Case GUICtrlGetHandle($idRepeatItem)
                        ToolTip(GUICtrlGetHandle($idRepeatItem), 600, 600)
                        MsgBox(0,0,"???????", '', $hGUI)
        EndSwitch                
    Return $GUI_RUNDEFMSG
EndFunc
各位大神,我的目的是当点击菜单项目$idRepeatItem的时候,执行Msgbox(),可是现在不管点击哪个菜单项目,不知道为什么都会弹出Msgbox()呢?
 楼主| 发表于 2020-2-12 12:48:37 | 显示全部楼层
afan 发表于 2020-2-12 12:23
直接在主循环的 Case $idRepeatItem 处理不香么?还多此一举GUIRegisterMsg($WM_COMMAND, "WM_COMMAND") … ...

A大,用GUIRegisterMsg($WM_COMMAND, "WM_COMMAND") 主要是为了“实时”。
发表于 2020-2-12 09:52:36 | 显示全部楼层
我这里测试正常
发表于 2020-2-12 10:21:21 | 显示全部楼层
哦哦,理解错了。你要获取的是菜单的句柄,那么你应该用_GUICtrlMenu_GetMenu
 楼主| 发表于 2020-2-12 10:42:40 | 显示全部楼层
haijie1223 发表于 2020-2-12 10:21
哦哦,理解错了。你要获取的是菜单的句柄,那么你应该用_GUICtrlMenu_GetMenu

谢谢发哥。
我把GUICtrlGetHandle($idRepeatItem)改为_GUICtrlMenu_GetMenu($idRepeatItem),结果还是一样的,不管点击的哪个菜单,都会往下执行。而我想实现的是,点击菜单$idRepeatItem才往下执行。
发表于 2020-2-12 10:46:50 | 显示全部楼层
试一下:注册事件更改一下:
Func WM_COMMAND($hWnd, $iMsg, $wParam, $ilParam)
 $iIDFrom = BitAND($wParam, 0xFFFF);contril id
           Switch $iIDFrom
                   Case $idRepeatItem;GUICtrlGetHandle($idRepeatItem)
                        ToolTip(GUICtrlGetHandle($idRepeatItem), 600, 600)
                        MsgBox(0,0,"???????", '', $hGUI)                        
        EndSwitch
        Return
EndFunc   ;==>WM_COMMAND
发表于 2020-2-12 10:51:10 | 显示全部楼层
应该不用句柄,直接control id匹配即可,control id从$wParam的低位值获得,…………没有动用 $lParam
发表于 2020-2-12 11:01:16 | 显示全部楼层
Func WM_COMMAND($hWnd, $iMsg, $wParam, $lParam)
        #forceref $hWnd, $iMsg
        Local $hWndFrom, $iIDFrom, $iCode
        $hWndFrom = $lParam
        $iIDFrom = BitAND($wParam, 0xFFFF) ; Low Word
        $iCode = BitShift($wParam, 16) ; Hi Word
        Switch $iIDFrom
                Case $idTopItem
                       
                Case $idRepeatItem
                       
                Case $idFunctionItem
                       
        EndSwitch
        Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_COMMAND
 楼主| 发表于 2020-2-12 11:47:03 | 显示全部楼层
floor6ggg 发表于 2020-2-12 10:46
试一下:注册事件更改一下:

试了一下,不行的。
 楼主| 发表于 2020-2-12 11:48:41 | 显示全部楼层
本帖最后由 smooth 于 2020-2-12 11:50 编辑
haijie1223 发表于 2020-2-12 11:01
Func WM_COMMAND($hWnd, $iMsg, $wParam, $lParam)
        #forceref $hWnd, $iMsg
        Local $hWndFrom, $iIDFrom ...

可以了,谢谢发哥。以下2行好像是不起作用的,测试了一下。

#forceref $hWnd, $iMsg

$hWndFrom = $lParam
发表于 2020-2-12 12:23:47 | 显示全部楼层
直接在主循环的 Case $idRepeatItem 处理不香么?还多此一举GUIRegisterMsg($WM_COMMAND, "WM_COMMAND") ……
发表于 2020-2-12 18:12:40 | 显示全部楼层
afan 发表于 2020-2-12 12:23
直接在主循环的 Case $idRepeatItem 处理不香么?还多此一举GUIRegisterMsg($WM_COMMAND, "WM_COMMAND") … ...

楼主应该是为了增加代码的复杂性,这样看起来比较高级。
发表于 2020-2-13 11:55:20 | 显示全部楼层
smooth 发表于 2020-2-12 12:48
A大,用GUIRegisterMsg($WM_COMMAND, "WM_COMMAND") 主要是为了“实时”。

实际上你理解错了,GUIGetMsg只有收到消息的时候才会返回,而返回后在主循环中就立即开始Switch判断并执行操作,因此这也是“实时”的。而注册事件反而多了传入的变量等等导致的耗时。
 楼主| 发表于 2020-2-14 09:19:50 | 显示全部楼层
本帖最后由 smooth 于 2020-2-14 09:21 编辑
haijie1223 发表于 2020-2-12 18:12
楼主应该是为了增加代码的复杂性,这样看起来比较高级。

发哥,不是为了增加代码的复杂性。在Func WM_COMMAND($hWnd, $iMsg, $wParam, $lParam)函数里,我还有其他代码,比如在input框输入后就自动返回结果,不用点击,也不用回车,只是我这里举例子的时候省略了。当然这并不影响在主循环里Case $idRepeatItem这个菜单,只是我觉得放到Func WM_COMMAND($hWnd, $iMsg, $wParam, $lParam)函数里,比较统一。
 楼主| 发表于 2020-2-14 09:24:12 | 显示全部楼层
itsky2 发表于 2020-2-13 11:55
实际上你理解错了,GUIGetMsg只有收到消息的时候才会返回,而返回后在主循环中就立即开始Switch判断并执 ...

在主循环的GUIGetMsg(),能实时响应?比如在input框中输入数据,不用鼠标点击,不用回车,就能自动返回结果?怎么实现,没研究过。
您需要登录后才可以回帖 登录 | 加入

本版积分规则

QQ|手机版|小黑屋|AUTOIT CN ( 鲁ICP备19019924号-1 )谷歌 百度

GMT+8, 2024-12-23 16:01 , Processed in 0.078901 second(s), 21 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表