WildByDesign Posted Friday at 11:56 AM Posted Friday at 11:56 AM I have worked a lot with menus and changing states of items within those menus. In this case, I am working with context menus and the items within them don't seem to want to change state after it's running. I can change state of a context menu item before GUISetState but not after. In the docs, the info for GUICtrlSetState states the following: Quote State of a "contextmenu" control cannot be changed. So that is something, of course. But to me, that refers to the whole contextmenu control and not to individual context menu entries. Besides, I can change the state of individual context menu entries as long as it is done before the GUI is running, just not after. In this example, I made the hotkey Esc trigger the disabling of the "About button" on the OK button's context menu. But as can be seen when running the example, it does not disable the context menu item. expandcollapse popup; right click on gui to bring up context Menu. ; right click on the "ok" button to bring up a controll specific context menu. #include <GUIConstantsEx.au3> #include <MsgBoxConstants.au3> Global $idMni_About HotKeySet("{Esc}", "_disable") Example() Func Example() GUICreate("My GUI Context Menu", 300, 200) Local $idContextmenu = GUICtrlCreateContextMenu() Local $idMnu_Newsub = GUICtrlCreateMenu("new", $idContextmenu) Local $idMni_NewsubmenuText = GUICtrlCreateMenuItem("text", $idMnu_Newsub) Local $idButton = GUICtrlCreateButton("OK", 100, 100, 70, 20) Local $idCtx_Button = GUICtrlCreateContextMenu($idButton) Local $idMni_About = GUICtrlCreateMenuItem("About button", $idCtx_Button) Local $idMni_Open = GUICtrlCreateMenuItem("Open", $idContextmenu) Local $idMni_Save = GUICtrlCreateMenuItem("Save", $idContextmenu) GUICtrlCreateMenuItem("", $idContextmenu) ; separator Local $idMni_Info = GUICtrlCreateMenuItem("Info", $idContextmenu) GUISetState(@SW_SHOW) ; Loop until the user exits. While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop EndSwitch WEnd GUIDelete() EndFunc ;==>Example Func _disable() GUICtrlSetState($idMni_About, $GUI_DISABLE) ConsoleWrite("Disable context menu item, please." & @CRLF) EndFunc Does anyone know of any tricks to change state of context menu items? I just need basic enable/disable. Thank you.
Dan_555 Posted Friday at 02:02 PM Posted Friday at 02:02 PM (edited) Make the menu items Global then add another Context menu item (or separator) to the Button and it will work. Edited Friday at 02:04 PM by Dan_555 WildByDesign 1 Some of my script sourcecode
Solution Nine Posted Friday at 02:07 PM Solution Posted Friday at 02:07 PM There is a couple of issues with your code. First you declare $idMni_About globally and then you declare it locally. So global variable is null. Second, you cannot execute code while your script shows a context menu. The hotkeyset is only executed after the context menu is closed. WildByDesign 1 “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Debug Messages Monitor UDF Screen Scraping Round Corner GUI UDF Multi-Threading Made Easy Interface Object based on Tag
Trong Posted Friday at 02:50 PM Posted Friday at 02:50 PM S: expandcollapse popup; right click on gui to bring up context Menu. ; right click on the "ok" button to bring up a controll specific context menu. #include <GUIConstantsEx.au3> #include <MsgBoxConstants.au3> Opt('GUICloseOnESC', 0) HotKeySet("{F8} ", "_Disable_MenuAbout") HotKeySet("{F9} ", "_Enable_MenuAbout") Global $hwnd, $idContextmenu, $idMnu_Newsub, $idMni_NewsubmenuText, $idButton, $idCtx_Button, $idMni_About, $idMni_Open, $idMni_Save, $idMni_Info _GUICreate() Func _GUICreate() $hwnd = GUICreate("My GUI Context Menu", 300, 200) $idContextmenu = GUICtrlCreateContextMenu() $idMnu_Newsub = GUICtrlCreateMenu("New", $idContextmenu) $idMni_NewsubmenuText = GUICtrlCreateMenuItem("Text", $idMnu_Newsub) $idButton = GUICtrlCreateButton("OK", 100, 100, 70, 20) $idCtx_Button = GUICtrlCreateContextMenu($idButton) $idMni_About = GUICtrlCreateMenuItem("About button", $idCtx_Button) $idMni_Open = GUICtrlCreateMenuItem("Open", $idContextmenu) $idMni_Save = GUICtrlCreateMenuItem("Save", $idContextmenu) GUICtrlCreateMenuItem("", $idContextmenu) ; separator $idMni_Info = GUICtrlCreateMenuItem("Info", $idContextmenu) GUISetState(@SW_SHOW, $hwnd) EndFunc ;==>_GUICreate ; Loop until the user exits. While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop Case $idButton, $idMni_About, $idMni_Open, $idMni_Save, $idMni_Info, $idMni_NewsubmenuText MsgBox(0, '', 'OK', 0, $hwnd) EndSwitch WEnd GUIDelete() Func _Disable_MenuAbout() GUICtrlSetState($idMni_About, $GUI_DISABLE) ConsoleWrite("! Context menu item Disabled !" & @CRLF) EndFunc ;==>_Disable_MenuAbout Func _Enable_MenuAbout() GUICtrlSetState($idMni_About, $GUI_ENABLE) ConsoleWrite("! Context menu item Enable!" & @CRLF) EndFunc ;==>_Enable_MenuAbout WildByDesign 1 Enjoy my work? Buy me a 🍻 or tip via ❤️ PayPal
argumentum Posted Friday at 04:03 PM Posted Friday at 04:03 PM 4 hours ago, WildByDesign said: In this case, expandcollapse popup; right click on gui to bring up context Menu. DONE ; right click on the "ok" button to bring up a controll specific context menu. YOUR TURN TO CODE IT #include <GUIConstantsEx.au3> #include <MsgBoxConstants.au3> Global $idMni_About ;~ HotKeySet("{Esc}", "_disable") Example() Func Example() Local $hGui = GUICreate("My GUI Context Menu", 300, 200) Local $idContextmenu = GUICtrlCreateContextMenu(GUICtrlCreateDummy()) Local $idMnu_Newsub = GUICtrlCreateMenu("new", $idContextmenu) Local $idMni_NewsubmenuText = GUICtrlCreateMenuItem("text", $idMnu_Newsub) Local $idButton = GUICtrlCreateButton("on", 100, 100, 70, 20) Local $idMni_AboutCM = GUICtrlCreateContextMenu(GUICtrlCreateDummy()) Local $idMni_About = GUICtrlCreateMenuItem("About button", $idMni_AboutCM) Local $idMni_Open = GUICtrlCreateMenuItem("Open", $idContextmenu) Local $idMni_Save = GUICtrlCreateMenuItem("Save", $idContextmenu) GUICtrlCreateMenuItem("", $idContextmenu) ; separator Local $idMni_Info = GUICtrlCreateMenuItem("Info", $idContextmenu) GUISetState(@SW_SHOW) While 1 ; Loop until the user exits. Switch GUIGetMsg() Case $GUI_EVENT_SECONDARYUP $aCursorInfo = GUIGetCursorInfo($hGui) If @error Then ContinueLoop ConsoleWrite('- $GUI_EVENT_SECONDARYUP - ' & $aCursorInfo[4] & @CRLF) If UBound($aCursorInfo) = 5 And GUICtrlRead($idButton) = 'on' Then Switch $aCursorInfo[4] Case 0 TrackPopupMenu($hGui, GUICtrlGetHandle($idContextmenu), MouseGetPos(0), MouseGetPos(1)) Case Else ; ..you do your part too =P TrackPopupMenu($hGui, GUICtrlGetHandle($idMni_AboutCM), MouseGetPos(0), MouseGetPos(1)) EndSwitch EndIf Case $idButton If GUICtrlRead($idButton) = 'on' Then GUICtrlSetData($idButton, 'off') Else GUICtrlSetData($idButton, 'on') EndIf Case $GUI_EVENT_CLOSE ExitLoop EndSwitch WEnd GUIDelete() EndFunc ;==>Example ;~ Func _disable() ;~ GUICtrlSetState($idMni_About, $GUI_DISABLE) ;~ ConsoleWrite("Disable context menu item, please." & @CRLF) ;~ EndFunc ; Show at the given coordinates (x, y) the popup menu (hMenu) which belongs to a given GUI window (hWnd) Func TrackPopupMenu($hWnd, $hMenu, $x, $y) DllCall("user32.dll", "int", "TrackPopupMenuEx", "hwnd", $hMenu, "int", 0, "int", $x, "int", $y, "hwnd", $hWnd, "ptr", 0) EndFunc ;==>TrackPopupMenu WildByDesign 1 Follow the link to my code contribution ( and other things too ). FAQ - Please Read Before Posting.
WildByDesign Posted Saturday at 12:01 AM Author Posted Saturday at 12:01 AM 9 hours ago, Nine said: There is a couple of issues with your code. First you declare $idMni_About globally and then you declare it locally. So global variable is null. Thank you for noticing my mistake of declaring it locally after having already declared it globally. That simple mistake was the problem. Small mistake but big consequences. I've made that mistake a few times before and I paid the price for it every time. Let's hope this is the last time. 9 hours ago, Nine said: Second, you cannot execute code while your script shows a context menu. The hotkeyset is only executed after the context menu is closed. This is good information that I was not aware of. I will have to keep this in mind.
WildByDesign Posted Saturday at 12:09 AM Author Posted Saturday at 12:09 AM Thank you @Trong for your example as well. It works very well. Thanks @argumentum for your example too. I've done some scripts with _GUICtrlMenu_TrackPopupMenu before which is interesting and I assume is likely similar to what you've done with the DLLCall in the TrackMenuPopup function. Although yours calls TrackPopupMenuEx while the other calls TrackPopupMenu. I'll dig into the MS docs because now I am curious. By the way, I have never used dummy controls because but yet I've seen them used a good amount. What is the benefit of dummy controls?
Nine Posted Saturday at 12:46 AM Posted Saturday at 12:46 AM 34 minutes ago, WildByDesign said: What is the benefit of dummy controls? It pushes in the message pump in order. So all messages are treated in the right sequence. By using a global variable for example, it may shortcut some messages and produce unpredictable results. WildByDesign 1 “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Debug Messages Monitor UDF Screen Scraping Round Corner GUI UDF Multi-Threading Made Easy Interface Object based on Tag
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now