Changing value of WPF property



So I’ve been playing around a bit with 3dsMax ui lately, and I’ve been trying to “Hide/Show Menu Bar” through maxscript.
As you may know it’s not exposed to maxscript at all.
But I found this utility called “Snoop” that basically allows you to spy on WPF forms. I found the variable that shows/hides the menu bar.

Now I “just” need to be able to change that value through maxscript instead of “Snoop”. And since I have no idea how to go on from here, I’m just throwing it out there, maybe someone knows how to proceed from here…



Here is a little something I found…

It’s also using “Autodesk.Windows.ToolBars.QuickAccessToolBarSource”


So I did some progress here…
Alex Krammer’s “Show .Net Property” tool actually can access “Autodesk.Windows.ToolBars.QuickAccessToolBarSource”.
(See screenshot)

But I’m still unable to change the property. Does anyone know why?

QAT_Toolbar = dotNetObject "Autodesk.Windows.ToolBars.QuickAccessToolBarSource"
QAT_Toolbar.IsMenuBarVisible = false


Don’t create a new toolbar, use the component manager singleton to fetch the existing one:

qatbar = (dotnetclass "Autodesk.Windows.ComponentManager").QuickAccessToolBar

qatbar.IsVisible = false
qatbar.IsMenuBarVisible = false

qatbar.IsVisible = true
qatbar.IsMenuBarVisible = true



Of course!

Thanks a lot biddle!


So I’m just going to leave this here, in case anyone is interested. It should get rid of the InfoCenter and the QuickAccessToolbar.

ComponentManager = (dotnetclass "Autodesk.Windows.ComponentManager")

ComponentManager.QuickAccessToolBar.IsVisible = false
ComponentManager.InfoCenterToolBar.MaxWidth = 0
ComponentManager.InfoCenterToolBar.MinWidth = 0

Thanks again biddle!

Edit: It looks so much better now… :slight_smile:


Just a quick question its a bit off topic where do you find

Autodesk.Windows etc… Assembly i dont see it in the SDK :frowning:


great stuff!
thank you for permanently killing the stupid info center for me!


It isn’t documented but you can use reflection to ferret out what you need.

I typically rely on the Object Browser that comes with Visual Studio to pull in assembly files and snoop around for things that look interesting, but you can discover a lot with 3dsmax alone.

The following snippet will dump all the exported types found in the assemblies located in your max root folder.

