Notifications
Clear all

[Closed] max rollout in .net dialog

there is a trick:


 fn CreateUser32Assembly forceRecompile:on =
(
	if (forceRecompile or 
		(classof ::User32Assembly) != dotNetObject or 
		((::User32Assembly.GetType()).ToString()) != "System.Reflection.Assembly") do
	(
		source = "using System;
"
		source += "using System.Runtime.InteropServices;
"
		source += "class User32
"
		source += "{
"
		source += " [DllImport(\"User32.DLL\", EntryPoint=\"GetWindowLong\")]
"
		source += " public static extern Int32 GetWindowLong(IntPtr hWnd, Int32 index);
"
		source += " [DllImport(\"User32.DLL\", EntryPoint=\"SetWindowLong\")]
"
		source += " public static extern Int32 SetWindowLong(IntPtr hWnd, Int32 index, Int32 newVal);
"
		source += " [DllImport(\"User32.DLL\", EntryPoint=\"SetWindowLong\")]
"
		source += " public static extern Int32 SetWindowLongPtr(IntPtr hWnd, Int32 index, IntPtr dwNewLong);
"
		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 += "}
"

		csharpProvider = dotnetobject "Microsoft.CSharp.CSharpCodeProvider"
		compilerParams = dotnetobject "System.CodeDom.Compiler.CompilerParameters"
						
		compilerParams.GenerateInMemory = true
		compilerResults = csharpProvider.CompileAssemblyFromSource compilerParams #(source)
		::User32Assembly = compilerResults.CompiledAssembly
	)
	::User32Assembly.CreateInstance "User32"
)
global User32 = CreateUser32Assembly()
fn setOwnerWindow main title = if (hwnd = windows.getChildHWND 0 title) != undefined do 
(
	hwnd = dotnetobject "IntPtr" hwnd[1]
	main = dotnetobject "IntPtr" main
	::User32.SetWindowLongPtr hwnd -8 main -- set ownership
	::User32.SetWindowPos hwnd 0 0 0 0 0 0x3 -- set z-top
	hwnd
)


try(destroydialog max_rol) catch()
try(win.close()) catch()

win = dotNetObject "MaxCustomControls.MaxForm"
win.size = dotNetObject "System.Drawing.Size" 200 70
win.Location = dotNetObject "System.Drawing.Point" 900 150
win.StartPosition = win.StartPosition.Manual
win.text = "Max Form"

rollout max_rol "Max Dialog"
(
	local sph 
	spinner sp "Radius: " fieldwidth:60 align:#right 
	on max_rol open do with undo off 
	(
		sph = sphere radius:(random 10 40) isselected:on
		sph.radius.controller = bezier_float()
		sp.controller = sph.radius.controller
	)
	on max_rol resized val do
	(
		if sp.pos.x != val.x-25 do sp.pos.x = val.x-25
	)
	fn close = 
	(
		if isvalidnode sph do with undo off delete sph
	)
)
	
win.showmodeless()
win.tag = dotnetmxsvalue #(max_rol)

p = win.RectangleToScreen win.ClientRectangle
createdialog max_rol p.width p.height p.left p.top bgcolor:white style:#() 
win.tag.value[2] = setOwnerWindow win.handle max_rol.title

fn onMove s a =
(
	p = s.RectangleToScreen s.ClientRectangle
	::User32.SetWindowPos s.tag.value[2] 0 p.x p.y p.width p.height 0
)
dotnet.addEventHandler win "Move" onMove
fn onResized s a =
(
	p = s.RectangleToScreen s.ClientRectangle
	::User32.SetWindowPos s.tag.value[2] 0 p.x p.y p.width p.height 0
)
dotnet.addEventHandler win "Resize" onResized
fn onClosing s a =
(
	s.tag.value[1].close()
)
dotnet.addEventHandler win "Closing" onClosing
 

you can do the same trick with RolloutFloater as well

PS. feel free to modify and improve.

5 Replies
 PEN

Now why did I just know that you would come up with something. I still havent sorted out how it is working but it looks cool.

 PEN

Can you provide a bit more explanation of what is going on here. I鈥檓 trying to add other dotNetObjects to the win but I鈥檓 not seeing them. I鈥檓 assuming that the rollout is over them?

ha that鈥檚 a neat trick, at first it appears that the rollout is actually contained within the form but after looking more closely, all that鈥檚 happening is that the border of the rollout has been removed by passing style:#() to the createdialog function and then the rollout is simply aligned and resized to fit the client area of the form when it is moved or resized. the rollout is still very much a part of max, you can call functions on it in the listener like setDialogPos max_rol [0,0] to see what I mean. So from this example, I guess that if you wanted to 鈥榗ontain鈥?a rollout or rolloutFloater within a form, all you have to do is modify the OnMove / OnResized events with appropriate position and size values

So Paul, to answer your question more directly: Yes – the rollout is over the other controls

Neat trick Denis!

very impressive to say the least

the need for rollouts was to hide certain controls and display them on demand
maxRollouts IMHO is a good solution for that , but making a maxRollout and hosting net objects inside resulted in certain settings being overriden .
for instance 鈥?i couldn鈥檛 change a .Net label font size if its hosted in a maxRollout
inside a maxForm 鈥?everything is ok.

this trick is working , but it feels little strange , once you click the spinner the form it self looses focus , away from that 鈥?the code is really freaking !

i鈥檓 trying to do a custom control in dotNet matching maxRollout , ain鈥檛 hard but ain鈥檛 so easy 鈥?, I Don鈥檛 want to make a control for myself !

honestly Denis , i鈥檇 rather spend a whole week trying to make it in c# than trying to decipher your monster code , i just hate extern methods inside maxScript !

Hi guys.

I gave you a little time to think how it works. Now I will give a little explanation of the trick. First, I want to tell my goals:

  1. It must be true max dialog (to fire and catch all events)
  2. It must be inside (technically it鈥檚 impossible) .net dialog
  3. Everything should be written in max script

Well.
Step #1 – Create max dialog without border and title. In the 鈥渄ialog鈥?case it鈥檚 easy. Just only use style. In the rollout floater case it鈥檚 a bit complicated. And as I have a time I will give you a snippet.
Step #2 – Using SetWindowLongPtr I made the max dialog the child of net dialog (see http://msdn.microsoft.com/en-us/library/ms644898(VS.85).aspx ). Now the net dialog is the owner of the max dialog. Minimize/Maximize/Close is inherited for child window from owner window.
Step #3 – Using SetWindowPos and flag HWND_TOP flag ( http://msdn.microsoft.com/en-us/library/ms633545(VS.85).aspx ) I set max dialog at the top of Z-order.
Step #4 – Using net form events I scale and move max dialog to keep it in the net window鈥檚 client area. But of cause it might be any position on the screen (or any size).

Because net dialog and max dialog are independent as windows when you pick any control from max dialog you are losing focus from net dialog. It鈥檚 expected. I can change this behavior but with serious 鈥渃-sharping鈥?(which is not following my goals).