Sign in to follow this  
Followers 0
thepip3r

Is there a way to make a submenu button clickable and also provide the submenu functionality?

11 posts in this topic

Let me elaborate... I've got a menu -> submenu style system and what I've been trying to figure out is if there's a way to make a menu that has a sub-menu also execute a function if the entry is say, double-clicked as opposed to single-clicked to show the submenu??

I've tried adding a GUICtrlSetOnEvent(-1,"__myParentMenuVarFun") under my GUICtrlCreateMenu("ParentMenuWithSub",-1,1) but alas, that didn't work. Does anyone know if this is possible?? Btw, when I tried the code, I didn't get an error or anything, just nothing happened but the submenu popped up on click.

Code Sample

$menuFileParent     = GUICtrlCreateMenu("&File")
$menuFileOpen       = GUICtrlCreateMenuitem("Open",$menuFileParent)
GUICtrlSetState(-1,$GUI_DEFBUTTON)
GUICtrlSetOnEvent(-1,"__menuFileOpen")
$menuFileRecent     = GUICtrlCreateMenu("Recent Files",$menuFileParent,1)
$menuFileExit       = GUICtrlCreateMenuItem("Exit",$menuFileParent)
GUICtrlSetOnEvent(-1,"__Exit")

$menuViewParent     = GUICtrlCreateMenu("View",-1,1)
$menuViewStatusBar  = GUICtrlCreateMenuitem ("Status Bar",$menuViewParent)
GUICtrlSetState(-1,$GUI_CHECKED)
GUICtrlSetOnEvent(-1,"__menuViewStatusToggle")

$menuRunParent  = GUICtrlCreateMenu("Run...",-1,2)
    $menuAllProgsParent = GUICtrlCreateMenu("All Programs",$menuRunParent)
        __DirtoMenu("C:\Documents and Settings\All Users\Start Menu\Programs",$menuAllProgsParent)
    $menuControlPanelParent = GUICtrlCreateMenuItem("Control Panel",$menuRunParent)
        GUICtrlSetOnEvent(-1,"__menuControlPanelClick")
    $menuSpecialFoldersParent = GUICtrlCreateMenu("Special Folders",$menuRunParent)
                                GUICtrlSetOnEvent(-1,"__myParentMenuVarFun") <---- This was my attempt; the function was just a msgbox to test it so far.
        For $i=0 To Ubound($arrSpecialFolders)-1
            $SpecialFoldersVal = GUICtrlCreateMenuItem($arrSpecialFolders[$i][0],$menuSpecialFoldersParent)
            GUICtrlSetOnEvent(-1,"__SpecialFoldersToMenu")
        Next
    $menuShell32DLLParent = GUICtrlCreateMenu("Shell32.DLL",$menuRunParent)
        For $i=0 To Ubound($arrShell32DLL)-1
            $Shell32DLLVal = GUICtrlCreateMenuItem($arrShell32DLL[$i][0],$menuShell32DLLParent)
            GUICtrlSetOnEvent(-1,"__Shell32DLLToMenu")
        Next

My Additions:- RunAs AdminDeviant Fun:- Variable Sound Volume

Share this post


Link to post
Share on other sites



Study this slightly modified help file sample:

