Highlight words in MaxScript Editor


#1

So, using the answer in this thread: https://stackoverflow.com/questions/92565/how-can-i-highlight-text-in-scintilla
I decided to try to make the same for the maxScript Editor.

Here is the code I have so far:


(
	g = (dotNetClass "Autodesk.Max.GlobalInterface").Instance
	mxse = g.TheMxsEditorInterface
	editorHandle = mxse.EditorGetMainHWND
	currentlyOpenTab = mxse.EditorGetEditHWND
	windowsSendMessage = windows.SendMessage
	windowsGetchildrenhwnd = windows.getchildrenhwnd
		
	function SendCommandToScintilla inCommand inLParam inWParam =	
		windowsSendMessage currentlyOpenTab inCommand inLParam inWParam
	
	scriptText = undefined		
	for c in (windowsGetchildrenhwnd editorHandle) where c[1] == currentlyOpenTab do scriptText = c[5]
	
	SCI_GETLINECOUNT = 2154
	SCI_SETINDICATORCURRENT  = 2500
	SCI_INDICSETSTYLE = 2080
	SCI_INDICATORCLEARRANGE = 2505
	SCI_INDICSETUNDER = 2510
	SCI_INDICSETALPHA = 2523
	SCI_INDICSETFORE = 2082
	SCI_INDICSETOUTLINEALPHA = 2558
	SCI_INDICATORFILLRANGE = 2504	
	SCI_SETTARGETSTART = 2190
	SCI_SETTARGETEND = 2192
	SCI_SETSEARCHFLAGS = 2198
	SCI_SEARCHINTARGET = 2197
	SCI_GETINDICATORCURRENT = 2501
	INDIC_BOX = 6	
	indic = 9
	

-- 	SendCommandToScintilla SCI_SETINDICATORCURRENT indic 0 
	SendCommandToScintilla SCI_SETINDICATORCURRENT 0 indic
	SendCommandToScintilla SCI_INDICATORCLEARRANGE indic scriptText.count
	
	SendCommandToScintilla SCI_INDICSETSTYLE indic INDIC_BOX
	SendCommandToScintilla SCI_INDICSETUNDER indic 1
	SendCommandToScintilla SCI_INDICSETFORE indic 0x0000ff
	SendCommandToScintilla SCI_INDICSETOUTLINEALPHA indic 50
	SendCommandToScintilla SCI_INDICSETALPHA indic 100
		
	SendCommandToScintilla SCI_SETTARGETSTART 0 0
	SendCommandToScintilla SCI_SETTARGETEND scriptText.count 0 
	--	SendCommandToScintilla SCI_SETSEARCHFLAGS 0 SCFIND_NONE
	
	curIndic = SendCommandToScintilla SCI_GETINDICATORCURRENT 0 0
	--	always return 0 !?
	format "curIndic: %\n" curIndic
	
	
	wordToHighlight = "marshal"
	
	marshal = dotnetclass "System.Runtime.InteropServices.Marshal"
	ptr = marshal.StringToHGlobalUni wordToHighlight
	
	wordLength = wordToHighlight.count
	
	--	find word "marshal"
	offset = SendCommandToScintilla SCI_SEARCHINTARGET wordLength ptr
	format "offset: %\n" offset
	
	--	highlight the word
	SendCommandToScintilla SCI_INDICATORFILLRANGE offset (wordLength + 1)
)

But it does not highlight any word. The code must find and highlight the word “marshal” and it finds the word, but the highlight part does not work. Also, the SCI_SETINDICATORCURRENT is also not working. Maybe this is the reason no words to be highlighted.

I have no idea if the words(more than one) highlighting is possible in MaxScript Editor.

Maybe someone have more experience with SCI_ commands?


#2

for c in (windowsGetchildrenhwnd editorHandle) where c[1] == currentlyOpenTab do scriptText = c[5]
you can’t get the whole doc like that

I tried to do something like this a long time ago, but for some reason I decided to bookmark the lines with the results instead of the words themselves.
Similar to listener mxse under the good is the scintilla editor, so the styling is governed by the lexer exclusively and you can’t simply colorize anything as you desire.

