Notifications
Clear all

[Closed] Set DirectX Cache state through Maxscript?

Perfect!, As always, you’re a star, Richard

BTW: Nvidia changed the naming convention of their direct3D drivers, so the following line needs to be changed to read:

(dialogTitle == “Configure Direct3D”) or (dialogTitle == “Configure MAXtremeD3D”) or (dialogTitle == “Configure 3ds Max Performance Driver”)

Finally, looking at the Microsoft URL you gave…, should this way of using a “case” function work for radiobuttons, say a set of 4 radiobuttons, in which only one can be selected…? Also, I’m still trying to work out where you identified code 240 or 241 from?

Regards,
Mike

1 Reply
(@zeboxx2)
Joined: 1 year ago

Posts: 0

Gotta love that

No. Each radiobutton is a single UI element and you will have to loop over all 4 until you hit the selected one.

Whenever you see one of those WM_something, BM_something, BN_something, LV_something things and you need the numeric code, hit google with “define WM_something” and similar.
In this case, BM_GETCHECK: http://www.google.com/search?q=define+bm_getcheck
You should get a few results, the important ones are where you see numbers behind the “BM_GETCHECK” in the results.

winuser.h is a good one for the more generic types
messages.h is a good one for a bunch of UI interaction types

But when what you need can’t be found in those, again, google usually finds the answer somewhere

Thanks Richard.
Got another problem which is similar…

I’m trying to automate the default settings for an import dialog windows when it appears.
However, the import dialog window ONLY appears after the “Select File to Import” dialog has appeared and a file has been selected and the “Open” button has been pressed. The code also needs to handle the user clicking the “X” in the top right of the dialog, hitting the “Cancel” button and also ONLY continue when a certain plugin file_type is being used!

I’m trying to put all this code within the startup.ms file as well…Here’s what I have so far:

callbacks.removescripts id:#nv_BREP_Import_Settings_START
callbacks.addscript #preImport "BREP_Import_Dialog_Settings_START()" id:#nv_BREP_Import_Settings_START

fn BREP_Import_Dialog_Settings_START =
(
dialogMonitorOps.enabled = true
dialogMonitorOps.interactive = false
dialogMonitorOps.unregisterNotification id:#setBREPImportDialogSettings
dialogMonitorOps.registerNotification BREP_SET_Import_Dialog_Settings id:#setBREPImportDialogSettings
)

fn BREP_SET_Import_Dialog_Settings =
(
	local hwnd = dialogMonitorOps.getWindowHandle()
	local dialogTitle = uiAccessor.getWindowText hwnd
	if (hwnd != 0) do (
		if (dialogTitle == "Select File to Import") then (
			--UIAccessor.pressButtonByName hwnd "Open"
			format "[%]
" dialogTitle
                        -- CODE TO HANDLE the multiple dialog windows needs to go here..?
			dialogMonitorOps.unRegisterNotification id:#setBREPImportDialogSettings
			dialogMonitorOps.enabled = false
		)
	)
	true
)

Thanks,
Mike

wouldn’t it be much easier to limit the user’s options my presenting your own file browse dialog (getOpenFilename), and then calling importFile on the selected file if appropriate? Then you only have to deal with that dialog.


Alternatively, you can just as well skip the file browsing dialog and only detect the BREP dialog, if the user has to select the file first anyway.


That said, your code’s slightly incorrect.

If you wanted to handle one dialog opening after another, and it -must- open after that other, you would use something like:


global firstDialogOpened
fn BREP_SET_Import_Dialog_Settings =
(
	local hwnd = dialogMonitorOps.getWindowHandle()
	local dialogTitle = uiAccessor.getWindowText hwnd
	if (hwnd != 0) do
	(
		if (dialogTitle == "Select File to Import") then ( firstDialogOpened = true )
		if ((firstDialogOpened) AND (dialogTitle == "The Other Dialog's Title")) then
		(
			-- process this dialog here
		)
	)
)
firstDialogOpened = false
-- code to invoke the first dialog here
firstDialogOpened = false

There’s no good way to detect whether the user pressed OK or Cancel or anything like that – you can only derive that from actions, callbacks, etc. that follow.

Hence… I’d suggest going with what I mentioned near the top… try to keep as much of it in your own control as possible

Or we could all go pester nPower to give better maxscript support to their tools.

-Eric

well if, when you open the dialog, it’s got the same settings you used before – then presumably it saves its settings something and loads it from there; which means you could manipulate that (if registry / ini file / flat file / xml).
From thereon, the exporter plugin -could- respect the option to not display any dialogs.

Then indeed, you wouldn’t even need the uiaccessor bits

Thanks Richard.
Unfortunately no ini/file is written/read to/from, so its simply a case of using UIAccessor.
I have it all working now, so thanks for the help.
One thing I did notice is that some of the UI elements (checkboxes/radiobuttons) are not available through the UiAccessor method…? Is this a case that the developer hasn’t done something to allow access to these parts of the dialog? Do you know how this is achieved so I can push the developer in the right direction?
Thanks,
Mike

