Jump to content

GUI ContextMenu created out of a TreeView


Holger
 Share

Recommended Posts

It's not really usefull but I was 'tired' to do some other things so I just made a context menu out of a treeview.

Just do with the code what you like to do.

It was just for fun :)

Greets

Holger

P.S. you can see it as flat menu by just replacing the $WS_DLGFRAME in the line:

Dim $hMenuGUI   = GUICreate("MenuGUI"...

with $WS_BORDER

post-1133-1187384557_thumb.jpg

treemenu.au3

post-1133-1187384977_thumb.jpg

Edited by Holger
Link to comment
Share on other sites

This is a nice example. Well done :)

My Programs:AInstall - Create a standalone installer for your programUnit Converter - Converts Length, Area, Volume, Weight, Temperature and Pressure to different unitsBinary Clock - Hours, minutes and seconds have 10 columns each to display timeAutoIt Editor - Code Editor with Syntax Highlighting.Laserix Editor & Player - Create, Edit and Play Laserix LevelsLyric Syncer - Create and use Synchronised Lyrics.Connect 4 - 2 Player Connect 4 Game (Local or Online!, Formatted Chat!!)MD5, SHA-1, SHA-256, Tiger and Whirlpool Hash Finder - Dictionary and Brute Force FindCool Text Client - Create Rendered ImageMy UDF's:GUI Enhance - Enhance your GUIs visually.IDEA File Encryption - Encrypt and decrypt files easily! File Rename - Rename files easilyRC4 Text Encryption - Encrypt text using the RC4 AlgorithmPrime Number - Check if a number is primeString Remove - remove lots of strings at onceProgress Bar - made easySound UDF - Play, Pause, Resume, Seek and Stop.
Link to comment
Share on other sites

  • 1 year later...

WOW, im abolutely stunned. :)

I searched almost any thread with the text "menu" in it to find an alternate context menu, which dont pause the scipt and works with a child GUI.

Now i see a graphical famous and functional context menu with tree view style.

Really thanks for that, i will use this for my Tool and give you credit >_<

Teamspeak 3 User Viewer - Quick and functional TS3 Query script, which shows online users.Cached Screenshot Deleter - Deletes older Fraps Screenshots if they exceed a specified limit.Unresolved Topics:Intercept and modify dragdrop text behaviour in scite
Link to comment
Share on other sites

Holger

Hey guru! Very, very nice example :) Little modification, if you do not object >_<

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <TreeViewConstants.au3>

GUIRegisterMsg($WM_NOTIFY, "WndProc")
GUIRegisterMsg($WM_ACTIVATE, "WndProc")

;*** Main-GUI ***
$hMainGUI       = GUICreate("My Tree Menu", 300, 200)

$nBtnMenu       = GUICtrlCreateButton("Show Menu", 10, 10, 100, 30)


;*** Tree-Menu-GUI ***
;Dim $hMenuGUI  = GUICreate("MenuGUI", 160, 160, -1, -1, BitOr($WS_POPUP, $WS_BORDER, $WS_CHILD), $WS_EX_TOOLWINDOW, $hMainGUI) ; Flat Menu
Dim $hMenuGUI   = GUICreate("MenuGUI", 160, 160, 120, 10, BitOr($WS_POPUP, $WS_DLGFRAME, $WS_CHILD))

DllCall("user32.dll", "int", "SetParent", "hwnd", $hMenuGUI, "hwnd", $hMainGUI)

Dim $nMenuTV    = GUICtrlCreateTreeView(0, 0, 160, 160, _
        BitOr($TVS_NOHSCROLL, $TVS_NONEVENHEIGHT, $TVS_FULLROWSELECT, $TVS_INFOTIP, $TVS_HASBUTTONS, $TVS_LINESATROOT)) ;, $TVS_TRACKSELECT))
GUICtrlSetBkColor(-1, 0xC0D0E0)
GUICtrlSetFont(-1, 10, -1, -1, "Comic Sans MS")