btw, If I use Find (ctrl+f) and press Mark All it marks the LINES and not the results…

code

(
	g = (dotNetClass "Autodesk.Max.GlobalInterface").Instance
	mxse = g.TheMxsEditorInterface
	editorHandle = mxse.EditorGetMainHWND
	currentlyOpenTab = mxse.EditorGetEditHWND
	windowsSendMessage = windows.SendMessage
	windowsGetchildrenhwnd = windows.getchildrenhwnd
		
	function SendCommandToScintilla inCommand inLParam inWParam =	
		windowsSendMessage currentlyOpenTab inCommand inLParam inWParam
	
	scriptText = undefined		
	
	fn getWindowText hwnd:currentlyOpenTab =
	(

		marshal = dotnetclass "System.Runtime.InteropServices.Marshal"
		str = ""
		try (
			
			len = windows.sendmessage hwnd 0xE 0 0
			lParam = marshal.AllocHGlobal (marshal.SystemDefaultCharSize*(len+1))
			windows.sendmessage hwnd 0xD (len+1) lParam 
				
			ptr = dotnetobject "System.IntPtr" lParam
			str = marshal.PtrToStringAuto ptr
			marshal.FreeHGlobal ptr
			
		) catch ()
		str
	)
	
	scriptText = getWindowText()
	format "doc length: %\n" scriptText.count
	
	SCI_GETLINECOUNT = 2154
	SCI_SETINDICATORCURRENT  = 2500
	SCI_INDICSETSTYLE = 2080
	SCI_INDICATORCLEARRANGE = 2505
	SCI_INDICSETUNDER = 2510
	SCI_INDICSETALPHA = 2523
	SCI_INDICSETFORE = 2082
	SCI_INDICSETOUTLINEALPHA = 2558
	SCI_INDICATORFILLRANGE = 2504	
	SCI_SETTARGETSTART = 2190
	SCI_SETTARGETEND = 2192
	SCI_SETSEARCHFLAGS = 2198
	SCI_SEARCHINTARGET = 2197
	SCI_GETINDICATORCURRENT = 2501
	INDIC_BOX = 6	
	indic = 9
	

	SendCommandToScintilla SCI_SETINDICATORCURRENT indic 0 
-- 	SendCommandToScintilla SCI_SETINDICATORCURRENT 0 indic
	SendCommandToScintilla SCI_INDICATORCLEARRANGE indic scriptText.count
	
	SendCommandToScintilla SCI_INDICSETSTYLE indic INDIC_BOX
	SendCommandToScintilla SCI_INDICSETUNDER indic 1
	SendCommandToScintilla SCI_INDICSETFORE indic 0x0000ff
	SendCommandToScintilla SCI_INDICSETOUTLINEALPHA indic 50
	SendCommandToScintilla SCI_INDICSETALPHA indic 100
		
	SendCommandToScintilla SCI_SETTARGETSTART 0 0
	SendCommandToScintilla SCI_SETTARGETEND scriptText.count 0 
	--	SendCommandToScintilla SCI_SETSEARCHFLAGS 0 SCFIND_NONE
	
	curIndic = SendCommandToScintilla SCI_GETINDICATORCURRENT 0 0
	--	always return 0 !?
	format "curIndic: %\n" curIndic
	
	
	wordToHighlight = "marshal"
	
	marshal = dotnetclass "System.Runtime.InteropServices.Marshal"
	ptr = marshal.StringToHGlobalUni wordToHighlight
	
	wordLength = wordToHighlight.count
	
	--	find word "marshal"
	offset = SendCommandToScintilla SCI_SEARCHINTARGET wordLength ptr
	format "offset: %\n" offset
	
	--	highlight the word
	SendCommandToScintilla SCI_INDICATORFILLRANGE offset (wordLength + 1)
)

#3

It gets the 50000 lines without any issues and then jumping to any line is also correct.

Your way of getting the doc always gives me an error on this line:

str = marshal.PtrToStringAuto ptr

I don’t know why. When I check the marshal methods the PtrToStringAuto is shown as existing method:

  .[static]<System.String>PtrToStringAuto <System.IntPtr>ptr
  .[static]<System.String>PtrToStringAuto <System.IntPtr>ptr <System.Int32>len

