Jump to content

Adding context menu on edit control (RESOLVED)


Recommended Posts

How do I do this? I know it's possible as I've seen other programs create a custom context menu that appears when they right click in an edit or input. ATNotes for example if you download it you will see what I am talking about.

I know the helpfile says otherwise but it can be achieved.

How do I override the system menus?

Edited by AustrianOak
Link to comment
Share on other sites

How do I do this? I know it's possible as I've seen other programs create a custom context menu that appears when they right click in an edit or input. ATNotes for example if you download it you will see what I am talking about.

GUICtrlCreateContextMenu()

I know the helpfile says otherwise but it can be achieved.

Where does it say that?

How do I override the system menus?

On what?

:P

Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Link to comment
Share on other sites

Where does it say that?

From helpfile:

Note: You can't create context menus for controls that already have system context menus, i.e. edit or input controls.

Here is what I did and as expected, it didn't work...

#Include <GUIConstantsEx.au3>
#Include <EditConstants.au3>

$gui = GUICreate("", 300, 300)
$edit = GUICtrlCreateEdit("", 20, 20, 200, 200)
$menu = GUICtrlCreateContextMenu($edit)
$menuitem = GUICtrlCreateMenuItem("Hello", $menu)
GUISetState()

While 1
    $msg = GUIGetMsg()
    Switch $msg
        Case $GUI_EVENT_CLOSE
            Exit
    EndSwitch
WEnd
Link to comment
Share on other sites

Here is what I did and as expected, it didn't work...

#Include <GUIConstantsEx.au3>
#Include <EditConstants.au3>

$gui = GUICreate("", 300, 300)
$edit = GUICtrlCreateEdit("", 20, 20, 200, 200)
$menu = GUICtrlCreateContextMenu($edit)
$menuitem = GUICtrlCreateMenuItem("Hello", $menu)
GUISetState()

While 1
    $msg = GUIGetMsg()
    Switch $msg
        Case $GUI_EVENT_CLOSE
            Exit
    EndSwitch
WEnd
You're right. I tried the function with a couple controls, but none that already had system context menus (like Edit). My mistake.

:P

Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Link to comment
Share on other sites

Yes, but maybe the approach I am taking is one step ahead. Is there any way I can create my own edit and stop the system from putting theirs before I make mine.

ATNotes is a classic example and a beautiful one at having complete custom menus on an edit or input control..

Link to comment
Share on other sites

IWantIt

I know its possible

Yes, with subclassing:

#include <GuiConstantsEx.au3>
#include <WindowsConstants.au3>
#include <EditConstants.au3>
#include <GuiMenu.au3>
#include <Constants.au3>
#include <WinAPI.au3>

Global Enum $idOpen = 1000, $idSave, $idInfo

$hGUI = GUICreate("Test", 300, 200)

$Edit1 = GUICtrlCreateEdit("", 10, 10, 280, 150, BitOR($WS_HSCROLL, $WS_VSCROLL, $ES_MULTILINE))

$hMenu = _GUICtrlMenu_CreatePopup()

_GUICtrlMenu_AddMenuItem($hMenu, "Open", $idOpen)
_GUICtrlMenu_AddMenuItem($hMenu, "Save", $idSave)
_GUICtrlMenu_AddMenuItem($hMenu, "Info", $idInfo)

GUISetState()

$wProcHandle = DllCallbackRegister("_WindowProc", "ptr", "hwnd;uint;wparam;lparam")

$wProcOld = _WinAPI_SetWindowLong(GUICtrlGetHandle($Edit1), $GWL_WNDPROC, DllCallbackGetPtr($wProcHandle))

While 1
    $msg = GUIGetMsg()
    Switch $msg
        Case $GUI_EVENT_CLOSE
            ExitLoop
    EndSwitch
WEnd

GUIDelete($hGui)
DllCallbackFree($wProcHandle)

Func _WindowProc($hWnd, $Msg, $wParam, $lParam)
    Switch $hWnd
        Case GUICtrlGetHandle($Edit1)
            Switch $Msg
                Case $WM_CONTEXTMENU
                    _GUICtrlMenu_TrackPopupMenu($hMenu, $wParam)
                    Return 0
                Case $WM_COMMAND
                    Switch $wParam
                        Case $idOpen
                            ConsoleWrite("-> Open" & @LF)
                        Case $idSave
                            ConsoleWrite("-> Save" & @LF)
                        Case $idInfo
                            ConsoleWrite("-> Info" & @LF)
                    EndSwitch
            EndSwitch
    EndSwitch
    
    Local $aRet = DllCall("user32.dll", "int", "CallWindowProc", "ptr", $wProcOld, _
                          "hwnd", $hWnd, "uint", $Msg, "wparam", $wParam, "lparam", $lParam)
    Return $aRet[0]