;*** Main-Menu ***
$nItemProgs     = GUICtrlCreateTreeViewItem("Office", $nMenuTV)
GUICtrlSetImage(-1, "shell32.dll", -20)
$nItemPrefs     = GUICtrlCreateTreeViewItem("Preferences", $nMenuTV)
GUICtrlSetImage(-1, "shell32.dll", -22)
$nItemAbout     = GUICtrlCreateTreeViewItem("About", $nMenuTV)
GUICtrlSetImage(-1, "shell32.dll", -24)
$nItemExit      = GUICtrlCreateTreeViewItem("Exit", $nMenuTV)
GUICtrlSetImage(-1, "shell32.dll", -28)

;*** Programs-Menu ***
$nItemCalc      = GUICtrlCreateTreeViewItem("Calculator", $nItemProgs)
GUICtrlSetImage(-1, "calc.exe", 0)
$nItemPaint     = GUICtrlCreateTreeViewItem("Paint", $nItemProgs)
GUICtrlSetImage(-1, "mspaint.exe", 0)
$nItemNote      = GUICtrlCreateTreeViewItem("Notepad", $nItemProgs)
GUICtrlSetImage(-1, "notepad.exe", 0)
$nItemWord      = GUICtrlCreateTreeViewItem("Wordpad", $nItemProgs)
GUICtrlSetImage(-1, "write.exe", 0)

;*** Prefs-Menu ***
GUICtrlCreateTreeViewItem("General", $nItemPrefs)
GUICtrlSetImage(-1, "shell32.dll", -13)
GUICtrlCreateTreeViewItem("Color", $nItemPrefs)
GUICtrlSetImage(-1, "mspaint.exe", 0)

GUISetState(@SW_SHOW, $hMainGUI)


While 1
    $Msg = GUIGetMsg()
    
    Switch $Msg
        Case $GUI_EVENT_CLOSE
            ExitLoop
            
        Case $nBtnMenu
            GUISetState(@SW_SHOW, $hMenuGUI)
    EndSwitch
WEnd

Exit

Func WndProc($hWnd, $Msg, $wParam, $lParam)
    Switch $Msg
        Case $WM_ACTIVATE
            Local $nState = BitShift($wParam, 16)
            Local $nActiv = BitAnd($wParam, 0x0000FFFF)
            Local $hActWnd = $lParam

            Switch $hActWnd
                Case 0
                    GUISetState(@SW_HIDE, $hMenuGUI)
                    
                Case $hMenuGUI
                    If $nActiv <> 0 Then
                        GUISetState(@SW_HIDE, $hMenuGUI)
                    Else
                        DllCall("user32.dll", "int", "SendMessage", "hwnd", $hMainGUI, "int", $WM_NCACTIVATE, "int", 1, "int", 0)
                    EndIf
            EndSwitch

    
        Case $WM_NOTIFY
            Local $stNMHDR = DllStructCreate("hwnd;uint;int", $lParam)
            Local $hWndFrom = DllStructGetData($stNMHDR, 1)
            Local $nIdFrom = DllStructGetData($stNMHDR, 2)
            Local $nCode = DllStructGetData($stNMHDR, 3)
            
            If $nIdFrom = $nMenuTV Then
                Local $stPT = DllStructCreate("int;int")
                GetCursorPos(DllStructGetPtr($stPT))
                ScreenToClient($hWnd, DllStructGetPtr($stPT))
                    
                Local $stTVHI = DllStructCreate("int[2];uint;hwnd")
                DllStructSetData($stTVHI, 1, DllStructGetData($stPT, 1), 1)
                DllStructSetData($stTVHI, 1, DllStructGetData($stPT, 2), 2)
                    
                GUICtrlSendMsg($nIdFrom, $TVM_HITTEST, 0, DllStructGetPtr($stTVHI))
                Local $hItem = DllStructGetData($stTVHI, 3)
                        
                Switch $nCode
                    Case $NM_CLICK
                        If $hItem <> 0 Then
                            GUICtrlSendMsg($nIdFrom, $TVM_EXPAND, $TVE_TOGGLE, $hItem)
                            
                            ;*** Now our treeview menu items ***
                            Switch $hItem
                                Case GUICtrlGetHandle($nItemCalc)
                                    Run("calc.exe")
                                    
                                Case GUICtrlGetHandle($nItemPaint)
                                    Run("mspaint.exe")
                                    
                                Case GUICtrlGetHandle($nItemNote)
                                    Run("notepad.exe")
                                    
                                Case GUICtrlGetHandle($nItemWord)
                                    Run("write.exe")
                                    
                                Case GUICtrlGetHandle($nItemAbout)
                                    MsgBox(64, "About", "TreeView-Menu Demo by Holger Kotsch")
                                    
                                Case GUICtrlGetHandle($nItemExit)
                                    Exit
                            EndSwitch
                            
                            Return 1
                        EndIf
                    
                    Case $NM_SETCURSOR
                        If $hItem <> 0 Then
                            GUICtrlSendMsg($nIdFrom, $TVM_SELECTITEM, $TVGN_CARET, $hItem)
                        Else
                            GUICtrlSendMsg($nIdFrom, $TVM_SELECTITEM, $TVGN_CARET, 0)
                        EndIf
                EndSwitch
            EndIf
            
            Return
    EndSwitch