but I always have an error.

-- Error occurred in anonymous codeblock; filename: ; position: 842; line: 26
-- MAXScript Listener Eval Exception:
-- Unknown system exception
-- MAXScript callstack:
--	thread data: threadID:11532
--	------------------------------------------------------
--	[stack level: 0]
--	In top-level

I don’t like this. :slight_smile:


#4

Clearly many things had changed since 2014 max, which is my default one. If there’s another simpler way to access the doc then use it of course.

all I can suggest at the moment is to use this:

#define SCI_STARTSTYLING 2032
#define SCI_SETSTYLING 2033

%D0%B8%D0%B7%D0%BE%D0%B1%D1%80%D0%B0%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5

but I don’t know how to reset these underlines.
The only method works for now is to select language maxscript again in the menu i.e.
windows.sendMessage editorHandle WM_COMMAND 1401 0

upd


made a little helper to play with the values and look how it behaves. I don’t get the logic behind, but perhaps it is possible to mark certain words somehow

code
try (destroydialog X ) catch ()
rollout X ""
(
	spinner spn1 "" range:[-1e6, 1e6, 0 ]  type:#integer
	spinner spn2 "" range:[-1e6, 1e6, 0 ]  type:#integer
	spinner len "len:" range:[0, 1e6, 16 ] type:#integer
	
	fn upd = 
	(
		g = (dotNetClass "Autodesk.Max.GlobalInterface").Instance
		mxse = g.TheMxsEditorInterface
		editorHandle = mxse.EditorGetMainHWND
		currentlyOpenTab = mxse.EditorGetEditHWND
		
		windows.sendMessage editorHandle 0x111 1401 0
		windows.sendMessage currentlyOpenTab 2032 2777 spn1.value -- 2777  is the offset in the doc
		windows.sendMessage currentlyOpenTab 2033 len.value   spn2.value		
	)
	
	on spn1 changed val do upd()
	on spn2 changed val do upd()
	on len  changed val do upd()
	

)
createDialog X pos:[100,100]

#5

Thank you.
So, it is possible to “highlight” a word. Now we have to see if more than one word can be highlighted at the same time.


#6

If only AD use newer version of scintilla it would be so easy.
I’ve checked dlls, and no, no such setting exist in newer max scintilla dll so it is still decade old one.


#7

ok, seems like I managed it to work, but without understanding how and why it works
%D0%B8%D0%B7%D0%BE%D0%B1%D1%80%D0%B0%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5

I’ve added another style to maxscript properties file (it is in maxroot folder), maybe you could try to add it programatically

word offsets are hardcoded so paste it and run

example code
-- add this to MaxScript.properties file
-- style.MAXScript.24=fore:#FF0000,back:#FFFF00  
try (destroydialog X ) catch ()
rollout X ""
(
	spinner spn1 "" range:[-1e6, 1e6, -1 ]  type:#integer
	spinner spn2 "" range:[-1e6, 1e6, 24 ]  type:#integer
	spinner len "len:" range:[0, 1e6, 7 ] type:#integer
	button reset "reset styling"
	
	on reset pressed do
	(
		g = (dotNetClass "Autodesk.Max.GlobalInterface").Instance
		mxse = g.TheMxsEditorInterface
		editorHandle = mxse.EditorGetMainHWND
		currentlyOpenTab = mxse.EditorGetEditHWND

		windows.sendMessage editorHandle 0x111 1401 0 -- reset styling		
	)
	
	fn upd = 
	(
		g = (dotNetClass "Autodesk.Max.GlobalInterface").Instance
		mxse = g.TheMxsEditorInterface
		editorHandle = mxse.EditorGetMainHWND
		currentlyOpenTab = mxse.EditorGetEditHWND

		windows.sendMessage editorHandle 0x111 1401 0 -- reset styling
		
		-- style word insinde comments
		windows.sendMessage currentlyOpenTab 2032 51 spn1.value
		windows.sendMessage currentlyOpenTab 2033    len.value spn2.value
		
		-- style word inside string
		windows.sendMessage currentlyOpenTab 2032 402 spn1.value
		windows.sendMessage currentlyOpenTab 2033    len.value spn2.value
		
		-- style first 'spinner'
		windows.sendMessage currentlyOpenTab 2032 144 spn1.value
		windows.sendMessage currentlyOpenTab 2033    len.value spn2.value

		-- style second 'spinner'
		windows.sendMessage currentlyOpenTab 2032 200 spn1.value
		windows.sendMessage currentlyOpenTab 2033     len.value spn2.value
		
		-- style third 'spinner'
		windows.sendMessage currentlyOpenTab 2032 256 spn1.value
		windows.sendMessage currentlyOpenTab 2033     len.value spn2.value
		
		-- style third 'spinner'
		windows.sendMessage currentlyOpenTab 2032 1960 spn1.value
		windows.sendMessage currentlyOpenTab 2033     len.value spn2.value
		
		-- comment these lines to see how it breaks the highlighting
		-- doc_length is the magic variable
-- 		doc_length = 1000
-- 		windows.sendMessage currentlyOpenTab 2032 0  0
-- 		windows.sendMessage currentlyOpenTab 2033 doc_length 0

-- 		this works as well, 430 is the offset of next line first character
		windows.sendMessage currentlyOpenTab 2032 430 0
		windows.sendMessage currentlyOpenTab 2033 0 0

	)
	
	on x open do upd()
	on spn1 changed val do upd()
	on spn2 changed val do upd()
	on len  changed val do upd()
	

)
createDialog X pos:[100,100]

