GUI, ListView, attempting to add ContextMenu Topic is solved

Get help with using AutoHotkey (v2 or newer) and its commands and hotkeys
arcylix
Posts: 54
Joined: 27 Sep 2022, 14:43

GUI, ListView, attempting to add ContextMenu

Post by arcylix » 29 May 2023, 10:22

I've been working on a project to familiarize myself with GUI as I have some larger projects in mind down the road. I'm at a roadblock and could use some assistance in figuring this out. Here is what this script is attempting to do.

1. It first checks for an ini file. If none exists, prompt the user for the location of their 'state' files, then write it to an ini file. This works.
2. After learning the directory for the state files, it browses the directory and reads the file contents of any .xml file, grabbing the plugin name and actual file name. This works.
3. If I double-click on a row, it will open up the state file in my default editor. This works.
4. If I right-click on the state file, it presents an option to delete the file. This is my roadblock.

I keep getting "Invalid callback" no matter what I try to do for the ContextMenu. Originally, I was going to have it just straight delete it, but I decided I wanted to make sure a user is deleting the proper file so it would present with a delete prompt. I'll also add the plugin name so that the user doesn't have to guess, but that's a separate task for now. Right now, I just want to be able to delete on a right-click menu. What am I missing?

Code: Select all

#SingleInstance Force
#Requires AutoHotkey v2.0

IniFile := A_ScriptDir "\state.ini"
defaultFileName := "e0eb198d8d5698e3b2f61483-"

if (!FileExist(IniFile))
   {
      StateLocation := DirSelect(, , "Select the 'state' folder location")
      IniWrite(StateLocation, IniFile, "State", "Location")
   } else {
      StateLocation := IniRead(IniFile, "State", "Location")
   }

FilePattern := StateLocation "\*.xml"
EasyStates := Gui("+Resize +Theme", "Easy States")
ESLV := EasyStates.Add("ListView", "r30 w600 sort grid", ["Plugin Name", "State File"])

