Jump to content

dynamic GUICtrlCreateMenuItem, please help


Recommended Posts

#include <GUIConstantsEx.au3>
#include <ListViewConstants.au3>
#include <WindowsConstants.au3>
#include <GuiListView.au3>
#include <GuiMenu.au3>

AutoItSetOption("GuiOnEventMode", 1)
$Form1 = GUICreate("Form1", 420, 234, 425, 205)
GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit")
$ListView1 = GUICtrlCreateListView("#|text", 8, 8, 394, 206)
GUICtrlSendMsg(-1, $LVM_SETCOLUMNWIDTH, 0, 50)
GUICtrlSendMsg(-1, $LVM_SETCOLUMNWIDTH, 1, 100)
Global $array_start[400]
Global $array_stop[400]
For $z = 0 To 3
    $item_name_default = GUICtrlCreateListViewItem("1|5512", $ListView1)
    GUICtrlSetBkColor(-1, 0xFFFFFF)
    $menu = GUICtrlCreateContextMenu($item_name_default)

    $array_start[$z] = GUICtrlCreateMenuItem("Start", $menu)
    GUICtrlSetOnEvent(-1, "_Start")

    $array_stop[$z] = GUICtrlCreateMenuItem("Stop", $menu)
    GUICtrlSetOnEvent(-1, "_Stop")
    GUICtrlSetState(-1, $GUI_DISABLE)

    GUICtrlCreateMenuItem("Delete", $menu)
    GUICtrlSetOnEvent(-1, "_Delete")
Next

GUISetState(@SW_SHOW)

While 1
    Sleep(10)
WEnd

Func _Start()
    $iCurrent_Param = _GUICtrlListView_GetItemParam($ListView1, _GUICtrlListView_GetSelectedIndices($ListView1))
    GUICtrlSetBkColor($iCurrent_Param, 0xBDF4B5)
    GUICtrlSetState($array_start[_GUICtrlListView_GetSelectedIndices($ListView1)], $GUI_DISABLE)
    GUICtrlSetState($array_stop[_GUICtrlListView_GetSelectedIndices($ListView1)], $GUI_ENABLE)
EndFunc   ;==>_Start

Func _stop()
    $iCurrent_Param = _GUICtrlListView_GetItemParam($ListView1, _GUICtrlListView_GetSelectedIndices($ListView1))
    GUICtrlSetBkColor($iCurrent_Param, 0xFFFFFF)
    GUICtrlSetState($array_stop[_GUICtrlListView_GetSelectedIndices($ListView1)], $GUI_DISABLE)
    GUICtrlSetState($array_start[_GUICtrlListView_GetSelectedIndices($ListView1)], $GUI_ENABLE)
EndFunc   ;==>_stop

Func _delete()
    _GUICtrlListView_DeleteItemsSelected($ListView1)
EndFunc   ;==>_delete

Func _Exit()
    Exit
EndFunc   ;==>_Exit

Hello,

 

I have a little problem, I would be grateful if someone can help me see what's wrong.
I did this script, apparently works fine, but if I press Delete on an item, then the Start and Stop function does not work properly.

 

It's a matter of logic in managing variables, I understand that, but I'm lost in this code ...

 

Thank you !

Link to comment
Share on other sites

Hi incepator :)
I run your script and don't find any problem in it, even after I delete an intem using its context menu.
Then other items keep responding normally in context menu (start => green background, stop => white background)

I did a little change before, to make sure what was the item deleted :

; $item_name_default = GUICtrlCreateListViewItem("1|5512", $ListView1)
$item_name_default = GUICtrlCreateListViewItem($z & "|" & "5512", $ListView1)

But even with your original script, I'm not having issues after deleting item(s), that's strange...

Edited by pixelsearch
Link to comment
Share on other sites

Update:

#include <GUIConstantsEx.au3>
#include <ListViewConstants.au3>
#include <WindowsConstants.au3>
#include <GuiListView.au3>
#include <GuiMenu.au3>

