dotNet + MXS


#421

or


fn Accelerator senderArg eventArg =
(
	enableAccelerators = not senderArg.ContainsFocus
)

fn onEnter senderArg eventArg =
(
	senderArg.BeginInit()
	senderArg.Update()
	senderArg.Refresh()
	senderArg.EndInit()
)

dotNet.addEventHandler t "Enter" onEnter
dotNet.addEventHandler t "mouseEnter" Accelerator


#422

nice denisT, much more cleaner/elegant version.

what is the relative .NET form for a MXS queryBox ?

i could only found messageBox :

research_01
research_02

thanks in advance


#423

messageBox in dotnet is used for everything…
here’s a queryBox setup:


 /*
  ----------------------------------------------------------
  System.Windows.Forms.MessageBoxButtons (Enumeration)
  ----------------------------------------------------------
  .AbortRetryIgnore
  .OK
  .OKCancel
  .RetryCancel
  .YesNo
  .YesNoCancel
  
  ----------------------------------------------------------
  System.Windows.Forms.MessageBoxDefaultButton (Enumeration)
  ----------------------------------------------------------
  .Button1
  .Button2
  .Button3
  
  ----------------------------------------------------------
  System.Windows.Forms.MessageBoxIcon (Enumeration)
  ----------------------------------------------------------
  .Asterisk
  .Error
  .Exclamation
  .Hand
  .Information
  .None
  .Question
  .Stop
  .Warning
  
  ----------------------------------------------------------
  MessageBox.show (Method)
  ----------------------------------------------------------
  MessageBox.show ( text, caption, buttons, icon, defaultButton )
  
  */ 
  
  (
 	 -- setup dotnet classes / objects
 	 local mb = dotNetClass "System.Windows.Forms.MessageBox"
 	 local buttons = dotNetClass "System.Windows.Forms.MessageBoxButtons"
 	 local icons = dotNetClass "System.Windows.Forms.MessageBoxIcon"
 	 local defaultButton = dotNetClass "System.Windows.Forms.MessageBoxDefaultButton"
 	 local dialogResult = dotNetClass "System.Windows.Forms.DialogResult"
 	 
 	 local result = mb.show "Do you want to save before quitting?" "Quit" buttons.YesNo icons.Warning defaultButton.Button1
 	 
 	 -- evaluate result of messageBox (which button has been pressed by the user)
 	 if ( result == dialogResult.Yes ) then
 	 (
 		 format "YES
"
 	 )
 	 else if ( result == dialogResult.No ) then
 	 (
 		 format "NO
"
 	 )
 	 else if ( result == dialogResult.Cancel ) then
 	 (
 		 format "CANCEL
"
 	 )
  )
 

PS. it’s not my code. thank some one else. :slight_smile:


#424

thanks again denisT !

question:

is it possible to clean up 3Dsmax´s memory using .NET (kill pointers, kill global vars, etc) ?

e.g
something like when you close and re-open the application.

research

thanks in advance


#425

i’m not sure what you want to clean but
use (dotnetclass “System.gc”).collect() for dotnet garbage collection,
dispose all disposable dotnet objects using <object>.Dispose(),
use gc() for max garbage collection,
and globalVars.remove [color=White]to remove some variables from list of globals.

[/color]


#426

yes, that is it denisT !

what the .Dispose() means ? and you mean place it into all my dotNET controls ?


#427

check some answers on your questions on the internet:
for example:
http://dotnetfacts.blogspot.com/2008/03/things-you-must-dispose.html
or
http://www.devx.com/dotnet/Article/33167


#428

Related to some earlier posts on this thread, I posted a blog entry with a full/working example of using DotNet sockets in MaxScript to send data to an outside tool (Python in this case).

http://techarttiki.blogspot.com/2009/12/maxscript-dotnet-sockets-with-python.html

I was unable to find a similar example anywhere, and thought this might be useful to some of you.


#429

I intend to use 3dsmax features through c# .net… most examples in the thread refer to using .net classes in 3dsmax… pls advise how I can access 3dsmax features like import, export, material editing and mapping coordinates using APIs directly in c# .Net in Visual Studio…