all UI elements should be available unless they’re using non-Win32 elements (a la WPF, Flash, that sort of thing)

try downloading winspy++* ( http://www.catch22.net/software/winspy ), drag the crosshair over the UI element of interest… it should register and tell you things like the current hwnd (can’t use that ‘as is’ as it changes anytime the dialog is opened), dialog resource ID, class name, etc. which you can then use to identify it in your own code. dialog resource ID in particular is useful as that shouldn’t change (except if there’s a new version of that dialog released and the dialog’s internal layout ordering was changed).

  • there’s other apps that do much the same – I just happen to like winspy++.

Thanks Richard
Got them all working now.
I still seem to have an initial ‘initialisation’ bug, which seems to be tied up with the “dialogMonitorOps.enabled” command not being set to “false”. I really wish the MaxScript documentation explained how “dialogMonitorOps.enabled” & “dialogMonitorOps.interactive” work or differ?
Could you shed some light? What’s the difference between the 2 commands? Is it advisable to have one without the other?

Thanks,Mike

for most scripting you should only use .enabled ; set true just before you do things that will need it, set false as soon as you’re done with it.

.interactive set to true just causes a popup query box asking you if you want to close the window that just opened, regardless of what window that actually is. It’s not particularly useful for scripting other than some debuggery purposes

Thanks… annoyingly I still seem to have 2 problems:

  1. I have a couple of radiobuttons which have the same “text” in the import dialog.
    “Medium” and “Medium” exist twice, but are for different settings. Their HWND, parent’s HWND, ancestor’s HWND and “class name as a string” are all the same. I guess the only way to search for them (as scanning by “text” [5] obviously isn’t going to work) is via the “UIAccessor.GetWindowResourceID”? Or is there a trick?

  2. I still seem to be having problems with getting the following commands to work correctly:

dialogMonitorOps.unRegisterNotification id:#setBREPImportDialogSettings
dialogMonitorOps.enabled = false

The code works, but it crashes and I’m sure its tied up with the order of registering and un-registering the dialogmonitorOps function in the last 3 lines of this code…

Here’s what I have so far (all in a startup.ms in maxroot\scripts\startup folder):


-- **REMOVE Startup SCRIPTS**
callbacks.removescripts id:#nv_BREP_preImport
-- **ADD Startup SCRIPTS**
callbacks.addscript #preImport "BREP_preImport_Dialog_Settings()" id:#nv_BREP_preImport
--
global firstDialogOpened
global WM_COMMAND = 0x111 -- Windows Message: Command
global BN_CLICKED = 0
global BM_SETCHECK = 241 -- checkbutton toggle message ID
--
--Render Mesh Quality
--1: "Coarse", 2: "Medium", 3: "Fine"
global BREP_RenderMeshQuality = 1
--
fn BREP_preImport_Dialog_Settings =
(
firstDialogOpened = false
dialogMonitorOps.enabled = true
dialogMonitorOps.interactive = false
dialogMonitorOps.unregisterNotification id:#setBREPImportDialogSettings
dialogMonitorOps.registerNotification BREP_SET_Import_Dialog_Settings id:#setBREPImportDialogSettings
)
--
fn BREP_SET_Import_Dialog_Settings =
(
local hwnd = dialogMonitorOps.getWindowHandle()
local DialogTitle = uiAccessor.getWindowText hwnd
if (hwnd != 0) do
	(
	if (DialogTitle == "Select File to Import") then ( firstDialogOpened = true )
	if ((firstDialogOpened) AND (DialogTitle == "Power IGES/STEP/SAT Import")) then
		(
		local dialogChildren = windows.getChildrenHWND hwnd
		local RenderMeshQuality = undefined
		RenderMeshQualityOption = case (BREP_RenderMeshQuality) of
			(
			1: "Coarse"
			2: "Medium"
			3: "Fine"
			default: "Coarse"
			)
		for dialogChild in dialogChildren do
			(
			if (dialogChild[5] == RenderMeshQualityOption) then
				(
				RenderMeshQuality = dialogChild
				--chk_RenderMeshQuality_id = UIAccessor.GetWindowResourceID RenderMeshQuality[1]
				--format "%
" (chk_RenderMeshQuality_id as string)
				)
			)
			--Render Mesh Quality
			local chk_RenderMeshQuality_hwnd = RenderMeshQuality[1]
			local chk_RenderMeshQuality_id = UIAccessor.GetWindowResourceID chk_RenderMeshQuality_hwnd
			windows.sendMessage chk_RenderMeshQuality_hwnd BM_SETCHECK 1 0
			windows.sendMessage hwnd WM_COMMAND ((bit.shift BN_CLICKED 16) + chk_RenderMeshQuality_id) chk_RenderMeshQuality_hwnd
		-- Press the "OK" Button to close the dialog...
		--UIAccessor.pressButtonByName hwnd "OK"
			format "% [%]
" "Success: BREP IMPORT Dialog settings have been assigned" localtime
		)
	)
dialogMonitorOps.unRegisterNotification id:#setBREPImportDialogSettings
dialogMonitorOps.enabled = false
true
)

Page 2 / 3