Loop Files, FilePattern, "R"
   {
      FileContents := FileRead(A_LoopFileFullPath)
      if (RegExMatch(FileContents, "Plugin: `"(.+?)`"", &Name))
         {
            ESLV.Add(, Name[1], A_LoopFileName)
         }
   }

RCMenu := Menu()
ESLV.OnEvent("DoubleClick", ESLV_DoubleClick)
ESLV.OnEvent("ContextMenu", ESLV_RClick)
EasyStates.OnEvent("Size", GuiSize)
ESLV.ModifyCol   
EasyStates.Show()

ESLV_DoubleClick(LV, RowNumber)
{
   filePath := StateLocation "\" LV.GetText(RowNumber, 2)
   Run filePath
}

GuiSize(thisGui, MinMax, width, height)
{
   if (MinMax = -1)
      return
   ESLV.Move(, , width - 20, height - 20)
}

ESLV_RClick(thisLV, info)
{
   RCMenu.Add "Delete", ESLV_Delete
   RCMenu.Show()
}

ESLV_Delete(thisLV, clickedRow)
{
   filePath := StateLocation "\" thisLV.GetText(clickedRow, 2)
   FileDelete(filePath)
   thisLV.Delete(clickedRow)
}

User avatar
boiler
Posts: 16902
Joined: 21 Dec 2014, 02:44

Re: GUI, ListView, attempting to add ContextMenu  Topic is solved

Post by boiler » 29 May 2023, 10:58

A ContxtMenu callback function has more parameters than you have defined, so to ignore the extra parameters, you need to add a *:

Code: Select all

ESLV_RClick(thisLV, info, *)

arcylix
Posts: 54
Joined: 27 Sep 2022, 14:43

Re: GUI, ListView, attempting to add ContextMenu

Post by arcylix » 29 May 2023, 11:43

@boiler
Oh, thanks! I amended ESLV_Delete to do the same thing.

After a couple of light bulb changes, I'm having a new issue:

Error: Parameter #3 of Menu.Prototype.Add requires an Object, but received an empty string.

Not sure what I am doing wrong here:

Code: Select all

ESLV_RClick(thisLV, info, *)
{
   RCMenu.Add "Delete " thisLV.GetText(info, 1), ESLV_Delete(thisLV, info, ) ;Had to add 'info' so that it would delete the correct state file
   RCMenu.Show()
}

ESLV_Delete(thisLV, clickedRow, *)
{
   filePath := StateLocation "\" ESLV.GetText(clickedRow, 2)
   MsgBox filePath
  FileDelete(filePath)
   ESLV.Delete(clickedRow)
}

User avatar
boiler
Posts: 16902
Joined: 21 Dec 2014, 02:44

Re: GUI, ListView, attempting to add ContextMenu

Post by boiler » 29 May 2023, 12:04

I don't understand. You say it produces an error, but in the comment you said you changed it so it would delete the correct file. So I don't know which is correct. You should post the whole modified script so that the error can be reproduced. Better yet, you should post a small script that isolates and reproduces the problem so that others can run without having to have things like a .ini file in place. Isolate the problem to a simple script, and if you can't troubleshoot that script, then post it. And actually, once you have your topic solved, you should post your new problem in a new thread.

arcylix
Posts: 54
Joined: 27 Sep 2022, 14:43

Re: GUI, ListView, attempting to add ContextMenu

Post by arcylix » 29 May 2023, 13:38

@boiler

The only part that was modified was what is in the last post. Nothing other than that was changed. What I meant by 'changed it so it would delete the correct file' is that when I added the MsgBox filePath, it showed the incorrect file (choosing the first row rather than the clicked row).

Regardless of it being a "new issue", it's still very much in the realm of ContextMenu, which is why I did not create a new thread. If it were for a separate project or something else that was not related to ContextMenu, I'd have created a new thread. But this is expanding off. Just to make it easier, I have commented out original code, brought in some 'help-friendly' code, just so that one can see what it is I'm facing. The image that follows is what I see after I right-click. The File Path pops up as expected, then I get the error.

Code: Select all

#SingleInstance Force
#Requires AutoHotkey v2.0

IniFile := A_ScriptDir "\state.ini"

;if (!FileExist(IniFile))
;   {
;      StateLocation := DirSelect(, , "Select the 'state' folder location")
;      IniWrite(StateLocation, IniFile, "State", "Location")
;   } else {
      StateLocation := A_ScriptDir ;IniRead(IniFile, "State", "Location")
;   }

FilePattern := StateLocation "\*.ahk" ;"\*.xml"
EasyStates := Gui("+Resize +Theme", "Easy States")
ESLV := EasyStates.Add("ListView", "r30 w600 sort grid", ["Plugin Name", "State File"])

Loop Files, FilePattern, "R"
   {
;      FileContents := FileRead(A_LoopFileFullPath)
;      if (RegExMatch(FileContents, "Plugin: `"(.+?)`"", &Name))
;         {
            ESLV.Add(, A_LoopFileName, A_LoopFileFullPath) ;ESLV.Add(, Name[1], A_LoopFileName)
;         }
   }

RCMenu := Menu()
ESLV.OnEvent("DoubleClick", ESLV_DoubleClick)
ESLV.OnEvent("ContextMenu", ESLV_RClick)
EasyStates.OnEvent("Size", GuiSize)
ESLV.ModifyCol   
EasyStates.Show()

ESLV_DoubleClick(LV, RowNumber)
{
   filePath := StateLocation "\" LV.GetText(RowNumber, 2)
   Run filePath
}

GuiSize(thisGui, MinMax, width, height)
{
   if (MinMax = -1)
      return
   ESLV.Move(, , width - 20, height - 20)
}

ESLV_RClick(thisLV, info, *)
{
   RCMenu.Add "Delete " thisLV.GetText(info, 1), ESLV_Delete(thisLV, info, )
   RCMenu.Show()
}

ESLV_Delete(thisLV, clickedRow, *)
{
   filePath := StateLocation "\" ESLV.GetText(clickedRow, 2)
   MsgBox filePath
   ;FileDelete(filePath)
   ;ESLV.Delete(clickedRow)
}

Image

teadrinker
Posts: 4325
Joined: 29 Mar 2015, 09:41
Contact:

Re: GUI, ListView, attempting to add ContextMenu

Post by teadrinker » 29 May 2023, 14:35

Code: Select all

RCMenu.Add "Delete " thisLV.GetText(info, 1), ESLV_Delete.Bind(thisLV, info)

arcylix
Posts: 54
Joined: 27 Sep 2022, 14:43

Re: GUI, ListView, attempting to add ContextMenu

Post by arcylix » 29 May 2023, 14:43

@teadrinker

This is precisely what was needed. Thank you! I wish we could accept two separate answers. Maybe boiler was right and I should have made this into a separate thread. Regardless, you have my many thanks, and it is a teaching lesson for me!


Post Reply

Return to “Ask for Help (v2)”