AutoItSetOption("GuiOnEventMode", 1)
$Form1 = GUICreate("Form1", 420, 234, 425, 205)
GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit")
$ListView1 = GUICtrlCreateListView("#|text", 8, 8, 394, 206)
GUICtrlSendMsg(-1, $LVM_SETCOLUMNWIDTH, 0, 50)
GUICtrlSendMsg(-1, $LVM_SETCOLUMNWIDTH, 1, 100)
Global $array_start[400]
Global $array_stop[400]
Global $array_delete[400]
For $z = 0 To 5
    $item_name_default = GUICtrlCreateListViewItem($z & "|a" & $z, $ListView1)
    GUICtrlSetBkColor(-1, 0xFFFFFF)
    $menu = GUICtrlCreateContextMenu($item_name_default)

    $array_start[$z] = GUICtrlCreateMenuItem("Start", $menu)
    GUICtrlSetOnEvent(-1, "_Start")

    $array_stop[$z] = GUICtrlCreateMenuItem("Stop", $menu)
    GUICtrlSetOnEvent(-1, "_Stop")
    GUICtrlSetState(-1, $GUI_DISABLE)

    $array_delete[$z] = GUICtrlCreateMenuItem("Delete", $menu)
    GUICtrlSetOnEvent(-1, "_Delete")
Next

GUISetState(@SW_SHOW)

While 1
    Sleep(10)
WEnd

Func _Start()
    $iCurrent_Param = _GUICtrlListView_GetItemParam($ListView1, _GUICtrlListView_GetSelectedIndices($ListView1))
    GUICtrlSetBkColor($iCurrent_Param, 0xBDF4B5)

    ConsoleWrite("START: " & $array_start[_GUICtrlListView_GetSelectedIndices($ListView1)] & " - " & "STOP: " & $array_stop[_GUICtrlListView_GetSelectedIndices($ListView1)] & " - " & "DELETE: " & $array_delete[_GUICtrlListView_GetSelectedIndices($ListView1)] & @CRLF)

    GUICtrlSetState($array_start[_GUICtrlListView_GetSelectedIndices($ListView1)], $GUI_DISABLE)
    GUICtrlSetState($array_delete[_GUICtrlListView_GetSelectedIndices($ListView1)], $GUI_DISABLE)
    GUICtrlSetState($array_stop[_GUICtrlListView_GetSelectedIndices($ListView1)], $GUI_ENABLE)
EndFunc   ;==>_Start

Func _stop()
    $iCurrent_Param = _GUICtrlListView_GetItemParam($ListView1, _GUICtrlListView_GetSelectedIndices($ListView1))
    GUICtrlSetBkColor($iCurrent_Param, 0xFFFFFF)

    ConsoleWrite("START: " & $array_start[_GUICtrlListView_GetSelectedIndices($ListView1)] & " - " & "STOP: " & $array_stop[_GUICtrlListView_GetSelectedIndices($ListView1)] & " - " & "DELETE: " & $array_delete[_GUICtrlListView_GetSelectedIndices($ListView1)] & @CRLF)


    GUICtrlSetState($array_stop[_GUICtrlListView_GetSelectedIndices($ListView1)], $GUI_DISABLE)
    GUICtrlSetState($array_delete[_GUICtrlListView_GetSelectedIndices($ListView1)], $GUI_ENABLE)
    GUICtrlSetState($array_start[_GUICtrlListView_GetSelectedIndices($ListView1)], $GUI_ENABLE)
EndFunc   ;==>_stop

Func _delete()
    _GUICtrlListView_DeleteItemsSelected($ListView1)
EndFunc   ;==>_delete

Func _Exit()
    Exit
EndFunc   ;==>_Exit

 

In the console you can see the ID difference

Link to comment
Share on other sites

I think your problem is that you're recording the index of the item started, but when you delete one, the indices change, and you're not updating the array. You could try and disable the delete function on the context menu after starting something, or you could work out a way to see what items are green, and rerecord the index for the contextmenu.

If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

Link to comment
Share on other sites

2 minutes ago, BrewManNH said:

I think your problem is that you're recording the index of the item started, but when you delete one, the indices change, and you're not updating the array. You could try and disable the delete function on the context menu after starting something, or you could work out a way to see what items are green, and rerecord the index for the contextmenu.