I really don’t get it
%D0%B8%D0%B7%D0%BE%D0%B1%D1%80%D0%B0%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5
%D0%B8%D0%B7%D0%BE%D0%B1%D1%80%D0%B0%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5


#8

Yes, it is strange :slight_smile: Here is a test on max2022(the style 24 is occupied alteady:

# Keywords13 - structure and FPS properties
style.MAXScript.24=fore:#000080,italics

)
but the behavior is almost the same as in your 3ds max:


#9

2014 & 2020 works fine

(
	local owner
	struct mxse_struct
	(
		doc = "",
		results = #(),
		editorHandle     = (dotNetClass "Autodesk.Max.GlobalInterface").Instance.TheMxsEditorInterface.EditorGetMainHWND,
		currentlyOpenTab = (dotNetClass "Autodesk.Max.GlobalInterface").Instance.TheMxsEditorInterface.EditorGetEditHWND,
		
		fn GetDocument =
		(	
			for c in (windows.getchildrenhwnd editorHandle) where c[1] == currentlyOpenTab do doc = c[5]
			format "doc length: %\n" doc.count
			
			if doc.count != (windows.sendmessage currentlyOpenTab (SCI_GETLENGTH = 2006) 0 0) do
			(
				format "getting doc differently...\n" 
				
				local marshal = dotnetclass "System.Runtime.InteropServices.Marshal"
				str = ""
				try (
					
					len = windows.sendmessage currentlyOpenTab 0xE 0 0
					lParam = marshal.AllocHGlobal (marshal.SystemDefaultCharSize*(len+1))
					windows.sendmessage currentlyOpenTab 0xD (len+1) lParam 
						
					ptr = dotnetobject "System.IntPtr" lParam
					str = marshal.PtrToStringAuto ptr
					marshal.FreeHGlobal ptr
					
				) catch ()
				doc = str
			)
			
		),
		
		fn ResetDocumentStyle = 
		(
			windows.sendMessage editorHandle (WM_COMMAND = 0x111) 1401 0 -- reset styling			
		),
		
		fn Colorize pos len style:24 = 
		(
			windows.sendMessage currentlyOpenTab (SCI_STARTSTYLING = 2032) pos -1
			windows.sendMessage currentlyOpenTab (SCI_SETSTYLING = 2033) len style
		),
	
		fn HighlightText txt reload:true =
		(
			if reload do GetDocument()
			
			local ss = (tolower owner.doc) as stringstream
			seek ss 0
			
			results = #()
			
			local query = tolower txt
			while undefined != skiptostring ss query do
			(
				append results (filePos ss - query.Count)
			)
					
			if results.count > 0 do ResetDocumentStyle()
			
			for res in results do owner.Colorize res txt.count
				
			format "results: %\n" results
			
			if results.count > 0 do 
			(
				seek ss (amax results)
				try
				(
					skipToNextLine ss -- skipping a few lines otherwise the last result isn't highlighted
					skipToNextLine ss
				)catch()
				
				owner.Colorize (filePos ss) 0 style:0 -- some magic to fix the last result
			)
		),
		
		fn GoToResult index:1 = if results.count > 0 do
		(
			if index > results.count do index = 1
				
			windows.sendMessage currentlyOpenTab (SCI_GOTOPOS = 2025) results[index] 0			
		),
		
		on create do owner = this
	)
	
	global mxse = mxse_struct()
	ok
)