Func testSubMenues()
    GUICreate("My GUI menu",300,200)

    Global $defaultstatus = "Ready"
    Global $status

    $filemenu = GUICtrlCreateMenu ("&File")
    $fileitem = GUICtrlCreateMenuitem ("Open",$filemenu)
    GUICtrlSetState(-1,$GUI_DEFBUTTON)
    $helpmenu = GUICtrlCreateMenu ("?")
    $saveitem = GUICtrlCreateMenuitem ("Save",$filemenu)
    GUICtrlSetState(-1,$GUI_DISABLE)
    $infoitem = GUICtrlCreateMenuitem ("Info",$helpmenu)
    $exititem = GUICtrlCreateMenuitem ("Exit",$filemenu)
    $recentfilesmenu = GUICtrlCreateMenu ("Recent Files",$filemenu,1)

    $separator1 = GUICtrlCreateMenuitem ("",$filemenu,2)    ; create a separator line

    $viewmenu = GUICtrlCreateMenu("View",-1,1)  ; is created before "?" menu
    $viewstatusitem = GUICtrlCreateMenuitem ("Statusbar",$viewmenu)
    GUICtrlSetState(-1,$GUI_CHECKED)
    $okbutton = GUICtrlCreateButton ("OK",50,130,70,20)
    GUICtrlSetState(-1,$GUI_FOCUS)
    $cancelbutton = GUICtrlCreateButton ("Cancel",180,130,70,20)

    $statuslabel = GUICtrlCreateLabel ($defaultstatus,0,165,300,16,BitOr($SS_SIMPLE,$SS_SUNKEN))
    Local $id="~" ; Need something but 0
    GUISetState ()
    While 1
        $msg = GUIGetMsg()
        if $msg = 0 then 
            sleep(100)
        else
            If $msg = $fileitem Then
                $file = FileOpenDialog("Choose file...",@TempDir,"All (*.*)")
                If @error <> 1 Then $id = GUICtrlCreateMenuitem ($file,$recentfilesmenu) ;;NOTE: Modified 
            EndIf 
            If $msg = $viewstatusitem Then
                If BitAnd(GUICtrlRead($viewstatusitem),$GUI_CHECKED) = $GUI_CHECKED Then
                    GUICtrlSetState($viewstatusitem,$GUI_UNCHECKED)
                    GUICtrlSetState($statuslabel,$GUI_HIDE)
                Else
                    GUICtrlSetState($viewstatusitem,$GUI_CHECKED)
                    GUICtrlSetState($statuslabel,$GUI_SHOW)
                EndIf
            EndIf
            ;NOTE: Why does $msg:=0 = $id:=~ return true? (autoit-v3.2.9.1)
            If $msg = $id Then msgbox(48, "Menu item selected", $id & " <==> " & $msg, 5) ;NOTE: New line 
            If $msg = $GUI_EVENT_CLOSE Or $msg = $cancelbutton Or $msg = $exititem Then ExitLoop
            If $msg = $infoitem Then Msgbox(0,"Info","Only a test...")
        EndIf
    WEnd
    GUIDelete()
EndFunc

Hope that helps..:)

Share this post


Link to post
Share on other sites

I might have misinterpreted your problem/task.

Can you give samples of applications having this behavior?

Let me elaborate... I've got a menu -> submenu style system and what I've been trying to figure out is if there's a way to make a menu that has a sub-menu also execute a function if the entry is say, double-clicked as opposed to single-clicked to show the submenu??

Share this post


Link to post
Share on other sites

yes i've been looking over your code sample and it looks to be the code sample from the online documentation. I understand how to make the menu, submenu style interface. I also understand how to make menu entries perform functions when you click them. My question is for those menu entries that have submenus under them: Instead of only showing the submenu which is what it's intrinsic function is, is there a way to also make it perform a UDF based off of another event also??? ...like say on a dbl click?


My Additions:- RunAs AdminDeviant Fun:- Variable Sound Volume

Share this post


Link to post
Share on other sites

As I understand it they are supposed to hide after the first click, so I don't think you will be able to do that.

You might be able to create hover like functionality by tracking mouse movement over the menu item.

If you want to (really need to) distinguish between single and double click's I believe you need a custom (not win32 native) menu item. Search for owner drawn and menu in the examples forum.

Share this post


Link to post
Share on other sites

hmm... i'm still not sure if my question is being understood or not. here's an example. If this is my working code:

#include <GUIConstants.au3>
#include <file.au3>
#include <array.au3>
#include <Constants.au3>
#include <GuiEdit.au3>
#NoTrayIcon

Opt("GuiOnEventMode", 1)
Opt("RunErrorsFatal", 0)


; ----------        GUI CREATION        -----------
$mainWindow =   GUICreate("RunAs Admin",400,325)


; ----------        MENU        -----------

$menuRunParent  = GUICtrlCreateMenu("Run...",-1,2)
    $menuAllProgsParent = GUICtrlCreateMenu("All Programs",$menuRunParent)
        $menutest   = GUICtrlCreateMenuItem("test",$menuAllProgsParent)
        GUICtrlSetOnEvent(-1,"__test")

GUISetOnEvent($GUI_EVENT_CLOSE, "__Exit")
GUISetState(@SW_SHOW)



GUISetState()
While 1
    Sleep(100)
WEnd


Func __Exit()
    Exit
EndFunc


Func __test()
    MsgBox(0,"","hooray!")
EndFunc