That's exactly the problem. When I delete an item, the index changes, but I do not know how I can save it correctly.
I'm working for 5 hours on this code, I can not find a solution.
I'll try again...

thank you.

Link to comment
Share on other sites

I solved!
A rather dubious solution but it works well, I'm happy now :'(:lmao:
If someone makes an elegant function for that, I would appreciate it.

 

#include <GUIConstantsEx.au3>
#include <ListViewConstants.au3>
#include <WindowsConstants.au3>
#include <GuiListView.au3>
#include <GuiMenu.au3>

AutoItSetOption("GuiOnEventMode", 1)
$Form1 = GUICreate("Form1", 420, 234, 425, 205)
GUISetOnEvent($GUI_EVENT_CLOSE, "_Exit")
$ListView1 = GUICtrlCreateListView("#|text", 8, 8, 394, 206)
GUICtrlSendMsg(-1, $LVM_SETCOLUMNWIDTH, 0, 50)
GUICtrlSendMsg(-1, $LVM_SETCOLUMNWIDTH, 1, 100)

Global $varrr = 1

For $z = 0 To 5
    $item_name_default = GUICtrlCreateListViewItem($z & "|a" & $z, $ListView1)
    GUICtrlSetBkColor(-1, 0xFFFFFF)
    $menu = GUICtrlCreateContextMenu($item_name_default)

    GUICtrlCreateMenuItem("Start", $menu)
    GUICtrlSetOnEvent(-1, "_Start")

    GUICtrlCreateMenuItem("Stop", $menu)
    GUICtrlSetOnEvent(-1, "_Stop")
    GUICtrlSetState(-1, $GUI_DISABLE)

    GUICtrlCreateMenuItem("Delete", $menu)
    GUICtrlSetOnEvent(-1, "_Delete")
Next

GUISetState(@SW_SHOW)

While 1
    Sleep(10)
WEnd

Func _Start()
    $iCurrent_Param = _GUICtrlListView_GetItemParam($ListView1, _GUICtrlListView_GetSelectedIndices($ListView1))
    GUICtrlSetBkColor($iCurrent_Param, 0xBDF4B5)

    GUICtrlSetState($iCurrent_Param + 2, $GUI_DISABLE)
    GUICtrlSetState($iCurrent_Param + 3, $GUI_ENABLE)
    GUICtrlSetState($iCurrent_Param + 4, $GUI_DISABLE)
EndFunc   ;==>_Start

Func _stop()
    $iCurrent_Param = _GUICtrlListView_GetItemParam($ListView1, _GUICtrlListView_GetSelectedIndices($ListView1))
    GUICtrlSetBkColor($iCurrent_Param, 0xFFFFFF)

    GUICtrlSetState($iCurrent_Param + 2, $GUI_ENABLE)
    GUICtrlSetState($iCurrent_Param + 3, $GUI_DISABLE)
    GUICtrlSetState($iCurrent_Param + 4, $GUI_ENABLE)
EndFunc   ;==>_stop


Func _delete()
    _GUICtrlListView_DeleteItemsSelected($ListView1)
EndFunc   ;==>_delete

Func _Exit()
    Exit
EndFunc   ;==>_Exit

 

Link to comment
Share on other sites

Hi incepator :)
I reworked it a bit, creating a single context menu for the listview control (instead of one context menu per item) . The context menu is dynamically rebuilt during the function WM_NOTIFY(), as soon as a right click is intercepted, before the context menu displays.

Then when you choose a line in it, an array is updated accordingly during the While...Wend loop.
The array wont be redimensioned even if you delete items, because the creation id's of each item are linked to the array rows. Each item got its own row in the array, with 3 columns (start, stop, delete) containing 0 if disabled, 1 if enabled... -1 if item deleted, that last one just for fun)

It was an interesting moment working on this script, the help file was... a big help :)

#include <GuiConstantsEx.au3>
#include <GuiListView.au3>
#include <WindowsConstants.au3>
; #include <Array.au3>

Global $hGUI = GUICreate("Right click items for context menu", 320, 450)
Global $idListview = GUICtrlCreateListView(" A | B | C | D | E | F | G", 25, 25, 270, 400)
GUICtrlSetBkColor(-1, 0xFFFFFF) ; white, as Stop will be disabled in all items 1st context menu

