Sign in to follow this  
Followers 0
Djordhan

Context Menu in Treeview Items

16 posts in this topic

#1 ·  Posted (edited)

Hi there,

I tried using GUICtrlCreateContextMenu on an Treeview item created with _GUICtrlTreeView_AddChild. Unfortunately, this function returns the handle instead of the ID. So GUICtrlCreateContextMenu can't be used. I try retreiving the ID using _WinAPI_GetDlgCtrlID($itemhandle) without success. It fails and return 0.

Is there a way to create a Context Menu on an item created with _GUICtrlTreeView_AddChild ?

Muchas gracias

JD

SOLVED

EDIT: Solution from Mat

#include <GuiConstantsEx.au3>
#include <GuiTreeView.au3>
#include <WindowsConstants.au3>
#include <Constants.au3>
#include <GUIMenu.au3>

Global $GUI, $hTreeView, $Context, $hMenu

_Main()

Func _Main()
    Local $iStyle = BitOR($TVS_EDITLABELS, $TVS_HASBUTTONS, $TVS_HASLINES, $TVS_LINESATROOT, $TVS_DISABLEDRAGDROP, $TVS_SHOWSELALWAYS)

    ;Create Main UI
    $GUI = GUICreate("Context Menu in UDF Treeview", 300, 404)

    ;Building the Treeview
    $hTreeView = _GUICtrlTreeView_Create($GUI, 2, 2, 296, 400, $iStyle, $WS_EX_CLIENTEDGE)
    _GUICtrlTreeView_BeginUpdate($hTreeView)
    $Parent = _GUICtrlTreeView_Add($hTreeView, 0, "Parent")
    For $x = 1 To 20
        _GUICtrlTreeView_AddChild($hTreeView, $Parent, "Child " & $x)
    Next
    _GUICtrlTreeView_EndUpdate($hTreeView)

    Local $aButtons[4] = [3, 0, 0, 0]

    $iDummy = GUICtrlCreateDummy()
    $Context = GUICtrlCreateContextMenu($iDummy)
    $hMenu = GUICtrlGetHandle($Context)
    $aButtons[1] = GUICtrlCreateMenuItem("Test 1", $Context)
    $aButtons[2] = GUICtrlCreateMenuItem("Test 2", $Context)
    $aButtons[3] = GUICtrlCreateMenuItem("Test 3", $Context)

    GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
    GUISetState(@SW_SHOW, $GUI)

    While 1
        $msg = GUIGetMsg()
        Switch $msg
            Case $GUI_EVENT_CLOSE
                Exit
            Case $aButtons[1]
                ConsoleWrite("1" & @LF)
            Case $aButtons[2]
                ConsoleWrite("2" & @LF)
            Case $aButtons[3]
                ConsoleWrite("3" & @LF)
        EndSwitch
    WEnd

    GUIDelete()
EndFunc   ;==>_Main

Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
    Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $selitem

    $tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
    $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
    $iIDFrom = DllStructGetData($tNMHDR, "IDFrom")
    $iCode = DllStructGetData($tNMHDR, "Code")
    Switch $hWndFrom
        Case $hTreeView
            Switch $iCode
                Case $NM_RCLICK
                    $clickPos = _WinAPI_GetMousePos(True, $GUI)
                    $selitem = _GUICtrlTreeView_HitTestItem($hTreeView, DllStructGetData($clickPos, "X"), DllStructGetData($clickPos, "Y"))
                    If $selitem = 0 Then Return $GUI_RUNDEFMSG
                    _GUICtrlTreeView_SelectItem($hTreeView, $selitem)

                    _GUICtrlMenu_TrackPopupMenu($hMenu, $GUI)
            EndSwitch
    EndSwitch

    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY
Edited by Djordhan

Share this post


Link to post
Share on other sites



Djordhan,

If you post the code you have I will look into it - but I am not writing a full script just to test something for you! :)

M23


Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______My UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Share this post


Link to post
Share on other sites

#3 ·  Posted (edited)

Sorry :) I was quite in a hurry and didn't think about it :)

There you go!

The interesting part is between lines 26 and 37.

