Notifications
Clear all

[Closed] How To Make Max Script Incremental Save?

Add Incremental Save Button to Script Save dialog on-fly:


   /*********************************************************
 by denisT
 
 Use at your own RISK!
 ******************************************************/
 
 global WinAssembly
 fn CreateWinAssembly forceRecompile:off =
 (
 	if forceRecompile or not iskindof ::WinAssembly dotnetobject or (::WinAssembly.GetType()).name != "Assembly" do
 	(
 		source  = "using System;
"
 		source += "using System.Runtime.InteropServices;
"
 		source += "using System.Text;
"
 		source += "class Win_User32
"
 		source += "{
"
 		source += " [DllImport(\"user32.dll\")]
"
 		source += " public static extern bool SetWindowPos(IntPtr hWnd, int hWndArg, int Left, int Top, int Width, int Height, int hWndFlags);
"
 		source += " [DllImport(\"user32.dll\")]
"
 		source += " public static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
"
 		source += "	[DllImport(\"user32.dll\")]
"
 		source += "	static extern bool GetClientRect(IntPtr hWnd, out POS rect);
"
 		source += "	public struct POS
"
 		source += "	{
"
 		source += "		public int Left;
"
 		source += "		public int Top;
"
 		source += "		public int Right;
"
 		source += "		public int Bottom;
"
 		source += "	}
"
 		source += "	public int[] GetClientRect(IntPtr hWnd)
"
 		source += "	{
"
 		source += "		POS rect;
"
 		source += "		if ( GetClientRect(hWnd, out rect) )
"
 		source += "		{
"
 		source += "			return new int[] { rect.Left, rect.Top, rect.Right - rect.Left, rect.Bottom - rect.Top };
"
 		source += "		}
"
 		source += "		return null;
"
 		source += "	}
"
 		source += "}
"
 
 		csharpProvider = dotnetobject "Microsoft.CSharp.CSharpCodeProvider"
 		compilerParams = dotnetobject "System.CodeDom.Compiler.CompilerParameters"
 						
 		compilerParams.GenerateInMemory = on
 		compilerResults = csharpProvider.CompileAssemblyFromSource compilerParams #(source)
 		
 		WinAssembly = compilerResults.CompiledAssembly
 		WinAssembly.CreateInstance "Win_User32"
 	)
 )
 global Win_User32 = if Win_User32 == undefined then CreateWinAssembly() else Win_User32
 --global Win_User32 = CreateWinAssembly forceRecompile:on
 
 DialogMonitorOPS.unRegisterNotification id:#saveAsMonitor
 /** for Debug only *****
 DialogMonitorOPS.Enabled = off
 **************************/
  
 fn saveAs_notification = 
 (
 	local hwnd, name, owner
 	
 	name = if UIAccessor.isWindow (hwnd = DialogMonitorOPS.GetWindowHandle()) do UIAccessor.GetWindowText hwnd
 	if (name == "Save File") or (name == "Save a Copy") do
 	(
 		owner = UIAccessor.GetParentWindow hwnd
 		if getfilenamefile (UIAccessor.GetWindowDllFileName owner) == "MXS_SciTE" do 
 		(
 			-- format "Dialog Window Handle: %
" hwnd
 
 			rollout inc_rol "Increment File Name" 
 			(
 				local ui
 				button inc_bt "+" width:0 height:0 tooltip:"Incremental Save/RC - Increment Filename"
 				
 				fn incrementFilename filename = 
 				(
 					file = getfilenamefile filename
 					body = trimRight file "0123456789"
 					id = if not iskindof (id = execute (replace file 1 body.count "")) Integer then 1 else (id+1)
 					body + (formattedprint id format:"02d") + (getfilenametype filename)
 				)
 				fn getIncremental saveit:off =
 				(
 					local filename = UIAccessor.GetWindowText ui[2]
 					if filename != "" do
 					(
 						UIAccessor.SetWindowText ui[2] (incrementFilename filename)
 						if saveit do UIAccessor.PressButton ui[3]
 					)
 --					setfocus inc_rol
 				)
 				on inc_bt pressed do getIncremental saveit:on
 				on inc_bt rightClick do getIncremental saveit:off
 			)
 			createdialog inc_rol 0 0 style:#()
 			
 			input = UIAccessor.GetNextWindow (windows.getChildHWND hwnd "File &name:")[1]
 			save_bt = (windows.getChildHWND hwnd "&Save")[1]
 			inc_rol.ui = #(hwnd, input, save_bt)
 
 			d_ptr = dotnetobject "IntPtr" (d = (windows.getChildHWND 0 inc_rol.title)[1])
 			b_ptr = dotnetobject "IntPtr" (windows.getChildHWND d "+")[1]
 
 			s_ptr = dotnetobject "IntPtr" save_bt
 			rect = Win_User32.GetClientRect s_ptr
 			b_size = [rect[4]-4, rect[4]-4]
 
 			::Win_User32.SetParent d_ptr s_ptr
 			::Win_User32.SetWindowPos d_ptr 0 (rect[3]-b_size.x-2) 2 b_size.x b_size.y 0
 			::Win_User32.SetWindowPos b_ptr 0 0 0 b_size.x b_size.y 0
 			
 			-- format "-- the end --
"
 		)
 	)
 	true
 )
 
 DialogMonitorOPS.RegisterNotification saveAs_notification id:#saveAsMonitor
 DialogMonitorOPS.Enabled = on
 DialogMonitorOPS.ShowNotification()
   

After running this code you will see “+” button in “Save File”, “Save As…”, and “Save a Copy…” dialogs. Right Click on “+” button -> increment filename. Press -> increment and save.

I did’t clean it up because I don’t suppose to use it. It was interesting for me just as a challenge.
You can modify the code and use it at your own risk!

3 Replies
 JHN

Ok, that’s pretty impressive, thanks for sharing!

-Johan

Hacking the MAXScript editor with MAXScript – pretty cool UIAccessor trick!
The ‘+’ button should be standard for all Save dialogs.

Thanks for sharing!
– MartinB

PS: What’s the :: construct doing?

nice one Denis!

J.