Global $aStatus[20][3] ; each item got a row. Then col 0 = Start, col 1 = Stop, col 2 = Delete
; each column contains : 0 if disabled in context menu, 1 if enabled, -1 if item deleted

For $i = 0 To 19 ; 20 items . Col F & G prepared randomly (sort when column header clicked)
    GUICtrlCreateListViewItem("A" & $i & "|B" & $i & "|C" & $i & "|D" & $i & "|E" & $i & _
        "|" & Chr(Random(65, 90, 1)) & $i & "|" & Chr(Random(65, 90, 1)) & $i, $idListview)
    $aStatus[$i][0] = 1 ; Start => enable
    $aStatus[$i][1] = 0 ; Stop => disable
    $aStatus[$i][2] = 1 ; Delete => enable
Next

; context menu for control listview : will be rebuilt during Func WM_NOTIFY() before display
Global $idMenu = GUICtrlCreateContextMenu($idListview)
Global $idMenu_start = GUICtrlCreateMenuItem("Start", $idMenu)
Global $idMenu_stop = GUICtrlCreateMenuItem("Stop", $idMenu)
GUICtrlSetState(-1, $GUI_DISABLE)
Global $idMenu_delete = GUICtrlCreateMenuItem("Delete", $idMenu)

; other useful variables
Global $hListview = GUICtrlGetHandle($idListview)
Global $idItem ; assigned in Func WM_NOTIFY() when right-click, then used in Gui main loop
Global $icol ; assigned in Func WM_NOTIFY() when click on column, then used in Gui main loop
Global $bSortSense = False ; ascending sort (1st left click on a column header, then toggled)
Global $bDo_Sort = False ; to return asap from Func WM_NOTIFY() and sort in main loop

Global $iDiff = $idListview + 1 ; ex. $idListview = 3 => $iDiff = 4
; 4 is the difference between an item control id and its row in $aStatus[][] : id 4 => row 0

; _ArrayDisplay($aStatus, "$aStatus", "", 4, Default, "Start|Stop|Delete")

GUIRegisterMsg($WM_NOTIFY, "WM_NOTIFY")
GUISetState()

While 1
    If $bDo_Sort Then ; sort here in main loop <=> leave asap Func WM_NOTIFY()
        _GUICtrlListView_SimpleSort($hListView, $bSortSense, $iCol) ; auto-toggle sort sense
        $bDo_Sort = False
    EndIf

    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            Exit

        Case $idMenu_start
            GUICtrlSetBkColor($idItem, 0xBDF4B5) ; light green
            $aStatus[$idItem - $iDiff][0] = 0 ; Start => disable
            $aStatus[$idItem - $iDiff][1] = 1 ; Stop => enable
            $aStatus[$idItem - $iDiff][2] = 0 ; Delete => disable
            ; _ArrayDisplay($aStatus, "$aStatus", "", 4, Default, "Start|Stop|Delete")

        Case $idMenu_stop
            GUICtrlSetBkColor($idItem, 0xFFFFFF) ; white
            $aStatus[$idItem - $iDiff][0] = 1 ; Start => enable
            $aStatus[$idItem - $iDiff][1] = 0 ; Stop => disable
            $aStatus[$idItem - $iDiff][2] = 1 ; Delete => enable
            ; _ArrayDisplay($aStatus, "$aStatus", "", 4, Default, "Start|Stop|Delete")

        Case $idMenu_delete
            _GUICtrlListView_DeleteItemsSelected($idListview)
            ; 3 next lines not mandatory, just for fun in case of _ArrayDisplay()
            $aStatus[$idItem - $iDiff][0] = -1 ; Start => item deleted
            $aStatus[$idItem - $iDiff][1] = -1 ; Stop => item deleted
            $aStatus[$idItem - $iDiff][2] = -1 ; Delete => item deleted
            ; _ArrayDisplay($aStatus, "$aStatus", "", 4, Default, "Start|Stop|Delete")
    EndSwitch
