Learn how easy it is to sync an existing GitHub or Google Code repo to a SourceForge project! See Demo

Close

How to get key events in np++ plugins?

Sid
2013-03-02
2013-03-03
  • Sid
    Sid
    2013-03-02

    Thanks for viewing my post.

    I am working on a small auto-complete-like plugins for notepad++. (the build-in one is not good enough)
    And tried to capture the ESC key, arrow keys and Ctrl+C hotkey with SCN_KEY, but finally found this event is not being sent for windows version of Scintilla.
    After looking through the header files, I'm desparated for a solution.

    And, btw, how to get notified when the np++ window is clicked?
    I want to hide the auto-complete window on such event.
    Since it's not the active window all along (it should not interrupt user input when shown), I can't use WM_ACTIVATE to detect this event.

    Anybody help?

     
  • You can probably only do this by subclassing N++, which is not really recommended (several plugins do it though). Have you looked at Scintilla User-Lists? They're more flexible than the autocomplete, and may avoid you having to write all the key handling code.

    Dave.

     
  • Several plugins use subclassing? I have not looked at how they do it, but with standard sublassing, you will probably have to compile a new version of the plugin for every version of N++, and I would not personally do that.

    If you want your plugin to be activated on some keys, the normal way to do it is with "shortcut mapper". You can map ESC, arrow keys and Ctrl+C with it, if you ensure they are not mapped to something else (Ctrl+C is mapped by default to SCI_COPY). Of course, your plugin should map back the arrows to Scintilla messages so they still work.

    Maybe I should not propose such solutions, but if you really need to hook messages sent to Scintilla, it is possible to patch ScintillaWin::WndProc in the vtable (quite complicated since the index will change in different versions of Scintilla) or patch the wndproc pointer of the window (you must also really know what you are doing; easier, but you will not hook messages sent through the DirectFunction). Of course, try more standard methods before trying this...

     
  • Several plugins use subclassing? I have not looked at how they do it, but with standard
    sublassing, you will probably have to compile a new version of the plugin for every
    version of N++, and I would not personally do that.

    Not true. I'm talking about subclassing the Window, not the native classes in C++. You subclass the window with SetWindowLongPtr(...), and you get the messages first, process / weed out the ones you're interested in and you don't want N++ to handle, and pass the rest on to N++. As long as it's done right, it works with every version. It's also much safer than trying to patch the vtable or other such dirty tricks - N++ sends almost all (I think) messages to Scintilla via the DirectFunction, so subclassing Scintilla isn't going to help much.

    I'd use the shortcut mapper as François suggested if you can, if not, use SetWindowLongPtr to subclass the N++ window handle, and put it back nicely when you're done (or on shutdown).

    Dave.

     
  • Sid
    Sid
    2013-03-03

    Thanks for all your replies.

    Actually I'm on the track of subclassing the np++ window, and still trying to find out a more "elegant" solution.
    But it looks like subclassing is the best I can do.

    Thanks.

     
  • To subclass a window more cleanly, you should probably use SetWindowSubclass instead of SetWindowLongPtr, otherwise you should never restore the original wndproc (if more than one plugin is subclassing, with SetWindowLongPtr, restoring the original wndproc might remove other subclassing at the same time, without them knowing about it).

    If several plugins are using this, maybe N++ should provide an API for hooking messages, and a way to configure plugin hook order.