Getting the Associated Icon for a filetype in 3dsMax

Aug 18, 2010 by     1 Comment     Posted under: DotNet

Another snippet, just translated into a maxcript-friendly format.

If you need to get the file icon that is associated with a particular type, you can’t get this ordinarily from within a managed environment. There are some great examples on how to use the windows API so these can be added into maxscript by converting them into a string and sending them to the VB/C# compiler from 3dsMax. As always, thanks go to all the great information on the interwebulator, as well as Mike Biddlecombe on CGTalk who figures out all this clever stuff in the first place.

Here is a function that returns a FileIconClass. It has a public method GetIcon(Filename) that returns an image from the file type string specified as the filename argument. It’s useful for treeviews and lists etc.

fn FileTypeIconClass = 
	(
	source = ""
	source += "Imports System.Drawingn"
	source += "Imports Microsoft.VisualBasicn"
	source += "Imports System.Windows.Formsn"
	source += "Public Class FileTypeIconsn"
	source += "Dim cIcons As New System.Collections.Hashtablen"
	source += "Public Declare Auto Function SHGetFileInfo Lib "shell32.dll" (ByVal pszPath As String, ByVal dwFileAttributes As Integer, ByRef psfi As SHFILEINFO, ByVal cbFileInfo As Integer, ByVal uFlags As Integer) As System.IntPtrn"
	source += "Public Const SHGFI_ICON As Integer = &H100n"
	source += "Public Const SHGFI_SMALLICON As Integer = &H1n"
	source += "Structure SHFILEINFOn"
	source += "Public hIcon As System.IntPtrn"
	source += "Public iIcon As Integern"
	source += "Public dwAttributes As Integern"
	source += " Public szDisplayName As Stringn"
	source += " Public szTypeName As Stringn"
	source += "End Structuren"
	source += "Private Function RetrieveShellIcon(ByVal argPath As String) As Imagen"
	source += "Dim mShellFileInfo As SHFILEINFOn"
	source += "Dim mSmallImage As System.IntPtrn"
	source += "Dim mIcon As System.Drawing.Iconn"
	source += "Dim mCompositeImage As  System.Drawing.Imagen"
	source += "mShellFileInfo = New SHFILEINFOn"
	source += "mShellFileInfo.szDisplayName = New String(Strings.Chr(0), 260)n"
	source += "mShellFileInfo.szTypeName = New String(Strings.Chr(0), 80)n"
	source += "mSmallImage = SHGetFileInfo(argPath, 0, mShellFileInfo, System.Runtime.InteropServices.Marshal.SizeOf(mShellFileInfo), SHGFI_ICON Or SHGFI_SMALLICON)n"
	source += "Tryn"
	source += "mIcon = System.Drawing.Icon.FromHandle(mShellFileInfo.hIcon)n"
	source += "mCompositeImage = mIcon.ToBitmapn"
	source +=  "Catch ex As System.Exceptionn"
	source += "mCompositeImage = New Bitmap(16, 16)n"
	source += "End Tryn"
	source += "Return mCompositeImagen"
	source += "End Functionn"
	source += "Public Function GetIcon(ByVal argFilePath As String) As Imagen"
	source += "Dim mFileExtension As String = System.IO.Path.GetExtension(argFilePath)n"
	source += "If cIcons.ContainsKey(mFileExtension) = False Thenn"
	source += "cIcons.Add(mFileExtension, RetrieveShellIcon(argFilePath))n"
	source += "End Ifn"
	source += "Return cIcons(mFileExtension)n"
	source += "End Functionn"
	source += "End Class"

		VBProvider = dotnetobject "Microsoft.VisualBasic.VBCodeProvider"
		compilerParams = dotnetobject "System.CodeDom.Compiler.CompilerParameters"
		compilerParams.ReferencedAssemblies.add "C:WindowsMicrosoft.NETFrameworkv2.0.50727System.Drawing.dll"	
		compilerParams.ReferencedAssemblies.add "C:WindowsMicrosoft.NETFrameworkv2.0.50727System.Windows.Forms.dll"	
		compilerParams.GenerateInMemory = on
		compilerResults = VBProvider.CompileAssemblyFromSource compilerParams #(source)
		
		-- this is very useful to debug your source code and check for referencing errors
		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:% %n" err.ErrorNumber err.Line 											  
													 err.Column err.ErrorText to:errs 
			)
			MessageBox (errs as string) title: "Errors encountered while compiling VB code"
			return undefined
		) 	
			-- create a dotnetobject from the class 
		return compilerResults.CompiledAssembly.CreateInstance "FileTypeIcons"
	)
	
FileTypeIconClass()
404