mxse.HighlightText "windows.sendmessage curr"
mxse.GoToResult()
-- mxse.ResetDocumentStyle()

#10

On max2020(from top to bottom):


#11

there were some bugs in the code. code updated, works in 2020 as well (don’t forget to add style in maxscript properties file)

if you’re still getting this white wall try this:
should return true if maxscript lexer is in use
81 == (windows.sendmessage mxse.currentlyOpenTab (SCI_GETLEXER = 4002) 0 0)


#12

ok, here’s it in action:
ctrl + doubleclick now highlights all words in a doc

I’ve added a HashSet of allowed messages in MessageSnooper class in order to improve performance of the editor, cause if every message gets sent to mxs you literally feel the slowdown when typing text

mxseditor window event loop listener
global mxse_listener
(
	local owner
	struct mxse_listener_struct
	(
		dll,

		fn LParamToPoint lparam = 
		(
			[ bit.and lparam 0xFFFF, bit.and (bit.shift lparam -16) 0xFFFF ]			
		),
		
		fn OnMessage ev = 
		(
			if /*ev.Msg == (WM_LBUTTONDBLCLK = 0x203) and*/ keyboard.controlPressed do 
			(
				format "Double-click & ctrl pressed...\n" 
-- 				format "coord: %\n" (owner.LParamToPoint ev.lparam)
				::mxse.HighlightSelection()
			)		
		),
		
		fn Start hwnd =
		(
			dll.assignHandle (dotNetObject "System.IntPtr" hwnd)
			dotnet.addEventHandler dll "MessageEvent" OnMessage
		),
		
		fn Stop = 
		(
			dll.releaseHandle()
			dotnet.removeEventHandlers dll "MessageEvent"	
		),
		
		on create do
		(
			owner = this
			local source = "
			using System;
			using System.Windows.Forms;
			class MessageSnooper : NativeWindow
			{
				public System.Collections.Generic.HashSet<int> allowed_messages = new System.Collections.Generic.HashSet<int>();
				public delegate void MessageHandler(object msg);
				public event MessageHandler MessageEvent;
				protected override void WndProc(ref Message m)
				{
					base.WndProc(ref m);
					if (MessageEvent != null && allowed_messages.Contains( m.Msg )) MessageEvent((object)m);
				}
			}"

			csharpProvider = dotnetobject "Microsoft.CSharp.CSharpCodeProvider"
			compilerParams = dotnetobject "System.CodeDom.Compiler.CompilerParameters"
			compilerParams.ReferencedAssemblies.AddRange #("system.dll", "system.windows.forms.dll", "system.core.dll");
			compilerParams.GenerateInMemory = on
			compilerResults = csharpProvider.CompileAssemblyFromSource compilerParams #(source)

			if (compilerResults.Errors.Count > 0 ) then
			(
				local errs = stringstream ""
				for i = 0 to (compilerResults.Errors.Count-1) do
				(
					local err = compilerResults.Errors.Item[i]
					format "Error:% Line:% Column:% %\n" err.ErrorNumber err.Line err.Column err.ErrorText to:errs
				)
				format "%\n" errs
				undefined
			)
			else dll = compilerResults.CompiledAssembly.CreateInstance "MessageSnooper"
			
		)
		
	)
	
	if ::mxse_listener != undefined do ( try ( ::mxse_listener.Stop(); mxse_listener = undefined ) catch() )

	::mxse_listener = mxse_listener_struct()
	::mxse_listener.Start (dotNetClass "Autodesk.Max.GlobalInterface").Instance.TheMxsEditorInterface.EditorGetEditHWND
	
	
	::mxse_listener.dll.allowed_messages.Add (WM_LBUTTONDBLCLK = 0x203)
	
	format "started...\n" 
)