#include <GuiConstantsEx.au3>
#include <GuiTreeView.au3>
#include <WindowsConstants.au3>
#include <File.au3>

Opt("GUIOnEventMode", 1)
Global $MenuParent, $gui, $contextmenu, $i, $n, $textitem, $Tree, $Child
Global $hTreeView, $aFolderList, $aScriptList

Main()

Func Main()

    Local $GUI, $aScriptList, $aFolderList, $hItem, $cItem, $contextmenu, $textitem, $nItem
    Local $iStyle = BitOR($TVS_EDITLABELS, $TVS_HASBUTTONS, $TVS_HASLINES, $TVS_LINESATROOT, $TVS_DISABLEDRAGDROP, $TVS_SHOWSELALWAYS)
    $GUI = GUICreate("(UDF Created) TreeView Create", 300, 1108, 0, 0)

    $hTreeView = _GUICtrlTreeView_Create($GUI, 2, 2, 296, 600, $iStyle, $WS_EX_CLIENTEDGE)
    GUISetState()

    GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")

    _GUICtrlTreeView_BeginUpdate($hTreeView)


    For $f = 1 To 10
        $hItem = _GUICtrlTreeView_Add($hTreeView, 0, "Parent " & $f)

        For $x = 1 To 3
            $cItem = _GUICtrlTreeView_AddChild($hTreeView, $hItem, "Child " & $x)

            $nItem = _WinAPI_GetDlgCtrlID($cItem)
            $contextmenu = GUICtrlCreateContextMenu($nItem)
            GUICtrlCreateMenuItem("Delete", $contextmenu)
        Next

    Next

    _GUICtrlTreeView_EndUpdate($hTreeView)

    ; Loop until user exits
    Do
    Until GUIGetMsg() = $GUI_EVENT_CLOSE
    GUIDelete()
EndFunc   ;==>_Main

Func contextMenu($MenuParent)
    $contextmenu = GUICtrlCreateContextMenu($MenuParent)
    $textitem = GUICtrlCreateMenuItem("Delete", $contextmenu)
        ;GUICtrlSetOnEvent ( $textitem, "Delete" )
EndFunc

Func Delete()
    _GUICtrlTreeView_Delete($Tree, _GUICtrlTreeView_GetSelection ($Tree))
EndFunc

Func Close()
    Exit
EndFunc

Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
    #forceref $hWnd, $iMsg, $iwParam
    Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $hWndTreeview, $item, $script
    $hWndTreeview = $hTreeView
    If Not IsHWnd($hTreeView) Then $hWndTreeview = GUICtrlGetHandle($hTreeView)

    $tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
    $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
    $iIDFrom = DllStructGetData($tNMHDR, "IDFrom")
    $iCode = DllStructGetData($tNMHDR, "Code")
    Switch $hWndFrom
        Case $hWndTreeview
            Switch $iCode
                Case $NM_CLICK ; The user has clicked the left mouse button within the control
                    _DebugPrint("$NM_CLICK" & @LF & "--> hWndFrom:" & @TAB & $hWndFrom & @LF & _
                            "-->IDFrom:" & @TAB & $iIDFrom & @LF & _
                            "-->Code:" & @TAB & $iCode)
