The Windows struct provides methods to access the Windows OS' User Interface elements.
Unless noted otherwise, these methods are available in 3ds Max 2008 and higher.
NEW in 3ds Max 2024:
Functions that take a HWND argument to specify the window operated on may instead take a RolloutFloater, Rollout, or the name #max
to specify the 3ds Max main window. The synopsis of those functions is updated below.
They were previously available in the Avguard Extensions .
windows.getMAXHWND()
This method returns the HWND of the main 3ds Max window as an integer (Pointer value).
windows.getDesktopHWND()
This method returns the HWND of the MS Window's desktop as an integer (Pointer value).
windows.sendMessage {<RolloutFloater>|<Rollout>|<int_HWND>|#max} <int message> <int messageParameter1> <int messageParameter2>
Sends a Win32 message to the HWND, RolloutFloater, Rollout, or 3ds Max main window specified in the first argument.
The second argument is the message ID, usually specified as hexadecimal number.
The third and fourth arguments are the message parameters. When no parameters are expected, pass 0 as a placeholder.
windows.postMessage {<RolloutFloater>|<Rollout>|<int_HWND>|#max} <int message> <int messageParameter1> <int messageParameter2>
Calls the Window's PostMessage function passing the argument values.
Available in 3ds Max 2011 and higher.
windows.processPostedMessages()
Runs a message pump that retrieves any pending Window's messages and dispatches them to 3ds Max.
Calling this method will process all pending messages. It can be used inside a MAXScript loop which would otherwise cause a "white screen" in Windows 7 due to 3ds Max being unresponsive while performing long calculations.
Available in 3ds Max 2011 and higher.
windows.getChildrenHWND {<RolloutFloater>|<Rollout>|<int_HWND>|#max} parent:{<RolloutFloater>|<Rollout>|<int_HWND>|#max}
This method returns an array of the children windows of the specified HWND, RolloutFloater, Rollout, or 3ds Max main window, recursively.
If the specified HWND is 0, only the top level desktop windows are returned (not recursively).
If the parent HWND is specified, only windows whose immediate parent is the specified window are returned.
If #max
is specified as the HWND, the HWND associated with the 3ds Max main window is used.
If the specified HWND does not exist, the value undefined
is returned.
Otherwise, an array is returned.
Each element of the array corresponds to a window, and contains an 8 elements array (originally, only the first 5 elements were returned in 3ds Max 2008)
The elements of these arrays represent the window's:
1: HWND
2: the parent HWND. This does not include the owner (GetAncestor(hWnd,GA_PARENT))
3: the parent or owner HWND. If the window is a child window, the return value is a handle to the parent window. If the window is a top-level window, the return value is a handle to the owner window. (GetParent(hWnd))
4: class name as a string (GetClassName(hWnd, className, bufSize)) - limit of 255 characters
5: window text as a string (GetWindowText(hWnd, windowText, bufSize)) - limit of 255 characters
6: the owner's HWND (GetWindow(hWnd,GW_OWNER))
7: root window HWND. The root window as determined by walking the chain of parent windows (GetAncestor(hWnd,GA_ROOT))
8: owned root window HWND. The owned root window as determined by walking the chain of parent and owner windows returned by GetParent (GetAncestor(hWnd,GA_ROOTOWNER))
FOR EXAMPLE, A PARTIAL RESULT FROM THE CALL
print (windows.getChildrenHWND #max)
looks like
...
#(16990604P, 25827408P, 25827408P, "#32770", "Main Toolbar", 25827408P, 25827408P, 25827408P)
#(2048768P, 16990604P, 16990604P, "CustToolbar", "", 0P, 25827408P, 25827408P)
#(8794706P, 2048768P, 2048768P, "CustSeparator", "", 0P, 25827408P, 25827408P)
#(33762226P, 2048768P, 2048768P, "CustButton", "", 0P, 25827408P, 25827408P)
#(34615562P, 2048768P, 2048768P, "CustButton", "", 0P, 25827408P, 25827408P)
#(999632P, 2048768P, 2048768P, "CustButton", "", 0P, 25827408P, 25827408P)
#(5908980P, 2048768P, 2048768P, "CustSeparator", "", 0P, 25827408P, 25827408P)
#(19083138P, 2048768P, 2048768P, "ComboBox", "All", 0P, 25827408P, 25827408P)
...
In this case, the Main Toolbar of 3ds Max is a docked window which has a HWND of 16990604, the 3ds Max main window's HWND is 25827408, the class name of the Main Toolbar is "#32770" and the window text of the toolbar is "Main Toolbar". It is owned by and rooted at the 3ds Max window with HWND 25827408, which explains elements 6,7 and 8.
The next element is the toolbar window itself which has a HWND of 2048768 and is parented to the Main Toolbar window with HWND 16990604. The class of the toolbar is "CustToolbar" and it does not display any text. It is not owned by a window (so the HWND is 0), but it is rooted at the 3ds Max window with HWND 25827408.
The next element is the first separator in the toolbar. It has a HWND of 8794706 and is parented to the custom toolbar with HWND of 2048768. Its class is "CustSeparator" and has no text associated with it. It has no owner and is rooted at the 3ds Max window.
After that we get the first icon in the Main Toolbar with HWND 33762226. It is also parented to the custom toolbar with HWND of 2048768 and has the class "CustButton" and no text. It has no owner and is rooted at the 3ds Max window.
After that come more buttons and separators. The one with HWND 19083138P is the Selection Filter ComboBox which displays "All" by default.
windows.getChildHWND {<RolloutFloater>|<Rollout>|<int_HWND>|#max} <string> parent:{<RolloutFloater>|<Rollout>|<int_HWND>|#max}
The mehod returns the child window of the specified HWND, RolloutFloater, Rollout, or 3ds Max main window with the given child window's text. Child windows are recursively searched.
If the specified HWND is 0, only the top level desktop windows are searched (not recursively).
If the parent HWND is specified, only windows whose immediate parent is the specified window are searched.
If #max
is specified as the HWND, the HWND associated with 3ds Max main window is used.
If the specified HWND does not exist, the value undefined
is returned.
If a child window with the specified text is not found, undefined
is returned.
The text comparison is case insensitive.
If a match is found, an 8 element array is returned. See the documentation of the windows.getChildrenHWND()
method above for details on their meaning.
FOR EXAMPLE, A PARTIAL RESULT FROM THE CALL
max file xref object -- open xref object dialog
xro_hwnd = windows.getChildHWND 0 "XRef Objects" parent:#max -- find xref object dialog
if xro_hwnd != undefined do windows.sendMessage xro_hwnd[1] 0x0010 0 0 -- if found, send close message
max file xref scene -- open xref sceen dialog
xrs_hwnd = windows.getChildHWND 0 "XRef Scenes" parent:#max -- find xref scene dialog
if xrs_hwnd != undefined do windows.sendMessage xrs_hwnd[1] 0x0010 0 0 -- if found, send close message
LISTENER OUTPUT:
OK
#(25961156P, 65552P, 25827408P, "#32770", "XRef Objects", 25827408P, 25961156P, 25827408P)
1
OK
#(26813124P, 65552P, 25827408P, "#32770", "XRef Scenes", 25827408P, 26813124P, 25827408P)
1
windows.getHWNDData {<RolloutFloater>|<Rollout>|<int_HWND>|#max}
Returns data associated with the specified HWND, RolloutFloater, Rollout, or 3ds Max main window.
If #max
is specified as the HWND, the HWND associated with the 3ds Max main window is used.
If the specified HWND does not exist, the value undefined is returned.
If a match is found, a 8 element array is returned. See the documentation of the windows.getChildrenHWND()
method above for details on their meaning.
Available in 3ds Max 2011 and higher.
Note that in 3ds Max 2011 and higher, rollouts and rollout controls expose a read-only .hwnd
property.
In the case of a rollout, the property contains the Window's HWND associated with the rollout, or 0 if the rollout is not open.
In the case of a rollout User Interface control, the property contains an array of the Window's HWND of the rollout containing the rollout, or an empty array of the rollout is not open.
windows.setWindowPos {<RolloutFloater>|<Rollout>|<int_HWND>|#max} <int x> <int y> <int width> <int height> <bool repaint> [ applyUIScaling:<true> ]
Set the position of the window specified by the HWND, RolloutFloater, Rollout, or 3ds Max main window to the X and Y coordinates specified by the second and third arguments.
Also set the Width and Height of the window to the values passed as fourth and fifth arguments.
When the sixth argument is set to True, the window will also be repainted.
The applyUIScaling
parameter indicates whether to apply scaling required on high DPI displays.
Available in 3ds Max 2014 and higher.
windows.setWindowPos {<RolloutFloater>|<Rollout>|<int_HWND>|#max} <Box2 rect> <bool repaint> [ applyUIScaling:<true> ]
Set the position of the window specified by the HWND, RolloutFloater, Rollout, or 3ds Max main window to the coordinates and size given by the second Box2 argument.
When the third argument is set to True, the window will also be repainted.
The applyUIScaling
parameter, when set to true, applies any scaling required on HDPI displays.
Available in 3ds Max 2014 and higher.
<Box2 rect>windows.getWindowPos {<RolloutFloater>|<Rollout>|<int_HWND>|#max} [ removeUIScaling:<true> ]
Returns the position of the upper left corner and the width and height of the window specified by the HWND, RolloutFloater, Rollout, or 3ds Max main window argument.
The position is expressed in screen coordinates relative to the upper-left corner of the screen.
The removeUIScaling
parameter, when true, removes any scaling applied on HDPI displays.
Available in 3ds Max 2014 and higher.
FOR EXAMPLE:
rollout test1 "Test" ( button btn "PRESS ME" ) --a test rollout
createDialog test1 200 50 120 140 --rollout, width, height, x, y
windows.getWindowPos test1.hwnd --get the resulting position and size
LISTENER OUTPUT:
Rollout:test1
true
(Box2 120 140 206 75)
--Note that the width and height include the borders and the title bar
--and can vary depending on the Windows Theme used.
NOW LET'S MOVE AND RESIZE IT:
windows.setWindowPos test1.hwnd 220 240 206 55 true
<int HWND> getCapture()
Returns the HWND of the window that is currently capturing the mouse. See the winuser.h GetCapture function for more information. Available in in 3ds Max 2022.2 Update and later
<Point2>windows.clientToScreen {<RolloutFloater>|<Rollout>|<int_HWND>|#max} <int x> <int y> [ applyUIScaling:<true> ]
<Point2>windows.clientToScreen {<RolloutFloater>|<Rollout>|<int_HWND>|#max} <Point2 clientCoord> [ applyUIScaling:<true> ]
Converts the coordinates from the Client space of the window specified by the first argument to coordinates relative to the upper left corner of the Screen.
The applyUIScaling
parameter, when set to true, applies any scaling required on HDPI displays.
Available in 3ds Max 2014 and higher.
<Point2>windows.screenToClient {<RolloutFloater>|<Rollout>|<int_HWND>|#max} <int x> <int y> [ applyUIScaling:<true> ]
<Point2>windows.screenToClient {<RolloutFloater>|<Rollout>|<int_HWND>|#max} <Point2 screenCoord> [ applyUIScaling:<true>]
Converts the coordinates from Screen space relative to the upper left corner into Client space of the window specified by the first argument.
The applyUIScaling
parameter, when set to true, applies any scaling required on HDPI displays.
Available in 3ds Max 2014 and higher.
FOR EXAMPLE:
tv = trackviews.getTrackView 1
--><MixinInterface:TrackView>
windows.getWindowPos tv.ui.hwnd
-->(Box2 244 242 1200 400)
screenPos = windows.clientToScreen tv.ui.hwnd 10 20
-->[262,312]
windows.screenToClient tv.ui.hwnd screenPos.x screenPos.y
-->[10,20]
windows.getWindowPos tv.ui.hwnd
-->(Box2 244 242 1200 400)
windows.setWindowPos tv.ui.hwnd 0 0 1200 400 true
-->true
windows.isWindowEnabled int_HWND
Returns true if the specified window is enabled, and able to receive mouse and keyboard inputs. See the Win32 API IsWindowEnabled documentation for more information.
windows.snapshot {<int_HWND>|#max} captureAlpha:<boolean> gammaCorrect:<boolean> captureScreenPixels:<boolean>
Creates a Bitmap snapshot of the specified HWND, RolloutFloater, Rollout, or 3ds Max main window.
If the specified HWND is 0, a snapshot of the Windows Desktop will be taken.
If the argument is set to #max
, the HWND associated with the 3ds Max main window will be used.
If the captureAlpha:
optional keyword argument is specified and set to True, the viewport Alpha will also be captured. If not specified or set to False, the returned image will contain no Alpha and only the RGB channels.
If the gammaCorrect:
optional keyword argument is not specified or set to True, gamma correction will be performed on the returned Bitmap value. If set to False, no gamma correction will be performed.
If the captureScreenPixels:
optional keyword argument is set to True, the window desktop pixels will be captured within the region of the specified window.
Available in 3ds Max 2015 and higher.
FOR EXAMPLE:
--Get a snapshot of the Windows Desktop:
ssBitmap1 = windows.snapshot 0
display ssBitmap1 caption:"Desktop Snapshot"
--Get a snapshot of the 3ds Max Main Window without gamma correction:
ssBitmap2 = windows.snapshot #max gammaCorrect:False
display ssBitmap2 caption:"3ds Max Main Window"
--Get a snapshot of the active viewport:
ssBitmap3 = windows.snapshot (viewport.getHWnd())
display ssBitmap3 caption:"Active Viewport"
See also Viewport.GetViewportDib() and gw.getViewportDib().
windows.getFocus
Returns the HWND handle of the window that currently has focus (meaning it is the window getting keyboard input). See the Win32 API GetFocus documentation for more information.
windows.addChild <int_HWND> <int_HWND>
Makes an ActiveX control whose HWND is passed as first argument the child of the window with HWND passed as second argument.
The first argument cannot be a MAXScript control or rollout, it must be an ActiveX control.
Given that ActiveX controls are considered obsolete since 3ds Max 9, this method can also be considered obsolete.
<bool>windows.isWindow {<RolloutFloater>|<Rollout>|<int_HWND>|#max}
NEW in 3ds Max 2024: Returns true if the specified handle for a RolloutFloater, Rollout, HWND or 3ds Max main window is an existing window.
<bool>windows.isWindowVisible {<RolloutFloater>|<Rollout>|<int_HWND>|#max}
NEW in 3ds Max 2024: Returns true if the specified handle for a RolloutFloater, Rollout, HWND or 3ds Max main window is an existing window and is visible.
windows.showWindow {<RolloutFloater>|<Rollout>|<int_HWND>|#max} <enum showCmd>
NEW in 3ds Max 2024:
Applies the specified showCmd
command to the the window for the specified RolloutFloater, Rollout, windows handle, or 3ds Max main window.
The showCmd
is one of these enums:
<enum showCmd> : #hide | #normal | #showNormal | #showMinimized | #maximize | #showMaximized | #showNoActivate | #show | #minimize | #showMinNoActive | #showNa | #Restore | #showDefault | #forceMinimize
For a description of the meaning of these command values, see the winuser.h ShowWindow function help.
<array>windows.getWindowPlacement {<RolloutFloater>|<Rollout>|<int_HWND>|#max} removeUIScaling:<true>
NEW in 3ds Max 2024: Returns the show state and the restored, minimized, and maximized positions for the specified RolloutFloater, Rollout, HWND or 3ds Max main window.
The returned array is in the form of: #(showCmd enum, [minPos], [maxPos], (Box2, NormalPos))
The removeUIScaling
parameters default to true. If false, the values will be affected by the scale factor on High DPI displays.
For more information about the format of the returned position values, see the Win32 help for the windows WINDOWPLACEMENT structure.
NEW in 3ds Max 2024:
<bool>windows.setWindowPlacement {<RolloutFloater>|<Rollout>|<int_HWND>|#max} <enum showCmd> <point2 minPos> <point2 maxPos> <box2 normalPos> applyUIScaling:<true>
<bool>windows.setWindowPlacement {<RolloutFloater>|<Rollout>|<int_HWND>|#max} <array> applyUIScaling:<true>
Sets the show state and the restored, minimized, and maximized positions for the specified RolloutFloater, Rollout, HWND, or 3ds Max main window.
The second version of this function takes the same array that is returned by getWindowPlacement()
(above).
The applyUIScaling
parameters default to true. If false, the values will be affected by the scale factor on High DPI displays.
For more information about the format of the position values, see the Win32 help for the windows WINDOWPLACEMENT structure.
<bool>windows.setFocus {<RolloutControl>|<RolloutFloater>|<Rollout>|<int_HWND>|#max} <bool> -- alias of setFocus function
NEW in 3ds Max 2024: Gives input / mouse focus to the specified RolloutControl, RolloutFloater, Rollout, HWND, or 3ds Max main window.
This is an alias of the SetFocus()
function.
<bool>windows.setForegroundWindow {<RolloutFloater>|<Rollout>|<int_HWND>|#max} -- alias of setForegroundWindow function.
NEW in 3ds Max 2024: Makes the specified RolloutFloater, Rollout, HWND or 3ds Max main window the "top" foreground window.
This is an alias of the setForegroundWindow()
function.
<intptr> windows.getWindowLong {<RolloutFloater>|<Rollout>|<int_HWND>|#max} {#exStyle|#instance|#id|#style|#userData|#wndproc|#dlgproc|#msgResult|#user|}
NEW in 3ds Max 2024:
Retrieves information about the specified window. For more information about the meaning of the second argument (the parameter to retrieve), see the GetWindowLongPtrW
function help.
The function returns undefined on failure, for example if it attempts to get private data.
<intptr> windows.setWindowLong {<RolloutFloater>|<Rollout>|<int_HWND>|#max} {#exStyle|#instance|#id|#style|#userData|#wndproc|#dlgproc|#msgResult|#user|} <intptr>
NEW in 3ds Max 2024:
Sets the specified attribute of the specified window to the value (the third parameter). Returns the previous value for the parameter. For more information about the meaning of the second argument (the parameter to set), see the SetWindowLongPtrW
function help.
The function returns undefined on failure, for example if it attempts to set private data.