mxseditor highlighter
(
	local owner
	struct mxse_struct
	(
		doc = "",
		results = #(),
		editorHandle     = (dotNetClass "Autodesk.Max.GlobalInterface").Instance.TheMxsEditorInterface.EditorGetMainHWND,
		currentlyOpenTab = (dotNetClass "Autodesk.Max.GlobalInterface").Instance.TheMxsEditorInterface.EditorGetEditHWND,
		
		fn GetDocument =
		(	
			for c in (windows.getchildrenhwnd editorHandle) where c[1] == currentlyOpenTab do doc = c[5]
-- 			format "doc length: %\n" doc.count
			
			if doc.count != (windows.sendmessage currentlyOpenTab (SCI_GETLENGTH = 2006) 0 0) do
			(
-- 				format "getting doc differently...\n" 
				
				local marshal = dotnetclass "System.Runtime.InteropServices.Marshal"
				str = ""
				try (
					
					len = windows.sendmessage currentlyOpenTab 0xE 0 0
					lParam = marshal.AllocHGlobal (marshal.SystemDefaultCharSize*(len+1))
					windows.sendmessage currentlyOpenTab 0xD (len+1) lParam 
						
					ptr = dotnetobject "System.IntPtr" lParam
					str = marshal.PtrToStringAuto ptr
					marshal.FreeHGlobal ptr
					
				) catch ()
				doc = str
			)
			
		),
		
		fn ResetDocumentStyle = 
		(
-- 			windows.sendmessage currentlyOpenTab (SCI_COLOURISE = 4003) 0 -1
			windows.sendMessage editorHandle (WM_COMMAND = 0x111) 1401 0 -- reset styling			
		),
		
		fn Colorize pos len style:24 = 
		(
			windows.sendMessage currentlyOpenTab (SCI_STARTSTYLING = 2032) pos -1
			windows.sendMessage currentlyOpenTab (SCI_SETSTYLING = 2033) len style
		),
	
		fn HighlightText txt reload:true =
		(
			if reload do GetDocument()
			
			local ss = (tolower owner.doc) as stringstream
			seek ss 0
			
			results = #()
			
			local query = tolower txt
			while undefined != skiptostring ss query do
			(
				append results (filePos ss - query.Count)
			)
					
			if results.count > 0 do ResetDocumentStyle()
			
			for res in results do owner.Colorize res txt.count
				
-- 			format "results: %\n" results
			
			if results.count > 0 do 
			(		
				
				seek ss (amax results)
				try
				(
					skipToNextLine ss -- skipping a few lines otherwise the last result isn't highlighted
					skipToNextLine ss
				)catch()
				
				owner.Colorize (filePos ss) 0 style:0 -- some magic to fix the last result
				
			)
		),
		
		fn HighlightSelection reload:true reset:true = 
		(
			local start = 1 + (windows.sendMessage currentlyOpenTab (SCI_GETSELECTIONSTART = 2143) 0 0)
			local end   = 1 + (windows.sendMessage currentlyOpenTab (SCI_GETSELECTIONEND = 2145)   0 0)
			
			if reset do
			(				
				windows.sendMessage currentlyOpenTab (SCI_SETSELECTIONSTART = 2142) (end - 1) 0
				windows.sendMessage currentlyOpenTab (SCI_SETSELECTIONEND = 2144) (end - 1) 0			
			)
			
			if reload do GetDocument()			
			
			local query = substring doc start (end - start)

			if query.count > 0 do HighlightText query reload:false
			
		),
		
		fn GoToResult index:1 = if results.count > 0 do
		(
			if index > results.count do index = 1
				
			windows.sendMessage currentlyOpenTab (SCI_GOTOPOS = 2025) results[index] 0			
		),
		
		fn IsMaxscriptLexer = 
		(
			81 == (windows.sendmessage currentlyOpenTab (SCI_GETLEXER = 4002) 0 0)			
		),
		
		on create do owner = this
	)
	
	global mxse = mxse_struct()
	ok
)

