Notifications
Clear all

[Closed] Bring Max Process to Front

Trying to figure out a way to make 3dsmax jump to front of windows focus. I’ve tried using this user32 method but it doesn’t seem to work. Any ideas? run this script, jump to another windows application, wait 15 seconds… max should come back to focus?

(
fn CreateUser32Assembly =
(
	src  = "using System;"
	src += "using System.Runtime.InteropServices;"
	src += "class User32"
	src += "{"
	src += "[DllImport(\"User32.dll\")]"
	src += "public static extern bool SetForegroundWindow(IntPtr hWnd);"
	src += "[DllImport(\"User32.dll\", SetLastError=true)]"
	src += "public static extern IntPtr SetActiveWindow(IntPtr hWnd);"
	src += "[DllImport(\"User32.dll\")]"
	src += "public static extern IntPtr GetActiveWindow();"
        src += "}"

    provider = dotnetobject "Microsoft.CSharp.CSharpCodeProvider"
	params = dotnetobject "System.CodeDom.Compiler.CompilerParameters"

	params.GenerateInMemory = true
	result = provider.CompileAssemblyFromSource params #(src)
	result.CompiledAssembly.CreateInstance "User32"
)
 
user32assembly


fn SetActiveWindowHWND hWnd=
(
	if user32assembly == undefined do user32assembly = CreateUser32Assembly()
	return (user32assembly.SetActiveWindow hWnd)
)

try (destroydialog ::RO_TEST) catch()

rollout RO_TEST "" width:176 height:72
(
	
	local maxHWND = windows.getMAXHWND()
	
	on RO_TEST open do
	(
		sleep 15
		SetActiveWindowHWND maxHWND
	)
)

createdialog RO_TEST
)
26 Replies

sorry my mistake

Tried that too, but it just makes the taskbar item flash… which is 50% better

What if you use SetForegroundWindow() instead?

(
	fn CreateUser32Assembly =
	(
		src  = "using System;"
		src += "using System.Runtime.InteropServices;"
		src += "class User32"
		src += "{"
		src += "[DllImport(\"User32.dll\")]"
		src += "public static extern bool SetForegroundWindow(IntPtr hWnd);"
		src += "}"
		
		provider = dotnetobject "Microsoft.CSharp.CSharpCodeProvider"
		params = dotnetobject "System.CodeDom.Compiler.CompilerParameters"
		
		params.GenerateInMemory = true
		result = provider.CompileAssemblyFromSource params #(src)
		result.CompiledAssembly.CreateInstance "User32"
	)
	
	user32assembly = CreateUser32Assembly()
	
	try (destroydialog ::RO_TEST) catch()

	rollout RO_TEST "" width:176 height:72
	(
		on RO_TEST open do
		(
			sleep 8
			maxHWND = dotnetobject "system.IntPtr" (windows.getMAXHWND())
			user32assembly.SetForegroundWindow maxHWND
		)
	)

	createdialog RO_TEST
)

try this one: ForceForegroundWindow

	src  = "using System;"
	src += "using System.Runtime.InteropServices;"
	src += "class User32"
	src += "{"
	src += "[DllImport(\"User32.dll\")]
        public static extern bool ShowWindow(IntPtr handle, int nCmdShow);
	[DllImport(\"User32.dll\")]
	static extern bool BringWindowToTop(IntPtr hWnd);
	[DllImport(\"User32.dll\")]
	public static extern IntPtr GetForegroundWindow();
	[DllImport(\"user32.dll\")]
	static extern bool AttachThreadInput(uint idAttach, uint idAttachTo,bool fAttach);
	[DllImport(\"user32.dll\")]
	static extern uint GetWindowThreadProcessId(IntPtr hWnd, IntPtr ProcessId);
	[DllImport(\"kernel32.dll\")]
	static extern uint GetCurrentThreadId();
		
	public static void ForceForegroundWindow(IntPtr hWnd)
	{
		uint foreThread = GetWindowThreadProcessId(GetForegroundWindow(), IntPtr.Zero);
		uint appThread = GetCurrentThreadId();    
                const int SW_SHOW = 5;
		if (foreThread != appThread)
		{			
			AttachThreadInput(foreThread, appThread, true);
			BringWindowToTop(hWnd);		
			ShowWindow(hWnd, SW_SHOW);
			AttachThreadInput(foreThread, appThread, false);

		}
		else
		{
			BringWindowToTop(hWnd);
			ShowWindow(hWnd, SW_SHOW);
		}
	}}"

based on this stackoverflow answer

if I switch to browser and wait until SetForegroundWindow will execute it just gets highlighted in the taskbar without actually switching back to max
tested on 2014 as usual

Maybe it’s a Windows issue? I tested on Win7 Max 2014.
Here is another one:

(
	fn CreateUser32Assembly =
	(
		src  = "using System;"
		src += "using System.Runtime.InteropServices;"
		src += "class User32"
		src += "{"
		src += "[DllImport(\"User32.dll\")]"
		src += "public static extern bool SwitchToThisWindow(IntPtr hWnd, bool fUnknown);"
		src += "}"
		
		provider = dotnetobject "Microsoft.CSharp.CSharpCodeProvider"
		params = dotnetobject "System.CodeDom.Compiler.CompilerParameters"
		
		params.GenerateInMemory = true
		result = provider.CompileAssemblyFromSource params #(src)
		result.CompiledAssembly.CreateInstance "User32"
	)
	
	user32assembly = CreateUser32Assembly()
	
	try (destroydialog ::RO_TEST) catch()

	rollout RO_TEST "" width:176 height:72
	(
		timer clock "" interval:8000
		
		on clock tick do
		(
			maxHWND = dotnetobject "system.IntPtr" (windows.getMAXHWND())
			user32assembly.SwitchToThisWindow maxHWND true
			destroydialog ::RO_TEST
		)
	)

	createdialog RO_TEST
)

This one does bring Max to the front even if minimized.

That brings it back only if it’s minimized, otherwise it flashes on taskbar…

Running on Windows 10 here

same story win7x64

This one appears to work though!

What I’m doing is making it so you can use Windows Toast notification to notify a user after max has been doing something for a very long time, it’ll pop up a toast, and then when you click on the notification it’ll bring that session of max back into focus.

Page 1 / 3