[Closed] Set photometric light preset via maxscript?
I want to be able to use maxscript to set a photometric light to one of it’s various preset values (i.e. D50, Halogen, HID Mercury, etc.) Is there any way to do this? I’ve started to learn a /little/ bit about dialog monitor/UI accessor stuff but this one is still a bit over my head.
I also think I read somewhere that because of the way dropdown lists are set up in Max, this can’t actually be done with them, but I don’t remember where it was so I can’t double check that. Can anyone confirm for me whether this is or is not possible, and if so how it can be done?
I noticed that mousewheel can also change preset in this combobox. But it should be focused somehow…
(
global WM_LBUTTONDOWN = 0x0201
global WM_LBUTTONUP = 0x0202
global WM_KEYDOWN = 0x0100
global WM_KEYUP = 0x0101
global _user32 = (
source = ""
source += "using System;
"
source += "using System.Runtime.InteropServices;
"
source += "class User32
"
source += "{
"
source += " [DllImport(\"user32.dll\")]
"
source += " public static extern int PostMessage(Int32 hWnd, int wMsg, int wParam, int lParam);
"
source += "}
"
csharpProvider = dotnetobject "Microsoft.CSharp.CSharpCodeProvider"
compilerParams = dotnetobject "System.CodeDom.Compiler.CompilerParameters"
compilerParams.GenerateInMemory = on
compilerResults = csharpProvider.CompileAssemblyFromSource compilerParams #(source)
compilerResults.CompiledAssembly.CreateInstance "User32"
)
maxchilds = windows.getChildrenHWND #max
comboboxPtr = for i=1 to maxchilds.count where maxchilds[i][5] == "Intensity/Color/Attenuation" do exit with maxchilds[i+5][1]
_user32.postmessage comboboxPtr ::WM_LBUTTONDOWN 0 0
_user32.postmessage comboboxPtr ::WM_LBUTTONUP 0 0
-- virtual keycodes
-- http://api.farmanager.com/ru/winapi/virtualkeycodes.html
for i=1 to 20 do (
windows.processPostedMessages()
format "%
" (windows.getHWNDData comboboxPtr)
_user32.postmessage comboboxPtr ::WM_KEYDOWN 0x28 0
_user32.postmessage comboboxPtr ::WM_KEYUP 0x28 0
)
)
and here goes focusing that particular ui element
source = ""
source += "using System;
"
source += "using System.Runtime.InteropServices;
"
source += "using System.Text;
"
source += "class Win32
"
source += "{
"
source += " [DllImport(\"user32.dll\")]
"
source += " public static extern int SendMessage(Int32 hWnd, int wMsg, int wParam, [MarshalAs(UnmanagedType.LPStr)] string lParam);
"
source += " [DllImport(\"user32\", CharSet = CharSet.Auto, SetLastError = true)]
"
source += " public static extern Int32 SetFocus(Int32 hWnd);
"
source += " [DllImport(\"user32\", CharSet = CharSet.Auto, SetLastError = true)]
"
source += " internal static extern int GetWindowTextLength(Int32 hWnd);
"
source += " [DllImport(\"user32\", CharSet = CharSet.Auto, SetLastError = true)]
"
source += " internal static extern int GetWindowText(Int32 hWnd, [Out, MarshalAs(UnmanagedType.LPTStr)] StringBuilder lpString, int nMaxCount);
"
source += " public static string GetWindowText(Int32 hWnd)
"
source += " {
"
source += " int length = GetWindowTextLength(hWnd);
"
source += " StringBuilder sb = new StringBuilder(length + 1);
"
source += " GetWindowText(hWnd, sb, sb.Capacity);
"
source += " return sb.ToString();
"
source += " }
"
source += "}
"
csharpProvider = dotnetobject "Microsoft.CSharp.CSharpCodeProvider"
compilerParams = dotnetobject "System.CodeDom.Compiler.CompilerParameters"
compilerParams.ReferencedAssemblies.Add "System.dll"
compilerParams.ReferencedAssemblies.Add "System.Drawing.dll"
compilerParams.GenerateInMemory = true
compilerResults = csharpProvider.CompileAssemblyFromSource compilerParams #(source)
Win32Assembly = compilerResults.CompiledAssembly
Win32Assembly.CreateInstance "Win32"
-- setting focus
Win32Assembly.setfocus comboboxPtr
all of the above based on samples from this forum. all the glory to it’s original authors
The first sample works great, thanks so much for bringing it to my attention!
The second gives me the following error:
-- Error occurred in anonymous codeblock; filename: ; position: 1769; line: 38
-- Unknown property: "setFocus" in dotNetObject:System.Reflection.RuntimeAssembly
I found out how to change that value
_user32.postmessage comboboxPtr 0x014E index 0
This stuff is beyond my comprehension at the moment, but I shall endeavor to understand it!
Hm, actually, where did you find the first sample? It works but leaves the combobox in an open state when it’s done which is not preferable
I would try windows.processPostedMessages or Uiaccessor.perssdefaultbutton then.
I’m not that much into winapi and all that stuff too
everything is much more simple…
to set/get current selection to a combobox control you have to use messages CB_SETCURSEL/CB_GETCURSEL (google for more details).
the problem is that technically you can make your own presets with own names and you have to know all available preset names.
to solve it we need a help from c#
global ComboBoxOpsAssembly
fn CreateComboBoxOpsAssembly =
(
source = ""
source += "using System;
"
source += "using System.Text;
"
source += "using System.Runtime.InteropServices;
"
source += "public class ComboBoxOps
"
source += "{
"
source += " [DllImport(\"user32.dll\")]
"
source += " public static extern int SendMessage(IntPtr window, int message, int wParam, IntPtr lParam);
"
source += " [DllImport(\"user32.dll\")]
"
source += " public static extern int SendMessage(IntPtr hWnd, int wMsg, int wParam, [MarshalAs(UnmanagedType.LPStr)] string lParam);
"
source += " public const int CB_GETCOUNT = 0x0146;
"
source += " public const int CB_GETCURSEL = 0x0147;
"
source += " public const int CB_GETLBTEXT = 0x0148;
"
source += " public const int CB_GETLBTEXTLEN = 0x0149;
"
source += " public const int CB_FINDSTRING = 0x014C;
"
source += " public const int CB_SELECTSTRING = 0x014D;
"
source += " public const int CB_SETCURSEL = 0x014E;
"
source += " [DllImport(\"user32.dll\", CharSet = CharSet.Auto)]
"
source += " static extern int SendMessage(Int32 hWnd, int msg, int wParam, [Out] StringBuilder param);
"
source += " public static string GetText(Int32 hWnd, int msg, int wParam, int length)
"
source += " {
"
source += " StringBuilder sb = new StringBuilder(length + 1);
"
source += " SendMessage(hWnd, msg, wParam, sb);
"
source += " return sb.ToString();
"
source += " }
"
source += "}
"
csharpProvider = dotnetobject "Microsoft.CSharp.CSharpCodeProvider"
compilerParams = dotnetobject "System.CodeDom.Compiler.CompilerParameters"
compilerParams.ReferencedAssemblies.Add("System.dll");
compilerParams.GenerateInMemory = true
compilerResults = csharpProvider.CompileAssemblyFromSource compilerParams #(source)
ComboBoxOpsAssembly = compilerResults.CompiledAssembly
ComboBoxOpsAssembly.CreateInstance "ComboBoxOps"
)
global ComboBoxOps = CreateComboBoxOpsAssembly()
so…
hwnd = <combobox hwnd>
-- num items
num = ComboBoxOps.SendMessage hwnd ComboBoxOps.CB_GETCOUNT 0 0
-- length of n-th (0 based) item's text
textlen = ComboBoxOps.SendMessage hwnd ComboBoxOps.CB_GETLBTEXTLEN n 0
-- text of n-th (0 based) item
ComboBoxOps.GetText hwnd ComboBoxOps.CB_GETLBTEXT 0 textlen
-- set n-th as current seelction
ComboBoxOps.SendMessage hwnd ComboBoxOps.CB_SETCURSEL n 0
-- get current seelction
n = ComboBoxOps.SendMessage hwnd ComboBoxOps.CB_GETCURSEL 0 0