Thank you for your creative discussion. I successfully achieved the desired effect
edit your MXS_EditorUser.properties, check and add style, I used a dark theme. This color may not be suitable for you
- Keywords14 - structure and FPS properties
- style.MAXScript.25=fore:#FFFF00,back:#3A52D8
This is my modified code. After execution, you can double-click the keyword to highlight it automatically.
(
local owner
struct mxse_struct
(
doc = "",
keywords = #("about","and","animate","as","at","attributes","by","case","catch","collect","continue","coordsys","do","else","exit","fn","for","from","function","global","if","in","local","macroscript","mapped","max","not","of","off","on","or","parameters","persistent","plugin","rcmenu","return","rollout","set","struct","then","throw","to","tool","try","undo","utility","when","where","while","with"),
ignore = keywords + #("(", ")", "[", "]", "{", "}", "#", "$", "%", ".", ":", "\"", "\'", "_", "==", "`", "=", "+", "-", ">", "<", "*", "/", "\\", "@", "^", "&", ";", ",", ":"), --排除
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:25 =
(
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:false =
(
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 then
(
query = (dotNetObject "System.String" query).Trim()
query = (dotNetObject "System.String" query).Replace "\n" ""
query = (dotNetObject "System.String" query).Replace "\t" ""
query = (dotNetObject "System.String" query).Replace "\r" ""
if findItem ignore query == 0 do HighlightText query reload:false
)else
(
ResetDocumentStyle()
)
),
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 =
(
(windows.sendmessage currentlyOpenTab (SCI_GETLEXER = 4002) 0 0) == 81
),
on create do owner = this
)
global mxse = mxse_struct()
ok
)
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 =
(
::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 0x202 --侦听鼠标左键单击 WM_LBUTTONUP 0x202 WM_LBUTTONDOWN 0x201
format "started...\n"
)