EndFunc

:P

Edited by rasim
Link to comment
Share on other sites

I extended the example on the default menu entries:

#include <GuiConstantsEx.au3>
#include <WindowsConstants.au3>
#include <EditConstants.au3>
#include <GuiMenu.au3>
#include <Constants.au3>
#include <WinAPI.au3>

Global Enum $idOpen = 1000, $idSave, $idInfo

$hGUI = GUICreate("Test", 300, 200)

$Edit1 = GUICtrlCreateEdit("", 10, 10, 280, 150, BitOR($WS_HSCROLL, $WS_VSCROLL, $ES_MULTILINE))

$hMenu = _GUICtrlMenu_CreatePopup()


_GUICtrlMenu_AddMenuItem($hMenu, "Open", $idOpen)
_GUICtrlMenu_AddMenuItem($hMenu, "Save", $idSave)
_GUICtrlMenu_AddMenuItem($hMenu, "Info", $idInfo)
_GUICtrlMenu_AddMenuItem($hMenu,"")
_GUICtrlMenu_AddMenuItem($hMenu, "Undo", $WM_UNDO)
_GUICtrlMenu_AddMenuItem($hMenu,"")
_GUICtrlMenu_AddMenuItem($hMenu, "Cut", $WM_CUT)
_GUICtrlMenu_AddMenuItem($hMenu, "Copy", $WM_COPY)
_GUICtrlMenu_AddMenuItem($hMenu, "Paste", $WM_PASTE)
_GUICtrlMenu_AddMenuItem($hMenu,"")
Global Const $ME_SELECTALL  =  $WM_USER + 0x7000
_GUICtrlMenu_AddMenuItem($hMenu, "Select All", $EM_SETSEL)


GUISetState()

$wProcHandle = DllCallbackRegister("_WindowProc", "ptr", "hwnd;uint;wparam;lparam")

$wProcOld = _WinAPI_SetWindowLong(GUICtrlGetHandle($Edit1), $GWL_WNDPROC, DllCallbackGetPtr($wProcHandle))

While 1
    $msg = GUIGetMsg()
    Switch $msg
        Case $GUI_EVENT_CLOSE
            ExitLoop
    EndSwitch
WEnd

GUIDelete($hGui)
DllCallbackFree($wProcHandle)

Func _WindowProc($hWnd, $Msg, $wParam, $lParam)
    Switch $hWnd
        Case GUICtrlGetHandle($Edit1)
            Switch $Msg
                Case $WM_CONTEXTMENU
                    _GUICtrlMenu_TrackPopupMenu($hMenu, $wParam)
                    Return 1
                Case $WM_COMMAND
                    Switch $wParam
                        Case $WM_UNDO,$WM_CUT,$WM_COPY,$WM_CLEAR,$WM_PASTE
                            _SendMessage($hWnd,$wParam)
                        Case $ME_SELECTALL
                            _SendMessage($hWnd,$EM_SETSEL,0,-1)
                        Case $idOpen
                            ConsoleWrite("-> Open" & @LF)
                        Case $idSave
                            ConsoleWrite("-> Save" & @LF)
                        Case $idInfo
                            ConsoleWrite("-> Info" & @LF)
                    EndSwitch
            EndSwitch
    EndSwitch
   
    Local $aRet = DllCall("user32.dll", "int", "CallWindowProc", "ptr", $wProcOld, _
                          "hwnd", $hWnd, "uint", $Msg, "wparam", $wParam, "lparam", $lParam)
    Return $aRet[0]
EndFunc

*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Link to comment
Share on other sites

I extended the example on the default menu entries:

Nice as always.

Only little bug: "Select All" doesn't work on my PC.

EDIT: I found it

just change

_GUICtrlMenu_AddMenuItem($hMenu, "Select All", $EM_SETSEL)

to

_GUICtrlMenu_AddMenuItem($hMenu, "Select All", $ME_SELECTALL)

Note: $ME_SELECTALL should be $EM_SELECTALL

Edited by Zedna
Link to comment
Share on other sites

What was the point of that?

Edit: And who would want default menu entries? Let's try to stay far away form that otherwise this great example is useless. Whoever wants default menu entries can stay with the system context menu.

Edited by IWantIt
Link to comment
Share on other sites

What was the point of that?

Edit: And who would want default menu entries? Let's try to stay far away form that otherwise this great example is useless. Whoever wants default menu entries can stay with the system context menu.

What bad post!!

I like that capability. Different scripters have different wants. So if we have these examples anybody can choose one for them.

