How To ... Insert Text in MXS Editor?


#1

open the editor, set cursor to any place (or select some text), and run the code:


fn myAssembly =
(
	source = ""
	source += "using System;
"
	source += "using System.Runtime.InteropServices;
"
	source += "public class MyOps
"
	source += "{
"
	source += "	[DllImport(\"user32.dll\")]
"
	source += "	public static extern int SendMessage(Int32 hWnd, int wMsg, int wParam, [MarshalAs(UnmanagedType.LPStr)] string lParam);
"
	source += "}
"

	csharpProvider = dotnetobject "Microsoft.CSharp.CSharpCodeProvider"
	compilerParams = dotnetobject "System.CodeDom.Compiler.CompilerParameters"

	compilerParams.ReferencedAssemblies.Add "System.dll"

	compilerParams.GenerateInMemory = on
	compilerResults = csharpProvider.CompileAssemblyFromSource compilerParams #(source)
		
	(compilerResults.CompiledAssembly).CreateInstance "MyOps"
)
global ops = if ops == undefined then myAssembly() else ops

(	
	fn _mxs_Textbox = 
	(
		tb = for c in (windows.getchildrenhwnd 0) where c[4] == "MXS_SciTEWindow" do exit with
		(
			for t in (windows.getchildrenhwnd c[1]) where t[4] == "MXS_Scintilla" do exit with t[1]
		)
		if tb != ok then tb else undefined
	)
	
	if (tb = _mxs_Textbox()) != undefined do
	(
		 EM_REPLACESEL = 0xC2
		
		any_text = "\"Hello World!\""
		
		-- Insert Text or Replace Selection:
		ops.SendMessage tb EM_REPLACESEL 1 any_text -- 1 means to make it undoable
	)
)

PS. I didn’t clean it up! Use at your own risk!


#2

this is awesome! :bowdown:


#3

Denis, you are the man!!


#4

do you also have code on how to open maxscript files in the editor using maxscript?

thanks this is very helpful :slight_smile:


#5

see mxs help -> edit()

The MAXScript Legacy Editor Windows[left]You can open a MAXScript Editor window from within the Listener or from other running scripts by calling the edit() method. The syntax for the edit() method is:
[/left]
[left]edit <filename_string>
[/left]
[left]where <filename_string> is a string literal or an expression that evaluates to a string, and specifies the name of the file whose contents are to be loaded into the new MAXScript Editor window.
[/left]


#6

Hi Denis,

I have a function that looks for a word inside an ms file and I want to be able to open the ms file and jump to that word.
Is it possible?

Cheers,
Matan.


#7

to catch event when MXS editor opens some file is not easy, but if you are OK with the loading a file with you own script it’s possible to open and jump to some word position in the text.


#8

yes this would be great.
I will open the script myself and I want to jump to a given position in it when it opens.


#9

global Win32Assembly
fn CreateWin32Assembly forceRecompile:on =
(
	if forceRecompile or not iskindof ::Win32Assembly dotnetobject or (::Win32Assembly.GetType()).name != "Assembly" do
	(
		source = "using System;
"
		source += "using System.Runtime.InteropServices;
"
		source += "using System.Text;
"
		source += "class Win32
"
		source += "{
"
		source += "		[DllImport(\"user32\", CharSet = CharSet.Auto, SetLastError = true)]
"
		source += "		public static extern Int32 SetFocus(Int32 hWnd);
"
		source += "		[DllImport(\"user32\", CharSet = CharSet.Auto, SetLastError = true)]
"
		source += "		internal static extern int GetWindowTextLength(Int32 hWnd);
"
		source += "		[DllImport(\"user32\", CharSet = CharSet.Auto, SetLastError = true)]
"
		source += "		internal static extern int GetWindowText(Int32 hWnd, [Out, MarshalAs(UnmanagedType.LPTStr)] StringBuilder lpString, int nMaxCount);
"
		source += "		public static string GetWindowText(Int32 hWnd)
"
		source += "		{
"
		source += "			int length = GetWindowTextLength(hWnd);
"
		source += "			StringBuilder sb = new StringBuilder(length + 1);
"
		source += "			GetWindowText(hWnd, sb, sb.Capacity);
"
		source += "			return sb.ToString();
"
		source += "		}
"
		source += "}
"

		csharpProvider = dotnetobject "Microsoft.CSharp.CSharpCodeProvider"
		compilerParams = dotnetobject "System.CodeDom.Compiler.CompilerParameters"

		compilerParams.ReferencedAssemblies.Add "System.dll"
		compilerParams.ReferencedAssemblies.Add "System.Drawing.dll"

		compilerParams.GenerateInMemory = true
		compilerResults = csharpProvider.CompileAssemblyFromSource compilerParams #(source)
		
		Win32Assembly = compilerResults.CompiledAssembly
		Win32Assembly.CreateInstance "Win32"
	)
)
global Win32 = CreateWin32Assembly()

fn findText word =
(
	EM_SETSEL = 0x00B1
	
	fn _mxs_Textbox = 
	(
		tb = for c in (windows.getchildrenhwnd 0) where c[4] == "MXS_SciTEWindow" do exit with
		(
			for t in (windows.getchildrenhwnd c[1]) where t[4] == "MXS_Scintilla" do exit with t[1]
		)
		if tb != ok then tb else undefined
	)
	tb = _mxs_Textbox()
	
	tx = Win32.GetWindowText tb
	if (k = findString tx word) != undefined do
	(
		windows.sendmessage tb EM_SETSEL (k-1) (k+word.count-1)
		Win32.SetFocus tb
	)
)
/*
findText "word"
*/

here is it…


#10

wow that was quick :eek:
I will give it a try tomorrow at work

thanks!


#11

Thanks Denis!
Your function worked perfectly.
I had only one issue with it though.
What I was doing was to use “edit <script.ms>”
and then to call your function to jump to the right pos.

If the script was already opened and focused, then it was working perfect
but if it wasn’t, then the “edit” command opened the file and gave it focus,
but it looks as if it would do that only after the whole script finish to evaluate.
That’s why the word didn’t get selected.

I was able to avoid this by creating a temp dialog and use a timer to trigger an event handler
a couple of milliseconds after this dialog opens, that will call your jump function.
That way I get a gap between the time I call the edit function and the time I call your function, that mxs doesn’t do anything. In that time the new script tab opens and gets focus and everything works perfect.

As you can see this is a bit messy, so my next and probably the final question would be -
How can I do this in a more elegant way?


#12

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.