mxse.HighlightText "windows.sendmessage curr"
mxse.GoToResult()
-- mxse.ResetDocumentStyle()

#13

It works for you, but not for me. The same white wall all the time. This is on max2020. Will test on 2022 tomorrow.
When I run theglobal mxse_listener code nothing happens(expected) except the started... text, printed in the listener.
When I run themxse.GoToResult() code - white wall. In any other tab Ctrl+doubleclick leads to white wall.
The style24 is added, 3ds max restarted - the same white wall.

I still wonder why the Indicators can’t be used. Every single example I found on the net about this topic(highlighthing word) is using indicators.

I forgot, this:

81 == (windows.sendmessage mxse.currentlyOpenTab (SCI_GETLEXER = 4002) 0 0)

return false.


#14

I couldn’t make them work, at least not at the moment.

try the second method to repaint the doc in ResetDocumentStyle, it should be more correct
windows.sendmessage currentlyOpenTab (SCI_COLOURISE = 4003) 0 -1
if it won’t work use Spy++ to know what to send instead of 1401 to your mxseditor (look for WM_COMMAND message) when switching to maxscript lexer in the menu

it is likely that
windows.sendMessage editorHandle (WM_COMMAND = 0x111) 1401 0 -- reset styling
just switches to a wrong lexer in your case
%D0%B8%D0%B7%D0%BE%D0%B1%D1%80%D0%B0%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5


#15

Your original code works on max2022.

On max2020 I have to use this

and then everything is ok.


#16

it was definitely a lexer issue

btw, for large documents it could be beneficial to redraw only the dirty part of the document

SCI_COLOURISE(position start, position end)
This requests the current lexer or the container (if the lexer is set to NULL) to style the document between start and end. If end is -1, the document is styled from start to the end.

And now the indicators.
Perhaps most of commands like clearrange & fillrange simply doesn’t work cause of the version of scintilla. Had to read some 20 years old discussions to make it. Still dont know how to reset the doc to initial state, SCI_COLOURISE isn’t working while setting lexer repaints the doc properly.
Didn’t test it with other indicators, except the first three, not even sure that we can use more than that
Didn’t like them compared to styles. No control over alpha (it is a bug, which was fixed later on), no control over text look. But for text search markings it could be enough

indicators example
(
	
	editorHandle     = (dotNetClass "Autodesk.Max.GlobalInterface").Instance.TheMxsEditorInterface.EditorGetMainHWND
	currentlyOpenTab = (dotNetClass "Autodesk.Max.GlobalInterface").Instance.TheMxsEditorInterface.EditorGetEditHWND

	fn SetupIndicator index style fore =
	(
		SCI_SETINDICATORCURRENT = 2500
		SCI_INDICSETSTYLE = 2080
		SCI_INDICSETALPHA = 2523
		SCI_INDICSETFORE = 2082
		SCI_INDICSETOUTLINEALPHA = 2558
		SCI_GETINDICATORCURRENT = 2501
		SCI_SETINDICATORVALUE = 2502
		
		windows.sendMessage currentlyOpenTab SCI_SETINDICATORCURRENT  index index	
		windows.sendMessage currentlyOpenTab SCI_INDICSETFORE 		  index fore
		windows.sendMessage currentlyOpenTab SCI_INDICSETSTYLE 		  index style
		windows.sendMessage currentlyOpenTab SCI_INDICSETOUTLINEALPHA index 128 -- not working
		windows.sendMessage currentlyOpenTab SCI_INDICSETALPHA		  index 128	-- not working https://sourceforge.net/p/scintilla/bugs/983/
		windows.sendMessage currentlyOpenTab SCI_SETINDICATORVALUE    index index		
	)

	-- #1
	SetupIndicator 0 7 0xFFFFFF
	SetupIndicator 1 8 0xFFFF00
	SetupIndicator 2 1 0x33FF33
	
	-- #2
	INDICS_MASK = 0xE0 -- all indicators
	INDIC_0 = 0x20
	INDIC_1 = 0x40
	INDIC_2 = 0x60
	
	-- #3
	windows.sendMessage currentlyOpenTab (SCI_STARTSTYLING = 2032) 0 INDICS_MASK
	windows.sendMessage currentlyOpenTab (SCI_SETSTYLING = 2033)   (doc_length = 2000) 0 -- removing all indicators
	
	-- #1
	windows.sendMessage currentlyOpenTab (SCI_STARTSTYLING = 2032) 996 INDICS_MASK
	windows.sendMessage currentlyOpenTab (SCI_SETSTYLING = 2033)   80  INDIC_0
	
	-- #2
	windows.sendMessage currentlyOpenTab (SCI_STARTSTYLING = 2032) 1094 INDICS_MASK
	windows.sendMessage currentlyOpenTab (SCI_SETSTYLING = 2033)   80  (bit.or INDIC_0 INDIC_2) -- apply both indicators to this part of the document
	
	-- #2
	windows.sendMessage currentlyOpenTab (SCI_STARTSTYLING = 2032) 1199 INDICS_MASK
	windows.sendMessage currentlyOpenTab (SCI_SETSTYLING = 2033)   80  INDIC_1
	
	
	windows.sendmessage currentlyOpenTab (SCI_COLOURISE = 4003) 0 -1 -- seems like not working
)