If you don't need something it doesn't mean nobody else will not use it!

So think more before you will post such SHIT.

Edited by Zedna
Link to comment
Share on other sites

I extended the example on the default menu entries:

Thank you for nice addition! :P

Zedna

Only little bug: "Select All" doesn't work on my PC.

Yes, need little correction:

#include <GuiConstantsEx.au3>
#include <WindowsConstants.au3>
#include <EditConstants.au3>
#include <GuiMenu.au3>
#include <Constants.au3>
#include <WinAPI.au3>

Global Enum $idOpen = 1000, $idSave, $idInfo, $idSelectAll

$hGUI = GUICreate("Test", 300, 200)

$Edit1 = GUICtrlCreateEdit("", 10, 10, 280, 150, BitOR($WS_HSCROLL, $WS_VSCROLL, $ES_MULTILINE))

$hMenu = _GUICtrlMenu_CreatePopup()


_GUICtrlMenu_AddMenuItem($hMenu, "Open", $idOpen)
_GUICtrlMenu_AddMenuItem($hMenu, "Save", $idSave)
_GUICtrlMenu_AddMenuItem($hMenu, "Info", $idInfo)
_GUICtrlMenu_AddMenuItem($hMenu,"")
_GUICtrlMenu_AddMenuItem($hMenu, "Undo", $WM_UNDO)
_GUICtrlMenu_AddMenuItem($hMenu,"")
_GUICtrlMenu_AddMenuItem($hMenu, "Cut", $WM_CUT)
_GUICtrlMenu_AddMenuItem($hMenu, "Copy", $WM_COPY)
_GUICtrlMenu_AddMenuItem($hMenu, "Paste", $WM_PASTE)
_GUICtrlMenu_AddMenuItem($hMenu,"")
_GUICtrlMenu_AddMenuItem($hMenu, "Select All", $idSelectAll)

GUISetState()

$wProcHandle = DllCallbackRegister("_WindowProc", "ptr", "hwnd;uint;wparam;lparam")

$wProcOld = _WinAPI_SetWindowLong(GUICtrlGetHandle($Edit1), $GWL_WNDPROC, DllCallbackGetPtr($wProcHandle))

While 1
    $msg = GUIGetMsg()
    Switch $msg
        Case $GUI_EVENT_CLOSE
            ExitLoop
    EndSwitch
WEnd

GUIDelete($hGui)
DllCallbackFree($wProcHandle)

Func _WindowProc($hWnd, $Msg, $wParam, $lParam)
    Switch $hWnd
        Case GUICtrlGetHandle($Edit1)
            Switch $Msg
                Case $WM_CONTEXTMENU
                    _GUICtrlMenu_TrackPopupMenu($hMenu, $wParam)
                    Return 1
                Case $WM_COMMAND
                    Switch $wParam
                        Case $WM_UNDO, $WM_CUT, $WM_COPY, $WM_CLEAR, $WM_PASTE
                            _SendMessage($hWnd, $wParam)
                        Case $idOpen
                            ConsoleWrite("-> Open" & @LF)
                        Case $idSave
                            ConsoleWrite("-> Save" & @LF)
                        Case $idInfo
                            ConsoleWrite("-> Info" & @LF)
                        Case $idSelectAll
                            _SendMessage($hWnd, $EM_SETSEL, 0, -1)
                    EndSwitch
            EndSwitch
    EndSwitch
   
    Local $aRet = DllCall("user32.dll", "int", "CallWindowProc", "ptr", $wProcOld, _
                          "hwnd", $hWnd, "uint", $Msg, "wparam", $wParam, "lparam", $lParam)
    Return $aRet[0]
EndFunc

:P

Link to comment
Share on other sites

Thank you for nice addition! :P

Zedna

Yes, need little correction:

CODE
#include <GuiConstantsEx.au3>

#include <WindowsConstants.au3>

#include <EditConstants.au3>

#include <GuiMenu.au3>

#include <Constants.au3>

#include <WinAPI.au3>

Global Enum $idOpen = 1000, $idSave, $idInfo, $idSelectAll

$hGUI = GUICreate("Test", 300, 200)

$Edit1 = GUICtrlCreateEdit("", 10, 10, 280, 150, BitOR($WS_HSCROLL, $WS_VSCROLL, $ES_MULTILINE))

$hMenu = _GUICtrlMenu_CreatePopup()

_GUICtrlMenu_AddMenuItem($hMenu, "Open", $idOpen)

_GUICtrlMenu_AddMenuItem($hMenu, "Save", $idSave)

_GUICtrlMenu_AddMenuItem($hMenu, "Info", $idInfo)