EndFunc


Func GetCursorPos($pPOINT)
    Local $nResult = DllCall("user32.dll", "int", "GetCursorPos", _
                                                    "ptr", $pPOINT)
    Return $nResult[0]
EndFunc


Func ScreenToClient($hWnd, $pPOINT)
    Local $nResult = DllCall("user32.dll", "int", "ScreenToClient", _
                                                    "hwnd", $hWnd, _
                                                    "ptr", $pPOINT)
    Return $nResult[0]
EndFunc
Link to comment
Share on other sites

Ok the Treeviewstyle is really cool, but practically i need a standard rebuild of a default context menu and its behaviour.

So with my humble knowledge about windows messages and handling, i tried to build a simple Menu with Submenu out of Helges treeview Menu.

I know, the changes are horrible to read, but maybe anyone has the feeling to clean that a bit up and maybe improve the noob-like workarounds i put up for some problems.

Like the $isParentItem array for defining the Items with submenu or the " >" appendix.

I wish this would be more automated and maybe callable over a UDF like __GUICtrlCreateRebuiltMenuItem("text", MenuID [,$isParent=0])

#include <GUIConstantsEx.au3>
#include <WindowsConstants.au3>
#include <TreeViewConstants.au3>
#Include <GuiTreeView.au3>


$timer = ""
$hcurrItem = ""
$hGUIHover = ""
$isOverParentItem = 0
;*** Main-GUI ***
$hMainGUI       = GUICreate("My Tree Menu", 300, 200)

$nBtnMenu       = GUICtrlCreateButton("Show Menu", 10, 10, 100, 30)

;*** Tree-Menu-GUI ***
;Dim $hMenuGUI  = GUICreate("MenuGUI", 160, 160, -1, -1, BitOr($WS_POPUP, $WS_BORDER, $WS_CHILD), $WS_EX_TOOLWINDOW, $hMainGUI) ; Flat Menu
Dim $hMenuGUI   = GUICreate("MenuGUI", 160, 160, -1, -1, BitOr($WS_POPUP, $WS_DLGFRAME, $WS_CHILD), $WS_EX_TOOLWINDOW, $hMainGUI)

Dim $nMenuTV    = GUICtrlCreateTreeView(0, 0, 160, 160, _
BitOr($TVS_NOHSCROLL, $TVS_NONEVENHEIGHT, $TVS_FULLROWSELECT, $TVS_INFOTIP, $TVS_HASBUTTONS)) ;, $TVS_TRACKSELECT))
GUICtrlSetBkColor(-1, 0xD4D0C8)
GUICtrlSetFont(-1, 10, -1, -1, "Arial")

