Assign material to materialbutton


#1

Hi,
i’m tring to assign a vray base material to a materialbutton when created using the parameter "material: " but when i drag it in the sme nothing happen.

try cui.UnRegisterDialogBar RapidMaterial catch() ;
try destroydialog RapidMaterial catch();
getsmepos = windows.getChildHWND 0 “Slate Material Editor”
posconv = windows.clientToScreen getsmepos[1] 180 50

rollout RapidMaterial “Rapid Material” (
local btwidth = 50
local btheight = 20

materialbutton vraybase “vray base” material:(VRay()) align:#left width:btwidth height:btheight across:8

)

createDialog RapidMaterial 500 40 pos:posconv parent:getsmepos[1]


#2

something like this should work

Rollout dragmat “Mat Drop”
(

materialbutton choosemtl “The Material”

on dragmat open do choosemtl.material = VRayMtl()

)
createDialog dragmat


#3

that’s it!
the problem was that you have to assign the material when rollout open, thanks.

now is there a way to quiet the allert when you drag the material? i mean i would like when i drag to create always a copy of the material without choosing from instance or copy


#4

You can of course detect this window using DialogMonitorOps
But why don’t you just create a group with these base materials?
rqsG7a9f24

    try DestroyDialog dragmat catch()
	Rollout dragmat "Mat Drop"
    (

		materialbutton choosemtl "The Material" material:(VRayMtl())

		local DialogMonitorOPS_initial_state
		fn OnWindow =
		(
			try
			(
				local hwnd = DialogMonitorOPS.GetWindowHandle()			
				local data = windows.getHWNDData hwnd
			
				if data[4] == "#32770" and data[5] == "Instance (Copy) Material" do
				(
					for w in windows.getChildrenHWND hwnd where w[5] == "Copy" do
					(
						-- left mouse click on button
						windows.sendMessage w[1] 0x201 1 0
						windows.sendMessage w[1] 0x202 1 0
					)
					
					UIAccessor.PressDefaultButton()
				)
			)
			catch()
			true
		)
		
		on dragmat open do 
		(
			choosemtl.material = VRayMtl()
			DialogMonitorOPS_initial_state = DialogMonitorOPS.Enabled
			
			DialogMonitorOPS.RegisterNotification OnWindow id:#xxx
			DialogMonitorOPS.Enabled = true
		)
		
		on dragmat close do 
		(
			choosemtl.material = VRayMtl()

			DialogMonitorOPS.UnRegisterNotification id:#xxx
			DialogMonitorOPS.Enabled = DialogMonitorOPS_initial_state
		)

		on choosemtl picked mtl do 
		(
			choosemtl.text = classof mtl.Name
		)
    )
    createDialog dragmat

#5

wow, how do you get the

windows.sendMessage w[1] 0x201 1 0

is it something from c#?
can it be used any time you need to “click” a button in a hwnd?


#6

You can check the messages that window receives using Spy++.
It is free and it comes with a Visual Studio I guess.

Knowing what messages the window expects it is possible to emulate user actions no matter what language you use. Maxscript provides windows.sendmessage function which is enough for most cases.

btw you can also check Rotem’s WindowShopper


#7

Thanks Serejah,
i’ve implemented it on the script and works fine!

what i’m trying to do is a custom toolbar attached to the top of the sme to have always a rapid access at base materials id like (somthing like substance designer for instance).

i’ve tryed with

icusttoolbar -icustmacrobutton

as you did here Toolbar ICustButton inconsistent state but i gave up in the end because i haven’t been able to do it so this is what i did (basically it’s a rollout that follows the sme position and open and close with it)

here is the code:

----try(msgSnooper.releaseHandle())catch() to stop the callback

