Notifications
Clear all

[Closed] Retrieving open tabs in the Script Editor

I feel like I should have been able to figure this out based on the help I’ve received previously, but I have to admit I still haven’t even slightly been able to wrap my mind around working with windowhandles

I’m trying to retrieve all open tabs in the script editor, the reason is that I want my script to close all open tabs that are not edited (does not have “*” in their title). I am able to retrieve the tab that I execute the script from, but I haven’t been able to retrieve all of the other tabs.

Here’s what I got so far:

g = (dotNetClass "Autodesk.Max.GlobalInterface").Instance
theMXSEditor = (g).theMXSEditorInterface
-- Get windowhandle of the MXS Editor
theMXSEditor_hwnd = theMXSEditor.EditorGetMainHWND
-- Get the number of tabs open in the MXS Editor
theMXSEditor_numTabs = theMXSEditor.EditorNumberDocuments

-- Try to retrieve open tabs in the editor
theMXSEditor_childs = (for i in (windows.getChildrenHWND theMXSEditor_hwnd) where i[4] == "MXS_Scintilla" collect i)
-- theMXSEditor_childs.count is less than the number of open tabs

So the “theMXSEditor.EditorNumberDocuments” returns the correct number of open tabs, but when I try to retrieve them by searching the children of “theMXSEditor_hwnd” I get a different result. It also seems like I get a lot of duplicates.

I was hoping someone could nudge me in the right direction?

EDIT: I’ve also tried to find out how the hotkey works (CTRL+TAB // CTRL+SHIFT+Tab), these shift through the tabs in the editor. However, they’re not specified in the hotkey editor, so I guess the MXS Editor has a separate configuration of hotkeys. Is it possible to find the code that runs when these hotkeys are used? Or are these hardcoded into the editor?

2 Replies

Did you check existing editor methods ?
https://help.autodesk.com/view/3DSMAX/2016/ENU/?guid=__cpp_ref_class_m_x_s___editor___interface_html

Editor_GetDocumentFilename gives you the filename which you can use to open the script using Editor_EditFile method.
then using SCI_GETMODIFY command it is possible to know if the doc is modified or not
sinply send this message with sendmessage to Editor_GetEditHWND window and see what it returns
1 is modified 0 is not
and then find a way to close the current document.
repeat until you left with modified docs only

All commands are documented here
https://www.scintilla.org/ScintillaDox.html

!!!
IDM_*** constants taken from here
https://github.com/moltenform/scite-files/blob/main/files/files/api_files/lua_scite_extension.api

upd

fn MxseOpenDocumentAtIndex index = 
(
	local g = (dotNetClass "Autodesk.Max.GlobalInterface").Instance	
	local mxse = g.TheMxsEditorInterface
	local SCI_GETDOCPOINTER = 2357
	
	local doc_ptr = windows.sendMessage mxse.EditorGetEditHWND SCI_GETDOCPOINTER 0 0
		
	windows.sendMessage mxse.EditorGetMainHWND 0x111 (0x104B0 + (index - 1)) 0
	
	-- check that we succesfully switched the doc
	doc_ptr != (windows.sendMessage mxse.EditorGetEditHWND SCI_GETDOCPOINTER 0 0)
)

fn MxseCloseCurrentDocument = 
(
	local g = (dotNetClass "Autodesk.Max.GlobalInterface").Instance	
	local mxse = g.TheMxsEditorInterface
	local IDM_CLOSE = 105
	
	windows.sendMessage mxse.EditorGetMainHWND 0x111 IDM_CLOSE 0
)

fn MxseCurrentDocumentIsModified = 
(
	local g = (dotNetClass "Autodesk.Max.GlobalInterface").Instance	
	local mxse = g.TheMxsEditorInterface
	local SCI_GETMODIFY = 2159
	
	(windows.sendMessage mxse.EditorGetEditHWND SCI_GETMODIFY 0 0) != 0 
)

then you use it like this


for i = num_docs to 1 by -1 where ((MxseOpenDocumentAtIndex i) and not MxseCurrentDocumentIsModified()) do MxseCloseCurrentDocument()
 

Wow, this was quite a “nudge”

Your explanation and links to the references (in addition to providing a perfect solution) is very much appreciated, thank you!