I took a look at your script but I think I didn’t completely understand the design of it. Is not that much the code, but the implementation.
So in an attempt to help with your request, I decided to take a completely different path and so I created a little utility based the things I can remember from the whole Thread.
I fully understand if this is not at all what you need, but I think there is a lot of code in the tool to help you implement your own solution.
The only thing I didn’t implement is the “Renaming” feature.
Renaming: I don’t understand what the purpose of it is, as renaming the filename of a registered MacroScript has no effect anywhere.
Hope you find it useful.
EDIT 1
Fixed a few minor things
Added default cell style
Added load individual MacroScript
EDIT 2
Some code reorganization
Some visual improvements
EDIT 3
Fixed bug in Delete MacroScript
EDIT 4
Added limit of shown MacroScript
/**********************************************************************************************
DESCRIPTION: Small Utility for Loading/Unloading/Deleting Users MacroScripts
AUTHOR: Jorge Rodríguez - www.polytools3d.com
DATE: 03.04.2019
NOTES:
For 3ds Max 2014+
Not fully implemented. It might containg bugs. Not optimized.
USE AT YOUR OWN RISK!
CGSociety Thread:
https://forums.cgsociety.org/t/run-an-mcr-file-but-ignore-its-macroscrip-header/1810600
/**********************************************************************************************/
(
try destroydialog ::RO_USER_MACROS_MANAGER catch()
rollout RO_USER_MACROS_MANAGER "User MacroScripts Manager" width:438 height:484
(
dotNetControl dnc_grid "DataGridView" pos:[ 8, 8] width:420 height:384
spinner sp_rowsCount "Limit:" pos:[ 8,405] fieldwidth:48 range:[1,1,1] type:#integer
button bt_load "Load" pos:[114,400] width:104 height:24
button bt_run "Run" pos:[220,400] width:104 height:24
button bt_edit "Edit" pos:[326,400] width:104 height:24
button bt_unload "Unload" pos:[ 8,440] width:104 height:32
button bt_rename "Rename" pos:[114,440] width:104 height:32
button bt_delete "Delete" pos:[220,440] width:104 height:32
button bt_reload "Reload All" pos:[326,440] width:104 height:32
local macroEntryClass
local userMacrosPath = getDir #userMacros
local macroEntries = #()
local gi = (dotnetclass "Autodesk.Max.GlobalInterface").instance
local actionTable = gi.coreinterface.ActionManager.GetTable 82
local headerCellStyle, disabledCellStyle, enabledCellStyle
local rowsCountLimit = 20
struct macroEntryClass
(
id = 0,
name = "",
category = "",
internalCategory = "",
fileName = "",
toolTip = "",
buttonText = "",
buttonIconFile = "",
buttonIconIndex = 0,
userFilename = "",
loaded = true
)
fn GetMacroScriptsInfo =
(
macroScripts = getfiles (userMacrosPath + "\\*.mcr")
macroEntries = for j in macroScripts collect
(
entry = gi.MacroScriptDir.LoadMacroScript j
macroEntryClass id:entry.Id \
name:entry.Name \
category:entry.Category \
internalCategory:entry.InternalCategory \
fileName:entry.FileName \
toolTip:entry.ToolTip \
buttonText:entry.ButtonText \
buttonIconFile:entry.ButtonIconFile \
buttonIconIndex:entry.ButtonIconIndex \
userFilename:j
)
fn sortByID e1 e2 order:1 =
(
if e1.id < e2.id then -order
else if e1.id > e2.id then order
else 0
)
qsort macroEntries sortByID order:1
)
fn DisableRow row:0 =
(
for j = 0 to 2 do dnc_grid.Rows.Item[row].Cells.Item[j].Style = disabledCellStyle
)
fn EnableRow row:0 =
(
for j = 0 to 2 do dnc_grid.Rows.Item[row].Cells.Item[j].Style = enabledCellStyle
)
fn UpdateGridContent =
(
if macroEntries.count > 0 do
(
dnc_grid.RowCount = rowsCountLimit
total = macroEntries.count
for j = 1 to rowsCountLimit do
(
rowIdx = j-1
entryIdx = total-rowsCountLimit+j
dnc_grid.Rows.Item[rowIdx].Selected = false
dnc_grid.Rows.Item[rowIdx].Cells.Item[0].Value = macroEntries[entryIdx].id
dnc_grid.Rows.Item[rowIdx].Cells.Item[1].Value = macroEntries[entryIdx].category
dnc_grid.Rows.Item[rowIdx].Cells.Item[2].Value = macroEntries[entryIdx].name
if macroEntries[entryIdx].loaded then EnableRow row:rowIdx else DisableRow row:rowIdx
)
)
)
fn SetupGrid =
(
(dotnetclass "system.gc").collect()
gc light:true
dnc_grid.EnableHeadersVisualStyles = false
dnc_grid.ColumnHeadersDefaultCellStyle = headerCellStyle
dnc_grid.RowsDefaultCellStyle = enabledCellStyle
dnc_grid.ColumnHeadersBorderStyle = dnc_grid.ColumnHeadersBorderStyle.Single
dnc_grid.SelectionMode = dnc_grid.SelectionMode.FullRowSelect
dnc_grid.ColumnHeadersHeightSizeMode = dnc_grid.ColumnHeadersHeightSizeMode.DisableResizing
dnc_grid.AllowUserToResizeColumns = false
dnc_grid.AllowUserToResizeRows = false
dnc_grid.AllowUserToAddRows = false
dnc_grid.ReadOnly = true
dnc_grid.ColumnHeadersHeight = 30
dnc_grid.Rows.Clear()
dnc_grid.ColumnCount = 3
dnc_grid.RowHeadersVisible = false
dnc_grid.TabStop = false
titles = #( #(80, "Macro ID"), #(160, "Macro Category"), #(160, "Macro Name"))
for j = 1 to titles.count do
(
dnc_grid.Columns.Item[j-1].Width = titles[j][1]
dnc_grid.Columns.Item[j-1].Name = titles[j][2]
)
dnc_grid.Columns.Item[2].AutoSizeMode = dnc_grid.Columns.Item[2].AutoSizeMode.Fill
)
fn DefineCellStyles =
(
headerCellStyle = dotnetobject "System.Windows.Forms.DataGridViewCellStyle"
headerCellStyle.BackColor = (dotnetclass "System.Drawing.Color").FromArgb 48 48 48
headerCellStyle.ForeColor = (dotnetclass "System.Drawing.Color").FromArgb 220 220 220
enabledCellStyle = dotnetobject "System.Windows.Forms.DataGridViewCellStyle"
enabledCellStyle.BackColor = (dotnetclass "System.Drawing.Color").FromArgb 250 250 250
enabledCellStyle.ForeColor = (dotnetclass "System.Drawing.Color").FromArgb 32 32 32
enabledCellStyle.SelectionBackColor = (dotnetclass "System.Drawing.Color").FromArgb 50 150 250
enabledCellStyle.SelectionForeColor = (dotnetclass "System.Drawing.Color").FromArgb 250 250 250
disabledCellStyle = dotnetobject "System.Windows.Forms.DataGridViewCellStyle"
disabledCellStyle.BackColor = (dotnetclass "System.Drawing.Color").FromArgb 200 200 200
disabledCellStyle.ForeColor = (dotnetclass "System.Drawing.Color").FromArgb 150 150 150
disabledCellStyle.SelectionBackColor = (dotnetclass "System.Drawing.Color").FromArgb 150 0 0
disabledCellStyle.SelectionForeColor = (dotnetclass "System.Drawing.Color").FromArgb 200 150 150
)
fn ReloadAllMacroScripts =
(
setwaitcursor()
GetMacroScriptsInfo()
UpdateGridContent()
rowsCountLimit = amin rowsCountLimit macroEntries.count
sp_rowsCount.range = [1,macroEntries.count,rowsCountLimit]
setarrowcursor()
)
fn GetSelectedMacrosIDs =
(
selRows = for j = 1 to dnc_grid.SelectedRows.Count collect dnc_grid.SelectedRows.Item[j-1].Index
result = for j in selRows collect #(dnc_grid.Rows.Item[j].Cells.Item[0].Value, j)
return result
)
fn LoadMacro id: =
(
if id != unsupplied do
(
if (gi.MacroScriptDir.ValidID id) then
(
for k in macroEntries where k.id == id do
(
if k.loaded == false then
(
gi.MacroScriptDir.LoadMacroScript k.userFilename
k.loaded = true
return true
)else messagebox ("MacroScript " + (id as string) + " is already Loaded")
)
)else format "Can't Load MacroScript | Invalid ID:%\n" id
)
return false
)
fn UnloadMacro id: =
(
/* @Serejah
https://forums.cgsociety.org/t/unload-macroscript-from-memory/2050211/3
action_table = gi.coreinterface.ActionManager.GetTable 82 -- Macro Scripts
your_action = action_table.GetAction 12345 -- your macro index
action_table.DeleteOperation your_action
*/
if id != unsupplied do
(
if (gi.MacroScriptDir.ValidID id) then
(
for k in macroEntries where k.id == id do
(
if k.loaded == false then
(
messagebox ("MacroScript " + (id as string) + " is already Unloaded")
)else(
actionTable.DeleteOperation (actionTable.GetAction id)
k.loaded = false
return true
)
)
)else format "Can't Unload MacroScript | Invalid ID:%\n" id
)
return false
)
fn DeleteMacroScriptFile id: =
(
if id != unsupplied do
(
if (gi.MacroScriptDir.ValidID id) then
(
for k = macroEntries.count to 1 by -1 where macroEntries[k].id == id do
(
if macroEntries[k].loaded == true do UnloadMacro id:id
if macroEntries[k].userFilename != "" then
(
deletefile macroEntries[k].userFilename
deleteitem macroEntries k
)else format "Could not locate file for MacroScript:%\n" id
)
)else format "Can't Delete MacroScript File | Invalid ID:%\n" id
)
return false
)
fn LoadSelectedMacroScripts =
(
ids = GetSelectedMacrosIDs()
if ids.count == 0 do return messagebox "Please select a Macro"
answer = querybox "You are attempting to LOAD one or more MacroScripts.\n\nDo you want to continue?"
if answer do for j in ids do if (LoadMacro id:j[1]) do EnableRow row:j[2]
)
fn RunSelectedMacroScripts =
(
ids = GetSelectedMacrosIDs()
if ids.count == 0 do return messagebox "Please select a Macro"
if ids.count > 1 then
(
answer = querybox "You are attempting to RUN more than 1 MacroScript.\n\nDo you want to continue?"
if answer do for j in ids do macros.run j[1]
)else macros.run ids[1][1]
)
fn EditSelectedMacroScripts =
(
ids = GetSelectedMacrosIDs()
if ids.count == 0 do return messagebox "Please select a Macro"
if ids.count > 1 then
(
answer = querybox "You are attempting to EDIT more than 1 MacroScript.\n\nDo you want to continue?"
if answer do for j in ids do macros.edit j[1]
)else macros.edit ids[1][1]
)
fn UnloadSelectedMacroScripts =
(
ids = GetSelectedMacrosIDs()
if ids.count == 0 do return messagebox "Please select a Macro"
answer = querybox "You are attempting to UNLOAD one or more MacroScripts.\n\nDo you want to continue?"
if answer do for j in ids do if (UnloadMacro id:j[1]) do DisableRow row:j[2]
)
fn RenameSelectedMacroScript =
(
messagebox "Not implemented."
)
fn DeleteSelectedMacroScripts =
(
ids = GetSelectedMacrosIDs()
if ids.count == 0 do return messagebox "Please select a Macro"
msg = "You are attempting to DELETE one or more MacroScript files.\n"
msg += "This procedure will also UNLOAD the MacroScripts from 3ds Max\n\n"
msg += "Do you want to continue?"
answer = querybox msg
if answer do
(
for j in ids do DeleteMacroScriptFile id:j[1]
UpdateGridContent()
)
)
on RO_USER_MACROS_MANAGER open do
(
DefineCellStyles()
SetupGrid()
ReloadAllMacroScripts()
)
on sp_rowsCount changed arg do
(
rowsCountLimit = arg
UpdateGridContent()
)
on bt_load pressed do LoadSelectedMacroScripts()
on bt_run pressed do RunSelectedMacroScripts()
on bt_edit pressed do EditSelectedMacroScripts()
on bt_unload pressed do UnloadSelectedMacroScripts()
on bt_rename pressed do RenameSelectedMacroScript()
on bt_delete pressed do DeleteSelectedMacroScripts()
on bt_reload pressed do ReloadAllMacroScripts()
)
createdialog RO_USER_MACROS_MANAGER style:#(#style_toolwindow, #style_sysmenu)
)