#17

Thank you.,

I can confirm - the styles looks much better than indicators.


#18

did you try

(SCI_STYLECLEARALL = 2050)
(SCI_STYLERESETDEFAULT = 2058)

to reset styles?


#19

But what is bad about styles is that it seems that you can’t modify/update them so the modification is persistent.


I couldn’t find a way to do it. Even changing the .properties file doesn’t update the style. But when you load it in editor and save it updates styles instantly.

No I didn’t, not this time. I used these command when I was coloring listener output and if I remember correctly it wiped away the default style so there’s no way back to default look.
.

reload mxseditor options

If anyone remembers there once was a project called MXSEditor and it has nice feature like ReloadOptions method which updates the styles etc whatever there is in .properties file. Unlike these three commands it doesn’t popup new document tab… no idea how to reload properties silently
sc0YGrWsK1

(
	hwnd = (dotNetClass "Autodesk.Max.GlobalInterface").Instance.TheMxsEditorInterface.EditorGetMainHWND
	windows.sendmessage hwnd 0x111 462 0
	windows.sendmessage hwnd 0x111 106 0
	windows.sendmessage hwnd 0x111 105 0
)

ha… found it in ida and looks like it disables the redraw of the mxseditor or something like that.
if anyone got a better ideas you’re welcome
%D0%B8%D0%B7%D0%BE%D0%B1%D1%80%D0%B0%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5

and this also doesn’t work, what a pity

-- EditorEditFile  <System.String>filename 
-- <System.Boolean>useOpenfilenameDialogIfFilenameNull 
-- <System.String>initialPath 
-- <System.Int32>openToPos 
-- <Autodesk.Max.Editor_Interface.OpenFlags>of 
-- <System.Boolean>unhide 
-- <System.Boolean>setFocus
mxse = (dotNetClass "Autodesk.Max.GlobalInterface").Instance.TheMxsEditorInterface
mxse.EditorEditFile (getdir #maxroot + "maxscript.properties") false (getdir #maxroot) 0 (dotnetclass "Autodesk.Max.Editor_Interface.OpenFlags").Quiet false false

#20

kinda works

fn ReloadMXSEditorProperties =
(	
	local hwnd = (dotNetClass "Autodesk.Max.GlobalInterface").Instance.TheMxsEditorInterface.EditorGetMainHWND

	local tabs = for w in windows.getChildrenHWND hwnd where w[4] == "SysTabControl32" collect w[1]
	local index = windows.sendMessage tabs[1] (TCM_GETCURSEL = 0x130B) 0 0

	windows.sendMessage hwnd 0xB 0 0

	windows.sendmessage hwnd 0x111 462 0
	windows.sendmessage hwnd 0x111 106 0
	windows.sendmessage hwnd 0x111 105 0

	windows.sendMessage hwnd 0xB 1 0
	windows.sendMessage hwnd 0x111 (0x104B0 + index) 0 -- switch to n-th tab 
)

ReloadMXSEditorProperties()