找回密码  加入

QQ登录

只需一步,快速开始

AUTOIT CN

搜索
查看: 188|回复: 21

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

[复制链接]
发表于 2020-2-12 09:28:34 | 显示全部楼层 |阅读模式

  1. #include <WindowsConstants.au3>
  2. #include <GUIConstantsEx.au3>
  3. Local $hGUI = GUICreate('', 400, 400)
  4. Local $idSetMenu = GUICtrlCreateMenu("设置[&S]", -1, 1)
  5. Local $idTopItem = GUICtrlCreateMenuItem("窗口置顶", $idSetMenu)
  6. GUICtrlSetState(-1, $GUI_CHECKED)
  7. Local $idRepeatItem = GUICtrlCreateMenuItem("结果去重", $idSetMenu)
  8. GUICtrlSetState(-1, $GUI_CHECKED)
  9. GUICtrlCreateMenuItem("", $idSetMenu, 2)
  10. Local $idFunctionItem = GUICtrlCreateMenuItem("功能设置", $idSetMenu)
  11. GUISetState(@SW_SHOW)
  12. WinSetOnTop($hGUI, "", 1)

  13. GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")
  14. While 1
  15.         $Msg = GUIGetMsg()
  16.         Switch $Msg
  17.                 Case -3
  18.                         Exit
  19.                 Case $idTopItem
  20.                         If BitAND(GUICtrlRead($idTopItem), $GUI_CHECKED) = $GUI_CHECKED Then
  21.                                 GUICtrlSetState($idTopItem, $GUI_UNCHECKED)
  22.                                 WinSetOnTop($hGUI, "", 0)
  23.                         Else
  24.                                 GUICtrlSetState($idTopItem, $GUI_CHECKED)
  25.                                 WinSetOnTop($hGUI, "", 1)
  26.                         EndIf
  27.                 Case $idRepeatItem
  28.                         If BitAND(GUICtrlRead($idRepeatItem), $GUI_CHECKED) = $GUI_CHECKED Then
  29.                                 GUICtrlSetState($idRepeatItem, $GUI_UNCHECKED)
  30.                         Else
  31.                                 GUICtrlSetState($idRepeatItem, $GUI_CHECKED)
  32.                         EndIf
  33.         EndSwitch
  34. WEnd

  35. Func WM_COMMAND($hWnd, $iMsg, $wParam, $lParam)
  36.         Switch $lParam
  37.                 Case GUICtrlGetHandle($idRepeatItem)
  38.                         ToolTip(GUICtrlGetHandle($idRepeatItem), 600, 600)
  39.                         MsgBox(0,0,"???????", '', $hGUI)
  40.         EndSwitch               
  41.     Return $GUI_RUNDEFMSG
  42. 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") 主要是为了“实时”。
回复 支持 1 反对 0

使用道具 举报

发表于 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 | 显示全部楼层
试一下:注册事件更改一下:
  1. Func WM_COMMAND($hWnd, $iMsg, $wParam, $ilParam)
  2. $iIDFrom = BitAND($wParam, 0xFFFF);contril id
  3.            Switch $iIDFrom
  4.                    Case $idRepeatItem;GUICtrlGetHandle($idRepeatItem)
  5.                         ToolTip(GUICtrlGetHandle($idRepeatItem), 600, 600)
  6.                         MsgBox(0,0,"???????", '', $hGUI)                        
  7.         EndSwitch
  8.         Return
  9. 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, 2020-2-27 03:12 , Processed in 0.078125 second(s), 21 queries .

Powered by Discuz! X3.4 Licensed

© 2001-2017 Comsenz Inc.

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