qwert Posted January 27, 2019 Share Posted January 27, 2019 (edited) I've been trying to fashion a custom context menu for an edit control. The help file for context menus clearly states that a direct method is not supported. So I've been trying alternative methods to intercept the right mouse click and take an action. So far, nothing has panned out. The code below shows a method that seems very close. The mouse click is detected, but the menu doesn't display. expandcollapse popup#include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <WinAPIDlg.au3> $hGUI = GUICreate("GUI Context Menu Test", 300, 200) $label = GUICtrlCreateLabel("", 20, 20, 260, 120) ; label control solely to support context menu $edit = GUICtrlCreateEdit("Test", 20, 20, 260, 120) $button = GUICtrlCreateButton("OK", 120, 170, 70, 20) $buttoncontext = GUICtrlCreateContextMenu($button) GUICtrlCreateMenuItem("About button", $buttoncontext) $idDummy = GUICtrlCreateDummy() ; created for a dummy control, because you $contextmenu = GUICtrlCreateContextMenu($idDummy) ; can't create a context menu for an edit control $case_0 = GUICtrlCreateMenuItem("Case 0", $contextmenu) $case_1 = GUICtrlCreateMenuItem("Case 1", $contextmenu) GUISetState() GUIRegisterMsg($WM_CONTEXTMENU, "WM_CONTEXTMENU") While 1 $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE Exit Case $button MsgBox(0, "Button", "The button was clicked.") Case $case_0 MsgBox(0, "Case 0", "This is Case 0") Case $case_1 MsgBox(0, "Case 1", "This is Case 1") EndSwitch WEnd Func WM_CONTEXTMENU($hWnd, $iMsg, $iwParam, $ilParam) Local $IDCtrl = _WinAPI_GetDlgCtrlID($iwParam) Local $x = BitAND($ilParam, 0x0000FFFF), $y = BitShift($ilParam, 16) Switch $IDCtrl Case $label ; because $edit doesn't seem to work TrackPopupMenu($hWnd, $contextmenu, $x, $y) EndSwitch EndFunc Func TrackPopupMenu($hWnd, $hMenu, $x, $y) ConsoleWrite($x & @CRLF) ; confirms that the menu is requested ConsoleWrite($y & @CRLF) DllCall("user32.dll", "int", "TrackPopupMenuEx", "hwnd", $hMenu, "int", 0, "int", $x, "int", $y, "hwnd", $hWnd, "ptr", 0) EndFunc I've seen topics on other forums that seem to indicate that this is possible, but I haven't seen a clear example. (BTW, I'll mention that it's fairly important to me to keep things simple.) Has anyone been successful at implementing such a menu? ... or maybe have ideas of what to try? Thanks in advance for any assistance. Edited January 28, 2019 by qwert Link to comment Share on other sites More sharing options...
BrewManNH Posted January 27, 2019 Share Posted January 27, 2019 1 hour ago, qwert said: BTW, I'll mention that it's fairly important to me to keep things simple Unfortunately, I don't think any answer to this is going to be simple. Here's one discussion on how to do it on StackOverflow, and it's definitely not a simple process. If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag GudeHow to ask questions the smart way! I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from. Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays. - ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script. - Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label. - _FileGetProperty - Retrieve the properties of a file - SciTE Toolbar - A toolbar demo for use with the SciTE editor - GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI. - Latin Square password generator Link to comment Share on other sites More sharing options...
qwert Posted January 27, 2019 Author Share Posted January 27, 2019 Thanks for your response. Yes, I had seen that one ... and, yes, that's the complexity I'm trying to avoid. But here's a post that implies simpler ways: post (... although it won't be the first time I've misinterpreted such things.) Link to comment Share on other sites More sharing options...
Subz Posted January 27, 2019 Share Posted January 27, 2019 The following old post works, you need to download the DllCallback.au3 and remove the @Unicode references for it to work. Link to comment Share on other sites More sharing options...
qwert Posted January 27, 2019 Author Share Posted January 27, 2019 Whoa! ... that's a great solution. I picked up the example on page 2 of that thread and my initial test indicates it does exactly what I need. FWIW, my take is that subclassing lets you reassign a control (in this case, the edit control) away from the standard processing ... and (if your want) to your own processing. It's hard to believe that this isn't more widely known/used (I've never seen it, before) because the standard context menu for edit/input controls is so poor (too many unneeded choices!) Thanks very much! Link to comment Share on other sites More sharing options...
pixelsearch Posted January 28, 2019 Share Posted January 28, 2019 Hi qwert, The solution we talked about : expandcollapse popup#include <GUIConstantsEx.au3> $hGUI = GUICreate("GUI Context Menu Test", 300, 200) $edit = GUICtrlCreateEdit("Test", 20, 20, 260, 120) $button = GUICtrlCreateButton("OK", 120, 170, 70, 20) $buttoncontext = GUICtrlCreateContextMenu($button) GUICtrlCreateMenuItem("About button", $buttoncontext) $label = GUICtrlCreateLabel("", 1, 1, 1, 1) $contextmenu = GUICtrlCreateContextMenu($label) $case_0 = GUICtrlCreateMenuItem("Case 0", $contextmenu) $case_1 = GUICtrlCreateMenuItem("Case 1", $contextmenu) $hcontextmenu = GUICtrlGetHandle($contextmenu) GUISetState() While 1 $aInfo = GUIGetCursorInfo() If not @error And $aInfo[3] = 1 And $aInfo[4] = $edit Then $mPos = MouseGetPos() DllCall("user32.dll", "int", "TrackPopupMenuEx", "hwnd", $hcontextmenu, _ "int", 0, "int", $mPos[0], "int", $mPos[1], "hwnd", $hGUI, "ptr", 0) EndIf $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE Exit Case $button MsgBox(0, "Button", "The button was clicked.") Case $case_0 MsgBox(0, "Case 0", "This is Case 0") Case $case_1 MsgBox(0, "Case 1", "This is Case 1") EndSwitch WEnd Good luck Subz 1 Link to comment Share on other sites More sharing options...
qwert Posted January 28, 2019 Author Share Posted January 28, 2019 @pixelsearch, thanks for keeping after this and posting the simplest solution! What I was after all along was a way to have different context menus for different edit controls. Your method does that, nicely. Here's an example with two edit controls set up with different menus ... and without subclassing or registered message processing: expandcollapse popup#include <GUIConstantsEx.au3> $hGUI = GUICreate("GUI Context Menu Test", 300, 350) $edit = GUICtrlCreateEdit("Test", 20, 20, 260, 120) $edit2 = GUICtrlCreateEdit("Also", 20, 180, 260, 120) $button = GUICtrlCreateButton("OK", 120, 320, 70, 20) $buttoncontext = GUICtrlCreateContextMenu($button) GUICtrlCreateMenuItem("About button", $buttoncontext) $label = GUICtrlCreateLabel("", 1, 1, 1, 1) $contextmenu = GUICtrlCreateContextMenu($label) $case_0 = GUICtrlCreateMenuItem("Case 0", $contextmenu) $case_1 = GUICtrlCreateMenuItem("Case 1", $contextmenu) $hcontextmenu = GUICtrlGetHandle($contextmenu) $label2 = GUICtrlCreateLabel("", 1, 1, 1, 1) $context2 = GUICtrlCreateContextMenu($label2) $case_2 = GUICtrlCreateMenuItem("Case 2", $context2) $case_3 = GUICtrlCreateMenuItem("Case 3", $context2) $hcontext2 = GUICtrlGetHandle($context2) GUISetState() While 1 $aInfo = GUIGetCursorInfo() If not @error And $aInfo[3] = 1 And $aInfo[4] = $edit Then $mPos = MouseGetPos() DllCall("user32.dll", "int", "TrackPopupMenuEx", "hwnd", $hcontextmenu, _ "int", 0, "int", $mPos[0], "int", $mPos[1], "hwnd", $hGUI, "ptr", 0) EndIf If not @error And $aInfo[3] = 1 And $aInfo[4] = $edit2 Then $mPos = MouseGetPos() DllCall("user32.dll", "int", "TrackPopupMenuEx", "hwnd", $hcontext2, _ "int", 0, "int", $mPos[0], "int", $mPos[1], "hwnd", $hGUI, "ptr", 0) EndIf $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE Exit Case $button MsgBox(0, "Button", "The button was clicked.", 1) Case $case_0 MsgBox(0, "Case 0", "This is Case 0", 1) Case $case_1 MsgBox(0, "Case 1", "This is Case 1", 1) Case $case_2 MsgBox(0, "Case 2", "This is Case 2", 1) Case $case_3 MsgBox(0, "Case 3", "This is Case 3", 1) EndSwitch WEnd I'm impressed. (Sorry I couldn't see the forest amongst the trees in your first script!) Thanks, again! Link to comment Share on other sites More sharing options...
pixelsearch Posted January 28, 2019 Share Posted January 28, 2019 yw qwert, always a pleasure to help friendly people Link to comment Share on other sites More sharing options...
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