Jump to content
Sign in to follow this  
jvnorris

Alternate Context menu

Recommended Posts

jvnorris

I was wondering if it is possible to creat an alternat context menu to run different stuff.

It would be like holding Alt and rigt clicking will bring up a menu that has special options or whatnot on it.

Any possibility?

THis menu is to show up no matter what window I am in also

Edited by jvnorris

Share this post


Link to post
Share on other sites
rasim

I think this impossible, because menu disappear if any key pressed.

Share this post


Link to post
Share on other sites
covaks

Well, this will create a context window for you anywhere. But you lose all your other context windows..

Unless.. I have a script I use at work that is similar to this below. Except it actually checks what window is active, and what control is under the mouse. That way I am able to create different context menus for different programs, depending on where you right click, or if I haven't made a context window for that particular window/control, it just passes on the event and brings up the default context menu. I used _CtrlGetByPos() function from Sm0ke_N, and modified the MouseSetOnEvent_UDF to let me set my own return values. So, on a mouse secondary down event, it checks the active window, checks _CtrlGetByPos to see what control is under the mouse, and then pops up the proper context menu. Otherwise, it simple returns 0 to pass on the event to the other window. If that makes any sense.. I'm tired and probably becoming incoherent. :-)

You can get the MouseSetOnEvent UDF Here

#include "MouseSetOnEvent_UDF.au3"
#include <GuiConstants.au3>

opt("GUIOnEventMode",1)

$hGui = GuiCreate("",1,1,-1,-1,$WS_POPUP)
GuiSetstate()


$hContext = GUICtrlCreateContextMenu()
$hItem1 = GUICtrlCreateMenuItem("Item1",$hContext)
GUICtrlSetOnEvent(-1,"Item1")
$hItem2 = GUICtrlCreateMenuItem("Item2",$hContext)
GUICtrlSetOnEvent(-1,"Item2")

_MouseSetOnEvent($MOUSE_SECONDARYDOWN_EVENT, "MouseSecondaryDown_Event")

Func MouseSecondaryDown_Event()
    Local $pos
    $pos = MouseGetPos()
    WinMove($hGui,"",$pos[0],$pos[1])
    GUISetState(@SW_SHOW)
EndFunc

Func Item1()
    GuiSetState(@SW_HIDE,$hGui)
    msgbox(0,"","Item 1")
EndFunc

Func Item2()
    GuiSetState(@SW_HIDE,$hGui)
    msgbox(0,"","Item 2")
EndFunc

While 1
    sleep(5)
WEnd

Share this post


Link to post
Share on other sites
smashly

Hi, same thing but using a condition that the CTRL key is pressed when right clicking offers the menu anywhere in windows.

(could make it just about any key as a modifier apart from ALT. As ALT key natively cancels any context menu in windows)

#include <GuiConstants.au3>
#include <Misc.au3>
#Include <WinAPI.au3>

Global $Key = "11" ;CTRL key

$hGUI = GUICreate("Menu", 1, 1, -1, -1, $WS_POPUP, BitOr($WS_EX_TOOLWINDOW, $WS_EX_TOPMOST))
$Context0 = GUICtrlCreateContextMenu()
$Context1 = GUICtrlCreateMenuItem("Do Something", $Context0)
GUICtrlCreateMenuItem("", $Context0)
$Context2 = GUICtrlCreateMenuItem("Exit", $Context0)
GUISetState(@SW_HIDE, $hGUI)

AdlibEnable("EnMenu", 10)

While 1
    $msg = GUIGetMsg()
    Switch $msg
        Case $GUI_EVENT_CLOSE, $Context2
            Exit    
        Case $Context1
            MsgBox(0, "Do what?", "What to do?")
    EndSwitch
WEnd

Func EnMenu()
    Local $GMP = _WinAPI_GetMousePos(False, $hGUI)
    WinMove($hGUI, "", DllStructGetData($GMP, "X"), DllStructGetData($GMP, "Y") )
    If Not BitAnd(WinGetState($hGUI), 2) And _IsPressed($Key) Then
        GUISetState(@SW_SHOW, $hGUI)
    ElseIf BitAnd(WinGetState($hGUI), 2) And (Not _IsPressed($Key)) Then 
        GUISetState(@SW_HIDE, $hGUI)
    EndIf
EndFunc

Cheers