...u can see the menu -> submenu style interface. But, what if i wanted to keep it the same way as above, except if the "All Programs" menu was dbl-clicked as well as being single-clickable or hovered over? And on that dbl-click, can i have it execute a function?? the only way I can conceptualize this with my limited knowledge of the Autoit gui commands using the code sample above is the following:

#include <GUIConstants.au3>
#include <file.au3>
#include <array.au3>
#include <Constants.au3>
#include <GuiEdit.au3>
#NoTrayIcon

Opt("GuiOnEventMode", 1)
Opt("RunErrorsFatal", 0)


; ----------        GUI CREATION        -----------
$mainWindow =   GUICreate("RunAs Admin",400,325)


; ----------        MENU        -----------

$menuRunParent  = GUICtrlCreateMenu("Run...",-1,2)
    $menuAllProgsParent = GUICtrlCreateMenu("All Programs",$menuRunParent)
                GUICtrlSetOnEvent(-1,"__someOtherFunc")
        $menutest   = GUICtrlCreateMenuItem("test",$menuAllProgsParent)
        GUICtrlSetOnEvent(-1,"__test")

GUISetOnEvent($GUI_EVENT_CLOSE, "__Exit")
GUISetState(@SW_SHOW)



GUISetState()
While 1
    Sleep(100)
WEnd


Func __Exit()
    Exit
EndFunc


Func __test()
    MsgBox(0,"","hooray!")
EndFunc

Func __someOtherFunc()
    MsgBox(0,"","hooray!")
EndFunc

My Additions:- RunAs AdminDeviant Fun:- Variable Sound Volume

Share this post


Link to post
Share on other sites

Pleas answer this: Do you know of any other application where this usage is implemented? Does not have to be an AutoIt application. Any one will do.

Share this post


Link to post
Share on other sites

yes... the Windows(XP) Start Menu. If you click Start, All Programs, and then dbl-click something on that menu (that has a sub menu), say the Microsoft Office entry (if you have it installed), it brings up Explorer with the path to the Microsoft Office folder. You can do that with all of the items on the All Programs folder that have sub menus. Does that help clear it up?


My Additions:- RunAs AdminDeviant Fun:- Variable Sound Volume

Share this post


Link to post
Share on other sites

#9 ·  Posted (edited)

Try this:

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

$Gui = GuiCreate("Menu Handler Demo")

$Main_Menu = GUICtrlCreateMenu("Menu")

$SubMenu = GUICtrlCreateMenu("SubMenu", $Main_Menu)
$MenuItem = GUICtrlCreateMenuItem("Item 1", $SubMenu)

GUISetState()

$ah_Timer = _TimerStart("CheckSubMenu_Proc", 100)

While 1
    $Msg = GUIGetMsg()
    Switch $Msg
        Case $GUI_EVENT_CLOSE
            _TimerStop($ah_Timer[0], $ah_Timer[1])
            Exit
        Case $MenuItem
            MenuItemClicked_Proc()
    EndSwitch
WEnd

Func CheckSubMenu_Proc($hWndGUI, $MsgID, $WParam, $LParam)
    If _IsPressed(1) Then
        Local $iOld_MCM = Opt("MouseCoordMode", 2)
        Local $aMouse_Pos = MouseGetPos()
        
        If $aMouse_Pos[0] >= 0 And $aMouse_Pos[0] <= 78 And $aMouse_Pos[1] >= 0 And $aMouse_Pos[1] <= 16 Then
            _TimerStop($ah_Timer[0], $ah_Timer[1])
            
            SubMenuClicked_Proc()
            
            $ah_Timer = _TimerStart("CheckSubMenu_Proc", 200)
        EndIf
        
        Opt("MouseCoordMode", $iOld_MCM)
    EndIf
EndFunc

Func MenuItemClicked_Proc()
    MsgBox(0, "", "MenuItem Clicked")
EndFunc

Func SubMenuClicked_Proc()
    MsgBox(0, "", "SubMenu Clicked")
EndFunc

Func _TimerStart($sFunction, $iTime=250)
    Local $hCallBack = DllCallbackRegister($sFunction, "none", "hwnd;int;int;dword")
    
    Local $aDll = DllCall("user32.dll", "int", "SetTimer", _
        "hwnd", 0, _
        "int", TimerInit(), _
        "int", $iTime, _
        "ptr", DllCallbackGetPtr($hCallBack))
    
    Local $aRet[2] = [$hCallBack, $aDll[0]]
    Return $aRet