(
	try cui.UnRegisterDialogBar RapidMaterial catch() 
	try destroydialog RapidMaterial catch()
	global msgSnooper
	try(msgSnooper.releaseHandle())catch()
		
	getsmepos = windows.getChildHWND 0 "Slate Material Editor"
	posconv = windows.clientToScreen getsmepos[1] 180 50
	user32
	theParent = windows.getChildHWND 0 "Slate Material Editor"	
	intPtr = dotnetClass "System.intPtr"
	intPt = dotnetObject intPtr theParent[1]



	rollout RapidMaterial "Rapid Material" (
		local btwidth = 50
		local btheight = 20
		local DialogMonitorOPS_initial_state
		
		fn OnWindow =
		(
			try
			(
				local hwnd = DialogMonitorOPS.GetWindowHandle()			
				local data = windows.getHWNDData hwnd
			
				if data[4] == "#32770" and data[5] == "Instance (Copy) Material" or data[5] == "Instance (Copy) Map" do
				(
					for w in windows.getChildrenHWND hwnd where w[5] == "Copy" do
					(
						-- left mouse click on button
						windows.sendMessage w[1] 0x201 1 0
						windows.sendMessage w[1] 0x202 1 0
					)
					
					UIAccessor.PressDefaultButton()
				)
			)
			catch()
			true
		)
		
		

		materialbutton VraybaseMTL "Vray" align:#left width:btwidth height:btheight quiet:true across:8
		mapbutton VRMix "Mix" align:#left width:btwidth height:btheight
		mapbutton CC "CC" align:#left width:btwidth height:btheight
		mapbutton VRNoise "FsNoise" align:#left width:btwidth height:btheight

		on RapidMaterial open do (

		VraybaseMTL.material = VRayMtl()	
			
		VRMix.map = mix()
		VRMix.caption = "Mix"

		CC.map = ColorCorrection()
		CC.caption = "CC"
			
		VRNoise.map = noise()
		VRNoise.caption = "Noise"
			
		
		
		
		DialogMonitorOPS_initial_state = DialogMonitorOPS.Enabled
			
		DialogMonitorOPS.RegisterNotification OnWindow id:#xxx
		DialogMonitorOPS.Enabled = true
			
	)
	
	
		on RapidMaterial close do 
			(
				DialogMonitorOPS.UnRegisterNotification id:#xxx
				DialogMonitorOPS.Enabled = DialogMonitorOPS_initial_state
			)
	
	
	

	)
		
			
	
		fn createAssembly =
	(		
		str="using System;\n"
		str+="using System.Runtime.InteropServices;\n"
		str+="using System.Windows.Forms;\n"
		str+="namespace WindowShopper\n"
		str+="{\n"
		str+="class MessageSnooper : NativeWindow\n"
		str+="{\n"
		str+="	public delegate void MessageHandler(object msg);\n"
		str+="	public event MessageHandler MessageEvent;\n"
		str+="	protected override void WndProc(ref Message m)\n"
		str+="	{\n"
		str+="		if (MessageEvent != null) MessageEvent((object)m);\n"
        str+="		base.WndProc(ref m);\n"
		str+="	}\n"
		str+="}\n"
		str+="class User32\n"
		str+="{\n"
		str+="	 public struct RECT { public int Left; public int Top; public int Right; public int Bottom; }\n"     
		str+="	 [DllImport(\"user32.dll\")]\n"
		str+="	 private static extern bool GetWindowRect(IntPtr hWnd, out RECT rect);\n" 
		str+="	 [DllImport(\"user32.dll\")]\n"
		str+="	 public static extern bool IsWindowVisible(IntPtr hWnd);\n" 
		str+="	 public int[] GetWindowRect(IntPtr hWnd)\n"
		str+="   {\n"
		str+="       RECT rect;\n"
		str+="       if (GetWindowRect(hWnd, out rect))\n"
		str+="       {\n"
		str+="           return new int[4] {rect.Left, rect.Top, rect.Right - rect.Left, rect.Bottom - rect.Top };\n"
		str+="       }\n"
		str+="       else return null;\n"
		str+="    }\n"
		str+="}\n"
		str+="}\n"

		local csharpProvider = dotnetobject "Microsoft.CSharp.CSharpCodeProvider"
		local compilerParams = dotnetobject "System.CodeDom.Compiler.CompilerParameters"
		compilerParams.ReferencedAssemblies.addRange #("System.dll","System.Windows.Forms.dll","System.Drawing.dll")
		compilerParams.GenerateInMemory = on
		local compilerResults = csharpProvider.CompileAssemblyFromSource compilerParams #(str)
		
		--for er =0 to compilerResults.errors.count-1 do print (compilerResults.errors.item[er].tostring())
		user32 = compilerResults.CompiledAssembly.CreateInstance "WindowShopper.User32"
		msgSnooper = compilerResults.CompiledAssembly.CreateInstance "WindowShopper.MessageSnooper"
	)
	
	fn getMsgName code =
	(
		case code of
		(
			0x0000: ("WM_NULL");0x0001: ("WM_CREATE");0x0002: ("WM_DESTROY");0x0003: ("WM_MOVE")
			0x0005: ("WM_SIZE");0x0006: ("WM_ACTIVATE");0x0007: ("WM_SETFOCUS");0x0008: ("WM_KILLFOCUS")
			0x000A: ("WM_ENABLE");0x000B: ("WM_SETREDRAW");0x000C: ("WM_SETTEXT");0x000D: ("WM_GETTEXT")
			0x000E: ("WM_GETTEXTLENGTH");0x000F: ("WM_PAINT");0x0010: ("WM_CLOSE");0x0011: ("WM_QUERYENDSESSION")
			0x0012: ("WM_QUIT");0x0013: ("WM_QUERYOPEN");0x0014: ("WM_ERASEBKGND");0x0015: ("WM_SYSCOLORCHANGE")
			0x0016: ("WM_ENDSESSION");0x0018: ("WM_SHOWWINDOW");0x001A: ("WM_WININICHANGE");0x001A: ("WM_SETTINGCHANGE")
			0x001B: ("WM_DEVMODECHANGE");0x001C: ("WM_ACTIVATEAPP");0x001D: ("WM_FONTCHANGE");0x001E: ("WM_TIMECHANGE")
			0x001F: ("WM_CANCELMODE");0x0020: ("WM_SETCURSOR");0x0021: ("WM_MOUSEACTIVATE");0x0022: ("WM_CHILDACTIVATE")
			0x0023: ("WM_QUEUESYNC");0x0024: ("WM_GETMINMAXINFO");0x0026: ("WM_PAINTICON");0x0027: ("WM_ICONERASEBKGND")
			0x0028: ("WM_NEXTDLGCTL");0x002A: ("WM_SPOOLERSTATUS");0x002B: ("WM_DRAWITEM");0x002C: ("WM_MEASUREITEM")
			0x002D: ("WM_DELETEITEM");0x002E: ("WM_VKEYTOITEM");0x002F: ("WM_CHARTOITEM");0x0030: ("WM_SETFONT")
			0x0031: ("WM_GETFONT");0x0032: ("WM_SETHOTKEY");0x0033: ("WM_GETHOTKEY");0x0037: ("WM_QUERYDRAGICON")
			0x0039: ("WM_COMPAREITEM");0x003D: ("WM_GETOBJECT");0x0041: ("WM_COMPACTING");0x0044: ("WM_COMMNOTIFY")
			0x0046: ("WM_WINDOWPOSCHANGING");0x0047: ("WM_WINDOWPOSCHANGED");0x0048: ("WM_POWER");0x004A: ("WM_COPYDATA")
			0x004B: ("WM_CANCELJOURNAL");0x004E: ("WM_NOTIFY");0x0050: ("WM_INPUTLANGCHANGEREQUEST");0x0051: ("WM_INPUTLANGCHANGE")
			0x0052: ("WM_TCARD");0x0053: ("WM_HELP");0x0054: ("WM_USERCHANGED");0x0055: ("WM_NOTIFYFORMAT")
			0x007B: ("WM_CONTEXTMENU");0x007C: ("WM_STYLECHANGING");0x007D: ("WM_STYLECHANGED");0x007E: ("WM_DISPLAYCHANGE")
			0x007F: ("WM_GETICON");0x0080: ("WM_SETICON");0x0081: ("WM_NCCREATE");0x0082: ("WM_NCDESTROY")
			0x0083: ("WM_NCCALCSIZE");0x0084: ("WM_NCHITTEST");0x0085: ("WM_NCPAINT");0x0086: ("WM_NCACTIVATE")
			0x0087: ("WM_GETDLGCODE");0x0088: ("WM_SYNCPAINT");0x00A0: ("WM_NCMOUSEMOVE");0x00A1: ("WM_NCLBUTTONDOWN")
			0x00A2: ("WM_NCLBUTTONUP");0x00A3: ("WM_NCLBUTTONDBLCLK");0x00A4: ("WM_NCRBUTTONDOWN");0x00A5: ("WM_NCRBUTTONUP")
			0x00A6: ("WM_NCRBUTTONDBLCLK");0x00A7: ("WM_NCMBUTTONDOWN");0x00A8: ("WM_NCMBUTTONUP");0x00A9: ("WM_NCMBUTTONDBLCLK")
			0x0100: ("WM_KEYFIRST");0x0100: ("WM_KEYDOWN");0x0101: ("WM_KEYUP");0x0102: ("WM_CHAR")
			0x0103: ("WM_DEADCHAR");0x0104: ("WM_SYSKEYDOWN");0x0105: ("WM_SYSKEYUP");0x0106: ("WM_SYSCHAR")
			0x0107: ("WM_SYSDEADCHAR");0x0108: ("WM_KEYLAST");0x010D: ("WM_IME_STARTCOMPOSITION");0x010E: ("WM_IME_ENDCOMPOSITION")
			0x010F: ("WM_IME_COMPOSITION");0x010F: ("WM_IME_KEYLAST");0x0110: ("WM_INITDIALOG");0x0111: ("WM_COMMAND")
			0x0112: ("WM_SYSCOMMAND");0x0113: ("WM_TIMER");0x0114: ("WM_HSCROLL");0x0115: ("WM_VSCROLL")
			0x0116: ("WM_INITMENU");0x0117: ("WM_INITMENUPOPUP");0x011F: ("WM_MENUSELECT");0x0120: ("WM_MENUCHAR")
			0x0121: ("WM_ENTERIDLE");0x0122: ("WM_MENURBUTTONUP");0x0123: ("WM_MENUDRAG");0x0124: ("WM_MENUGETOBJECT")
			0x0125: ("WM_UNINITMENUPOPUP");0x0126: ("WM_MENUCOMMAND");0x0132: ("WM_CTLCOLORMSGBOX");0x0133: ("WM_CTLCOLOREDIT")
			0x0134: ("WM_CTLCOLORLISTBOX");0x0135: ("WM_CTLCOLORBTN");0x0136: ("WM_CTLCOLORDLG");0x0137: ("WM_CTLCOLORSCROLLBAR")
			0x0138: ("WM_CTLCOLORSTATIC");0x0200: ("WM_MOUSEFIRST");0x0200: ("WM_MOUSEMOVE");0x0201: ("WM_LBUTTONDOWN")
			0x0202: ("WM_LBUTTONUP");0x0203: ("WM_LBUTTONDBLCLK");0x0204: ("WM_RBUTTONDOWN");0x0205: ("WM_RBUTTONUP")
			0x0206: ("WM_RBUTTONDBLCLK");0x0207: ("WM_MBUTTONDOWN");0x0208: ("WM_MBUTTONUP");0x0209: ("WM_MBUTTONDBLCLK")
			0x020A: ("WM_MOUSEWHEEL");0x020A: ("WM_MOUSELAST");0x0209: ("WM_MOUSELAST");0x0210: ("WM_PARENTNOTIFY")
			0x0211: ("WM_ENTERMENULOOP");0x0212: ("WM_EXITMENULOOP");0x0213: ("WM_NEXTMENU");0x0214: ("WM_SIZING")
			0x0215: ("WM_CAPTURECHANGED");0x0216: ("WM_MOVING");0x0218: ("WM_POWERBROADCAST");0x0219: ("WM_DEVICECHANGE")
			0x0220: ("WM_MDICREATE");0x0221: ("WM_MDIDESTROY");0x0222: ("WM_MDIACTIVATE");0x0223: ("WM_MDIRESTORE")
			0x0224: ("WM_MDINEXT");0x0225: ("WM_MDIMAXIMIZE");0x0226: ("WM_MDITILE");0x0227: ("WM_MDICASCADE")
			0x0228: ("WM_MDIICONARRANGE");0x0229: ("WM_MDIGETACTIVE");0x0230: ("WM_MDISETMENU");0x0231: ("WM_ENTERSIZEMOVE")
			0x0232: ("WM_EXITSIZEMOVE");0x0233: ("WM_DROPFILES");0x0234: ("WM_MDIREFRESHMENU");0x0281: ("WM_IME_SETCONTEXT")
			0x0282: ("WM_IME_NOTIFY");0x0283: ("WM_IME_CONTROL");0x0284: ("WM_IME_COMPOSITIONFULL");0x0285: ("WM_IME_SELECT")
			0x0286: ("WM_IME_CHAR");0x0288: ("WM_IME_REQUEST");0x0290: ("WM_IME_KEYDOWN");0x0291: ("WM_IME_KEYUP")
			0x02A1: ("WM_MOUSEHOVER");0x02A3: ("WM_MOUSELEAVE");0x0300: ("WM_CUT");0x0301: ("WM_COPY")
			0x0302: ("WM_PASTE");0x0303: ("WM_CLEAR");0x0304: ("WM_UNDO");0x0305: ("WM_RENDERFORMAT")
			0x0306: ("WM_RENDERALLFORMATS");0x0307: ("WM_DESTROYCLIPBOARD");0x0308: ("WM_DRAWCLIPBOARD");0x0309: ("WM_PAINTCLIPBOARD")
			0x030A: ("WM_VSCROLLCLIPBOARD");0x030B: ("WM_SIZECLIPBOARD");0x030C: ("WM_ASKCBFORMATNAME");0x030D: ("WM_CHANGECBCHAIN")
			0x030E: ("WM_HSCROLLCLIPBOARD");0x030F: ("WM_QUERYNEWPALETTE");0x0310: ("WM_PALETTEISCHANGING");0x0311: ("WM_PALETTECHANGED")
			0x0312: ("WM_HOTKEY");0x0317: ("WM_PRINT");0x0318: ("WM_PRINTCLIENT");0x0358: ("WM_HANDHELDFIRST")
			0x035F: ("WM_HANDHELDLAST");0x0360: ("WM_AFXFIRST");0x037F: ("WM_AFXLAST");0x0380: ("WM_PENWINFIRST")
			0x038F: ("WM_PENWINLAST");0x8000: ("WM_APP");0x0400: ("WM_USER"); default:("UNKNOWN")
		)
	)
	
	fn msgEvent m =
	(
		msgname = (getMsgName m.msg)
		if findstring msgname "MOVE" != undefined and findstring msgname "MOUSE" == undefined then 
		(
			--print msgname
			local rect = user32.GetWindowRect intPt
			--print (rect as string)
			setDialogPos RapidMaterial [rect[1]+280,rect[2]+100]
		)
		
		
		if msgname == "WM_ACTIVATE" do (if MatEditor.isOpen() then (
			if sme.IsOpen() == true do (posconv = windows.clientToScreen getsmepos[1] 265 50; createDialog RapidMaterial 500 30 pos:posconv parent:getsmepos[1] style:#(#style_minimizebox))
			
			)
			else (
				
					try cui.UnRegisterDialogBar RapidMaterial catch() 
					try destroydialog RapidMaterial catch()
					
			))
	)
	
	fn initMsgSnooper =
	(
		msgSnooper.releaseHandle()
		dotnet.addEventHandler msgSnooper "MessageEvent" msgEvent
	)

			
			
	createAssembly()
	initMsgSnooper()
	msgSnooper.assignHandle intPt
	

)

#8

With a bit of extra effort you can also make the rollout background transparent
Here’s how to
VriWSmF2WW


#9

That would be amazing but i don’t know how to implement dotnet yet.
Can you please point me a resource where i can learn more about windows interaction?
i tried many time to wrap my head around those c++ things but i can’t get over standard max script.


#10

that’s quite an advanced thing, i tried too but no luck, maybe it’s needed to learn c++ and sdk, i had a look at the reference sdk but it’s quite overwhelming intead of the “simple” maxscript


#11

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


#12

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 :smiley: 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


#13

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

#14

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?


#15

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


#16

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


#17

you can use this ugly workaround

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

#18

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)

#19

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)