Just transfered the struct code to another file and the struct is being instantiated through a fileIn now. Still working.
EDIT: This is with my script from yesterday. Just going to play around with Pete’s example above to see what is happening there. Hadn’t had a chance to yet.
thanks for the help chaps, i just tried putting the filein to the maxform code in the struct, with the same lack of event handler action.
I can see why your method works Mat, that’s how i do it currently, via a maxrollout. I use flowlayoutpanels a lot which have nested dotnet controls, all with event handlers which also work fine. (since the addition of setlifetimecontrol I hasten to add)
However the moment you try to use dotnet.addeventhandler in a maxform it yields zero.
It probably worth noting that if this had of worked i would have made controls via MXS, not a dedicated dotnet assembly as i have ended up putting the lost functionality into the custom UI class. So it’s been a good learning experience.
here is how i do it…
test_Attr = attributes EventTest
(
rollout evtest "Params"
(
local floater
button bt_float "Floater ..." across:2 width:70 align:#left offset:[-2,0]
button bt_close "Close" width:70 align:#left offset:[2,0]
on bt_float pressed do
(
rollout floater "Floater" width:162 height:33
(
dotnetcontrol lb "Label" pos:[0,0]
on floater open do
(
size = getdialogsize floater
lb.size = dotNetObject "System.Drawing.Size" size[1] size[2]
bt = dotNetObject "Button"
bt.text = "Press"
bt.dock = bt.dock.fill
fn OnMouseClick sender args = print "Button Pressed ..."
dotNet.addEventHandler bt "MouseClick" OnMouseClick
lb.controls.add bt
)
on floater resized size do
(
lb.size = dotNetObject "System.Drawing.Size" size[1] size[2]
)
)
createdialog floater style:#(#style_titlebar, #style_border, #style_sysmenu, #style_resizing, #style_minimizebox, #style_maximizebox)
)
fn closeFloater = try
(
destroydialog floater
) catch()
on bt_close pressed do closeFloater()
on evtest close do closeFloater()
)
)
custAttributes.add (modPanel.getCurrentObject()) test_Attr
it’s very similar to Mat’s solution but I don’t use structures and filein. Also on Floater’s close event I save the floater’s position, size, some settings, etc. in param block of CA (to show the floater next time with previous settings). All dotnet events work fine for me…
if you would add CA several times you will see than every CA has its own floater.
PS. I played a lot with MAX Form trying to make it work same way as max dialog but I haven’t had any luck.
I was just about to post the same solution Denis. I have the fileIn working with it but I have to do the same thing, use createDialog to launch a floater that in the open event does the fileIn.
Here are my files, just place them both in the scripted folder.
http://penProductions.ca/temp/formTest.ms
http://penProductions.ca/temp/formTestCAdefLaunch.ms
Run the second one and it will make a box with the def on it.
Bit of a mess in the struct as I was trying things.
i don’t use filein in these kind of tasks because filein returns true or false but I usually need a result data (or pointer to something). So using filein i have to create (same as in your sample) some global vars. Also using “filein” UI I can’t pass some local vars or params from my CA. It’s a big limitation for me.
fileIn actually returns the result of the last statement in the included script, just like how a function works. You’re right about the fact that there’s no way to make any local variables visible to the script that is loaded using fileIn. However, since fileIn returns the last statement of the included script, you could do something like this:
Script to be included (called TheFn.ms)
(
fn __TheFunction__ a =
(
format "The value of variable a is %.
" a
)
)
Script that calls fileIn (saved in the same folder):
(
local myPath = getFileNamePath (getSourceFileName())
local theFn = fileIn (myPath + "theFn.ms")
theFn 54
)
I agree, it’s a bit of a hack
Martijn
i didn’t double-check it but …
if you use global struct with dotnet objects(forms) you don’t have to set lifeTime to controls (they should be lifetime because they are in global struct)
I think that I have still had them stop after a max GC. Will have to check again.
Hello All,
Sorry its taken me so long to comment on your replies, I am just spammed with work at the moment.
I looked into the event issue a bit more. I tried using an inherited form control to check what was going on. The form had a maxscript call in the load event 'hardcoded' into the assembly. This called a global function that I had previously evaluated in max. Even then, the max form was unable to register the events on any controls placed on it.
So in the end, I went with Mat's suggestion, which works brilliantly. Thanks a lot Mat, and everyone else for your input.
One thing that i noticed about dotnetcontrol is that you are unable to configure the panel before it is created, all things with the exception of dimensions have to be placed in the open handler of the max rollout. I run a dark UI, so i get a flash as the panel draws itself with the light windows control background, and then updates with the dark max ui color. This is why I initially looked at hosting on a maxform, as this can be configured in the dotnetobject before showing the form. It would be nice if dotnetcontrol could be passed extra visual constructors on creation, like you can with other max classes.
My solution for this for a while was to develop a dotnet class that could use the colorman interface, so that a dotnet control could probe max for the UI color and set up the object in the dotnet new() sub within the assembly, effectively before maxhandles it. This avoids the UI flash. Not a massive deal admittedly, but it bugs me!
Here is the VB class, you will need to reference the managed services dll to compile it.
Imports System.Drawing
Namespace Integration
Public Class ColorMan
Private Function GetMaxUIColor(ByVal ColorManparameter As String) As Color
ManagedServices.MaxscriptSDK.ExecuteMaxscriptCommand("LR_DotNetColorMan_Query = colorMan.getColor " & ColorManparameter)
Dim r As Single = ManagedServices.MaxscriptSDK.ExecuteFloatMaxscriptQuery("(LR_DotNetColorMan_Query[1] * 255.0f)")
Dim g As Single = ManagedServices.MaxscriptSDK.ExecuteFloatMaxscriptQuery("(LR_DotNetColorMan_Query[2] * 255.0f)")
Dim b As Single = ManagedServices.MaxscriptSDK.ExecuteFloatMaxscriptQuery("(LR_DotNetColorMan_Query[3] * 255.0f)")
Dim Maxcolor As Drawing.Color = Drawing.Color.FromArgb(CInt(r), CInt(g), CInt(b))
ManagedServices.MaxscriptSDK.ExecuteMaxscriptCommand("LR_DotNetColorMan_Query = undefined")
Return Maxcolor
End Function
' #background
' The background for all controls and buttons
Public ReadOnly Property Background() As Color
Get
Return GetMaxUIColor("#background")
End Get
End Property
'#text
' The text for all controls and buttons
Public ReadOnly Property Text() As Color
Get
Return GetMaxUIColor("#text")
End Get
End Property
'#hilight
' The hilight color for 3d controls
Public ReadOnly Property Hilight() As Color
Get
Return GetMaxUIColor("#hilight ")
End Get
End Property
'#shadow
' The shadow color for 3d controls
Public ReadOnly Property Shadow() As Color
Get
Return GetMaxUIColor("#Shadow")
End Get
End Property
'#activeCommand
' The color command mode buttons turn when pressed
Public ReadOnly Property ActiveCommand() As Color
Get
Return GetMaxUIColor("#activeCommand")
End Get
End Property
'#activeCaption
' The color of the active caption
Public ReadOnly Property ActiveCaption() As Color
Get
Return GetMaxUIColor("#activeCaption")
End Get
End Property
'#rollupTitleFace
' Rollout title background
Public ReadOnly Property RollupTitleFace() As Color
Get
Return GetMaxUIColor("#rolluptitleface")
End Get
End Property
'#rollupTitleText
' rollout title text
Public ReadOnly Property RollupTitleText() As Color
Get
End Get
End Property
'#window
' The background color for edit boxes, list boxes and other windows
Public ReadOnly Property Window() As Color
Get
Return GetMaxUIColor("#window")
End Get
End Property
'#toolTipBackground
' The background for viewport tool tips
Public ReadOnly Property ToolTipBackground() As Color
Get
Return GetMaxUIColor("#tooltipbackground")
End Get
End Property
'#toolTipText
' The text color for viewport tool tips
Public ReadOnly Property ToolTipText() As Color
Get
Return GetMaxUIColor("#toolTipText")
End Get
End Property
'#hilightText
' The hilight color in the stack view drop-down list
Public ReadOnly Property HilightText() As Color
Get
Return GetMaxUIColor("#hilightText")
End Get
End Property
'#windowText
' The color used in edit boxes, list boxes and other windows
Public ReadOnly Property WindowText() As Color
Get
Return GetMaxUIColor("#windowText")
End Get
End Property
'#itemHilight
' The item hilite color
Public ReadOnly Property ItemHilight() As Color
Get
Return GetMaxUIColor("#itemHilight")
End Get
End Property
'#subObjectColor
' The color used to hilight sub-object levels in StackView
Public ReadOnly Property SubObjectColor() As Color
Get
Return GetMaxUIColor("#subObjectColor")
End Get
End Property
'#3dDarkShadow
' the dark shadow color on 3d controls
Public ReadOnly Property DarkShadow3D() As Color
Get
Return GetMaxUIColor("#3dDarkShadow")
End Get
End Property
'#3dLight
' the light color on 3d controls
Public ReadOnly Property Light3D() As Color
Get
Return GetMaxUIColor("#3dLight")
End Get
End Property
'#appWorkspace
' the application workspace color
Public ReadOnly Property AppWorkspace() As Color
Get
Return GetMaxUIColor("#appWorkspace")
End Get
End Property
'#trackbarBg
' trackbar background
Public ReadOnly Property TrackbarBg() As Color
Get
Return GetMaxUIColor("#trackbarBg")
End Get
End Property
'#trackbarBgSel
' trackbar background for selected keys
Public ReadOnly Property trackbarBgSel() As Color
Get
Return GetMaxUIColor("#trackbarBgSel")
End Get
End Property
'#trackbarText
' trackbar text
Public ReadOnly Property TrackbarText() As Color
Get
Return GetMaxUIColor("#trackbarText")
End Get
End Property
'#trackbarTicks
' trackbar ticks
Public ReadOnly Property TrackbarTicks() As Color
Get
Return GetMaxUIColor("#trackbarTicks")
End Get
End Property
'#trackbarKeys
' trackbar keys
Public ReadOnly Property TrackbarKeys() As Color
Get
Return GetMaxUIColor("#trackbarKeys")
End Get
End Property
'#trackbarSelKeys
' track bar selected keys
Public ReadOnly Property TrackbarSelKeys() As Color
Get
Return GetMaxUIColor("#trackbarSelKeys")
End Get
End Property
'#trackbarCursor
' track bar cursor
Public ReadOnly Property TrackbarCursor() As Color
Get
Return GetMaxUIColor("#trackbarCursor")
End Get
End Property
'#pressedButton
' background color for pressed buttons, like the transform constraints
Public ReadOnly Property PressedButton() As Color
Get
Return GetMaxUIColor("#pressedButton")
End Get
End Property
'#timeSliderBg
' The background for the time slider bar.
Public ReadOnly Property TimeSliderBg() As Color
Get
Return GetMaxUIColor("#timeSliderBg")
End Get
End Property
'#viewportBorder
' The viewport border color
Public ReadOnly Property ViewportBorder() As Color
Get
Return GetMaxUIColor("#viewportBorder t")
End Get
End Property
'#activeViewportBorder
' The active viewport border color
Public ReadOnly Property ActiveViewportBorder() As Color
Get
Return GetMaxUIColor("#activeViewportBorder")
End Get
End Property
'#rollupTitleHilight
' rollout title 3d highlight
Public ReadOnly Property RollupTitleHilight() As Color
Get
Return GetMaxUIColor("#rollupTitleHilight")
End Get
End Property
'#rollupTitleShadow
' rollout title 3d shadow
Public ReadOnly Property RollupTitleShadow() As Color
Get
Return GetMaxUIColor("#rollupTitleShadow")
End Get
End Property
'#selectionRubberBand
' the selection marquee color
Public ReadOnly Property SelectionRubberBand() As Color
Get
Return GetMaxUIColor("#selectionRubberBand")
End Get
End Property
'#stackViewSelection
Public ReadOnly Property stackViewSelection() As Color
Get
Return GetMaxUIColor("#stackViewSelection")
End Get
End Property
End Class
End Namespace
In most of my custom assemblies I store a private variable of this dotnet colorman class. This means that in the control I call something like mydotnetcontrol.backcolor = colorman.background and it's automatically matched to the 3dsmax UI right in the assembly.
In the case of the UI i was developing and Mat’s solution, I created an inherited panel control and placed the colorman call directly in the designer file. Since i was using a custom control assembly anyway I just added it as part of it.
I hope to write up all this info shortly, with details of the new system I’ve been developing. Thanks again everyone.
Hi Pete,
I have searched the 3ds Max .NET SDK and have found classes and methods that can be useful for what you’re doing.
To get Max CUI colors, there is the CuiUpdater class in the 3ds Max .NET SDK. For example see its GetMaxColor() method.
To update its colors, a custom control, panel or form can inherit and implement CuiUpdatable interface. For example, MaxForm inherits this interface and implements its UpdateColors() method. You have just to place the ColorMan calls in the UpdateColors() method of your custom panel if you inherit this interface. So the colors are updated whenever the Max CUI colors are changed.