Creating a new Main Menu in 3ds Max


#1

I’m somewhat familiar with the reference to the Menu Manager for creating menus in 3ds Max, but I was hoping it was possible to do this in a simpler manner, and without actually having to create macro-scripts for each item you want in your menu.

I know that I’m asking about something people rarely see the use for, and which might not even be possible, but for the sake of simplicity I would really like to find a better solution for making and maintaining menus in 3dsMax. The reason why I want to call the scripts directly instead of having macros, is that whenever a script is called directly it will close the previous instance of itself (which is something I appreciate).

I’ve created some sort of pseudo-code of what I ideally would want as a way of defining a new menu in 3dsMax:

MenuName = "Script Menu"
SubMenu1 = menuMan.createMenu "Scripts Category 1"
SubMenu1.menuItem1 = fileIn(@"PathToScriptFolder\MeshScripts\CurrentMeshScript1.ms")
SubMenu1.menuItem2 = fileIn(@"PathToScriptFolder\MeshScripts\CurrentMeshScript2.ms")
SubMenu2 = menuMan.createMenu "Scripts Category 2"
SubMenu2.menuItem1 = fileIn(@"PathToScriptFolder\TransformScripts\CurrentTransformScript1.ms")
SubMenu2.menuItem2 = fileIn(@"PathToScriptFolder\TransformScripts\CurrentTransformScript2.ms")

I highly doubt it, but is it possible to simplifiy the process of creating/maintaining menus in 3ds Max even remotely close to my example?


#2

It depends entirely on how your scripts are written, the macro has nothing to do with it.
Just define variables in global scope so the next time you execute the macro it could destroy existing instance of the tool.

You can add menu items bypassing the menuMan interface, but since macro isn’t really a problem I wouldn’t recommend doing that.


#3

Thank you, and point taken about macro’s not needing to be a problem. However what I’ m actually wondering is if it’s there some simpler way to create a new menu within 3dsMax, preferably by making the menu through maxscript itself :slight_smile:


#4

This sample might help you:

fn CreateMenu Name:"Name" Title:"Title" ParentMenu: =
(
	MenuItem = menuMan.CreateMenu Name
	MenuItem.setTitle Title
	SubMenuItem = menuMan.createsubMenuItem Name MenuItem
	if ParentMenu != undefined do ParentMenu.addItem SubMenuItem -1
	MenuItem
)
	
MainMenu = menuMan.getMainMenuBar()
Menu = CreateMenu Name:"Menu" Title:"Menu" ParentMenu:MainMenu
SubMenu1 = CreateMenu Name:"SubMenu1" Title:"SubMenu1" ParentMenu:Menu
SubMenu2 = CreateMenu Name:"SubMenu2" Title:"SubMenu2" ParentMenu:SubMenu1
menuMan.updateMenuBar()

#5

Thank you! :grinning:


#6

I’m sorry, I haven’t really tried your code until now, but could I be so bold as to ask a stupid question?

Your scripts is very clean, and it created menu’s as it should. My question is, how do I go about adding the actual scripts to the menu.

I’m thinking of retrieving the scripts from a folder within a loop:

scriptsFolder = @"My\Path\To\Scripts"
scriptFiles = getFiles (scriptsFolder + "*.mcr")
scriptNames = (for currFile in scriptFiles collect (filenameFromPath currFile))

Then I would like to add these scripts to the menu within a loop.

I don’t really need any submenu’s, I just want to add all of my macros to the menu created. How do I go about doing this? I’ve had a look at “menuMan.createActionItem”, but I can’t seem to get it to work :face_with_raised_eyebrow:

Again, any help would be much appreciated :slight_smile:


#7

I’ll try to be a bit more clear as to what my problem is specifically. The problem occurs once I try to add an ActionItem to the menu, I’ve added an example-code below:

MyMainMenu = menuMan.getMainMenuBar()
MyNewMenu = menuMan.createMenu "MenuName"
MyMenuItem = menuMan.createSubMenuItem "MenuItem" MyNewMenu
MyMainMenu.addItem MyMenuItem (MyMainMenu.numItems()+1)
MyAction = menuMan.createActionItem "NameOfMyMacro" "Title of the Macro"
MyNewMenu.addItem MyAction (MyNewMenu.numItems()+1)
menuMan.updateMenuBar()

When the code hits the the line where I try to add an actionitem, I get a long error-message (pasted below). To be clear, the name of the macro I’m trying to add is initialized in max, which is why I can’t for the life of me figure out why it fails.

Here’s the error-message I recieve (which does not make sense to me at all):

-- Error occurred in anonymous codeblock; filename: ; position: 285; line: 6
-- Known system exception
-- ########################################################################
-- Address: 0x9cb87565; nCode: 0x00000000C0000005
-- Desc: EXCEPTION_ACCESS_VIOLATION The thread tried to read from or write to a virtual address for which it does not have the appropriate access.
--       Read of Address: 0x0000000000000000
-- ########################################################################
-- MAXScript callstack:
--	thread data: threadID:28268
--	------------------------------------------------------
--	[stack level: 0]
--	In top-level
-- ########################################################################
-- C++ callstack:
-- (menus): (filename not available): ReleaseIMenu
-- (MAXScrpt): (filename not available): Generic::apply
-- (MAXScrpt): (filename not available): CodeTree::eval
-- (MAXScrpt): (filename not available): SourceFileWrapper::eval
-- (MAXScrpt): (filename not available): IsMAXScriptListenerInViewport
-- (USER32): (filename not available): ScreenToClient
-- (USER32): (filename not available): ScreenToClient
-- (USER32): (filename not available): ScreenToClient
-- (USER32): (filename not available): CallWindowProcW
-- (USER32): (filename not available): CallWindowProcW
-- (UIControls): (filename not available): (function-name not available)
-- (UIControls): (filename not available): (function-name not available)
-- (USER32): (filename not available): CallWindowProcW
-- (USER32): (filename not available): DispatchMessageW
-- (USER32): (filename not available): IsDialogMessageW
-- (3dsmax): (filename not available): NodeAndAnims::SetNode
-- ########################################################################

#8

I’m such a dumbass. I figured out that the second argument of menuMan.createActionItem is the category of the macro I’m trying to add :roll_eyes:

Either eay, while I’m bumping this thread again - might as well ask another question. Is it possible to call scripts from a menu without using macro’s at all? As in just executing a *.ms file from a menu?