Macro Recording?

Apr 10, 2012 at 11:25 AM

Hi, I was wondering if anyone's been able to make Macro Recording work - it says on the homepage that it is working, but I can't seem to find any new documentation or discussions about it (other than the ones which are years old). Is there any example code which shows how to implement macro recording? Thanks!


Apr 22, 2012 at 6:13 AM

I know this sounds crazy--being that I'm a ScintillaNET developer--but I've never actually used the macro recording and so you'll have to report back to me and tell me if it works.

Basically the idea is that the INativeScintilla.StartRecord and INativeScintilla.StopRecord enable and disable the firing of the Scintilla.MacroRecord (or INativeScintilla.MacroRecord) event(s).

It's the responsibility of the user (you) to record those transmissions. Once stored you can 'playback' the recorded macros by sending the msg, wParam, and lParam back to Scintilla through the INativeScintilla.SendMessageDirect method.



Jun 11, 2012 at 8:45 PM

But when you listen to the MacroRecord event, there are just incoming messages like:
msg=0x204e (WM_REFLECT + WM_NOTIFY) hwnd=0x371504 wparam=0x371504 lparam=0x36e18c result=0x0

And it makes no difference which key i press. It looks always the same. So... What do I need to do, to record the messages which I can send later to Scintilla to repeat some keypresses etc. Because - as I understand it - I need to tell Scintilla what it needs to do, but when the recorded messages always are the same, how does it know what it needs to do? Because when I press the "e" key, it is the same message as when I would press the "l" key.


I hope you can help me.

Jun 14, 2012 at 4:37 PM

So you're saying every message is exactly the same? The msg, wparam, and lparam properties?


Jun 14, 2012 at 7:32 PM

Jap. Thats it. No i found a workaroung. I listened to the "ProcessKeyMessage" void, and send save then all the incoming messages. Maybe that is not the way it should be done, but at least it works.

Jan 15, 2013 at 1:12 PM

Hi all,

I'm having trouble with Macros as well - I'm thinking it must be something silly, because everything else I've looked at so far with ScintillNet has been a breeze :)

When I called INativeScintilla.StartRecord() and pressed LeftArrow, then my MacroRecordEventArgs contains 'msg=8270  lparam=0  wparam=0'
I was expecting 'msg=2304  lparam=0  wparam=0', as 2304 is defined in Scintilla.h as SCI_CHARLEFT., and there is nothing defined as 8270.
Sure enough if I call ((INativeScintilla)this).SendMessageDirect(SCI_CHARLEFT   ,  0, 0 ); then the caret moves left one space. Nothing happens if I send 8270.

If I press any character, I always get 'msg=8270  lparam=67233200  wparam=0' - I'm already thinking that the 8270 is wrong, but what does lparam represent? - it kind of looks like a pointer that needs marshaling?

Also, when I come playback the macro by calling SendMessageDirect(), do I need to wrap up whatever lparam was pointing to in a new SCNotification to marshal back?


I rather suspect I'm going about this the wrong way, so If anyone has actually got macros working, any chance you can post some code examples? Actually any help at all would be really appreciated :)




Jan 15, 2013 at 3:17 PM

ok, I think I've sorted it.

I bit the bullet and edited/rebuilt the scintillaNet source,

MacroRecordEventArgs.cs :

        public MacroRecordEventArgs(NativeScintillaEventArgs ea)
            _recordedMessage = ea.Msg;
            _recordedMessage.Msg    = ea.SCNotification.message;    //   <-- added this line
            _recordedMessage.LParam = ea.SCNotification.lParam;
            _recordedMessage.WParam = ea.SCNotification.wParam;


then in my MacroRecord event handler I marshal lparam as if it's a char*

string lparamStr = Marshal.PtrToStringAnsi(arg.RecordedMessage.LParam);

so: (uint)arg.RecordedMessage.Msg and lparamStr are what I need to save for playback later.


to play back i do:

                IntPtr sNative = Marshal.StringToHGlobalAuto(mmes.LParamStr);
                ((INativeScintilla)this).SendMessageDirect((UInt32)mmes.Msg, mmes.WParam, sNative.ToInt32());

where mmes is defined as

        private class MacroKeyStrokeMessage
            public UInt32 Msg       {get; private set;}
            public string LParamStr {get; private set;}
            public Int32  WParam    {get; private set;}
            public MacroKeyStrokeMessage(UInt32 msg, string lparamStr, Int32 wparam)
                this.Msg    = msg;
                this.LParamStr = lparamStr;
                this.WParam = wparam;


This certainly appears to work, BUT, is this what is supposed to happen? and if so do I need to file a bug ?