;*** Main-Menu ***
$nItemProgs     = GUICtrlCreateTreeViewItem("Office                       >", $nMenuTV)
GUICtrlSetImage(-1, "shell32.dll", -20)
$nItemPrefs     = GUICtrlCreateTreeViewItem("Preferences              >", $nMenuTV)
GUICtrlSetImage(-1, "shell32.dll", -22)
$nItemAbout     = GUICtrlCreateTreeViewItem("About", $nMenuTV)
GUICtrlSetImage(-1, "shell32.dll", -23)
$nItemExit      = GUICtrlCreateTreeViewItem("Exit", $nMenuTV)
GUICtrlSetImage(-1, "shell32.dll", -24)

Dim $isParentItem[10] = [1,1,0,0,0]


$hSubMenuGUI    = GUICreate("MenuGUI", 160, 160, -1, -1, BitOr($WS_POPUP, $WS_DLGFRAME, $WS_CHILD), $WS_EX_TOOLWINDOW, $hMainGUI)

$nSubMenuTV = GUICtrlCreateTreeView(0, 0, 160, 160, _
BitOr($TVS_NOHSCROLL, $TVS_NONEVENHEIGHT, $TVS_FULLROWSELECT, $TVS_INFOTIP, $TVS_HASBUTTONS)) ;, $TVS_TRACKSELECT))
GUICtrlSetBkColor(-1, 0xD4D0C8)
GUICtrlSetFont(-1, 10, -1, -1, "Arial")

$nItemCalc      = GUICtrlCreateTreeViewItem("Calculator", $nSubMenuTV)
GUICtrlSetImage(-1, "calc.exe", 0)
$nItemPaint     = GUICtrlCreateTreeViewItem("Paint", $nSubMenuTV)
GUICtrlSetImage(-1, "mspaint.exe", 0)
$nItemNote      = GUICtrlCreateTreeViewItem("Notepad", $nSubMenuTV)
GUICtrlSetImage(-1, "notepad.exe", 0)
$nItemWord      = GUICtrlCreateTreeViewItem("Wordpad", $nSubMenuTV)
GUICtrlSetImage(-1, "write.exe", 0)



GUISetState(@SW_SHOW, $hMainGUI)
GUIRegisterMsg($WM_NOTIFY, "MY_WM_NOTIFY")

GUIRegisterMsg($WM_SETCURSOR, "MY_WM_NOTIFY")



$i = 0
While 1
    $i += 1
    GUICtrlSetData($nBtnMenu,$i)
    If $i = 100 Then $i = 0
    Sleep(20)
    
    
    
    If $timer <> "" Then
        If TimerDiff($timer) > 500 Then
            If $hGUIHover <> $hSubMenuGUI And Not $isOverParentItem Then ; if timer and
                ConsoleWrite("hmm hide?" & @CRLF)
                _GUICtrlTreeView_EndUpdate($nMenuTV)
                GUISetState(@SW_HIDE, $hSubMenuGUI)
                GUICtrlSetState($nMenuTV,$GUI_FOCUS)
                DllCall("user32.dll", "int", "SendMessage", "hwnd", $hMainGUI, "int", $WM_NCACTIVATE, "int", 1, "int", 0)
                $timer = ""
            ElseIf $hGUIHover = $hMenuGUI And $isOverParentItem then
                $arPos = WinGetPos($hMenuGUI)
                If IsArray($arPos) Then
                    $itemidx = _GUICtrlTreeView_Index($nMenuTV, $hcurrItem)
                    ConsoleWrite("verschiebe Submenu" & @CRLF)
                    WinMove($hSubMenuGUI, "", $arPos[0]+$arPos[2], $arPos[1]+$itemidx*21) ; +$parentidx*21
                EndIf
                _GUICtrlTreeView_BeginUpdate($nMenuTV)
                GUISetState(@SW_SHOW, $hSubMenuGUI)
                GUICtrlSetState($nSubMenuTV,$GUI_FOCUS)
                $timer = ""
            Else
                
            EndIf
        EndIf
    EndIf

    $Msg = GUIGetMsg()
    Switch $Msg
        Case $GUI_EVENT_CLOSE
            ExitLoop
            
        Case $nBtnMenu
            $arPos = ControlGetPos($hMainGUI, "", $nBtnMenu)
            If IsArray($arPos) Then
                $stPT = DllStructCreate("int;int")
                DllStructSetData($stPT, 1, $arPos[0])
                DllStructSetData($stPT, 2, $arPos[1])
                
                ClientToScreen($hMainGUI, DllStructGetPtr($stPT))
                
                WinMove($hMenuGUI, "", DllStructGetData($stPT, 1) + 100, DllStructGetData($stPT, 2))
                GUISetState(@SW_SHOW, $hMenuGUI)
                
                DllCall("user32.dll", "int", "SendMessage", "hwnd", $hMainGUI, "int", $WM_NCACTIVATE, "int", 1, "int", 0)
            EndIf
    EndSwitch