;~                  Return 1 ; nonzero to not allow the default processing
                    Return 0 ; zero to allow the default processing
                Case $NM_DBLCLK ; The user has double-clicked the left mouse button within the control
                    $item = _GUICtrlTreeView_GetSelection($hWndTreeview)
                    $script = _GUICtrlTreeView_GetText($hWndTreeview, $item)
                    Run("C:\Program Files\AutoIt3\Scite\scite.exe C:\Autotest\Abutment\TestCases\Scripts\" & $script)
                    _DebugPrint("$NM_DBLCLK" & @LF & "--> hWndFrom:" & @TAB & $hWndFrom & @LF & _
                            "-->IDFrom:" & @TAB & $iIDFrom & @LF & _
                            "-->Code:" & @TAB & $iCode)
;~                  Return 1 ; nonzero to not allow the default processing
                    Return 0 ; zero to allow the default processing
                Case $NM_RCLICK ; The user has clicked the right mouse button within the control
                    _DebugPrint("$NM_RCLICK" & @LF & "--> hWndFrom:" & @TAB & $hWndFrom & @LF & _
                            "-->IDFrom:" & @TAB & $iIDFrom & @LF & _
                            "-->Code:" & @TAB & $iCode)
;~                  Return 1 ; nonzero to not allow the default processing
                    Return 0 ; zero to allow the default processing
                Case $NM_RDBLCLK ; The user has clicked the right mouse button within the control
                    _DebugPrint("$NM_RDBLCLK" & @LF & "--> hWndFrom:" & @TAB & $hWndFrom & @LF & _
                            "-->IDFrom:" & @TAB & $iIDFrom & @LF & _
                            "-->Code:" & @TAB & $iCode)
;~                  Return 1 ; nonzero to not allow the default processing
                    Return 0 ; zero to allow the default processing
                Case $NM_KILLFOCUS ; control has lost the input focus
                    _DebugPrint("$NM_KILLFOCUS" & @LF & "--> hWndFrom:" & @TAB & $hWndFrom & @LF & _
                            "-->IDFrom:" & @TAB & $iIDFrom & @LF & _
                            "-->Code:" & @TAB & $iCode)
                    ; No return value
                Case $NM_RETURN ; control has the input focus and that the user has pressed the key
                    _DebugPrint("$NM_RETURN" & @LF & "--> hWndFrom:" & @TAB & $hWndFrom & @LF & _
                            "-->IDFrom:" & @TAB & $iIDFrom & @LF & _
                            "-->Code:" & @TAB & $iCode)
;~                  Return 1 ; nonzero to not allow the default processing
                    Return 0 ; zero to allow the default processing
;~              Case $NM_SETCURSOR ; control is setting the cursor in response to a WM_SETCURSOR message
;~                  Local $tinfo = DllStructCreate($tagNMMOUSE, $ilParam)
;~                  $hWndFrom = HWnd(DllStructGetData($tinfo, "hWndFrom"))
;~                  $iIDFrom = DllStructGetData($tinfo, "IDFrom")
;~                  $iCode = DllStructGetData($tinfo, "Code")
;~                  _DebugPrint("$NM_SETCURSOR" & @LF & "--> hWndFrom:" & @TAB & $hWndFrom & @LF & _
;~                          "-->IDFrom:" & @TAB & $iIDFrom & @LF & _
;~                          "-->Code:" & @TAB & $iCode & @LF & _
;~                          "-->ItemSpec:" & @TAB & DllStructGetData($tinfo, "ItemSpec") & @LF & _
;~                          "-->ItemData:" & @TAB & DllStructGetData($tinfo, "ItemData") & @LF & _
;~                          "-->X:" & @TAB & DllStructGetData($tinfo, "X") & @LF & _
;~                          "-->Y:" & @TAB & DllStructGetData($tinfo, "Y") & @LF & _
;~                          "-->HitInfo:" & @TAB & DllStructGetData($tinfo, "HitInfo"))
;~                  Return 0 ; to enable the control to set the cursor
;~                  Return 1 ; nonzero to prevent the control from setting the cursor
                Case $NM_SETFOCUS ; control has received the input focus
                    _DebugPrint("$NM_SETFOCUS" & @LF & "--> hWndFrom:" & @TAB & $hWndFrom & @LF & _
                            "-->IDFrom:" & @TAB & $iIDFrom & @LF & _
                            "-->Code:" & @TAB & $iCode)
                    ; No return value
                Case $TVN_BEGINDRAGA, $TVN_BEGINDRAGW
                    _DebugPrint("$TVN_BEGINDRAG")
                Case $TVN_BEGINLABELEDITA, $TVN_BEGINLABELEDITW
                    _DebugPrint("$TVN_BEGINLABELEDIT")
                Case $TVN_BEGINRDRAGA, $TVN_BEGINRDRAGW
                    _DebugPrint("$TVN_BEGINRDRAG")
                Case $TVN_DELETEITEMA, $TVN_DELETEITEMW
                    _DebugPrint("$TVN_DELETEITEM")
                Case $TVN_ENDLABELEDITA, $TVN_ENDLABELEDITW
                    _DebugPrint("$TVN_ENDLABELEDIT")
                Case $TVN_GETDISPINFOA, $TVN_GETDISPINFOW
                    _DebugPrint("$TVN_GETDISPINFO")
                Case $TVN_GETINFOTIPA, $TVN_GETINFOTIPW
                    _DebugPrint("$TVN_GETINFOTIP")
                Case $TVN_ITEMEXPANDEDA, $TVN_ITEMEXPANDEDW
                    _DebugPrint("$TVN_ITEMEXPANDED")
                Case $TVN_ITEMEXPANDINGA, $TVN_ITEMEXPANDINGW
                    _DebugPrint("$TVN_ITEMEXPANDING")
                Case $TVN_KEYDOWN
                    _DebugPrint("$TVN_KEYDOWN")
                Case $TVN_SELCHANGEDA, $TVN_SELCHANGEDW
                    _DebugPrint("$TVN_SELCHANGED")
                Case $TVN_SELCHANGINGA, $TVN_SELCHANGINGW
                    _DebugPrint("$TVN_SELCHANGING")
                Case $TVN_SETDISPINFOA, $TVN_SETDISPINFOW
                    _DebugPrint("$TVN_SETDISPINFO")
                Case $TVN_SINGLEEXPAND
                    _DebugPrint("$TVN_SINGLEEXPAND")
            EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY

Func _DebugPrint($s_text, $line = @ScriptLineNumber)
    ConsoleWrite( _
            "!===========================================================" & @LF & _
            "+======================================================" & @LF & _
            "-->Line(" & StringFormat("%04d", $line) & "):" & @TAB & $s_text & @LF & _
            "+======================================================" & @LF)
EndFunc   ;==>_DebugPrint
Edited by Djordhan

Share this post


Link to post
Share on other sites

Djordhan,

Sorry, I cannot get context menus when using a UDF-created TreeView - and searching the forum shows that no-one else can either. :P

But why are you using the GuiTreeView UDF anyway? Can you not use a native TreeView instead? :)