_GUICtrlMenu_AddMenuItem($hMenu,"")

_GUICtrlMenu_AddMenuItem($hMenu, "Undo", $WM_UNDO)

_GUICtrlMenu_AddMenuItem($hMenu,"")

_GUICtrlMenu_AddMenuItem($hMenu, "Cut", $WM_CUT)

_GUICtrlMenu_AddMenuItem($hMenu, "Copy", $WM_COPY)

_GUICtrlMenu_AddMenuItem($hMenu, "Paste", $WM_PASTE)

_GUICtrlMenu_AddMenuItem($hMenu,"")

_GUICtrlMenu_AddMenuItem($hMenu, "Select All", $idSelectAll)

GUISetState()

$wProcHandle = DllCallbackRegister("_WindowProc", "ptr", "hwnd;uint;wparam;lparam")

$wProcOld = _WinAPI_SetWindowLong(GUICtrlGetHandle($Edit1), $GWL_WNDPROC, DllCallbackGetPtr($wProcHandle))

While 1

$msg = GUIGetMsg()

Switch $msg

Case $GUI_EVENT_CLOSE

ExitLoop

EndSwitch

WEnd

GUIDelete($hGui)

DllCallbackFree($wProcHandle)

Func _WindowProc($hWnd, $Msg, $wParam, $lParam)

Switch $hWnd

Case GUICtrlGetHandle($Edit1)

Switch $Msg

Case $WM_CONTEXTMENU

_GUICtrlMenu_TrackPopupMenu($hMenu, $wParam)

Return 1

Case $WM_COMMAND

Switch $wParam

Case $WM_UNDO, $WM_CUT, $WM_COPY, $WM_CLEAR, $WM_PASTE

_SendMessage($hWnd, $wParam)

Case $idOpen

ConsoleWrite("-> Open" & @LF)

Case $idSave

ConsoleWrite("-> Save" & @LF)

Case $idInfo

ConsoleWrite("-> Info" & @LF)

Case $idSelectAll

_SendMessage($hWnd, $EM_SETSEL, 0, -1)

EndSwitch

EndSwitch

EndSwitch

Local $aRet = DllCall("user32.dll", "int", "CallWindowProc", "ptr", $wProcOld, _

"hwnd", $hWnd, "uint", $Msg, "wparam", $wParam, "lparam", $lParam)

Return $aRet[0]

EndFunc

:P
You sir, are a steely-eyed scripting man!

:o

Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Link to comment
Share on other sites

I've been trying to get this to work with rasim's implementation of the custom context menus and I am having trouble getting it to work.

Can someone take a look plz?

#include <GuiConstantsEx.au3>
#include <GuiEdit.au3>
#include <GuiMenu.au3>
#include <WindowsConstants.au3>
#include <Constants.au3>
#include <WinAPI.au3>

Global $LineCount = 1, $LineLen = 0
Global $lastdragIP = -1
Dim $hInput_GUI[6], $Input[6]
Global Enum $idOpen = 1000, $idSave, $idInfo

$hGUI = GUICreate("Test", 300, 200)

$button = GUICtrlCreateButton("", 50, 50, 50, 20)

GUIRegisterMsg($WM_COMMAND, "WM_COMMAND")

GUISetState()

$wProcHandle = DllCallbackRegister("_WindowProc", "ptr", "hwnd;uint;wparam;lparam")
$wProcOld = _WinAPI_SetWindowLong(GUICtrlGetHandle($Input), $GWL_WNDPROC, DllCallbackGetPtr($wProcHandle))

