how is about max script? using listener… max file save
BTW… why do you want to punish artists so hard?
I know users could do it through maxscript but the point is to make a custom ui for artists to use and navigate about. Giving them less options and places to mess up.
i’m agreeing with you. we must remove all unused tools, update existing tools and create new tools.
he he, seems we had to life with it, I do’n know how we can remove(or optional) some other unused (for general users! not developers) tools from bottom toolbar like listener window, statusbar, curveeditor etc. maybe I had to remove toolbar and recreate my own.
Speaking of UI hacks, here is one I wanted to post for April Fools but forgot.
You can put it in your co-workers /scripts/startup folder. It is guaranteed to make you the most hated person in the office
(
global toolbarRandomizer
struct toolbarRandomizerStr
(
randomizer,
--FUNCTIONS
fn createAssembly =
(
str="using System;
"
str+="using System.Runtime.InteropServices;
"
str+="using System.Windows.Forms;
"
str+="using System.Text;
"
str+="using System.Collections.Generic;
"
str+="namespace ToolbarRandomizer
"
str+="{
"
str+="class ToolbarRandomizer : NativeWindow
"
str+="{
"
str+="public IntPtr HWnd
{
get { return Handle; }
set
{
if (Handle != IntPtr.Zero)
{
ReleaseHandle();
}
AssignHandle(value);
}
}
"
str+="private static IntPtr ParentWindow;
"
str+="protected override void WndProc(ref Message m)
"
str+="{
"
str+=" if (m.Msg == 0x210 && Handle != IntPtr.Zero) {
"
str+=" Randomize();
"
str+=" }
"
str+=" base.WndProc(ref m);
"
str+="}
"
str+="[DllImport(\"user32.dll\", SetLastError = true, CharSet = CharSet.Auto)]
private static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);
private static string GetClassName(IntPtr hWnd)
{
StringBuilder sb = new StringBuilder(255);
GetClassName(hWnd, sb, 255);
return sb.ToString();
}"
str+="[DllImport(\"user32.dll\", ExactSpelling = true, CharSet = CharSet.Auto)]
public static extern IntPtr GetParent(IntPtr hWnd);
"
str+="[DllImport(\"user32\")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool EnumChildWindows(IntPtr window, EnumWindowProc callback, IntPtr i);
"
str+="public static List<IntPtr> GetChildWindows(IntPtr parent)
{
ParentWindow = parent;
List<IntPtr> result = new List<IntPtr>();
GCHandle listHandle = GCHandle.Alloc(result);
try
{
EnumWindowProc childProc = new EnumWindowProc(EnumWindow);
EnumChildWindows(parent, childProc, GCHandle.ToIntPtr(listHandle));
}
finally
{
if (listHandle.IsAllocated)
listHandle.Free();
}
return result;
}
"
str+="private static bool EnumWindow(IntPtr handle, IntPtr pointer)
{
GCHandle gch = GCHandle.FromIntPtr(pointer);
List<IntPtr> list = gch.Target as List<IntPtr>;
if (list == null)
{
throw new InvalidCastException(\"GCHandle Target could not be cast as List<IntPtr>\");
}
if (GetParent(handle) != ParentWindow) return true;
if (GetClassName(handle) != \"CustButton\") return true;
RECT r;
GetWindowRect(handle, out r);
if (Math.Abs((r.Right - r.Left) - (r.Bottom - r.Top)) > 2) return true;
list.Add(handle);
return true;
}
"
str+="public delegate bool EnumWindowProc(IntPtr hWnd, IntPtr parameter);
"
str+="private void Randomize()
{
List<IntPtr> children = GetChildWindows(HWnd);
List<RECT> rects = new List<RECT>(children.Count);
List<RECT> newRects = new List<RECT>(children.Count);
foreach (IntPtr c in children)
{
RECT r;
GetWindowRect(c, out r);
rects.Add(r);
}
Random rand = new Random(Environment.TickCount);
for (int i = 0; i < children.Count; i++)
{
int index = rand.Next(rects.Count);
POINT P = new POINT();
P.X = rects[index].Left;
P.Y = rects[index].Top;
ScreenToClient(Handle, ref P);
SetWindowPos(children[i], 0, P.X, P.Y, 0, 0, 5);
rects.RemoveAt(index);
}
}
"
str+="public void Stop() { base.ReleaseHandle(); }
"
str+="[StructLayout(LayoutKind.Sequential)]
public struct POINT { public int X; public int Y; }
"
str+="public struct RECT { public int Left; public int Top; public int Right; public int Bottom; }
"
str+="[DllImport(\"user32.dll\")]
static extern bool ScreenToClient(IntPtr hWnd, ref POINT lpPoint);
"
str+="[DllImport(\"user32.dll\")]
"
str+="private static extern bool GetWindowRect(IntPtr hWnd, out RECT rect);
"
str+="[DllImport(\"user32.dll\")]
"
str+="[return: MarshalAs(UnmanagedType.Bool)]
"
str+="public static extern bool SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);
"
str+="}
"
str+="}
"
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())
return compilerResults.CompiledAssembly.createInstance "ToolbarRandomizer.ToolbarRandomizer"
),
fn init =
(
if (randomizer != undefined) do randomizer.stop()
randomizer = createAssembly()
local hwnd = for w in windows.GetChildrenHwnd #max where w[5] == "Main Toolbar" collect uiAccessor.getFirstChildWindow w[1]
randomizer.hwnd = dotnetObject "System.IntPtr" hwnd[1]
),
_init = init()
)
::toolbarRandomizer = toolbarRandomizerStr()
ok
)
Example of what? Run the code and click a button on the main toolbar. It could help train workers to use keyboard shortcuts instead of the mouse.
lol :), it was very fun, is it possible to access bottom toolbar by this method?
Sure, you just need to find the right handles. You can then hide controls using the ShowWindow native win32 function.