Then context menus are easy! :)

M23


Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______My UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

But why are you using the GuiTreeView UDF anyway? Can you not use a native TreeView instead? :)

Then context menus are easy! :)

Ya I guess I should do that since I absolutely need context menu. I just don't know if all Treeview UDF function can be used with a Treeview created with the native one. I remember reading something about that but I can't remember if that said that all functions are compatible or if they're not :P

Since some native functions are not compatible with UDF treeview, I assume that some UDF functions (some of them are pretty cool) wont't work with native Treeview, what do you think?

Thanks for trying though! :D

Edited by Djordhan

Share this post


Link to post
Share on other sites

Djordhan,

Since some native functions are not compatible with UDF treeview, I assume that some UDF functions (some of them are pretty cool) wont't work with native Treeview, what do you think?

In general, I would advise against mixing the two, but some UDF functions will work on native controls (e.g. a lot of the GUIListView ones) - just try them and see. :)

If you do use UDF functions, I would strongly recommend getting the handle of the native control via GUICtrlGetHandle and using that as the ID for a UDF function - the UDF functions are supposed to check and do that themselves, but not all do. :)

M23


Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______My UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Share this post


Link to post
Share on other sites

Ok then I'll go with the native treeview and resolve issues as they come while trying to use UDF functions on it :)

Thank you very much!

JD

Share this post


Link to post
Share on other sites

Djordhan

resolve issues as they come

Happy to help resolve them if I can! :)

M23


Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______My UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Share this post


Link to post
Share on other sites

Just a quick follow up on this topic in case anyone is interested.

I really needed some events using WS_COMMAND and WS_NOTIFY and I didn't want to use interstellar dll calls to retreive them with standard GUIGetMsg().. So, what I did is keep the treeview created with UDF and simply create my own little '$WS_POPUP' GUI acting like a context menu. Works perfectly!

Share this post


Link to post
Share on other sites

#10 ·  Posted (edited)

Djordhan,

Glad you got it working. :)

Perhaps you could post a short example to help anyone else searching for the same thing? :)

M23

Edit: Typnig!

Edited by Melba23

Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind._______My UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Share this post


Link to post
Share on other sites

There you go!