for dllname in getfiles ((getdir #maxroot)+"*.dll") do
	try (
		asm = dotnet.LoadAssembly dllname
		format "
		format "[%] exports:
" dllname
		for etype in (asm.GetExportedTypes()) do
			format "%
" etype.FullName
	catch ()

The “Autodesk” namespace contains code that looks to be shared with (or derived from) the stuff that is in AutoCAD. Perhaps you can look there for enlightenment? link

I tried poking around adding buttons to the quick access bar & such, but it seemed kind of klunky.



Thank you… it helped me alot. Im now looking into assemblies, could you possibly post example how you add buttons to toolbar because i made few examples since but just cant run them in max.


Actually there is another undocumented method of adding items to the QAT toolbar:

fn QATaddItem MacroScriptName Category =

	maintoolbar_file = pathConfig.removePathLeaf((symbolicPaths.getPathValue "$userscripts")) + "\\ui\\MaxStartUI.cui"

	--First save our current CUI file as the MaxStartUI.cui
	deleteFile maintoolbar_file
	cui.saveConfigAs maintoolbar_file

	--Read Current Item count
	QATItemCount = getINISetting maintoolbar_file "QATItems" "QATItemCount"

	--Set value
	setINISetting maintoolbar_file "QATItems" ("Item" + QATItemCount) ("647397|" + MacroScriptName + "`" + Category)

	--Reload cui file
	cui.loadConfig maintoolbar_file


Ok finally did it

Autodesk.Windows.ToolBars.QuickAccessToolBarSource strip = ComponentManager.QuickAccessToolBar;
           if (strip != null)
               RibbonButton rb = new RibbonButton();
               rb.Text = "test";
               rb.Description = "Desc";
               rb.Image = GetIcon(theImage);

This adds button to quick launch bar.

EDIT: Managed to add new WPF panel like graphite modeling tools it works really awesome, still trying to add button to main max menu, i add item to menu i see empty space but it does not show icon or text but still working on it.


We might be going a bit offtopic here but, I just realized what a mess the whole QAT is…

There seem to be multiple ways of adding/removing stuff from the toolbar.

You can add/remove items from the Customize window or directly by changing the cui file and reloading. (or simply use qat.add)

But, you can also add items through the ribbon interface, right clicking items and clicking on “Add to QAT”. (You can also add separators by rightclicking in the QAT.)
But, NONE of the items added through the ribbon interface will be saved in the cui file, so they will not show up next time you run 3dsMax. So it’s… completly useless for the user?

Either you add items through the old Customize window, but you won’t be able to add all the items you want, and you won’t be able to change icons and other things.
Or… you add items through the ribbon interface, but they will be gone next time you start 3dsmax! :banghead:


What about a startup script? i did it with your snipplet to remove the call center stuff, it’s in my stdscripts folder and works great.
The whole max custom UI stuff is very unreliable anyway, the ribbon gets easily corrupted. It makes no sense for the user to customize it, because changes are not portable (all or nothing), and if it corrupts you have to start again.


Yep, I realized that as well. It is really slow as well… just switching between subselections in editable poly, takes away 1s to 2s :eek:

A startup script that repopulates the QAT could be possible… but I’m wondering why would Autodesk give you the option to customize the QAT, if you can’t save the changes? :shrug:


Perhaps you can hook the “CollectionChanged” event of the toolbar’s Item collection and save off the state to the ini file when it changes?

fn PropertyWatcher sender args =
	format "
changed property [%]
" args.PropertyName

fn CollectionWatcher sender args =
	format "
Item collection has changed, action is [%]
" (args.action.ToString())
	if args.NewItems != undefined do
		format "There are % new items, starting at index %
" args.NewItems.count args.NewStartingIndex
	if args.OldItems != undefined do
		format "There are % old items, starting at index %
" args.OldItems.count args.OldStartingIndex
	format "You will want to update the CUI ini file if you intend to make this change permanent...

qatbar =(dotnetclass "Autodesk.Windows.ComponentManager").QuickAccessToolBar

-- Clear out handler (if we excute this script more than once)
dotnet.removeeventhandlers qatbar "PropertyChanged"
dotnet.removeeventhandlers qatbar.items "CollectionChanged"

dotnet.addeventhandler qatbar "PropertyChanged" PropertyWatcher
dotnet.addeventhandler qatbar.items "CollectionChanged" CollectionWatcher

-- Trigger some property change events
qatbar.IsVisible = false
qatbar.IsVisible = true

rb = dotnetobject "Autodesk.Windows.RibbonButton"

-- Create an icon with the correct size
uri = dotnetobject "Uri" ((getdir #maxroot)+@"ui\Icons\ApplicationMenu\summaryInfo_32.ico") (dotnetclass "UriKind").Absolute
rb.Image =  dotnetobject "System.Windows.Media.Imaging.BitmapImage" 
rb.Image.UriSource = uri
rb.Image.DecodePixelWidth = 16
rb.Image.DecodePixelHeight = 16

-- Trigger some item collection changed events = (qatbar.items.count + 1000) as string -- Pick an unused ID
rb.Description = "A new button with ID " +
qatbar.AddStandardItem rb

rb = rb.Clone() = (qatbar.items.count + 1000) as string
rb.Description = "A new button with ID " +
qatbar.AddStandardItem rb

rb = rb.Clone() = (qatbar.items.count + 1000) as string
rb.Description = "A new button with ID " +
qatbar.AddStandardItem rb

---Remove any 'extra' items
while qatbar.items.count > 6 do
	qatbar.RemoveStandardItem qatbar.items.item[qatbar.items.count-1]

Saving the state may not be useful in the end because you are probably going want to bind the click of the button you add to some maxscript function at startup anyhow.



I managed to customize ribbon adding stuff but i agree ribbon control is so slow. But its nice that you can customize start up interface to something different… Its weird that so much is undocumented.


that looks awesome :smiley:


hmmmm… I was wondering… perhaps the 3dsmax icon on the upper left corner can be deleted? It seems to be inside AdImpApplicationFrame, but I can’t find anything that could make it invisible.

I have managed however to get rid of it by reshacking 3dsmax.exe and deleting the bmp’s of the button. :blush:


after several steps of rationalization I got this… it’s not a final! :wink: