3ds Max File Drop via DotNet

Aug 26, 2008 by     3 Comments    Posted under: 3dsMax, DotNet, Tips and Tricks

If you need to mimic the way that max presents you with merge/open/xref options when you drag into a viewport, you can perform this yourself with DotNet. Max expects a dataobject containing a string array. Depending on the filetype that this string member points to will decide whether max will prompt you with a file open menu or a texture map as viewport background. The other option is you can also pass a map path to drag onto slots on the material editor.

Below is a snippet of the code for this operation. It is entirely handled within the mousedown handler of the control. It makes sense in this case as you wouldn’t put it in the mousemove handler for example as this would mean the code would be needlessly called multiple times.

on btndragdrop mouseDown sender args do 
( 
theIniFile = getdir #maxData + "3dsmax.ini" 
theKeys = getIniSetting theIniFile "FileList" 
maxfilearray = for o in theKeys where o != "MaxFiles" collect (getIniSetting theIniFIle "FileList" o)
intnum = dotnetobject "System.Int32" 0 
filenamestring= dotnetobject "System.string" maxfilearray[1] 
dropfile = dotnetobject "System.String[]" 1 
dropfile.setvalue filenamestring intnum 
DataObj = dotnetobject "DataObject" ((dotnetclass "DataFormats").filedrop) dropfile 
sender.dodragdrop Dataobj ((dotnetclass "DragDropEffects").Copy) 
)

The only thing to note is that the Dataobject takes an object as it’s first parameter. This can basically be anything you like, except this in this case. The SDK notes that it needs an array in this object. The square brackets after the dropfile variable denotes that it is an array of strings with 1 member, not a string. Passing a string object therefore has no effect and does not present you with the menu seen below, which is the result of the correct format of the DataObject.

Not the end of the story…

I noticed an odd behavior using drag and drop in max. When employed on a dotnetcontrol in a maxscript window, it classes it as being ‘inside’ max even though it is a dotnet object. Therefore you could in theory initialize the drag and drop onto the label control to perform a legitimate drop. This behavior is possibly not wanted, if you needed to perform other handlers – the drag drop might get triggered accidentally. The way around this is to use the mouseeventargs to check if the mouse has moved outside the client area of the control.

on DragDropOps open do 
( 
btndragdrop.allowdrop = false
btndragdrop.text = "Hooray! A Drag/Drop Enabled Label!!!\n\nTo drop a Texturemap, just pass the map path string in the dataobject instead of a max file path. This will also work if draging a map to the material editor" btndragdrop.borderstyle = (dotNetClass "System.Windows.Forms.BorderStyle").fixedsingle 
btndragdrop.backcolor = (dotnetclass "System.Drawing.Color").orangered 
btndragdrop.forecolor = (dotnetclass "System.Drawing.Color").yellow 
) 

on btndragdrop mousemove sender args do 
(
if (sender.clientrectangle.contains args.x args.y) then 
( 
setsyscur #arrow 
) 
else 
(
 setSysCur #move
) 
) 

on btndragdrop mouseup sender args do 
(
if (sender.clientrectangle.contains args.x args.y) then 
( ) 
else 
( 
theIniFile = getdir #maxData + "3dsmax.ini" 
theKeys = getIniSetting theIniFile "FileList" m
axfilearray = for o in theKeys where o != "MaxFiles" collect getIniSetting theIniFIle "FileList" o 
filenameString = maxfilearray[1] 
dropfile = dotnetobject "System.String[]" 1 
dropfile.setvalue filenameString 0 
DataObj = dotnetobject "DataObject" ((dotnetclass "DataFormats").filedrop) dropfile 
sender.dodragdrop Dataobj ((dotnetclass "DragDropEffects").Copy) ) )
404
order generic viagra online viagra pills non prescription