Edit: Added the Key at the top of the script to make it easier to customise the modifier key.

Edited by smashly

Share this post


Link to post
Share on other sites
rasim

smashly

Nice example my frend! I like it! :)

Share this post


Link to post
Share on other sites
jvnorris

@Smashly

Wonderful Job mate. THanks for the example. I can now use this as a base at least for what I want to do. (Using the CTRL Key makes Cutting and pasting hard) Also I had to add another include I will repost when At my office computer with what it was

Share this post


Link to post
Share on other sites
wraithdu

Here's another example using the MouseSetOnEvent() UDF that I just used for an app of mine.

Advantages - no need for Adlib (some people don't like it), can use the ALT key modifier

Disadvantage - you cannot click off the context menu to make it disappear, so the 'Cancel' option is needed

PS - I really like smashly's example though, very slick :P

#include <GuiConstantsEx.au3>
#include <WindowsConstants.au3>
#include <_MouseSetOnEvent.au3>
#include <Misc.au3>

Opt("GUIOnEventMode", 1)

Global $hwnd = -1
Global $user32 = DllOpen("user32.dll")

$gui = GUICreate("dummy", 40, 40, -100, -100, -1, $WS_EX_TOOLWINDOW)
$label = GUICtrlCreateLabel("", 0, 0, 20, 20)
$context = GUICtrlCreateContextMenu($label)
$menu = GUICtrlCreateMenuItem("Menu Item", $context)
GUICtrlCreateMenuItem("", $context)
$cancel = GUICtrlCreateMenuItem("Cancel", $context)
$exit = GUICtrlCreateMenuItem("Exit", $context)

GUICtrlSetOnEvent($menu, "_MenuAction")
GUICtrlSetOnEvent($cancel, "_ClickOff")
GUICtrlSetOnEvent($exit, "_GUIClose")

GUISetOnEvent($GUI_EVENT_CLOSE, "_GUIClose")

_MouseSetOnEvent($MOUSE_SECONDARYDOWN_EVENT, "_dummy")
_MouseSetOnEvent($MOUSE_SECONDARYUP_EVENT, "_Menu")

GUISetState()

While 1
    Sleep(1000)
WEnd

Func _Menu()
    If _IsPressed("10", $user32) And _IsPressed("11", $user32) Then
        ControlClick($gui, "", $label, "right")
    Else
        _MouseSetOnEvent($MOUSE_SECONDARYDOWN_EVENT)
        _MouseSetOnEvent($MOUSE_SECONDARYUP_EVENT)
        MouseUp("right")
        _MouseSetOnEvent($MOUSE_SECONDARYDOWN_EVENT, "_dummy")
        _MouseSetOnEvent($MOUSE_SECONDARYUP_EVENT, "_Menu")
    EndIf
EndFunc

Func _dummy()
    If Not _IsPressed("10", $user32) Or Not _IsPressed("11", $user32) Then
; allow click
        _MouseSetOnEvent($MOUSE_SECONDARYDOWN_EVENT)
        _MouseSetOnEvent($MOUSE_SECONDARYUP_EVENT)
        MouseDown("right")
        _MouseSetOnEvent($MOUSE_SECONDARYDOWN_EVENT, "_dummy")
        _MouseSetOnEvent($MOUSE_SECONDARYUP_EVENT, "_Menu")
    EndIf
EndFunc

Func _ClickOff()
    ControlClick($gui, "", $label, "left")
    $hwnd = -1
EndFunc

Func _MenuAction()
    MsgBox(0, "", "Menu Action")
    $hwnd = -1
EndFunc

Func _GUIClose()
    DllClose($user32)
    Exit
EndFunc
Edited by wraithdu

Share this post


Link to post
Share on other sites
wraithdu

Hmm, I've been working with these 2 examples, and performance seems to be better for smashly's example. But I'm having a problem. My script (big one) uses OnEventMode. The menu item events are not fired unless the 1px GUI is showing (ie not hidden). But the adlib keeps running and hides the GUI as soon as I let go the modifier keys. So to fire a menu event, I have to keep my modifier keys held when I click the menu item.

Ideally I need a way to test if the context menu is showing or not, and only rehide the GUI if it is not showing (user clicked off the menu). So far I haven't found a way to do it. Any ideas? I'd rather not convert the script to msg mode if it can be avoided.

Share this post


Link to post
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
Sign in to follow this  

×