Unable to convert dotNetControl to dotNetObject

Unable to convert dotNetControl to dotNetObject

dmitriy.shpilevoy
Collaborator Collaborator
1,025 Views
8 Replies
Message 1 of 9

Unable to convert dotNetControl to dotNetObject

dmitriy.shpilevoy
Collaborator
Collaborator

Hello, folks.

I'm trying to show stuff when cursor is over spinner buttons and hide it when cursor is out. Since native max spinner doesn't have these events, I'm using dotnet. For simplicity, spinner's color will serve as "stuff".

 

First iteration. Kind of almost works, but cursor has to be precisely on spinner's border to change color. As soon as it moves in or outside, color is set back to default.

 

try(destroyDialog myRollout) catch()
(
rollout myRollout "spinnerTest" (
    dotNetControl spinner "System.Windows.Forms.NumericUpDown" pos:[10,50] width:100

	on spinner MouseEnter senderArg arg do (
		spinner.BackColor = (dotNetClass "System.Drawing.Color").Yellow
	)
	on spinner MouseLeave senderArg arg do (
		spinner.BackColor = (dotNetClass "System.Drawing.Color").White
	)
)
createDialog myRollout 150 150
)

 

 

Decided to add handlers to child controls instead. And here it gets weird. Well, weirder.
Field behaves as expected - enter and leave will change color. But UpDown buttons seem to never generate Leave event.

try(destroyDialog myRollout) catch()
(
local myEnter, myLeave

rollout myRollout "spinnerTest" (
	dotNetControl spinner "System.Windows.Forms.NumericUpDown" pos:[10,50] width:100

	on myRollout open do (
			local childControl0 = myRollout.spinner.Controls.Item[0]
			local childControl1 = myRollout.spinner.Controls.Item[1]
			dotNet.addEventHandler childControl0 "MouseEnter" myEnter
			dotNet.addEventHandler childControl0 "MouseLeave" myLeave
			dotNet.addEventHandler childControl1 "MouseEnter" myEnter
			dotNet.addEventHandler childControl1 "MouseLeave" myLeave
	)
)
fn myEnter = (
	myRollout.spinner.BackColor = (dotNetClass "System.Drawing.Color").Yellow
)
fn myLeave = (
	myRollout.spinner.BackColor = (dotNetClass "System.Drawing.Color").White
)
createDialog myRollout 150 150
)

 

 

 

So now my idea is to start with no handlers for spinner and only mouseEnter for UpDown buttons.
When cursor enters UpDown I will change color and add mouseLeave handler for spinner.

Leave function will change color back to default and remove handler from spinner.

This thing doesn't work at all 8(
It throws error "Unable to convert: dotNetControl:spinner:System.Windows.Forms.NumericUpDown to type: dotNetObject"

try(destroyDialog myRollout) catch()
(
local myEnter, myLeave

rollout myRollout "spinnerTest" (
	dotNetControl spinner "System.Windows.Forms.NumericUpDown" pos:[10,50] width:100

	on myRollout open do (
			local childControl0 = myRollout.spinner.Controls.Item[0]
			local childControl1 = myRollout.spinner.Controls.Item[1]
			dotNet.addEventHandler childControl0 "MouseEnter" myEnter
			dotNet.addEventHandler childControl1 "MouseEnter" myEnter
	)
)
fn myLeave = (
	myRollout.spinner.BackColor = (dotNetClass "System.Drawing.Color").White
	dotNet.removeAllEventHandlers myRollout.spinner
)
fn myEnter = (
	myRollout.spinner.BackColor = (dotNetClass "System.Drawing.Color").Yellow
	dotNet.addEventHandler myRollout.spinner "MouseLeave" myLeave
)
createDialog myRollout 150 150
)

 

 

 

 

The question is: how can I handle spinner as dotNetObject instead of dotNetControl?

Or maybe there is no need for this and everything can be fixed at very first step with some flag that allows parent control to properly generate enter/leave events? Hm, in this case I would like to learn both: the easy fix and how to solve object/control issue.

0 Likes
Accepted solutions (2)
1,026 Views
8 Replies
Replies (8)
Message 2 of 9

trykle
Contributor
Contributor

This is not the best way, but it is a simple solution.

try(destroyDialog myRollout) catch()

rollout myRollout "spinnerTest" 
(
	dotNetControl textBox "System.Windows.Forms.TextBox" pos:[10,10] width:100
	dotNetControl spinner "System.Windows.Forms.NumericUpDown" pos:[110,10] width:20
 
	on textBox MouseLeave do
	( 
		print "MouseLeave"
		textBox.BackColor = (dotNetClass "System.Drawing.Color").Green
	)

	on textBox MouseEnter do
	(
		print "MouseEnter"
		textBox.BackColor = (dotNetClass "System.Drawing.Color").Red
	)
)

createDialog myRollout 200 150

 

0 Likes
Message 3 of 9

dmitriy.shpilevoy
Collaborator
Collaborator
Accepted solution

Thank you, but UpDownEdit can generate MouseLeave event properly, so it's possible to use NumericUpDown to detect mouse entering and leaving edit field. I need to detect mouse hover on buttons though.

 

Solved it by placing spinner inside a panel and it works, but in field conditions it breaks in a new way I didn't thought of 8(

Stuff that I show and hide is combobox list and as soon as it opens, it captures focus and I can't click spinner buttons anymore.

 

Code for mouse hover detection on spinner buttons:

 

