View Full Version : Dock/undock command panel through script?

03 March 2012, 04:22 PM
Title say it all. Is this possible?

Would need to be able to check if command panel is docked, and if not, dock it.

03 March 2012, 07:35 PM
Is it possible? Yes.
Is it pretty? No. :)

fn getCommandPanelDocked =
local pos = getIniSetting (cui.getConfigFile()) "Command Panel" "CurPos"
return pos[1] == "8"

fn setCommandPanelDocked state =
local f = cui.getConfigFile()
local pos = getIniSetting f "Command Panel" "CurPos"
if (pos[1] == "8" and state) or (pos[1] == "1" and not state) do return undefined
local posArr = filterString pos " "
if posArr.count == 5 do
local newPos = if state then "8 " else "16 "
for p = 2 to 5 do newPos+= posArr[p] + " "
setIniSetting f "Command Panel" "CurPos" newPos
cui.loadConfig f

03 March 2012, 08:05 PM
fn doesCommandPanelFloat =
local act = off
for d in UIAccessor.GetPopupDialogs() while not act do act = (UIAccessor.GetWindowText d == "Command Panel")

03 March 2012, 08:46 PM
another idea:
if (windows.getchildhwnd 0 "Command Panel") == undefined then <command panel doesn't float>

03 March 2012, 09:07 PM
so using LO's original idea we have:

fn doesCommandPanelFloat = (windows.getchildhwnd 0 "Command Panel" != undefined)
fn dockCommandPanel state:on = if doesCommandPanelFloat() == state do
local ini = cui.getConfigFile()
local pos = getIniSetting ini "Command Panel" "CurPos"

pos = (if state then "8" else "16") + (trimleft pos "0123456789")
setIniSetting ini "Command Panel" "CurPos" pos
cui.loadConfig ini


i try to avoid using of cui.saveConfig() because usually it takes time.

03 March 2012, 09:11 PM
also i don't care about Comman Panel visibility (it's the first bit as i understood). If the user wants to dock/float the panel user expects to have it visible.

03 March 2012, 09:27 PM
Nice optimization.

also i don't care about Comman Panel visibility (it's the first bit as i understood). If the user wants to dock/float the panel user expects to have it visible.

That part is actually exposed to maxscript: cui.commandPanelOpen = on

03 March 2012, 09:44 PM
ok... what we have. the first number of Command Panel position setting:
4 - dock left
8 - dock right
16 - float
what are 1 and 2?

numbers 2..5 are: left, top, right, bottom corners... technically using getwindowpos (usr32) function we can set them.

03 March 2012, 09:59 PM
I think the first number is a value of this enumeration (from custcont.h):

#define CUI_TOP_DOCK (1<<0) //!< Can be docked at the top.
#define CUI_BOTTOM_DOCK (1<<1) //!< Can be docked at the bottom.
#define CUI_LEFT_DOCK (1<<2) //!< Can be docked on the left.
#define CUI_RIGHT_DOCK (1<<3) //!< Can be docked at the right.
#define CUI_ALL_DOCK (CUI_TOP_DOCK|CUI_BOTTOM_DOCK|CUI_LEFT_DOCK|CUI_RIGHT_DOCK) //!< Can be docked at any of the four positions.
#define CUI_HORIZ_DOCK (CUI_TOP_DOCK|CUI_BOTTOM_DOCK) //!< Can be docked a tthe top or bottom.
#define CUI_VERT_DOCK (CUI_LEFT_DOCK|CUI_RIGHT_DOCK) //!< Can be docked at the left or right.
#define CUI_FLOATABLE (1<<4) //!< Can be floated.
#define CUI_FLOATING (1<<4) //!< Synonym for CUI_FLOATABLE.
#define CUI_CONNECTABLE (1<<5) //!< Not currently implemented.
#define CUI_SM_HANDLES (1<<6) //!< Set if frame should display size/move handles
#define CUI_SLIDING (1<<7) //!< Frame doesn't butt up against the one next to it.
#define CUI_MAX_SIZED (1<<8) //!< Frame takes up the entire row. Nothing can be docked next to it.
#define CUI_DONT_SAVE (1<<9) //!< Don't save this CUI frame in the .cui file
#define CUI_HAS_MENUBAR (1<<10) //!< CUI frames that have a menu bar need to be treated differently

03 March 2012, 10:20 PM
just to detect if the command panel is currently floating just run through array of handles UIAccessor.GetPopupDialogs() returns, as Commandpanel reports as popup if floating, and not if docked.

so i would do the following

* check if command panel is open

* get array of popup ( window handles )

* find the correct window in the above array - do NOT use window title ("Command Panel") cause it varies with the language used. Thus search for windows with resources sitting in "core.dll", luckily the command panel reports this correctly. Now check the first subwindow handle's windowclass, which should be "EPResizeHandle" for the command panel

function GetCommandPanel=
local notFound=true

for hWnd in (UIAccessor.GetPopupDialogs()) while notFound do
local dllName=UIAccessor.GetWindowDllFileName hWnd
if( dllName!=undefined AND filenameFromPath dllName=="core.dll" AND UIAccessor.GetWindowClassName ( UIAccessor.GetFirstChildWindow hWnd ) == "EPResizeHandle" ) then
return hWnd
return 0

* after that i would try to send a corresponding windows message to the handle using the following
UIAccessor.SendMessage <HWND>hwndDlg <integer>MessageID <integer>wParam <integer>lParam

( eg. WM_MENUSELECT uItem:61007 seems to be dock left) etc...
If that fails i would too go for the cui config route and the windows states...

There is some error in my logic above, as the function GetCommandPanel would only report the handle if Command Panel is currently floating ( i already was dressed for bedtime after i found the thread yesterday ;-) )
Thus the function should be modified to do the following:
* if the panel is not found in the popupdialogs array, we know that it is currently docked and we have to search through all childwindows of the Main Max window using the same technique already in the function above

03 March 2012, 10:21 PM
#define CUI_CONNECTABLE (1<<5) //!< Not currently implemented.

can't wait to get it implemented. i need it badly :)

03 March 2012, 08:12 AM
i try to avoid using of cui.saveConfig() because usually it takes time.

Keep in mind you are potentially discarding any other changes the user has made to the UI in the current session.

03 March 2012, 06:27 PM
Thank you very much!!! This all helps tremendously!

CGTalk Moderation
03 March 2012, 06:27 PM
This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.