WEnd

Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam)
    Local $tNMHDR, $hWndFrom, $iIDFrom, $iCode

    $tNMHDR = DllStructCreate($tagNMHDR, $lParam)
    $hWndFrom = HWnd(DllStructGetData($tNMHDR, "hWndFrom"))
    $iIDFrom = DllStructGetData($tNMHDR, "IDFrom")
    $iCode = DllStructGetData($tNMHDR, "Code")

    Switch $iCode
        Case $NM_RCLICK ; right click
            ; ConsoleWrite("handle = " & $hWndFrom & "  ***  id = " & $iIDFrom & @CRLF)
            Switch $hWndFrom
                Case $hListview ; in list view (note: headers got a different handle & no id)
                    $idItem = GUICtrlRead($idListview) ; controlID of the selected item
                    If $idItem > 0 Then ; an item is selected
                        GUICtrlSetState($idMenu_start, _
                            (($aStatus[$idItem - $iDiff][0] = 0) ? $GUI_DISABLE : $GUI_ENABLE))
                        GUICtrlSetState($idMenu_stop, _
                            (($aStatus[$idItem - $iDiff][1] = 0) ? $GUI_DISABLE : $GUI_ENABLE))
                        GUICtrlSetState($idMenu_delete, _
                            (($aStatus[$idItem - $iDiff][2] = 0) ? $GUI_DISABLE : $GUI_ENABLE))
                        Return ; or Return $GUI_RUNDEFMSG . If Return 0 or Return 1 => no menu
                    EndIf
            EndSwitch
            ; disable context menu, in case user right click on columns headers or empty places
            GUICtrlSetState($idMenu_start, $GUI_DISABLE)
            GUICtrlSetState($idMenu_stop, $GUI_DISABLE)
            GUICtrlSetState($idMenu_delete, $GUI_DISABLE)

        Case $LVN_COLUMNCLICK ; a column header was left clicked => sort the column
            Local $tInfo = DllStructCreate($tagNMLISTVIEW, $lParam)
            $iCol = DllStructGetData($tInfo, "SubItem")
            $bDo_Sort = True ; sort in main loop <=> leave asap Func WM_NOTIFY()
    EndSwitch

    Return $GUI_RUNDEFMSG
EndFunc

 

Edited by pixelsearch
Disable context menu if no item selected . Sort now possible
Link to comment
Share on other sites

Hi everybody :)

The script I presented in the precedent comment works only with native GUICtrlCreateListViewItem() because we can retrieve each item controlID, using GUICtrlRead() or even _GUICtrlListView_GetItemParam()
In case one uses the UDF to add items, it wont work, i.e with _GUICtrlListView_AddItem()

My question is : why is the UDF _GUICtrlListView_AddItem() treated differently and no controlID can't be retrieved for the item ?

i'm not talking about the optional $iParam found in _GUICtrlListView_AddItem() or _GUICtrlListView_SetItemParam() , retrieved with _GUICtrlListView_GetItemParam()

Thanks for anyone who could provide an answer

Link to comment
Share on other sites

ControlIDs are only generated for AutoIt created controls. Windows native controls have handles, but not AutoIt control IDs because AutoIt doesn't create them.

If I posted any code, assume that code was written using the latest release version unless stated otherwise. Also, if it doesn't work on XP I can't help with that because I don't have access to XP, and I'm not going to.
Give a programmer the correct code and he can do his work for a day. Teach a programmer to debug and he can do his work for a lifetime - by Chirag Gude
How to ask questions the smart way!

I hereby grant any person the right to use any code I post, that I am the original author of, on the autoitscript.com forums, unless I've specifically stated otherwise in the code or the thread post. If you do use my code all I ask, as a courtesy, is to make note of where you got it from.

Back up and restore Windows user files _Array.au3 - Modified array functions that include support for 2D arrays.  -  ColorChooser - An add-on for SciTE that pops up a color dialog so you can select and paste a color code into a script.  -  Customizable Splashscreen GUI w/Progress Bar - Create a custom "splash screen" GUI with a progress bar and custom label.  -  _FileGetProperty - Retrieve the properties of a file  -  SciTE Toolbar - A toolbar demo for use with the SciTE editor  -  GUIRegisterMsg demo - Demo script to show how to use the Windows messages to interact with controls and your GUI.  -   Latin Square password generator

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...