EndFunc

Func _TimerStop($hCallBack, $hTimer)
    DllCallBackFree($hCallBack)
    Local $aRet = DllCall("user32.dll", "int", "KillTimer", "hwnd", 0, "int", $hTimer)
    Return $aRet[0]
EndFunc

I really have no idea how to get current hovered submenu id/handle (all known to me methods faild), that's why i used mouse coords method.

P.S

I don't think that start menu uses standard Menu, the class says ToolbarWindow32, so it probably a custom toolbar with buttons and custom items.

Edited by MsCreatoR

 

Spoiler

Using OS: Win 7 Professional, Using AutoIt Ver(s): 3.3.6.1 / 3.3.8.1

AutoIt_Rus_Community.png AutoIt Russian Community

My Work...

Spoiler

AutoIt_Icon_small.pngProjects: ATT - Application Translate Tool {new}| BlockIt - Block files & folders {new}| SIP - Selected Image Preview {new}| SISCABMAN - SciTE Abbreviations Manager {new}| AutoIt Path Switcher | AutoIt Menu for Opera! | YouTube Download Center! | Desktop Icons Restorator | Math Tasks | KeyBoard & Mouse Cleaner | CaptureIt - Capture Images Utility | CheckFileSize Program

AutoIt_Icon_small.pngUDFs: OnAutoItErrorRegister - Handle AutoIt critical errors {new}| AutoIt Syntax Highlight {new}| Opera Library! | Winamp Library | GetFolderToMenu | Custom_InputBox()! | _FileRun UDF | _CheckInput() UDF | _GUIInputSetOnlyNumbers() UDF | _FileGetValidName() UDF | _GUICtrlCreateRadioCBox UDF | _GuiCreateGrid() | _PathSplitByRegExp() | _GUICtrlListView_MoveItems - UDF | GUICtrlSetOnHover_UDF! | _ControlTab UDF! | _MouseSetOnEvent() UDF! | _ProcessListEx - UDF | GUICtrl_SetResizing - UDF! | Mod. for _IniString UDFs | _StringStripChars UDF | _ColorIsDarkShade UDF | _ColorConvertValue UDF | _GUICtrlTab_CoverBackground | CUI_App_UDF | _IncludeScripts UDF | _AutoIt3ExecuteCode | _DragList UDF | Mod. for _ListView_Progress | _ListView_SysLink | _GenerateRandomNumbers | _BlockInputEx | _IsPressedEx | OnAutoItExit Handler | _GUICtrlCreateTFLabel UDF | WinControlSetEvent UDF | Mod. for _DirGetSizeEx UDF
 
AutoIt_Icon_small.pngExamples: 
ScreenSaver Demo - Matrix included | Gui Drag Without pause the script | _WinAttach()! | Turn Off/On Monitor | ComboBox Handler Example | Mod. for "Thinking Box" | Cool "About" Box | TasksBar Imitation Demo

Like the Projects/UDFs/Examples? Please rate the topic (up-right corner of the post header: Rating AutoIt_Rating.gif)

* === My topics === *

==================================================
My_Userbar.gif
==================================================

 

 

 

AutoIt is simple, subtle, elegant. © AutoIt Team

Share this post


Link to post
Share on other sites

Yes that explains what you want (or where you got the consept..:) If you use au3info.exe you will probably see that it is not a stock menu ( as MsCreatoR pointed out) but a special kind of application. To create your own you can create the root level menu ( as seen in most applications beneath the title bar). When a user hits (by mouse or hotkey) a menu item (say File) You pop up your special window (no border) filled with buttons//image areas? Or take a look at my previous suggestion..:)

Share this post


Link to post
Share on other sites

thanx so much for the help guys... i'm sorry for not getting back sooner. While the method does work that MSCreator suggested, it simply makes a hotspot on the gui that performs a function when clicked (as you guys already know). LoL, it took me looking at the code for like 5 mins before i figured out how you were doing it. Unfortunately while I really do appreciate the code MSCreator, I'm afraid I'd only want that hot spot if it only worked when the menu ID was clicked and more unfortunately, I'm not good enough to figure that out on my own. I'm going to suspend this endeavor for my gui for now since I seem to get so side-tracked on something so trivial.

Thanx again Uten and MSCreator.


My Additions:- RunAs AdminDeviant Fun:- Variable Sound Volume

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  
Followers 0