[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
)
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…
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.