Regards
Samir


#430

thanks a lot for the usefull links denisT !!

say i want to do the inverse operation using a ColorDialog, e.g:


  		dN_UI = dotNetObject "System.Windows.Forms.Form"
  			dN_UI.location = dotNetObject "System.Drawing.Point" 0 0
  			dN_UI.text = "dotNET test"
  			dN_UI.width = 200
  			dN_UI.height = 300
  			dN_UI.showInTaskBar = true
     
  				btn_1  = dotNetObject "System.Windows.Forms.Button"
  					btn_1.size = dotNetObject "System.Drawing.Size" 120 50
  					btn_1.name = "btn_1"
  					btn_1.location = dotNetObject "System.Drawing.Point" 20 150
  					btn_1.backColor = (dotNetClass "System.Drawing.Color").Green
  			   
  		dN_UI.controls.add(btn_1)
  	   
  			fn btn_mouseUp senderArg eventArg =
  			(
  				senderArg.Focus()
  				case (senderArg.Name) of
  				(
  					"btn_1":
  					(
  						if (eventArg.button == eventArg.button.left) do
  						(
  							-- ColorDialog
  							cd_1  = dotNetObject "System.Windows.Forms.ColorDialog"
  							cd_1.Color = (dotNetClass "System.Drawing.Color").AliceBlue
  							cd_1.FullOpen = false
  							cd_1.AllowFullOpen = false
  							cd_1.ShowDialog()
  						   
  							btn_1.backColor = (dotNetClass "System.Drawing.Color").fromARGB cd_1.Color.r cd_1.Color.g cd_1.Color.b
  							$Sphere01.wirecolor = btn_1.backColor
  							cd_1.Dispose()
  						) -- end if
  
  					) -- 1
  
  				) -- end case
  
  			) --
  		   
  			dotNet.addEventHandler btn_1 "mouseUp" btn_mouseUp
  		   
  		dN_UI.Show()
  

– returns
>> MAXScript dotNet event handler Exception: – Unable to convert: dotNetObject:System.Drawing.Color to type: Color <<

what should i have to do ?


#431

dotcolor = (dotNetClass “System.Drawing.Color”).Red
maxcolor = color dotcolor.r dotcolor.g dotcolor.b


#432

thanks a lot denisT , works like a charm !!

Other question:

unfortunately i couldn´t make numericUpDowns forms work with float values, just with integers even setting the minimum/maximum values as fractionaries… e.g


  	  
 		dN_UI = dotNetObject "System.Windows.Forms.Form"
 			dN_UI.location = dotNetObject "System.Drawing.Point" 0 0
 			dN_UI.text = "dotNET test"
 			dN_UI.width = 200
 			dN_UI.height = 300
 			dN_UI.showInTaskBar = true
 
 		-- numericUpDown (nud)
 		nud = dotNetObject "System.Windows.Forms.NumericUpDown"
 			nud.name = "nud_RenderIters"
 			nud.size = dotNetObject "System.Drawing.Size" 120 50
 			nud.minimum = 0.01
 			nud.maximum = 100.0
			nud.value = 1.5
			nud.DecimalPlaces = 2
			nud.InterceptArrowKeys = true
 			nud.location = dotNetObject "System.Drawing.Point" 10 10
 			nud.Enabled = true
 			
 		dN_UI.controls.add(nud)
 		dN_UI.Show()
  

is there any workaround ??


#433

this any use to you? I refer to YPeuch’s excelent solution as a way of solving this natively in Max, rather than a custom assembly.

http://lonerobot.net/?p=530


#434

		dN_UI = dotNetObject "System.Windows.Forms.Form"
			dN_UI.size = dotNetObject "System.Drawing.Size" 200 200
--			dN_UI.location = dotNetObject "System.Drawing.Point" 0 0
			dN_UI.text = "dotNET test"
