Notifications
Clear all

[Closed] Compress on Save

Hey there,

I know that “compress on save” is not exposed via MXS and that you can change the INI setting (even though this method is no helpful to me since it requires to restart your 3dsMax).

I was trying to find if there is any function I could use from the Autodesk.Max.dll but I couldn’t find any. Did I missed anything?

Thanks,
Nick

10 Replies
 lo1

You could definitely hack together a UIAccessor based solution if you’re into tolerating that sort of thing.

UIAccessor doesn’t it mean that I have to open all these dialogs and check/uncheck the setting?
if yes, I was looking for a more sleek solution.

 lo1

Yes that’s exactly what it means. It’s ugly as hell, but it’s my never-fail last resort for a lot of things.

Thanks lo,

Yesterday, I did some tests and I had a couple of problems and I think everything had to do with the fact that “Preference Settings” is a modal windows and every time it starts, Max Pauses any code execution.
Have you ever tried to change stuff in the “Preference Settings” dialog?

Btw, I’ve also tried to execute code from a second 3dsMax (in the futures it could probably be am external cmd app) by passing max’s handle. At this case, I’ve managed to press “ok” in the dialog but I could change the “Tab” since I could find “General”, “Rendering” but no “Files”. But even with the “General” button found, I was trying to press this button/tab with this command “UIAccessor.PressButton <HWND>hwnd” but nothing was happening

 lo1

you will need to use DialogMonitorOps to perform code inside the modal dialog.

See the TabbedDialog struct to change pages of the preferences dialog.

And use this function for setting the state of a checkbox:

fn setUICheckboxState hwnd state =
(
/***********************************************  ***********************
	<DOC> toggle an UI checkbox's checked state via UI messages/notifications
	Arguments:
		<int> hwnd:			HWND of the control
		<int> state: 		checked state.  1 = check, 0 = uncheck
	Return:
		<ok>  should check/uncheck the checkbox and have its change effected
********************************************  **************************/
	local BN_CLICKED = 0 -- clicky message ID
	local BM_SETCHECK = 241 -- checkbutton toggle message ID
	local WM_COMMAND = 273 -- windows command message

	local parent = UIAccessor.getParentWindow hwnd
	local id = UIAccessor.getWindowResourceID hwnd
	windows.sendMessage hwnd BM_SETCHECK state 0
	windows.sendMessage parent WM_COMMAND ((bit.shift BN_CLICKED 16) + id) hwnd
	OK
)

That was really helpful! Thank you very much! My only problem is that I can find the tab control, but it doesn’t have any children or something so I can’t understand how I can find the page and then try to click on the correct one…

Here is where I’ve gone so far


(
 local
  checkBoxState; --Store the value for the checkbox so I can pass it in the function
 
 --Change checkbox state
 fn setUICheckboxState hwnd state = (
 /****************************************************************************
  <DOC> toggle an UI checkbox's checked state via UI messages/notifications
  Arguments:
   <int> hwnd:   HWND of the control
   <int> state:   checked state.  1 = check, 0 = uncheck
  Return:
   <ok>  should check/uncheck the checkbox and have its change effected
 ****************************************************************************/
  local BN_CLICKED = 0 -- clicky message ID
  local BM_SETCHECK = 241 -- checkbutton toggle message ID
  local WM_COMMAND = 273 -- windows command message
  local parent = UIAccessor.getParentWindow hwnd
  local id = UIAccessor.getWindowResourceID hwnd
  windows.sendMessage hwnd BM_SETCHECK state 0
  windows.sendMessage parent WM_COMMAND ((bit.shift BN_CLICKED 16) + id) hwnd
  OK
 )
 
 --DialogMonitorOPS Function
 fn preferencesDialog = (
  returnVal = true
 
  try (
   local
	preferencesDialogHandle = DialogMonitorOPS.GetWindowHandle(),
	children = UIAccessor.GetChildWindows preferencesDialogHandle,
	compress,
	okButton,
	SysTabControl32;
 
   --Collect the OK button, the Compress On Save checkbox and the SysTabControl(?!)
   itmsFound = 0
   for c in children where itmsFound < 3 do (
	if UIAccessor.GetWindowClassName c == "SysTabControl32" AND UIAccessor.GetParentWindow c == preferencesDialogHandle then ( SysTabControl32 = c; itmsFound += 1 )
	else if UIAccessor.GetWindowText c == "Compress on Save" then ( compress = c; itmsFound += 1 )
	else if UIAccessor.GetWindowText c == "OK" then ( okButton = c; itmsFound += 1 )
   )
 
   --At this point it needs to change tab
 
   --Check box
   setUICheckboxState compress checkBoxState
   UIAccessor.PressButton okButton
  )
  catch ( returnVal = false )
 
  returnVal
 )
 
 
 --Main Function
 fn saveCompressed = (
  --Enable DialogMonitorOPS and register function
  DialogMonitorOPS.Enabled = true
  DialogMonitorOPS.RegisterNotification preferencesDialog  ID:#preferencesDialog
 
  --Check / Save / uncheck
  checkBoxState = 1
  max file preferences
  -- Here will go the save code and then I'll restore it back to 0
  checkBoxState = 0
  max file preferences
 
  --Disable DialogMonitorOPS and unregister function
  DialogMonitorOPS.UnRegisterNotification ID:#preferencesDialog
  DialogMonitorOPS.Enabled = false
 )
 
 --Start
 saveCompressed()
)
 
 lo1

Here you go

 fn preferencesDialog = (
  try (
	if not (tabbedDialogs.isOpen #preferences) do return true
	for i = 1 to (tabbedDialogs.getNumPages #preferences) do
	(
		if (tabbedDialogs.getPageTitle #preferences i) == "Files" do
		(
			tabbedDialogs.setCurrentPage #preferences i
		)
	)
	local prefsDlg = dialogMonitorOps.getWindowHandle()
	for w in windows.getChildrenHwnd prefsDlg where w[5] == "Compress on Save" do
	(
		setUICheckboxState w[1] checkBoxState
		tabbedDialogs.CommitPages #preferences
		tabbedDialogs.CloseDialog #preferences
		return true
	)
	return false
)
  catch
	  (
	  print (getcurrentexception())
	  return false
	  )
 )

Thanks!!

Btw… when you wrote “See the TabbedDialog struct to change pages of the preferences dialog.” I typed “TabbedDialog” on the Listener to see if that was actually a struct and it returned undefined so I though that I understood something wrong and that it was something outside of MXS so I google it and I didn’t got any results… Now that I saw your current code I saw that there was a missing “s” at the end and if I had done the search in MXS doc I would have found it… damn me!

Anyway, much appreciated, thanks!

1 Reply
 lo1
(@lo1)
Joined: 2 years ago

Posts: 0

Sorry, meant to write TabbedDialogs of course

Don’t ask sorry! You saved me a lot of hours! Thanks again! Cya