While 1
    $msg = GUIGetMsg()
    Switch $msg
        Case $GUI_EVENT_CLOSE
            ExitLoop
        Case $button
                If $lastdragIP < 5 Then
                    $lastdragIP += 1
                    createNextdragIP($lastdragIP)
                EndIf
        Case $GUI_EVENT_PRIMARYDOWN
           
            $aMouse_Pos = MouseGetPos()
            $sel = -1
            For $n = 0 To $lastdragIP
                GUISwitch($hInput_GUI[$n])
                $aCursorInfo = GUIGetCursorInfo()
               
                If Not IsArray($aCursorInfo) Then ContinueLoop
                If $aCursorInfo[4] = $Input[$n] Then
                    $sel = $n
                    ExitLoop
                EndIf
               
            Next
            If $sel = -1 Then ContinueLoop
            $aInputGUI_Pos = WinGetPos($hInput_GUI[$sel])
            While IsArray($aCursorInfo) And $aCursorInfo[2] = 1
                $aCursorInfo = GUIGetCursorInfo()
                $aCurrent_Mouse_Pos = MouseGetPos()

                WinMove($hInput_GUI[$sel], "", _
                $aInputGUI_Pos[0] - $aMouse_Pos[0] + $aCurrent_Mouse_Pos[0], _
                $aInputGUI_Pos[1] - $aMouse_Pos[1] + $aCurrent_Mouse_Pos[1])
            WEnd
    EndSwitch
    If _GUICtrlEdit_GetLineCount(GUICtrlGetHandle($input)) > $LineCount Then
        $LineCount = _GUICtrlEdit_GetLineCount(GUICtrlGetHandle($input))
        $aPos = ControlGetPos($hGUI, "", $input)
        GUICtrlSetPos($input, $aPos[0], $aPos[1], $aPos[2], $aPos[3] + 15)
    ElseIf _GUICtrlEdit_GetLineCount(GUICtrlGetHandle($input)) < $LineCount Then
        $LineCount = _GUICtrlEdit_GetLineCount(GUICtrlGetHandle($input))
        $aPos = ControlGetPos($hGUI, "", $input)
        GUICtrlSetPos($input, $aPos[0], $aPos[1], $aPos[2], $aPos[3] - 15)
    EndIf
WEnd

GUIDelete($hGui)
DllCallbackFree($wProcHandle)

Func createNextdragIP($nw)
    $start = WinGetPos($hgui)
    $hInput_GUI[$nw] = GUICreate("", 120, 22, 100, 100, $WS_POPUP, $WS_EX_TOOLWINDOW)
    $Input[$nw] = GUICtrlCreateEdit("", 0, 0, 120, 22, BitOR($ES_AUTOVSCROLL, $ES_AUTOHSCROLL, $ES_WANTRETURN))
   
    $hMenu = _GUICtrlMenu_CreatePopup()

    _GUICtrlMenu_AddMenuItem($hMenu, "Open", $idOpen)
    _GUICtrlMenu_AddMenuItem($hMenu, "Save", $idSave)
    _GUICtrlMenu_AddMenuItem($hMenu, "Info", $idInfo)
   
    GUISetState()   

EndFunc

Func WM_COMMAND($hWnd, $Msg, $wParam, $lParam)
    Local $iIDFrom = BitAND($wParam, 0xFFFF)
    Local $iCode = BitShift($wParam, 16)
   
    Switch $iCode
        Case $EN_UPDATE
            Local $iLen = _GUICtrlEdit_LineLength($iIDFrom)
           
            Local $aInputPos = ControlGetPos($hWnd, "", $iIDFrom)
            Local $aWinPos = WinGetPos($hWnd)
           
            If ($aInputPos[2] / $iLen) < 6.5 Then
                WinMove($hWnd, "", $aWinPos[0], $aWinPos[1], $aWinPos[2] + 10, $aWinPos[3])
                GUICtrlSetPos($iIDFrom, $aInputPos[0], $aInputPos[1], $aInputPos[2] + 10, $aInputPos[3])
            ElseIf ($aInputPos[2] / $iLen) > 6.5 Then
                WinMove($hWnd, "", $aWinPos[0], $aWinPos[1], $aWinPos[2] - 10, $aWinPos[3])
                GUICtrlSetPos($iIDFrom, $aInputPos[0], $aInputPos[1], $aInputPos[2] - 10, $aInputPos[3])
            EndIf
    EndSwitch

    Return $GUI_RUNDEFMSG   
EndFunc

Func _WindowProc($hWnd, $Msg, $wParam, $lParam)
    Switch $hWnd
        Case GUICtrlGetHandle($Input[$nw])
            Switch $Msg
                Case $WM_CONTEXTMENU
                    _GUICtrlMenu_TrackPopupMenu($hMenu, $wParam)
                    Return 0
                Case $WM_COMMAND
                    Switch $wParam
                        Case $idOpen
                          Msgbox(0, "", "!")
                        Case $idSave
                            ConsoleWrite("-> Save" & @LF)
                        Case $idInfo
                            ConsoleWrite("-> Info" & @LF)
                    EndSwitch
            EndSwitch
    EndSwitch
   
    Local $aRet = DllCall("user32.dll", "int", "CallWindowProc", "ptr", $wProcOld, _
                          "hwnd", $hWnd, "uint", $Msg, "wparam", $wParam, "lparam", $lParam)
    Return $aRet[0]
EndFunc
Link to comment
Share on other sites

I've been trying to get this to work with rasim's implementation of the custom context menus and I am having trouble getting it to work.

Can someone take a look plz?

Your $nw is a local variable input in one function, but is used in another. Same problem with $hMenu.

That much is just from running syntax check...

:P

Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Link to comment
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...