Community
    • Login

    Hi and I'm working on a WPF fork of NppCSharpPluginPack

    Scheduled Pinned Locked Moved Notepad++ & Plugin Development
    18 Posts 5 Posters 1.3k Views
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • Jonathan JohansenJ
      Jonathan Johansen
      last edited by

      Hi! I’ve been loving Notepad++ for years, as expected ;-). I’m a WPF developer by day, so I was wanting to make a plugin with it (to evaluate Common Lisp code from files - so maybe you can push me to alternatives that might do that). But before going straight in, I’ve started trying to migrate Mark Olson’s cool NppCSharpPluginPack (thanks Mark for it!) to WPF to get a feel for if it was feasible. I see WPF isn’t mentioned much in the forum,

      I’ve just been messing around, but I’ve got a few of the UI’s migrated, but I’m fighting to get keyboard input into TextBoxes when in a docked UI. I can paste in text, and KeyDown events fire, but no text gets inserted.

      So this post is to see what you knowledgeable people think about the idea, alternatives, and if anyone else is interested in bashing heads with me on WPF in a plugin.

      I’ll fork Mark’s repo and replay my changes (I should have started that way…) in the next week or so - but if that’s too long, let me know. Will post the repo in a reply here when done.

      Thanks!
      Jonathan Johansen
      www.carelinks.net

      Mark OlsonM pbarneyP 2 Replies Last reply Reply Quote 1
      • Mark OlsonM
        Mark Olson @Jonathan Johansen
        last edited by Mark Olson

        @Jonathan-Johansen

        Hi, I’m the maintainer of NppCSharpPluginPack. Glad to hear you’re interested in creating a new variant with WPF, and I hope you’re able to make something you’re happy with.

        I don’t know anything about WPF, but I do know that forms (especially docking forms) in a Notepad++ plugin have to do a bunch of annoying fiddly things to ensure that they work correctly. I recommend reading carefully through NppFormHelper.cs and FormBase.cs, because they contain a few methods that you need to create WPF versions of to ensure your forms work correctly.

        More specifically, I’m guessing that your keyboard input problem is due to not registering your form with NPPM_MODELESSDIALOG.

        Jonathan JohansenJ 1 Reply Last reply Reply Quote 2
        • Jonathan JohansenJ
          Jonathan Johansen @Mark Olson
          last edited by

          @Mark-Olson Thanks! I have been migrating your code in-place, and I do get the ElementHost’s handle and pass it to Npp.notepad.AddModelessDialog(handle);. I will read through thoroughly - I’m also thinking to check something diagnostic like Spy++?

          Jonathan JohansenJ 1 Reply Last reply Reply Quote 0
          • Jonathan JohansenJ
            Jonathan Johansen @Jonathan Johansen
            last edited by Jonathan Johansen

            Oh, it’s interesting - When I don’t call Npp.notepad.AddModelessDialog(host.Handle);, I can type into the TextBox, but I can’t copy/paste with Ctrl+C/Ctrl+V. When I do call Npp.notepad.AddModelessDialog(host.Handle);, I can’t type in, but I can copy/paste with Ctrl+C/Ctrl+V. Curious.

            Mark OlsonM 1 Reply Last reply Reply Quote 0
            • Jonathan JohansenJ
              Jonathan Johansen
              last edited by

              The fork is here: https://github.com/framlingham/NppCSharpPluginPack#

              1 Reply Last reply Reply Quote 0
              • Mark OlsonM
                Mark Olson @Jonathan Johansen
                last edited by

                @Jonathan-Johansen said in Hi and I'm working on a WPF fork of NppCSharpPluginPack:

                Oh, it’s interesting - When I don’t call Npp.notepad.AddModelessDialog(host.Handle);, I can type into the TextBox, but I can’t copy/paste with Ctrl+C/Ctrl+V. When I do call Npp.notepad.AddModelessDialog(host.Handle);, I can’t type in, but I can copy/paste with Ctrl+C/Ctrl+V. Curious.

                OK, that’s really weird. I’ve never had any problem like that before. @rdipardo is kind of a wizard when it comes to the low-level operation of forms; I’m mentioning him in the hopes that he will be able to give you some advice.

                rdipardoR 1 Reply Last reply Reply Quote 1
                • pbarneyP
                  pbarney @Jonathan Johansen
                  last edited by

                  @Jonathan-Johansen What is the benefit of using WPF instead of what we already have?

                  Jonathan JohansenJ 1 Reply Last reply Reply Quote 1
                  • rdipardoR
                    rdipardo @Mark Olson
                    last edited by

                    @Mark-Olson said in Hi and I'm working on a WPF fork of NppCSharpPluginPack:

                    @rdipardo is kind of a wizard when it comes to the low-level operation of forms

                    I’m also unfamiliar with WPF, but I can suggest to @Jonathan-Johansen that hosting the docking form on a WindowsFormsHost might be a better approach. That would at least provide access to a Win32-style window procedure, useful for debugging how (of if) the WM_CHAR message is being handled.

                    Alternatively, try to expose the window handle of the existing WPF UserControl and pass that to the NPPM_MODELESSDIALOG wrapper instead of the ElementHost (as was tried already ). Or maybe there’s a way for WPF controls to broadcast messages to their child components…🤔?

                    Jonathan JohansenJ 1 Reply Last reply Reply Quote 1
                    • Jonathan JohansenJ
                      Jonathan Johansen @pbarney
                      last edited by

                      @pbarney The benefit of using WPF is that (in my opinion):

                      • I like WPF and have 6 years experience in it, but no experience with WinForms.
                      • It provides strong layout options (e.g. Grid)
                      • It provides flexible data binding
                      • It provides Styles.

                      Some links from others.

                      pbarneyP 1 Reply Last reply Reply Quote 1
                      • Jonathan JohansenJ
                        Jonathan Johansen @rdipardo
                        last edited by

                        @rdipardo Thanks for the suggestions! WPF doesn’t have handles for controls like WinForms, and WindowsFormsHost would do the opposite of ElementHost. Thankfully, ElementHost lets you override the WndProc method (which I do here), so I’ll poke around in there for a bit.

                        Jonathan JohansenJ 1 Reply Last reply Reply Quote 0
                        • Jonathan JohansenJ
                          Jonathan Johansen @Jonathan Johansen
                          last edited by

                          Update: when I inspect the WndProc messages that come through $"{m.Msg} {m.WParam} {m.LParam}", I note these (mostly tangential, but I’d like to document them):

                          • Pressing ‘normal’ keys (e.g. a-z, arrows, 0-9, punctuation) does not send a message to the ElementHostEx, but instead (after I turned the volume up on my laptop), it somehow triggers a bell sound.
                          • Mouse click comes through with 528 513 36634781 and 33 723656 33619969
                          • Switching to another program sends 8 0 0, and switching back to NPP sends 1024 0 0
                          • Pasting into the TextBox works, but does not trigger any messages. Similarly for copying, deleting and backspacing.
                          • Opening the WPF About window sent 8 1116900 0

                          I’d like to convert the msg id to a string, I’m not familiar with their values. But there still aren’t that many messages, so perhaps I haven’t set up the dock panel correctly. I’ll try the same thing in the existing Forms version and see what comes up for comparison.

                          Jonathan JohansenJ 1 Reply Last reply Reply Quote 0
                          • pbarneyP
                            pbarney @Jonathan Johansen
                            last edited by

                            @Jonathan-Johansen Thanks for the clarification. I don’t develop Windows apps, so I just didn’t know what the two were. After looking at it, it seems that WinForms is more imperative and tightly coupled and WPF is more declarative and modular.

                            Jonathan JohansenJ 1 Reply Last reply Reply Quote 1
                            • Jonathan JohansenJ
                              Jonathan Johansen @pbarney
                              last edited by

                              @pbarney no worries. I think your assessment is probably accurate, but of course you can do amazing things in both.

                              1 Reply Last reply Reply Quote 0
                              • Jonathan JohansenJ
                                Jonathan Johansen @Jonathan Johansen
                                last edited by

                                Another update: After trying lots of things, running Spy++, Copilot suggested putting a Form around the ElementHost, and I’ve now got (when calling NppFormHelper.RegisterFormIfModeless) it doing something when I press a key, but I don’t think it’s that helpful - For every key press, I get many (>100) and only:

                                • 13 = 0xD = WM_GETTEXT WParam is always 256 and LParam is always 737269504944
                                • 135 = 0x87 = WM_GETDLGCODE WParam and LParam are always 0 for these.

                                I found this page about windows message IDs, which was nice, but then I saw that Visual Studio has some special debugging ToString on System.Windows.Forms.Message` that tells you what the ID means when you mouse over during debugging. Nice. But anyway, still no key-specific events / messages.

                                Well, because keyboard typing works when I don’t send NPPM_MODELESSDIALOG, but cut/paste/delete works when I do, I’m thinking to look at what the message [2036] NPPM_MODELESSDIALOG does internally, to see if I can combine the good sides of both modes for a WPF version.

                                CoisesC 1 Reply Last reply Reply Quote 2
                                • CoisesC
                                  Coises @Jonathan Johansen
                                  last edited by

                                  @Jonathan-Johansen said in Hi and I'm working on a WPF fork of NppCSharpPluginPack:

                                  look at what the message [2036] NPPM_MODELESSDIALOG does internally

                                  Puts the window handle of the dialog on a list of window handles which are passed, in turn, to IsDialogMessage in the message loop. If that function returns true, no further message processing is done. If all calls return false, the message is passed to TranslateAccelerator, and if that returns false the message is translated and dispatched normally.

                                  Jonathan JohansenJ 1 Reply Last reply Reply Quote 2
                                  • Jonathan JohansenJ
                                    Jonathan Johansen @Coises
                                    last edited by

                                    @Coises thanks! Sounds like I won’t find the answer there. And I looked up WM_GETDLGCODE out of curiosity and figured it may help, then eventually found this SO question from 16 years ago, and will investigate fixing this way. It seems to be a pretty close fit for the issue here!

                                    Jonathan JohansenJ 1 Reply Last reply Reply Quote 0
                                    • Jonathan JohansenJ
                                      Jonathan Johansen @Jonathan Johansen
                                      last edited by

                                      And it works now! The latest push has enabled it. I cleared out the MSG logging display because it happily lets me type now. Thanks for all your help and input guys! I’ll let you guys know how it all comes together :)

                                      1 Reply Last reply Reply Quote 0
                                      • Jonathan JohansenJ
                                        Jonathan Johansen
                                        last edited by

                                        I figure I’d better document the solution(s) for others that may tread this path. A summary of some of the steps needed (of course built on top of Mark’s work!):

                                        1. Ensure you register your modeless dialog with NPP (NPPM_MODELESSDIALOG, in Main.cs we call NppFormHelper.RegisterFormIfModeless(Form, bool))
                                        2. The WPF System.Windows.Controls.UserControl should be in an System.Windows.Forms.Integration.ElementHost, which is in a System.Windows.Forms.Form.
                                        3. I’ve subclassed the ElementHost to handle WM_SHOWWINDOW to update the Visible property, and to trigger a (slightly delayed) refresh of the visuals when we get a WM_SIZE. There I invalidate the visuals and update layouts. There may be a way to skip this, but it’s working, so I’m not trying to fix it.
                                        4. In the WPF UserControl, when it’s Loaded, we have to get the presentation source (as a HwndSource) and add a hook to respond to the WM_GETDLGCODE and tell the source that we DLGC_WANTCHARS and DLGC_WANTARROWS, and maybe we also need DLGC_HASSETSEL.

                                        I’ve pulled most of it into a method called MakeModelessDialog. And now for a short recording of it working!

                                        2025-06-28 Typing in Notepad++ modeless WPF dialog works.gif

                                        1 Reply Last reply Reply Quote 2
                                        • First post
                                          Last post
                                        The Community of users of the Notepad++ text editor.
                                        Powered by NodeBB | Contributors