Context menu in UDF Treeview, with customizable style! Hehe :)

The sad part is that you have to manually adjust each control to fit the context menu but I'm sure a little function could take care of it for you! I'll code it later...

Enjoy!

#include <GuiConstantsEx.au3>
#include <GuiTreeView.au3>
#include <WindowsConstants.au3>
#include <GDIPlus.au3>
#include <Constants.au3>
#include <StaticConstants.au3>

Opt('MouseCoordMode', 2)

Global $GUI, $hTreeView, $Context, $currentBtn = 0, $hGraphic, $hPen, $CurrentItem = ""

_Main()

Func _Main()
    Local $iStyle = BitOR($TVS_EDITLABELS, $TVS_HASBUTTONS, $TVS_HASLINES, $TVS_LINESATROOT, $TVS_DISABLEDRAGDROP, $TVS_SHOWSELALWAYS)

    ;Create Main UI
    $GUI = GUICreate("Context Menu in UDF Treeview", 300, 404)

    ;Building the Treeview
    $hTreeView = _GUICtrlTreeView_Create($GUI, 2, 2, 296, 400, $iStyle, $WS_EX_CLIENTEDGE)
    _GUICtrlTreeView_BeginUpdate($hTreeView)
    $Parent = _GUICtrlTreeView_Add($hTreeView, 0, "Parent")
    For $x = 1 To 20
        _GUICtrlTreeView_AddChild($hTreeView, $Parent, "Child " & $x)
    Next
    _GUICtrlTreeView_EndUpdate($hTreeView)

    GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
    GUISetState(@SW_SHOW, $GUI)

    ;Create Context Menu UI
    $Context = GUICreate("Context", 100, 69, 0, 0, $WS_POPUP, -1, $GUI)
    GUISetBkColor(0xFFFFFF)
    ;Initialize GDI for Context Menu Border (You can't change border color of windows with $WS_BORDER, so a little cheat is needed here)
    _GDIPlus_Startup ()
    $hGraphic = _GDIPlus_GraphicsCreateFromHWND($Context)
    $hPen = _GDIPlus_PenCreate (0x88888888)

    ;Create Context Menu options
    $cButton1 = GUICtrlCreateLabel("Action 1", 1, 1, 98, 18, BitOR($SS_CENTER,$SS_CENTERIMAGE))
    GUICtrlSetBkColor(-1, 0xFFFFFF)
    $cButton2 = GUICtrlCreateLabel("Action 2", 1, 21, 98, 18, BitOR($SS_CENTER,$SS_CENTERIMAGE))
    GUICtrlSetBkColor(-1, 0xFFFFFF)
    $sep = GUICtrlCreateLabel("———————————————", 7, 40, 86, 8)
    GUICtrlSetColor(-1, 0xDDDDDD)
    $cButton3 = GUICtrlCreateLabel("Action 3", 1, 50, 98, 18, BitOR($SS_CENTER,$SS_CENTERIMAGE))
    GUICtrlSetBkColor(-1, 0xFFFFFF)

    ;Array for menu options faster update
    Dim $aButtons[4] = [3, $cButton1, $cButton2, $cButton3]

    While 1
        ;Update menu option's color depending on current mouse hovering
        $info = GUIGetCursorInfo($Context)
        If $info[4] <> 0 And $info[4] <> 5 And $info[4] <> $currentBtn Then
            GUICtrlSetBkColor($info[4], 0x342D7E)
            GUICtrlSetColor($info[4], 0xFFFFFF)
            $currentBtn = $info[4]
            For $b = 1 To $aButtons[0]
                If $info[4] <> $aButtons[$b] Then
                    GUICtrlSetBkColor($aButtons[$b], 0xFFFFFF)
                    GUICtrlSetColor($aButtons[$b], 0x000000)
                EndIf
            Next
        EndIf
        $msg = GUIGetMsg()
        Switch $msg
            Case $GUI_EVENT_CLOSE
                Exit
            Case $cButton1
                GUISetState(@SW_HIDE, $Context)
                ConsoleWrite("Action 1 on " & $CurrentItem & @CRLF)
            Case $cButton2
                GUISetState(@SW_HIDE, $Context)
                ConsoleWrite("Action 2 on " & $CurrentItem & @CRLF)
            Case $cButton3
                GUISetState(@SW_HIDE, $Context)
                ConsoleWrite("Action 3 on " & $CurrentItem & @CRLF)
        EndSwitch
    WEnd
    ; Clean up resources
    _GDIPlus_GraphicsDispose ($hGraphic)
    _GDIPlus_Shutdown ()
    GUIDelete()
EndFunc   ;==>_Main

Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
    Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $hWndTreeview, $item, $script, $test
    $hWndTreeview = $hTreeView
    If Not IsHWnd($hTreeView) Then $hWndTreeview = GUICtrlGetHandle($hTreeView)

    $tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
    $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
    $iIDFrom = DllStructGetData($tNMHDR, "IDFrom")
    $iCode = DllStructGetData($tNMHDR, "Code")
    Switch $hWndFrom
        Case $hWndTreeview
            Switch $iCode
                Case $NM_CLICK
                    ;Hide Context menu if user click outside
                    GUISetState(@SW_HIDE, $Context)
                Case $NM_RCLICK
                    ;Select right clicked item and show Context Menu
                    GUISetState(@SW_HIDE, $Context)
                    $clickPos = MouseGetPos()
                    $winpos = WinGetPos("Context Menu in UDF Treeview")
                    $xTest = $clickPos[0] + $winpos[0] + 10
                    $yTest = $clickPos[1] + $winpos[1] + 20
                    $selitem = _GUICtrlTreeView_HitTestItem($hWndTreeview, $clickPos[0], $clickPos[1]-4)
                    _GUICtrlTreeView_SelectItem($hWndTreeview, $selitem)
                    $CurrentItem = _GUICtrlTreeView_GetText($hWndTreeview, $selitem)
                    WinMove("Context", "", $xTest, $yTest)
                    GUISetState(@SW_SHOW, $Context)
                    _GDIPlus_GraphicsDrawRect ($hGraphic, 0, 0, 99, 68, $hPen)
            EndSwitch
    EndSwitch
    Return $GUI_RUNDEFMSG
EndFunc

Share this post


Link to post
Share on other sites

Why did you choose that method out of interest? This works perfectly fine:

#include <GuiConstantsEx.au3>
#include <GuiTreeView.au3>
#include <WindowsConstants.au3>
#include <Constants.au3>
#include <GUIMenu.au3>

Global $GUI, $hTreeView, $Context, $hMenu

_Main()

Func _Main()
    Local $iStyle = BitOR($TVS_EDITLABELS, $TVS_HASBUTTONS, $TVS_HASLINES, $TVS_LINESATROOT, $TVS_DISABLEDRAGDROP, $TVS_SHOWSELALWAYS)

    ;Create Main UI
    $GUI = GUICreate("Context Menu in UDF Treeview", 300, 404)

    ;Building the Treeview
    $hTreeView = _GUICtrlTreeView_Create($GUI, 2, 2, 296, 400, $iStyle, $WS_EX_CLIENTEDGE)
    _GUICtrlTreeView_BeginUpdate($hTreeView)
    $Parent = _GUICtrlTreeView_Add($hTreeView, 0, "Parent")
    For $x = 1 To 20
        _GUICtrlTreeView_AddChild($hTreeView, $Parent, "Child " & $x)
    Next
    _GUICtrlTreeView_EndUpdate($hTreeView)

    Local $aButtons[4] = [3, 0, 0, 0]

    $iDummy = GUICtrlCreateDummy()
    $Context = GUICtrlCreateContextMenu($iDummy)
    $hMenu = GUICtrlGetHandle($Context)
    $aButtons[1] = GUICtrlCreateMenuItem("Test 1", $Context)
    $aButtons[2] = GUICtrlCreateMenuItem("Test 2", $Context)
    $aButtons[3] = GUICtrlCreateMenuItem("Test 3", $Context)

    GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
    GUISetState(@SW_SHOW, $GUI)

    While 1
        $msg = GUIGetMsg()
        Switch $msg
            Case $GUI_EVENT_CLOSE
                Exit
            Case $aButtons[1]
                ConsoleWrite("1" & @LF)
            Case $aButtons[2]
                ConsoleWrite("2" & @LF)
            Case $aButtons[3]
                ConsoleWrite("3" & @LF)
        EndSwitch
    WEnd

    GUIDelete()
EndFunc   ;==>_Main

Func WM_NOTIFY($hWnd, $iMsg, $iwParam, $ilParam)
    Local $hWndFrom, $iIDFrom, $iCode, $tNMHDR, $selitem

    $tNMHDR = DllStructCreate($tagNMHDR, $ilParam)
    $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
    $iIDFrom = DllStructGetData($tNMHDR, "IDFrom")
    $iCode = DllStructGetData($tNMHDR, "Code")
    Switch $hWndFrom
        Case $hTreeView
            Switch $iCode
                Case $NM_RCLICK
                    $clickPos = _WinAPI_GetMousePos(True, $GUI)
                    $selitem = _GUICtrlTreeView_HitTestItem($hTreeView, DllStructGetData($clickPos, "X"), DllStructGetData($clickPos, "Y"))
                    If $selitem = 0 Then Return $GUI_RUNDEFMSG
                    _GUICtrlTreeView_SelectItem($hTreeView, $selitem)

                    _GUICtrlMenu_TrackPopupMenu($hMenu, $GUI)
            EndSwitch
    EndSwitch

    Return $GUI_RUNDEFMSG
EndFunc   ;==>WM_NOTIFY

Share this post


Link to post
Share on other sites

And you say it only now!! :)

