如何获取菜单项目的句柄以便触发动作?
#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()呢?
afan 发表于 2020-2-12 12:23
直接在主循环的 Case $idRepeatItem 处理不香么?还多此一举GUIRegisterMsg($WM_COMMAND, "WM_COMMAND") … ...
A大,用GUIRegisterMsg($WM_COMMAND, "WM_COMMAND") 主要是为了“实时”。 我这里测试正常 哦哦,理解错了。你要获取的是菜单的句柄,那么你应该用_GUICtrlMenu_GetMenu
haijie1223 发表于 2020-2-12 10:21
哦哦,理解错了。你要获取的是菜单的句柄,那么你应该用_GUICtrlMenu_GetMenu
谢谢发哥。
我把GUICtrlGetHandle($idRepeatItem)改为_GUICtrlMenu_GetMenu($idRepeatItem),结果还是一样的,不管点击的哪个菜单,都会往下执行。而我想实现的是,点击菜单$idRepeatItem才往下执行。 试一下:注册事件更改一下:
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 应该不用句柄,直接control id匹配即可,control id从$wParam的低位值获得,…………没有动用 $lParam
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 floor6ggg 发表于 2020-2-12 10:46
试一下:注册事件更改一下:
试了一下,不行的。 本帖最后由 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
直接在主循环的 Case $idRepeatItem 处理不香么?还多此一举GUIRegisterMsg($WM_COMMAND, "WM_COMMAND") …… afan 发表于 2020-2-12 12:23
直接在主循环的 Case $idRepeatItem 处理不香么?还多此一举GUIRegisterMsg($WM_COMMAND, "WM_COMMAND") … ...
楼主应该是为了增加代码的复杂性,这样看起来比较高级。 smooth 发表于 2020-2-12 12:48
A大,用GUIRegisterMsg($WM_COMMAND, "WM_COMMAND") 主要是为了“实时”。
实际上你理解错了,GUIGetMsg只有收到消息的时候才会返回,而返回后在主循环中就立即开始Switch判断并执行操作,因此这也是“实时”的。而注册事件反而多了传入的变量等等导致的耗时。 本帖最后由 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)函数里,比较统一。
itsky2 发表于 2020-2-13 11:55
实际上你理解错了,GUIGetMsg只有收到消息的时候才会返回,而返回后在主循环中就立即开始Switch判断并执 ...
在主循环的GUIGetMsg(),能实时响应?比如在input框中输入数据,不用鼠标点击,不用回车,就能自动返回结果?怎么实现,没研究过。
页:
[1]
2