Notifications
Clear all

[Closed] Assign material to materialbutton

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]

18 Replies

something like this should work

Rollout dragmat “Mat Drop”
(

materialbutton choosemtl “The Material”

on dragmat open do choosemtl.material = VRayMtl()

)
createDialog dragmat

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

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

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?

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

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
	

)

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

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.

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

Page 1 / 2