Notifications
Clear all

[Closed] Control some option in viewport config through Script

Thanks Richard,

very interesting, in cases where MAXScript is otherwise locked out, this seems to be a viable method to get things done anyway!

But what the heck is that last line doing?!
Also, BN_CLICKED is undefined. What value should I use?

– MartinB

2 Replies
(@zeboxx2)
Joined: 11 months ago

Posts: 0

To an extent

Whoops. BN_CLICKED should be 0 (zero). Adjusted the script in my post.

Haha… I wonder that myself sometimes.

The first sendMessage line changes the checked state of the UI control; this does not actually signal the UI that its state changed. The proper way to do that, next, is to simulate a user interaction; in our case, a click.

However, you can’t just ‘click’ the checkbox (control_hwnd).

Oh no, no, no…
You have to

  1. signal (WM_COMMAND | Windows Message)
  2. to the parent dialog (controlParent) that
  3. the UI element with the given ID (controlID)
  4. was clicked (BN_CLICKED | Button Notification. Yes, a checkbox is a type of button*. Don’t look at me, MSFT designed that. )
    And
  5. for good measure we pass it the handle (control_hwnd) as a parameter again so that if controlParent wanted to do something with that, it could.

3 and 4 have to be combined somehow as there’s only so many parameters you can pass (wParam, lParam) – but thankfully either can only be 16bit, by design, so we can stick one if the first 16bits and the other in the last 16bits of a 32bit value.

  • And with that realization finally snapping into my head… at least for checkbuttons, you could also use UIAccessor’s PressButton and/or PressButtonByName (get the parent hwnd first).

 BN_CLICKED = 0
 BM_SETCHECK = 241
 fn getModifyPanelControl str = (
 	max_hwnd = windows.getMAXHWND()
 	max_children = windows.getChildrenHWND max_hwnd
 	modifyPanelFound = false
 	for el in max_children do (
 		if (el[4] == "ModifyTask") then ( modifyPanelFound = true )
 		if (modifyPanelFound) then ( -- ignore if we haven't found the modify panel!
 			if (el[5] == str) then ( exit with el )
 			if (el[4] == "HierarchyTask") then ( exit with undefined ) -- hierarchy panel, no luck.
 		)
 	)
 )
 hemiSphere_ui = getModifyPanelControl "Hemisphere"
 if (hemiSphere_ui != undefined) do (
 	 control_hwnd = hemiSphere_ui[1]
 	 controlParent = hemiSphere_ui[2]
 	 controlID = UIAccessor.GetWindowResourceID hemiSphere_ui[1]
 	 windows.sendMessage control_hwnd BM_SETCHECK 1 0 -- 0 0 to uncheck
 	UIAccessor.pressButton control_hwnd -- that's much prettier ^.^'
 )
 
(@martinb)
Joined: 11 months ago

Posts: 0

Thanks very much. That makes it a bit clearer. I guess it would help if one had experience in programming Windows?

Thanks again, I stored these examples away, in case I encounter non-scriptable UI elements again.

– MartinB

Just to do the pressButtonByName bit and some further processing…


-- for each rollout in the modify panel
-- returns the hwnd to the actual rollout client dialog, plus the title of the rollout
fn getModifyPanelRollouts = (
	theRollouts = #()
	max_hwnd = windows.getMAXHWND()
	max_children = windows.getChildrenHWND max_hwnd
	modifyPanelFound = false
	for i = 1 to max_children.count do (
		el = max_children[i]
		if (el[4] == "ModifyTask") then ( modifyPanelFound = true )
		if (modifyPanelFound) then (
			if (el[4] == "RollupPanel") then (
				append theRollouts #(max_children[i+2][1],max_children[i+1][5])
			)
			if (el[4] == "HierarchyTask") then ( exit )
		)
	)
	theRollouts
)
modPanelRollouts = getModifyPanelRollouts()
#(#(29361592P, "Pick Boolean"), #(25561248P, "Parameters"), #(26609968P, "Display/Update"))
UIAccessor.pressButtonByName modPanelRollouts[1][1] "Pick Operand B"
true

Another useful example, thank you! I figured it runs when an old Boolean object is selected and the Modify panel is active. Interesting that I had to change modPanelRollouts[1][1] to modPanelRollouts[3][1] on my 3ds Max 2009 64bit. Maybe the order in which the children are reported is not reliable or changes with versions of 3ds Max?

– MartinB

oh, quite possibly, Martin – but that’s why I included the title of the rollout in the result as well; just didn’t bother to actually utilize it in the one-liner

Page 2 / 2