As you can see in the previous post, we couldn't get it to work on UDF treeview...looks like it works fine using a dummy..

Well, at least now I can make some funny looking context menu! :)

Thanks Mat.

Share this post


Link to post
Share on other sites

#14 ·  Posted (edited)

You could always have used a UDF menu as well, or gone with what Melba said and use a normal Treeview control, with UDF functions.

As a general rule with programming, if you are going through a long workaround to do something simple - you are probably doing it wrong. Save yourself the time and find the proper solution instead :)

Edited by Mat

Share this post


Link to post
Share on other sites

Ya I often realized that I'm trying to do something that already exists but it let me learn a lot doing so :)

I was just wondering why the normal Context Menu (without using a dummy) wasn't working on a UDF treeview. Where's the difference ?

Share this post


Link to post
Share on other sites

Ya I often realized that I'm trying to do something that already exists but it let me learn a lot doing so :)

I guess so, but in many cases it's better to learn how to do it properly. I suppose if you are learning GUI's then it would be good though.

I was just wondering why the normal Context Menu (without using a dummy) wasn't working on a UDF treeview. Where's the difference ?

You need to understand how AutoIt works. Since it's closed source, we can only guess based on what we see, and what would make sense.

An AutoIt control is the same as a native control. If you go down deep enough, the methodology for the two are the same in the AutoIt and the UDF's. However, AutoIt keeps an array or something like that with all the handles, and returns a control ID instead.

There are two places where they differ:

1) Items in listviews and treeviews are NOT controls. They do have an ID in AutoIt, but they don't have a handle or an id in native terms.

2) Menus in AutoIt are made so much easier for us. We don't have to do a few of the steps that are usually required to make the main menu bar, and context menus aren't really recognized by the system. As shown above, you need to handle right click messages yourself and call TrackPopupMenuEx. AutoIt does that all for you. You don't get the option of just making a menu though that isn't associated with anything :) Thats why there is the dummy.

Now the solutions are:

1) Do everything natively. It'll save confusion between the two, but you lose one of the big reasons for using AutoIT in the first place.

2) Do everything in AutoIt. Most of the commands you want have got AutoIt equilavents, and if not you can just use GUICtrlGetHandle and use it just like a native control with UDF functions. This is how most people choose to do it.

3) Mix the two. I did it above because I was trying to show an alternative that was similar to what you already had. In this case I was using an AutoIt menu and a native treeview. I don't really recommend this, as it is confusing (particularly as I am in the bad habit of using $hControl to represent AutoIt controls).

My recommendation? Use No. 2. Have two variables for the treeview: $iTreeView (AutoIt ID), $hTreeView (Native handle) and then you get the best of both worlds.

Mat

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