WEnd


Exit


Func MY_WM_NOTIFY($hWnd, $Msg, $wParam, $lParam)
    Switch $Msg
        Case $WM_SETCURSOR
            Switch $hWnd
                Case $hGUIHover
                Case Else
                    ConsoleWrite("Changed focus to: ")
                    Switch $hWnd
                        Case $hMainGUI
                            $hGUIHover = $hMainGUI
                            ConsoleWrite("MainGUI, Timer init" & @CRLF)
                            $timer = TimerInit()
                            $isOverParentItem = 0
                            Return $Gui_RUNDEFMSG
                        Case $hMenuGUI
                            $hGUIHover = $hMenuGUI
                            ConsoleWrite("MenuGUI, timer init" & @CRLF)
                            $timer = TimerInit()
                        Case $hSubMenuGUI
                            $hGUIHover = $hSubMenuGUI
                            ConsoleWrite("SubMenuGUI" & @CRLF)
                    EndSwitch
            EndSwitch

        Case $WM_NOTIFY
            Local $stNMHDR = DllStructCreate("hwnd;uint;int", $lParam)
            Local $hWndFrom = DllStructGetData($stNMHDR, 1)
            Local $nIdFrom = DllStructGetData($stNMHDR, 2)
            Local $nCode = DllStructGetData($stNMHDR, 3)
            If $hGUIHover = $hMenuGUI And $nIdFrom <> $nMenuTV Then Return $Gui_RUNDEFMSG
            If $hGUIHover = $hSubMenuGUI And $nIdFrom <> $nSubMenuTV Then Return $Gui_RUNDEFMSG
            Switch $nIdFrom
                Case $nMenuTV,$nSubMenuTV

                    Local $stPT = DllStructCreate("int;int")
                    GetCursorPos(DllStructGetPtr($stPT))
                    ScreenToClient($hWnd, DllStructGetPtr($stPT))
                    
                    Local $stTVHI = DllStructCreate("int[2];uint;hwnd")
                    DllStructSetData($stTVHI, 1, DllStructGetData($stPT, 1), 1)
                    DllStructSetData($stTVHI, 1, DllStructGetData($stPT, 2), 2)
                        
                    GUICtrlSendMsg($nIdFrom, $TVM_HITTEST, 0, DllStructGetPtr($stTVHI))
                    Local $hItem = DllStructGetData($stTVHI, 3)
            EndSwitch
            
            Switch $nCode
                Case $NM_SETCURSOR
