mmMaxControls : .NET Controls with a 3dsmax Style

Lately I’ve seen several posts on the CGTalk MAXScript forum asking how one could make the standard .Net WinForms controls look like the standard 3dsmax UI elements.

Towards this end, I’ve written a collection of some commonly used controls that imitate the 3dsmax look and feel to the pixel, thus maintaining uniformity in your scripted or compiled interface, but giving you the high level of control that DotNet offers.

The package is called mmMaxControls, and is freely available for personal or commercial use. It targets version 2.0 of the DotNet framework, which should make is backwards compatible many versions (the earliest I’ve tested is 3dsmax 2009, theoretically it may work on as far back as 3dsmax 9).

General Features:

  • Look exactly like 3dsmax controls.
  • Control colors update when 3dsmax colors update.
  • No keyboard focus issues that plague standard DotNet controls in 3dsmax (EnableAccelerators is automatically managed by the library).
  • All the customization options of DotNet controls.
  • Can be used in any DotNet language. e.g. if you are developing a 3dsmax plugin in c# without referencing the 3dsmax SDK (for example, for versions earlier than 3dsmax 2012SAP), this is your best bet for native-looking 3dsmax controls.
  • Can be used in both a MAXScript Rollout as a DotNetControl or in a WinForms Form.

Download mmMaxControls v1.02 (12k)

The library is fully documented: Online | Zipped HTML.

Below is the code used for creating the MAXScript rollout at the top of this post.

dotnet.loadAssembly @"C:\mmMaxControls.dll"
try(destroyDialog mmMaxControls)catch()
rollout mmMaxControls "mmMaxControls" width:235
(
	groupBox grpBtn "Button" width:225 height:55 pos:[5,5]
	dotNetControl mmBtn1 "mmMaxControls.Button" width:62 height:25 pos:[15,25]
	dotNetControl mmBtn2 "mmMaxControls.Button" width:60 height:25 pos:[80,25]
	dotNetControl mmBtn3 "mmMaxControls.Button" width:25 height:25 pos:[143,25]
	dotNetControl mmBtn4 "mmMaxControls.Button" width:50 height:25 pos:[171,25]
	
	groupBox grpChk "CheckButton" width:225 height:55 pos:[5,65]
	dotNetControl mmChk1 "mmMaxControls.CheckButton" width:25 height:25 pos:[15,85]
	dotNetControl mmChk2 "mmMaxControls.CheckButton" width:70 height:25 pos:[45,85]
	dotNetControl mmChk3 "mmMaxControls.CheckButton" width:72 height:25 pos:[120,85]
	dotNetControl mmChk4 "mmMaxControls.CheckButton" width:25 height:25 pos:[195,85]
	
	groupBox grpFlyBtn "FlyoutButton" width:110 height:60 pos:[5,125]
	dotNetControl mmFlyBtn "mmMaxControls.FlyoutButton" width:32 height:32 pos:[43,145]
	
	groupBox grpFlyChk "FlyoutCheckButton" width:110 height:60 pos:[120,125]
	dotNetControl mmFlyChk "mmMaxControls.FlyoutCheckButton" width:32 height:32 pos:[157,145]
	
	groupBox grpDrop "DropDownList" width:225 height:50 pos:[5,190]
	dotNetControl mmDrop "mmMaxControls.DropDownList" width:200 height:21 pos:[15,210]
	
	groupBox grpTxt "TextBox" width:225 height:120 pos:[5,245]
	dotNetControl mmText1 "mmMaxControls.TextBox" width:200 height:21 pos:[15,265]
	dotNetControl mmText2 "mmMaxControls.TextBox" width:200 height:63 pos:[15,290]
		
	groupBox grpSpn "Spinner" width:225 height:65 pos:[5,370]
	label mmSpn1Lab "That's draggable" pos:[15,390]
	dotNetControl mmSpn1 "mmMaxControls.Spinner" width:80 height:16 pos:[140,390]
	label mmSpn2Lab "And screen-wrapping" pos:[15,412]
	dotNetControl mmSpn2 "mmMaxControls.Spinner" width:80 height:16 pos:[140,412]
		
	on mmMaxControls open do
	(
		local logoImg = dotnetObject "System.Drawing.Bitmap" @"C:\logo.png"
		local blueImg = dotnetObject "System.Drawing.Bitmap" @"C:\logoBlue.png"
		local flyoutStrip = dotnetObject "System.Drawing.Bitmap" @"C:\imageStrip.png"
		
		mmBtn1.text = "DotNet"
		mmBtn1.image = logoImg
		mmBtn1.imageAlign = mmBtn1.imageAlign.MiddleLeft
		mmBtn1.TextAlign = mmBtn1.textAlign.MiddleRight
		
		mmBtn2.text = "Controls"
		
		mmBtn3.image = logoImg
		mmBtn3.ShowFocusFrame = off
						
		mmBtn4.text = "With"
		mmBtn4.FrameOnMouseOverOnly = on
		
		mmChk1.text = "A"
			
		mmChk2.text = "3dsmax"
		mmChk2.image = blueImg
		mmChk2.imageAlign = mmChk1.imageAlign.MiddleLeft
		mmChk2.TextAlign = mmChk1.textAlign.MiddleRight
		mmChk2.ShowFocusFrame = off
		
		mmChk3.text = "Look"
		mmChk3.ShowFocusFrame = off
		mmChk3.FrameOnMouseOverOnly = on
		
		mmChk4.image = blueImg
		mmChk4.ShowFocusFrame = off
		mmChk4.FrameOnMouseOverOnly = on
		
		mmText2.multiLine = on
			
		mmSpn1.minimum = 0.1
		mmSpn1.maximum = 1
		mmSpn1.increment = .001
		mmspn1.value = mmspn1.defaultValue = 0.5
		mmSpn1.decimalPlaces = 3
		
		mmSpn2.increment = 1
		mmSpn2.maximum = 10000
		mmSpn2.value = mmSpn2.defaultValue = 100
		mmSpn2.decimalPlaces = 0
			
		mmDrop.items.addRange #("A", "DropDownList", "control", "that", "inherits", "from", "Combobox")
		mmDrop.selectedIndex = 0
		
		mmFlyBtn.setImageStrip flyoutStrip 4
		mmFlyBtn.toolTips = #("Easily", "Set", "Button", "Tooltips")
		
		mmFlyChk.setImageStrip flyoutStrip 4
		mmFlyChk.toolTips = #("Same", "Thing", "But", "Checkable")
		mmFlyChk.flyoutTime = 100
	)
)
createDialog mmMaxControls