--			dN_UI.showInTaskBar = true

		-- numericUpDown (nud)
		nud = dotNetObject "System.Windows.Forms.NumericUpDown"
			nud.name = "nud_RenderIters"
			nud.size = dotNetObject "System.Drawing.Size" 120 50
			nud.DecimalPlaces = 2
			nud.Increment = 0.01
			nud.minimum = 0.01
			nud.maximum = 100.0
			nud.value = 1.5
			nud.InterceptArrowKeys = true
			nud.location = dotNetObject "System.Drawing.Point" 10 10
			nud.Enabled = true
		
fn onValueChanged s a = 
(
	format "% %
" s.value ((v = s.get_value asdotnetobject:on).ToSingle v)
)	
		dotnet.addEventHandler nud "ValueChanged" onValueChanged

		dN_UI.controls.add nud
		dN_UI.Show()


#435
   thanks for the input [b]Pete[/b], but that custom Assembly thing doesn´t make sense for me yet ...is it some kind of compiled .dll ? what is the pipeline about it ?? (e.g VS, load libraries, use as references, make your own code snipets, compile, input/output data from Max, etc....) ?

Although for study purposes i´m going to implement standard forms like denisT suggested, then soon dive more into custom things.

cheers !


#436

how to do a pick color inside dotNET ?

     in the test below, it´s possible to change nodes wirecolor using a dotNET button :

          
          (
          	local MAX_color = black
          	local DotNET_Color = (dotNetClass "System.Drawing.Color").fromARGB 0 0 0
          	
          	dN_UI = dotNetObject "System.Windows.Forms.Form"
          		dN_UI.text = "Color testing"
          		dN_UI.width = 200
          		dN_UI.height = 300
          		dN_UI.topMost = true
          		dN_UI.showIcon = false
          
          		btn_1 = dotNetObject "System.Windows.Forms.Button"
          			btn_1.size = dotNetObject "System.Drawing.Size" 120 50
          			btn_1.name = "btn_1"
          			btn_1.location = dotNetObject "System.Drawing.Point" 20 150
          			btn_1.backColor = (dotNetClass "System.Drawing.Color").Green
          
          		cd_1 = dotNetObject "System.Windows.Forms.ColorDialog"
          			cd_1.Color = (dotNetClass "System.Drawing.Color").AliceBlue
       			cd_1.FullOpen = true
       			cd_1.AnyColor = true
       			cd_1.AllowFullOpen = true
       
          	dN_UI.controls.add(btn_1)
          	
          	fn btn_mouseUp senderArg eventArg =
          	(
          		
          		senderArg.Focus()
          			case (senderArg.Name) of
          			(
          				"btn_1":
          				(
          					if (eventArg.button == eventArg.button.left) do
          					(
          						cd_1.ShowDialog()
          						DotNET_Color = (dotNetClass "System.Drawing.Color").fromARGB cd_1.Color.r cd_1.Color.g cd_1.Color.b
          						btn_1.backColor = DotNET_Color
          						dN_Color = btn_1.backColor
          						MAX_color = color (dn_Color.r) (dn_Color.g) (dn_Color.b)
          						selection.wirecolor = MAX_Color
          					) -- end if
          
          					if (eventArg.button == eventArg.button.right) do
          					(
          						selection.wirecolor = MAX_Color
          					) -- end if
          					
          				) -- 1
          				
          			) -- end case
          			
          	) --
          	
          	dotNet.addEventHandler btn_1 "mouseUp" btn_mouseUp
        
          dN_UI.Show()
          )
          
          
          
     Would be cool if i could do the inverse operation, e.g sets the colorDialog.Color (or the button.backColor) by picking a node wirecolor or even whatever color in the screen.
     
   ** EDIT **
   
   MXS (from help):

       rollout change_wirecolor "Object Color Changer"
       (
       	colorpicker theColor "Wireframe color:" color:[0,0,255] modal:false
       	
       	 on theColor changed new_col do 
       	 (
       		selection.wirecolor = new_col
       	 )
       )
       createDialog change_wirecolor 
       

Another thing i noticed was using standards color picker´s ‘changed value’ handler can be dynamically (changes color on the spot), where colorDialog can´t…


  --EVENTS OF dotNetObject:System.Windows.Forms.ColorDialog
 Disposed sender e = ( ... )
HelpRequest sender e = ( ... )
  
 Any suggestions about it ?
   
     thanks in advance

