Notifications
Clear all

[Closed] dotNet Event Handler not working properly inside Struct

Hi all,

I have this problem with dotNet event handler working inside struct. The event handler can’t seems to read the properties from the struct. And it works perfectly if it is just an ordinary function.


 struct dotNetFormStruct
 (
 	-- Properties
 	btnStored = undefined,
 	
 	-- Event Handlers
 	fn testButton control arg =
 	(
 		print control.text
 		print btnStored.text
 	),
 
 	-- Normal functions
 	fn print_btnStored =
 	(
 		print btnStored.text
 	),
 	 
 	-- Interface
 	fn init =
 	(   
 		-- Init Maxform
 		dotNet.loadAssembly "MaxCustomControls.dll"
 		
 		testfrm= dotNetObject "MaxCustomControls.MaxForm"
 		testfrm.Size = dotNetObject "System.Drawing.Size" 100 100	  
 		
 		-- Init Button
 		btnTest = dotNetObject "System.Windows.Forms.Button"
 		btnTest.location = dotNetobject "System.drawing.point" 2 2
 		btnTest.text = "test button"
 		btnStored = btnTest
 		
 		testfrm.controls.addRange(#(btnTest))
 		
 		-- Init Events
 		dotNet.addEventHandler btnTest "click" testButton
 		
 		-- Show Form
 		testfrm.show()
 	)
 )
 dotNetForm = dotNetFormStruct() 
 

After i do a dotNetForm.init(), by clicking on the button, i get the error of it not being an instance.
However if i were just to do a dotNetForm.print_btnStored(), it has no problem accessing the btnStored inside the struct.

I can do a “print dotNetForm.btnStored.text” instead inside the event handler. However that seems so inappropriate and lost the meaning of making it a struct.

Does anyone have a similar problem or better solution?
Thanks.

4 Replies

I can do it in a dirty way by assigning btnStored to the tag of btnTest so that i can still access it using event handler.

btnTest.tag = btnStored

but is there any more elegant way to do it? Just wonder.
Thanks.

I can’t really say if this is a better solution or more elegant, but the why I handle this type of thing (and that I’ve seen done in other people’s scripts) is the declare the variable holding the struct, ‘dotNetForm’ in your case, global. And then you can add that into the struct itself inside functions that need access back into the struct.

global dotNetForm
  
  struct dotNetFormStruct
   (
  	 -- Properties
  	 btnStored = undefined,
  	 
  	 -- Event Handlers
  	 fn testButton control arg =
  	 (
  		 print control.text
  		 print dotNetForm.btnStored.text
  	 ),
   
  	 -- Normal functions
  	 fn print_btnStored =
  	 (
  		 print btnStored.text
  	 ),
  	  
  	 -- Interface
  	 fn init =
  	 (   
  		 -- Init Maxform
  		 dotNet.loadAssembly "MaxCustomControls.dll"
  		 
  		 testfrm= dotNetObject "MaxCustomControls.MaxForm"
  		 testfrm.Size = dotNetObject "System.Drawing.Size" 100 100	  
  		 
  		 -- Init Button
  		 btnTest = dotNetObject "System.Windows.Forms.Button"
  		 btnTest.location = dotNetobject "System.drawing.point" 2 2
  		 btnTest.text = "test button"
  		 btnStored = btnTest
  		 
  		 testfrm.controls.addRange(#(btnTest))
  		 
  		 -- Init Events
  		 dotNet.addEventHandler btnTest "click" testButton
  		 
  		 -- Show Form
  		 testfrm.show()
  	 ),
  	
  	initIt = init()
   )
   dotNetForm = dotNetFormStruct() 

Look at the testButton function and see how I changed the second print line to reference the dotNetForm variable so that it can access the bnStored value. You could also define btnTest outside of the init function and access it directly without having to store it in another variable. I define all of my dotNet controls that way so that I have easy access to them later if I need.

Here’s how that would look…

global dotNetForm
  
  struct dotNetFormStruct
   (
  	 -- Properties
  	testfrm= dotNetObject "MaxCustomControls.MaxForm",
  	btnTest = dotNetObject "System.Windows.Forms.Button",
  
  	 -- Event Handlers
  	 fn testButton control arg =
  	 (
  		 print control.text
  		 print dotNetForm.btnTest.text
  	 ),
   
  	 -- Normal functions
  	 fn print_btnStored =
  	 (
  		 print btnStored.text
  	 ),
  	  
  	 -- Interface
  	 fn init =
  	 (   
  		 -- Init Maxform
  		 dotNet.loadAssembly "MaxCustomControls.dll"
  		 
  		 testfrm.Size = dotNetObject "System.Drawing.Size" 100 100	  
  		 
  		 -- Init Button
  		 btnTest.text = "test button"
  		btnTest.location = dotNetobject "System.drawing.point" 2 2
  		 
  		 testfrm.controls.addRange(#(btnTest))
  		 
  		 -- Init Events
  		 dotNet.addEventHandler btnTest "click" testButton
  		 
  		 -- Show Form
  		 testfrm.show()
  	 ),
  	
  	initIt = init()
   )
   dotNetForm = dotNetFormStruct() 

I also added a line at the end of your struct to actually run the init function when the it’s created so that you don’t have to do that as a seperate step.

Thanks JHaywood.

I had thought of that solution as well.

Of course it would work perfectly. However, the struct becomes so name dependent that you always had to declare it using the fix name, and losing the flexibility in creating an instance.

Cracking head still.

Yeah, I know what you mean. I don’t like relying on names either, but all the large structs I’ve created have been one-offs made mainly to keep from filling up the global pool, so it’s tolerable in that case.