These are the bitmaps used in the example code:


Update: v1.01

I’ve updated the library to v1.01, fixing a few bugs and adding a few small methods.
Changes:

  • Spinner: Backspace key was not working.
  • Spinner: now behaves correctly for resetting and cancelling a spin operation.
  • Spinner: now goes faster/slower with control/alt buttons pressed, as native 3dsmax spinner.
  • Spinner: text area would not accept the enter key when used as a DotNetControl.
  • Spinner: now shows the correct mouse cursor when dragging.
  • Spinner: ‘dragging’ behavior now only begins when the mouse has left the control area.
  • Spinner: Added .Clear() method for setting the control in an indeterminate state.
  • Spinner: Added events for ButtonDown and ButtonUp, similar to the native 3dsmax events.
  • Button: Contents are now corrently moved 1 pixel to the right and down when pressed.
  • CheckButtons: Frame is now always shown when button is checked, even if FrameOnMouseOverOnly is on.
  • Flyout controls: Opening the flyout no longer steals focus from the host dialog.
  • Flyout controls: Added .ShowFlyout() method for programmatically opening the flyout, e.g. – when you want another button to open the flyout.

Thanks to DenisT from CGTalk for catching most of these bugs.

Another Update: v1.02

I’ve fixed some more bugs and inaccuracies:

  • Spinner: Very minor change of point of transitioning from click to drag behavior, now completely matches 3dsmax.
  • CheckButton: Now shows checked background on mouse down, instead of mouse up.
  • FlyoutButton and FlyoutCheckButton: Flyout items are now correctly shifted 1 pixel right and down on mouse over.
  • FlyoutButton: ItemSelected is now also triggered when the button is clicked without the flyout opening.

23 thoughts on “mmMaxControls : .NET Controls with a 3dsmax Style

    • I’ve uploaded all the HTML files zipped, there is a link in the post, as well as updated the library.

  1. These controls look great. I’m especially happy about the flyoutbutton. Thank you very much.

    One thing I noticed though, if the controls are used inside a scripted plugin, it doesn’t seem to be possible to assign controllers and animation.

    parameters test rollout:test_rl
    (
    — this doesn’t work
    testvar type:#float ui:mmSpn
    )

    rollout test_rl “test”
    (
    dotnetcontrol mmSpn “mmMaxControls.Spinner”
    )

    I’m sure it’s not easy to implement that kind of functionality, but maybe utilizing the Autodesk.Max.dll could work. I am writing my own custom control currently and will let you know if I get any good results.

    • Thanks for your feedback.

      Regarding controller hookups, that is definitely not possible to implement on the .NET side of things.
      One thing that might work is:

      * Create a mmMaxControls.Spinner.
      * Create a 3dsmax Spinner control and set it to visible:false (hidden).
      * Connect the parameter to the hidden Spinner.
      * Hook up the relevant events from mmMaxControls.Spinner to change the value of the hidden Spinner control.

        • The first one is a silly bug on my part. It happens when setting the SelectedIndex property while the Images property is null. I will fix it on the next update.

          Regarding the second question, what exactly is the hover color? Do you mean the backcolor of the control while it is pressed/checked? That is taken from the 3dsmax color configuration.

          • Excuse me.
            Hover color it’s mouseover color, before mouse click.

            By the way, it would be nice to be able to change color when pressed.

          • Currently these features are not configurable. The goal of the project is to provide controls which mimic standard 3dsmax controls and follow the selected 3dsmax color scheme.

    • The Appearance should be Appearance.Button. If you want a regular checkbox style control, you can just use a normal checkbox.

  2. assembly is impossible to use a 2012 Max.
    “System.IO.FileNotFoundException: Could not load file or assembly ‘mmMaxControls, Version=1.0.1.0, Culture=neutral, PublicKeyToken=null’ or one of its dependencies.”

    File mmMaxControls.dll located in the folder “c: \ Program Files \ Autodesk \ 3ds Max 2012 \ bin \ assemblies \”

    what I did wrong ..?

  3. Pingback: mmMaxControls recompiled for 3ds max 2017 | Monotone Minimal

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>