Control Loft params from MXS.

Control Loft params from MXS.

dmitriy.shpilevoy
Collaborator Collaborator
500 Views
5 Replies
Message 1 of 6

Control Loft params from MXS.

dmitriy.shpilevoy
Collaborator
Collaborator

Hello, fellas.

I want to control Loft's Surface and Skin parameters.

Showproperties only dumps couple of useless things in my case.
Documentation is not much of a help either, unless I want to deal with SDK. And I don't because I can't.
Found a way to set checkboxes, not sure how clean or stable it is, but it works.

Spinners defeated me though.
Setting text to Edit field works, but doesn't stick. If I deselect Loft object and select it again, Length/Width Repeat values are reset.
Best I got is listed below. Idea was to set "fake" text and then "make it real" by clicking the SpinnerControl.
Value I set is treated as purely visual and is being overwritten by some internal value + increment from spinner click.

1.0 becomes 1.01 and not 10.01.

max2024

(
	commandPanelHwnd = windows.getChildHWND #max "Command Panel"
	local allControls = windows.getChildrenHWND commandPanelHwnd[1]
	local WM_LBUTTONDOWN = 0x0201
	local WM_LBUTTONUP   = 0x0202

	for ctrl in allControls do (
		-- ctrl[1] HWND, ctrl[4] class, ctrl[5] text
		if ctrl[5] == "Length Repeat:" then (
			local parentHwnd = UIAccessor.GetParentWindow ctrl[1]
			spinnerControls = (windows.getChildrenHWND parentHwnd)
			for sctrl in spinnerControls do (
				if sctrl[4] == "Edit" then (
					UIAccessor.SetWindowText sctrl[1] "10"
				)
				if sctrl[4] == "SpinnerControl" then (
					--format "%\t%\t%\n" sctrl[1] sctrl[4] sctrl[5]
					windows.sendMessage sctrl[1] WM_LBUTTONDOWN 0 0
					windows.sendMessage sctrl[1] WM_LBUTTONUP 0 0
				)
			)

		)
	)
)

 

0 Likes
Accepted solutions (2)
501 Views
5 Replies
Replies (5)
Message 2 of 6

dmitriy.shpilevoy
Collaborator
Collaborator

Okay, it's definitely not clean or stable. Nor does it work 😃
Command Panel behaves in a weird way - can't find it by name until I undock and dock it again. And since I can't find a way to script this redocking process, this is my code now for searching Command Panel (I have Mirror button always present in Modify panel):

for c in windows.getChildrenHWND #max do (
    if c[5] == "Mirror" do (
		thisParent = UIAccessor.GetParentWindow c[1]
		format "%\t|%|\n" thisParent (UIAccessor.GetWindowText thisParent)
		thisParent2 = UIAccessor.GetParentWindow thisParent
		commandPanelHwnd = UIAccessor.GetParentWindow thisParent2
	)
)


This is bad enough as it is, but on top of that both versions can't find Command Panel while it's undocked/floating.
Is it still a child of main max window in this state? If so, I can't find it.

 

0 Likes
Message 3 of 6

denisT.MaxDoctor
Advisor
Advisor
Accepted solution

Let's break down your questions:

fn editSpinner hwnd val = 
(
	WM_CHAR 	= 0x0102
	VK_RETURN 	= 0x000D

	uiaccessor.setwindowtext hwnd (val as string)
	windows.sendMessage hwnd WM_CHAR VK_RETURN 0 -- press ENTER key
)

 

it's how I do it.

Message 4 of 6

denisT.MaxDoctor
Advisor
Advisor
Accepted solution

How is it about:

iGlobal = (dotNetClass "Autodesk.Max.GlobalInterface").Instance
iGlobal.CoreInterface.CommandPanelRollup.Hwnd

?

Message 5 of 6

dmitriy.shpilevoy
Collaborator
Collaborator

Hi, Denis! Am I glad to see you, man. Max was bullying me again.

Spinner function works. Values are being set and persist.
I was ready to try sending RMB + click, N LMB clicks, N Alt + LMB clicks to hack it.

And the dotnet way to get Command Panel's hwnd works also. But there is a nuance...
If I redock and get it as windows.getChildHWND #max "Command Panel" and then dump children, it shows everything in every tab - 241 item. For example, even stuff from Utilities tab is getting listed.
It's not like I need inactive tab's controls, but listing children of dotnet-accessed panel seems to only show controls from first column - 24 items (if Command Panel was manually resized to get more info on the screen by increasing its width). By going 2 levels up from dotnet result I can get reliable, docking-state independent access and same "everything you wanted and more" amount of children.

This is what I ended up with:

(
	fn editSpinner hwnd val = 
	(
		WM_CHAR 	= 0x0102
		VK_RETURN 	= 0x000D

		uiaccessor.setwindowtext hwnd (val as string)
		windows.sendMessage hwnd WM_CHAR VK_RETURN 0 -- press ENTER key
	)
	iGlobal = (dotNetClass "Autodesk.Max.GlobalInterface").Instance
	cmdPanel_a = iGlobal.CoreInterface.CommandPanelRollup.Hwnd
	cmdPanel_b = UIAccessor.GetParentWindow cmdPanel_a
	cmdPanel = UIAccessor.GetParentWindow cmdPanel_b
	allControls = windows.getChildrenHWND cmdPanel

	for ctrl in allControls do (
		-- format "%\n" ctrl
		-- ctrl[1] HWND, ctrl[4] class, ctrl[5] text
		if ctrl[5] == "Length Repeat:" then (
			spnrParentHwnd = UIAccessor.GetParentWindow ctrl[1]
			loftSurfParams = (windows.getChildrenHWND spnrParentHwnd)
			for lspCtrl in loftSurfParams do (
				if lspCtrl[4] == "Edit" then (
					editSpinner lspCtrl[1] "10"
				)
			)
		)
	)
)



Thank you!

0 Likes
Message 6 of 6

denisT.MaxDoctor
Advisor
Advisor

You found the right solution.

CommandPanelRollup

 is a page. You need its grand-grand parent which is … let’s call it “COMMAND TASK PANEL” 🙂

0 Likes