#437

MaxColorPicker solution:


fn CreateMXSProxy forceRecompile:on =
(
	if (forceRecompile or 
		(classof ::MXSProxyAssembly) != dotNetObject or 
		((::MXSProxyAssembly.GetType()).ToString()) != "System.Reflection.Assembly") do
	(
		sb = "using System.Text;
"
		sb += "class MXSProxy
"
		sb += "{
"
		sb += "  public System.String cmd;
"
		sb += "  public MXSProxy() {
"
		sb += "  }
"
		sb += "  public void Invoke(System.Object obj, CSharpUtilities.ValueChangedEventArgs<System.Drawing.Color> clr) {
"
		sb += "	if (cmd.Length > 0) {
"
		sb += "	  ManagedServices.MaxscriptSDK.ExecuteMaxscriptCommand(cmd);
" 
		sb += "	}
"
		sb += "  }
"
		sb += "}
"

		csharpProvider = dotnetobject "Microsoft.CSharp.CSharpCodeProvider"
		compilerParams = dotnetobject "System.CodeDom.Compiler.CompilerParameters"
						
		compilerParams.ReferencedAssemblies.Add("System.dll");		
		compilerParams.ReferencedAssemblies.Add("System.Drawing.dll");		
		compilerParams.ReferencedAssemblies.Add((getdir #maxroot) + "CSharpUtilities.dll");
		compilerParams.ReferencedAssemblies.Add((getdir #maxroot) + "ManagedServices.dll");
		
		compilerParams.GenerateInMemory = true
		compilerResults = csharpProvider.CompileAssemblyFromSource compilerParams #(sb)
		
		if (compilerResults.Errors.Count > 0 ) then
		(
			errs = stringstream ""
			for i = 0 to (compilerResults.Errors.Count-1) do
			(
				err = compilerResults.Errors.Item[i]
				format "Error:% Line:% Column:% %
" err.ErrorNumber err.Line \											  
													 err.Column err.ErrorText to:errs 
			)
			MessageBox (errs as string) title: "Errors encountered while compiling C# code"
			format "%
" errs
			::MXSProxyAssembly = undefined
			return undefined
		)
		else
		(
			::CreateMXSProxyAssembly = compilerResults.CompiledAssembly
		)
	)
	::CreateMXSProxyAssembly.CreateInstance "MXSProxy"
)

-- Create a delegate that will forward the event properties on to maxscript
ccehType = (dotnet.gettype "ManagedServices.ConfirmColorEventHandler") 
changeDelly = (dotnetclass "Delegate").CreateDelegate ccehType (CreateMXSProxy()) "Invoke"
confirmDelly = (dotnetclass "Delegate").CreateDelegate ccehType (CreateMXSProxy()) "Invoke"

try(mcp.Close()) catch()
mcp = dotnetobject "ManagedServices.MaxColorPicker" (dotnetobject "System.IntPtr" (windows.getMAXHWND())) off "Pick Wirecolor"
if selection.count > 0 do mcp.currentcolor = (dotNetClass "System.Drawing.Color").fromARGB selection[1].wirecolor.r selection[1].wirecolor.g selection[1].wirecolor.b	  
mcp.ColorChanged = changeDelly
mcp.ColorConfirmed = confirmDelly

fn applyValue = 
(
	col = color mcp.currentcolor.R mcp.currentcolor.G mcp.currentcolor.B 
	if selection.count > 0 do selection.wirecolor = col
)	
-- You can combine delegates to allow more than one event handler	
-- mcp.ColorChanged = changeDelly.combine mcp.ColorChanged changeDelly

-- Note that these are C# string formating rules. You should be able to modify the maxscript that executes dynamically
changeDelly.target.cmd = "applyValue()"

mcp.showmodeless()

don’t forget to thank biddle…


#438

thanks denisT !

Question:

Is it possible to program .NET UIs for Max using external IDE (MS Visual Studio, or something else) and export the txt code ?

I was wondering if i could build UIs faster…

thanks in advance


#439


#440

Cheers Alex, these sor t of things are always useful! :thumbsup: