Notifications
Clear all

[Closed] Assign material to materialbutton

You can compile c# assembly on the fly, and it should be enough to make it work
Example

Add SetLayeredWindowAttributes method definition to the above example and try a little more. It only looks complicated at the very beginning

hi
this is what i ended up thinking should work. but it doesn’t.

this is the code from the pinvoke link

SetWindowLong(Handle, GWL_EXSTYLE, GetWindowLong(Handle, GWL_EXSTYLE) ^ WS_EX_LAYERED);
SetLayeredWindowAttributes(Handle, 0, 128, LWA_ALPHA);

this is the version i think should be more or less ok but is somehow totally wrong

--original
GWL_STYLE 		= -16 
WS_BORDER	   = 0x00800000
WS_DLGFRAME	 = 0x00400000
WS_THICKFRAME   = 0x00040000
WS_POPUP		= 0x80000000
WS_CHILD		= 0x40000000
WS_DISABLED	 = 0x08000000

--new

GWL_EXSTYLE = -20
WS_EX_LAYERED = 0x80000
LWA_ALPHA = 0x2
LWA_COLORKEY = 0x1



f = ::User32.GetWindowLong win.tag.value[2] GWL_STYLE

f = bit.xor f (WS_BORDER + WS_DLGFRAME + WS_THICKFRAME + WS_CHILD + WS_POPUP)

--::User32.SetWindowLong win.tag.value[2] GWL_STYLE f    -----------original

::User32.SetWindowLong win.tag.value[2] GWL_EXSTYLE f WS_EX_LAYERED

::User32.SetLayeredWindowAttributes win.tag.value[2] 0 128 LWA_ALPHA

other than not working at all this code will also break this line
f = bit.xor f (WS_BORDER + WS_DLGFRAME + WS_THICKFRAME + WS_CHILD + WS_POPUP)

which i don’t understand why really but who knows

i am starting to get a small grasp of it but in a non working way something like this

1 – set the SetWindowLong to be layered
2 – SetLayeredWindowAttributes of the handle with alpha

if i’m going to make it a toggle as you did i should use a UpdateLayeredWindow (but first i would need a working layered window)

thank you so much for the support it helped so far

color key is ok for buttons but not for any king of labels


global WindowTransparency =
(
	source = "using System;\n"
	source += "using System.Runtime.InteropServices;\n"
	source += "class WindowTransparency\n"
	source += "{\n"
	source += " [DllImport(\"user32.dll\")]\n"
	source += " public static extern Int32 GetWindowLong(IntPtr hWnd, Int32 index);\n"
	source += " [DllImport(\"user32.dll\")]\n"
	source += " public static extern Int32 SetWindowLong(IntPtr hWnd, Int32 index, Int32 newVal);\n"
	source += " [DllImport(\"user32.dll\")]\n"
	source += " public static extern bool SetLayeredWindowAttributes(IntPtr hwnd, uint crKey,byte bAlpha, uint dwFlags);\n"
	source += "}\n"

	csharpProvider = dotnetobject "Microsoft.CSharp.CSharpCodeProvider"
	compilerParams = dotnetobject "System.CodeDom.Compiler.CompilerParameters"

	compilerParams.GenerateInMemory = on
	compilerResults = csharpProvider.CompileAssemblyFromSource compilerParams #(source)

	assembly = compilerResults.CompiledAssembly
	assembly.CreateInstance "WindowTransparency"
)


fn SetWindowOpacity hwnd opacity =
(
	local GWL_EXSTYLE   = -20
	local WS_EX_LAYERED = 0x80000
	local LWA_ALPHA     = 0x2 
	local LWA_COLORKEY  = 0x1
	
	local hwnd = if not isKindOf hwnd dotNetObject then dotNetObject "System.IntPtr" hwnd else hwnd
	local windowStyle = ::WindowTransparency.GetWindowLong hwnd GWL_EXSTYLE
		  
	if (bit.and windowStyle (WS_EX_LAYERED + LWA_ALPHA + LWA_COLORKEY)) == 0 do
	(	
		windowStyle = bit.xor windowStyle WS_EX_LAYERED	
		::WindowTransparency.SetWindowLong hwnd GWL_EXSTYLE windowStyle		
	)
	
	-- opacity range 0 - 255
	opacity = int (amin (amax 0 opacity) 255)
	
	/*
	BOOL WINAPI SetLayeredWindowAttributes(
	  _In_ HWND     hwnd,
	  _In_ COLORREF crKey,
	  _In_ BYTE     bAlpha,
	  _In_ DWORD    dwFlags
	);
	*/
	
	-- set opacity by level
    ::WindowTransparency.SetLayeredWindowAttributes hwnd 0 opacity LWA_ALPHA
)