try(destroyDialog myRollout) catch()
(
	local myMouseEnter
	fn myMouseEnter sender args = (
		myRollout.pc.Controls.item[0].BackColor = (dotNetClass "System.Drawing.Color").Yellow
		local rollClr = (colorMan.getColor #background)
		rollClr *= 255
		myRollout.pc.BackColor = (dotNetClass "System.Drawing.Color").FromArgb 255 (rollClr).x (rollClr).y (rollClr).z
		
	)

	rollout myRollout "spinnerTest" (
		dotNetControl pc "System.Windows.Forms.Panel" pos:[10,40] width:120 height:80
		on myRollout open do (
			local spinner = dotNetObject "System.Windows.Forms.NumericUpDown"
			spinner.Location = dotNetObject "System.Drawing.Point" 10 10
			spinner.Width = 100
			myRollout.pc.Controls.Add spinner

			dotNet.addEventHandler myRollout.pc.Controls.item[0].Controls.item[0] "MouseEnter" myMouseEnter
		)
		on pc MouseLeave senderArg arg do (
			myRollout.pc.Controls.item[0].BackColor = (dotNetClass "System.Drawing.Color").White
		)
	)

createDialog myRollout 150 150
)

 

0 Likes
Message 4 of 9

denisT.MaxDoctor
Advisor
Advisor

I'm not entirely clear on what you're looking for. Could you clarify the following points?

 

1. Should something be hidden or revealed when the mouse hovers over and leaves the spinner (such as the edit and buttons)?

2. Should something be hidden or revealed when the mouse enters or leaves the spinner (again, referring to the edit and buttons)?

3. Should the item be hidden while the mouse is pressed down on the spinner (or just the buttons), and then revealed when the mouse is released?

 

0 Likes
Message 5 of 9

denisT.MaxDoctor
Advisor
Advisor

by the way: 

try(destroyDialog myRollout) catch()
(
	rollout myRollout "spinnerTest" 
	(

	)

	createDialog myRollout 150 150
)

 

it doesn't make sense ... the rollout is defined in the local scope and it's not visible to "global" destroy. So, try's block does nothing 

0 Likes
Message 6 of 9

dmitriy.shpilevoy
Collaborator
Collaborator

Full disclosure: spinner is used to manually sort position of selected item in combobox list. Spinner edit is hidden, only buttons are visible. The point of it all is for user to see item's new position as it changes, instead of counting number of clicks needed or going back and forth between combobox and spinner to check "are we there yet?".

 

When mouse enters spinner buttons, something is shown and stays on until mouse leaves spinner buttons.

Clicks do separate thing (controlling item's position), they don't affect visibility.

Hope that explains it better. Sorry, I don't understand the difference between 1 and 2 in your question.

 

> it doesn't make sense ... the rollout is defined in the local scope and it's not visible to "global" destroy. So, try's block does nothing

Thank you. Moving destroy attempt inside the main block works.

Sometimes it stops working like that and I don't know why. Will need to create a separate thread on this at some point, but right now I'm not ready to provide a clean example of code that doesn't work (as I think it should).

0 Likes
Message 7 of 9

denisT.MaxDoctor
Advisor
Advisor
Accepted solution

@dmitriy.shpilevoy wrote:

Full disclosure: spinner is used to manually sort position of selected item in combobox list. Spinner edit is hidden, only buttons are visible. The point of it all is for user to see item's new position as it changes, instead of counting number of clicks needed or going back and forth between combobox and spinner to check "are we there yet?".

 

When mouse enters spinner buttons, something is shown and stays on until mouse leaves spinner buttons.

Clicks do separate thing (controlling item's position), they don't affect visibility.

Hope that explains it better. Sorry, I don't understand the difference between 1 and 2 in your question.

 

> it doesn't make sense ... the rollout is defined in the local scope and it's not visible to "global" destroy. So, try's block does nothing

Thank you. Moving destroy attempt inside the main block works.

Sometimes it stops working like that and I don't know why. Will need to create a separate thread on this at some point, but right now I'm not ready to provide a clean example of code that doesn't work (as I think it should).


"Hovering" means the mouse stays over a control for a certain amount of time. "Entering" happens when the mouse first touches a control. When moving between entering and leaving, the mouse can continue to move. However, while hovering, the mouse must remain still.

 

 

 

 

try(destroyDialog rol) catch()

rollout rol "spinnerTest" 
(
	dotNetControl sp "NumericUpDown" pos:[10,50] width:100

	fn onMouseHover s a = 
	(
		--xformat_ "mouse hover" s
		s.Parent.BackColor = s.BackColor.Red
	)
	on sp MouseLeave s arg do 
	(
		--xformat_ #leave arg
		s.BackColor = s.BackColor.Gray
	)
	
	fn initSpinner = 
	(
		hwnd = uiaccessor.GetFirstChildWindow sp.hwnd[1]
		base = (dotnetclass "Control").FromHandle hwnd
		bts = base.Controls.Item[0]
		dotnet.addEventHandler bts #MouseHover onMouseHover
	)
	on rol open do
	(
		initSpinner()
	)
)

createDialog rol 150 150

 

 

 

 

The Hover event was designed, among other things, to eliminate accidental mouse control #interaction when moving the cursor over the screen. 
   

Message 8 of 9

dmitriy.shpilevoy
Collaborator
Collaborator

Thank you. Works perfectly.

What are xformat thingies are for? Can't find it in maxscript documentation.

0 Likes
Message 9 of 9

denisT.MaxDoctor
Advisor
Advisor

xformat_ is one of my mxs extension methods...  similar to Python's print

0 Likes