;~                  ConsoleWrite(_WhichGUI($hWnd)&" <> "&_WhichGUI($hGUIHover) & @CRLF)
                    If $nIdFrom = $nMenuTV Then
                        If $hItem <> 0 Then
                            If $hcurrItem = $hItem Then Return $Gui_RUNDEFMSG
                            $hcurrItem = $hItem
                            $_idx = _GUICtrlTreeView_Index($nMenuTV, $hcurrItem)
                            $isOverParentItem = 0
                            If $_idx >= 0 And $isParentItem[$_idx] Then
                                $isOverParentItem = 1
                                If $timer = "" Then
                                    ConsoleWrite("timer start" & @CRLF)
                                    _GUICtrlTreeView_EndUpdate($nMenuTV)
                                    GUICtrlSetState($nMenuTV,$GUI_FOCUS)
                                    $timer = TimerInit()
                                EndIf
                            EndIf
                            $timer = TimerInit()
                            _GUICtrlTreeView_EndUpdate($nMenuTV)
                            GUICtrlSetState($nMenuTV,$GUI_FOCUS)
    ;~                      DllCall("user32.dll", "int", "SendMessage", "hwnd", $hMenuGUI, "int", $WM_NCACTIVATE, "int", 1, "int", 0)
                            GUICtrlSendMsg($nIdFrom, $TVM_SELECTITEM, $TVGN_CARET, $hItem)
    ;~                      ConsoleWrite("selecting item: "&$_idx & @CRLF)
                        Else
    ;~                      ConsoleWrite("selecting item 0"& @CRLF)
    ;~                      DllCall("user32.dll", "int", "SendMessage", "hwnd", $hMenuGUI, "int", $WM_NCACTIVATE, "int", 1, "int", 0)
                            GUICtrlSendMsg($nIdFrom, $TVM_SELECTITEM, $TVGN_CARET, 0)
                        EndIf
                    ElseIf $nIdFrom = $nSubMenuTV Then
                        If $hItem <> 0 Then
                            $hcurrItem = $hItem
                            If $timer = "" Then
                                ConsoleWrite("new:"&$hcurrItem & @CRLF)
                                $timer = TimerInit()
                            EndIf
                            GUICtrlSendMsg($nIdFrom, $TVM_SELECTITEM, $TVGN_CARET, $hItem)
                        Else
                            GUICtrlSendMsg($nIdFrom, $TVM_SELECTITEM, $TVGN_CARET, 0)
                        EndIf

                    EndIf
                Case $NM_CLICK
                    If $hItem <> 0 Then
                        GUICtrlSendMsg($nIdFrom, $TVM_EXPAND, $TVE_TOGGLE, $hItem)
                        
                        ;*** Now our treeview menu items ***
                        Switch $hItem
                            Case GUICtrlGetHandle($nItemCalc)
                                Run("calc.exe")
                                
                            Case GUICtrlGetHandle($nItemPaint)
                                Run("mspaint.exe")
                                
                            Case GUICtrlGetHandle($nItemNote)
                                Run("notepad.exe")
                                
                            Case GUICtrlGetHandle($nItemWord)
                                Run("write.exe")
                                
                            Case GUICtrlGetHandle($nItemAbout)
                                MsgBox(64, "About", "TreeView-Menu Demo by Holger Kotsch")
                                
                            Case GUICtrlGetHandle($nItemExit)
                                Exit
                        EndSwitch
                        
                        Return 1
                    EndIf
            EndSwitch
            
    EndSwitch
    Return $Gui_RUNDEFMSG
EndFunc


Func GetCursorPos($pPOINT)
    Local $nResult = DllCall("user32.dll", "int", "GetCursorPos", _
                                                    "ptr", $pPOINT)
    Return $nResult[0]
EndFunc


Func ScreenToClient($hWnd, $pPOINT)
    Local $nResult = DllCall("user32.dll", "int", "ScreenToClient", _
                                                    "hwnd", $hWnd, _
                                                    "ptr", $pPOINT)
    Return $nResult[0]
EndFunc


Func ClientToScreen($hWnd, $pPOINT)
    Local $nResult = DllCall("user32.dll", "int", "ClientToScreen", _
                                                    "hwnd", $hWnd, _
                                                    "ptr", $pPOINT)
    Return $nResult[0]
EndFunc

Func _WhichGUI($hWnd)
    Switch $hWnd
        Case $hMainGUI
            Return "MainGUI"
        Case $hMenuGUI
            Return "MenuGUI"
        Case $hSubMenuGUI
            Return "SubMenuGUI"
    EndSwitch
EndFunc
Teamspeak 3 User Viewer - Quick and functional TS3 Query script, which shows online users.Cached Screenshot Deleter - Deletes older Fraps Screenshots if they exceed a specified limit.Unresolved Topics:Intercept and modify dragdrop text behaviour in scite
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...