fn SetWindowColorKey hwnd colorkey =
(
	local GWL_EXSTYLE   = -20
	local WS_EX_LAYERED = 0x80000
	local LWA_ALPHA     = 0x2 
	local LWA_COLORKEY  = 0x1
	
	local hwnd = if not isKindOf hwnd dotNetObject then dotNetObject "System.IntPtr" hwnd else hwnd
	local windowStyle = ::WindowTransparency.GetWindowLong hwnd GWL_EXSTYLE
		  
	if (bit.and windowStyle (WS_EX_LAYERED + LWA_ALPHA + LWA_COLORKEY)) == 0 do
	(	
		windowStyle = bit.xor windowStyle WS_EX_LAYERED	
		::WindowTransparency.SetWindowLong hwnd GWL_EXSTYLE windowStyle		
	)
	
	color_as_int = (int colorkey.r) + (bit.shift (int colorkey.g) 8) + (bit.shift (int colorkey.b) 16)
	
	/*
	BOOL WINAPI SetLayeredWindowAttributes(
	  _In_ HWND     hwnd,
	  _In_ COLORREF crKey,
	  _In_ BYTE     bAlpha,
	  _In_ DWORD    dwFlags
	);
	*/
	-- set opacity by color key
    ::WindowTransparency.SetLayeredWindowAttributes hwnd color_as_int 0 LWA_COLORKEY	

)

try (destroydialog X ) catch ()
rollout X "" (

	button btn "button"
	spinner spn "opacity" range:[0,255,128] 
		
	on x open do SetWindowColorKey x.hwnd blue
	
	on btn pressed do SetWindowColorKey x.hwnd blue
	on spn changed val do SetWindowOpacity x.hwnd spn.value

)
createDialog X bgcolor:blue

i achived the same result using the property opacity in a dotnet form

fn functionbutton = (print "I'm a transparent form!!")
ColorRed = (dotnetclass "System.Drawing.Color").red
Colorgreen = (dotnetclass "System.Drawing.Color").green

mButton = dotNetObject "button"
mbutton.text= "Button 1"
mbutton.Width = 100
mbutton.height = 50
mbutton.backcolor = Colorgreen

rolloutdotnet = dotNetObject "form"
rolloutdotnet.Width = 250
rolloutdotnet.height = 150
rolloutdotnet.Topmost = true
rolloutdotnet.backcolor = ColorRed
--rolloutdotnet.Opacity = 0.2 --makes transparent the form and all it's content 

rolloutdotnet.TransparencyKey = ColorRed

rolloutdotnet.controls.add mButton



dotNet.addEventHandler mButton "click" functionbutton 


rolloutdotnet.show() 

it seems way easier to me, what do you think?

Easier for sure. But you can’t add mxs controls to dotnet form and thus you can’t have texture and material drag-n-drop as you do using rollout

yeah that seems the case,
i’m going to rewrite all the script in a dotnet version with a custom drag and drop to make all the code more clean.

the drag and drop part it’s fairly simple i guess, the problem is create a material in the mouse position (relative to the sme space). I was thinking to get the mouse position on drop and move the material in that position but i don’t know if it’s possible to get the sme space

you can use this ugly workaround

dragAndDrop.dropPackage sme_view_hwnd mouse.screenpos "C:\tmp\dummy.bmp"

I’ve found this script of LoneRobot that seems what i should do but it seems to work only with bitmap, maybe i could replace the bitmap with a material but it’s only a workaround…

try (destroyDialog ::DragDropOps) catch()
rollout DragDropOps "LoneRobot Drag Drop" width:136 height:150
(
	dotNetControl btndragdrop "label" pos:[5,5] width:125 height:139 
	on DragDropOps open do
	(
		btndragdrop.allowdrop = true
		btndragdrop.text = "Hooray! A Drag/Drop Enabled Label!!! 

To 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 (print "asd")
		else
		(			
			theIniFile = getdir #maxData  + "3dsmax.ini" 
			theKeys = getIniSetting theIniFile "FileList"
			
			
-- 			filenameString = "D:\Object.max" -- max object
 			filenameString = "D:\Texture.jpg" -- texture
--			filenameString = "?????????" -- material
-- 			matLib = loadTempMaterialLibrary "D:\MatLib.mat"
-- 			filenameString = matLib[1]
			
			dropfile = dotnetobject "System.String[]" 1
			dropfile.setvalue filenameString 0			
			DataObj = dotnetobject "DataObject" ((dotnetclass "DataFormats").filedrop) dropfile
			sender.dodragdrop Dataobj ((dotnetclass "DragDropEffects").Copy)
		)
	)
)
createdialog DragDropOps style:#(#style_toolwindow, #style_sysmenu)

Something like this seems to work pretty fine

try (destroyDialog ::DragDropOps) catch()



			fn Mat_Replace =
			(
			interf = sme.GetView (sme.activeView)
			selarray = interf.GetSelectedNodes()
				
				print selarray[1].position
				
				interf.CreateNode (VRayMtl()) selarray[1].position
				interf.DeleteSelection() 
				
				)
				

			



rollout DragDropOps "LoneRobot Drag Drop" width:136 height:150
(
	dotNetControl btndragdrop "label" pos:[5,5] width:125 height:139 
	on DragDropOps open do
	(
		btndragdrop.allowdrop = true
		btndragdrop.text = "button"
		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 (print "asd")
		else
		(			
			theIniFile = getdir #maxData  + "3dsmax.ini" 
			theKeys = getIniSetting theIniFile "FileList"
 			filenameString = "D:\Texture.jpg" -- texture

			
			dropfile = dotnetobject "System.String[]" 1
			dropfile.setvalue filenameString 0			
			DataObj = dotnetobject "DataObject" ((dotnetclass "DataFormats").filedrop) dropfile
			sender.dodragdrop Dataobj ((dotnetclass "DragDropEffects").Copy)
			
			
			::Mat_Replace()
			
		)
	)
)
createdialog DragDropOps style:#(#style_toolwindow, #style_sysmenu)
Page 2 / 2