• Login
Community
  • Login

My first plugin development: CollectionInterface [was: Need help with getting started using C++ Plugin Template]

Scheduled Pinned Locked Moved Notepad++ & Plugin Development
67 Posts 8 Posters 2.5k 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.
  • A
    Alan Kilborn @Coises
    last edited by Feb 26, 2025, 11:47 AM

    @Coises said:

    Every time I think, “Maybe that should just be a plugin of its own,” I shudder at the housekeeping needed to start one. I plan for this to end up as a Visual Studio template that will appear in the “Create a new project” list. (I have that working, but I haven’t updated it with the many changes I’ve already made to the code, so I just made a zip of the trial project that I’ll eventually turn back into a template.)

    This sounds like a great idea. Others have had a similar idea but I don’t know that anyone has ever taken it so far as to produce a really solid “this IS the C++ plugin template” to use.

    Perhaps a collaborative effort with @ThosRTanner (another with a better-plugin-template idea; see HERE ) would be in order.

    1 Reply Last reply Reply Quote 1
    • C
      Coises @Alan Kilborn
      last edited by Feb 26, 2025, 4:33 PM

      @Alan-Kilborn said in Need help with getting started using C++ Plugin Template:

      @Coises said:

      Under Build Events, select Post-Build Event

      Regarding this approach, it surprises me that it works, because that file is going to be a different file from the one the IDE knows about. When the plugin is “run” under the debugger, the IDE runs Notepad++ (due to the other setup step), but I’d think when it loads the DLL file (copy!), it wouldn’t hit any breakpoints because it would be “keying on” the DLL file (and supporting debug data) it built into the plugin’s Debug folder, not some solitary copy of the file elsewhere in the file system.

      As I understand it, there is a GUID in compiled modules. When you run the debugger within the project, it has the locations of the source and symbol files. Upon loading a module (exe or dll) the debugger looks to see if it has a symbol file (pdb) for that module name and then checks that the GUIDs match. It doesn’t care from where the module was loaded.

      I didn’t figure out that this would work, though… I copied it from somewhere else, I just don’t remember where.

      I did make a mistake and an omission in what I wrote earlier (to @PeterJones). %ProgramFiles% works in the Post-Build Event command, but for some reason you have to spell out the actual path in the Debugging command. And to use the automatic copying into Program Files, you have to change the permissions on the Plugins folder so that privilege elevation isn’t required to modify it — OK on a personal development machine, not so good on a shared machine.

      P 1 Reply Last reply Feb 26, 2025, 5:04 PM Reply Quote 1
      • P
        PeterJones @Coises
        last edited by PeterJones Feb 26, 2025, 5:04 PM Feb 26, 2025, 5:04 PM

        @Coises ,

        I did make a mistake and an omission in what I wrote earlier (to @PeterJones). %ProgramFiles% works in the Post-Build Event command, but for some reason you have to spell out the actual path in the Debugging command.

        I actually figured that out. $(ProgramFiles) works for the Debugging Command –

        for some reason

        I think the difference is that Post-Build Event is essentially a cmd.exe script, whereas the Debugging Command goes through VS variable substitution then gets sent to something akin to ShellExecute, probably without a cmd.exe wrapper, so it doesn’t know cmd environment variable syntax.

        And to use the automatic copying into Program Files, you have to change the permissions on the Plugins folder so that privilege elevation isn’t required to modify it —

        Yeah, that “permissions” bit me at first, trying it that way.

        I switched over to @Alan-Kilborn’s symbolic link-- but if I do both the mkdir and the mklink, the mklink complains; doing the mklink from the plugins\ directory without doing the mkdir first works to make the psuedo-directory for the plugin.

        OK on a personal development machine, not so good on a shared machine.

        Interesting to note: the DebuggerCommand seems to be stored in blah.vcxproj.user whereas the PostBuildEvent gets stored in blah.vcxproj (at least in my experiments)… so when multiple people are developing in the same project, but one needs to run $(ProgramFiles)\notepad++\notepad++.exe but the other needs to run c:\path\to\portable\notepad++.exe, the DebuggerCommand can be separate for the two developers. OTOH, if the DLL gets copied to a fixed location in DebuggerCommand, that will try to do the same copy for both users, which wouldn’t work. Having each developer just create the symbolic link from the appropriate plugins\ directory pointing to their local <arch>\Debug directory with the appropriate DLL and meta-information seems to make good logical sense to me

        A 1 Reply Last reply Feb 26, 2025, 5:35 PM Reply Quote 0
        • X
          xomx @Alan Kilborn
          last edited by Feb 26, 2025, 5:06 PM

          @Alan-Kilborn said in Need help with getting started using C++ Plugin Template:

          , it surprises me that it works, because that file is going to be a different file from the one the IDE knows about.

          @Coises is right. There is a PDB (debug symbols file, which binds together the source code and its binary) location info inside the binary PE-header. It’s not a GUID but simply an original path to the PDB-file. A sample of that info from my custom PythonScript plugin:

          PE-PDB-info.png

          A 1 Reply Last reply Feb 26, 2025, 5:32 PM Reply Quote 2
          • A
            Alan Kilborn @xomx
            last edited by Alan Kilborn Feb 26, 2025, 5:33 PM Feb 26, 2025, 5:32 PM

            @xomx said in Need help with getting started using C++ Plugin Template:

            simply an original path to the PDB-file

            Ah, so as long as that file stays where it is, the project can be “debugged” from the IDE no matter where the DLL is located. Ok, well, thanks for filling in that little nugget of seemingly missing info!

            …from my custom PythonScript plugin

            Oooh. What kind of customizations? :-)

            X 1 Reply Last reply Feb 26, 2025, 11:27 PM Reply Quote 0
            • A
              Alan Kilborn @PeterJones
              last edited by Feb 26, 2025, 5:35 PM

              @PeterJones said in Need help with getting started using C++ Plugin Template:

              but if I do both the mkdir and the mklink, the mklink complains; doing the mklink from the plugins\ directory without doing the mkdir first works to make the psuedo-directory for the plugin.

              Ah, sorry about that detail; I was going from some old notes I had rather than actually trying it out. :-(
              Good that you got it working, though.

              1 Reply Last reply Reply Quote 0
              • X
                xomx @Alan Kilborn
                last edited by Feb 26, 2025, 11:27 PM

                @Alan-Kilborn said in Need help with getting started using C++ Plugin Template:

                from my custom PythonScript plugin
                

                Oooh. What kind of customizations? :-)

                Sorry, no new functionality if you expected so - that was just a slightly debugging enhanced version for fixing the PS-console not showing bug after N++ relaunching.

                1 Reply Last reply Reply Quote 0
                • T
                  ThosRTanner @PeterJones
                  last edited by ThosRTanner Mar 7, 2025, 11:54 PM Mar 7, 2025, 11:52 PM

                  @PeterJones as far as building goes, I’ve never had any problems building notepad++ i normal mode and my dll in debug mode. However, it’s a littel tricky getting n++ to recognise your dll. You have to either hijack another plugin’s directory, or go to plugin admin mode and point it to a zip file you’ve built.

                  Some instructions on installing a plugin manually (pretty sure you wrote them) are here: https://github.com/ThosRTanner/notepad-pp-linter/blob/master/README.md

                  But to build it, you’ll need to add a post build step - see https://github.com/ThosRTanner/notepad-pp-linter/blob/master/post-build.ps1 or https://github.com/ThosRTanner/Docking_Dialogue_Interface/blob/master/post-build.ps1 for examples on that.

                  You also need to customise the debug command to point to the actual notepad++ exe (doesn’t need the debug version) - then the debugger loads up notepad+ and will hit the breakpoints in your dll

                  1 Reply Last reply Reply Quote 0
                  • P
                    PeterJones
                    last edited by PeterJones Apr 3, 2025, 7:16 PM Apr 3, 2025, 7:08 PM

                    I’ve been making “good” progress on this plugin. (Or, at least, good for me, considering I have never written a real plugin before.)

                    I stuck with the original template for this plugin, since I’d already started, but I will be trying out @Coises’s VS Template for my next. Though I still maintain that Don’s grandmom is brilliant.

                    This plugin will be facilitating downloading the UDL, FunctionList definition, and AutoCompletion definitions from the UDL Collection, and themes from the Themes collection.

                    021ae604-3454-40ce-8030-fee6ca66dc6c-image.png

                    I am not a GUI designer, and my first idea for the interface isn’t always the best for most users, so I’d like to as a UI/UX opinion question of the readers here:

                    If the plugin has a dialog which will enable you to download a file with a DOWNLOAD button, but the user might want to do more than one dialog in a row (for example, if you want to grab a UDL file and then its FL), would you prefer:

                    1. After hitting DOWNLOAD for the first file, the dialog closes itself, so you have to re-run the Plugin command to get the next file
                    2. After hitting DOWNLOAD for the first file, when it’s done, it pops up a MessageBox to inform you it’s done, and you can go immediately get another file from the same dialog
                    3. After hitting DOWNLOAD for the first file, when it’s done, it changes a status bar on that dialog to indicate that it’s complete
                    4. Other ideas (the less complicated, the better)

                    I was originally planning on #2, but am starting to wonder if #3 is better. #1 was added to the options for completeness – though if that’s your preference, I’ll probably need an example of how to initialize/create a dialog once, but then hide it instead of closing it so that it can be reshown without being re-created. And I added #4 in case you want to make an alternative suggestion, even though I don’t guarantee that I’ll be able to implement the idea if it’s much more complicated than the current GUI design.


                    alpha testing

                    For those interested in alpha testing, the copy at https://github.com/pryrt/NppPlugin-CollectionInterface should now have all features implemented, though it definitely needs error handling improvements (right now, it will throw uncaught exceptions)

                    C Lycan ThropeL 4 Replies Last reply Apr 3, 2025, 7:39 PM Reply Quote 1
                    • C
                      Coises @PeterJones
                      last edited by Coises Apr 3, 2025, 7:39 PM Apr 3, 2025, 7:39 PM

                      @PeterJones said in Need help with getting started using C++ Plugin Template:

                      If the plugin has a dialog which will enable you to download a file with a DOWNLOAD button, but the user might want to do more than one dialog in a row (for example, if you want to grab a UDL file and then its FL)

                      Consider using a List Box or a List View instead of a Combo Box. If you make it multi-selection, the user can highlight everything wanted at once and then click a button to download and relaunch. (That would be similar to the Plugins Admin… though I would not recommend putting the Install button at the top!)

                      Drop-downs can be annoying when you’re trying to select from a long list. They save space, but when there’s nothing much else in the dialog, you could display enough items at once in a List Box to make it easier for a user to scroll through, even if you make it single selection.

                      I’m pretty sure List Box is no more complex to use than Combo Box (aside from processing multiple selections, if you allow that). I don’t recall using a List View, but it does look like a bit more work.

                      1 Reply Last reply Reply Quote 1
                      • Lycan ThropeL
                        Lycan Thrope @PeterJones
                        last edited by Lycan Thrope Apr 3, 2025, 8:32 PM Apr 3, 2025, 8:21 PM

                        @PeterJones ,
                        This is kind of unfair, as you’ve already seen my clunky interface for the dBASE UDL installer. :-)

                        That aside, considering that, like the dBASE UDL, it’s really considered a package if you have all those files for the same language so it would make sense that the user should just pick the UDL they want to download, and your plugin would pick all the files needed for that package. This, of course, would be dependent on your application being aware of the files needed for it…and my guess is that since you’re trying to set it up to pull from the UDL repository, it would make sense that the repository have some kind of mechanism for the plugin to be able to read that mechanism’s connection of the different files for that language and be able to use that to collect all the relevant files for download at once.

                        Just my input, as it would seem to really simplify the process of getting UDL languages installed into Notepad++, so folks like me wouldn’t have to write their own installers to get the right files into the right directories. This is especially important if you have more than just a UDL definition, and also create the other files (functionList, autoCompletion, light and dark modes), because the problem is that they are all named the same, and hence, the need to have an installer.

                        I’ll try your plugin and see if I can help or not.

                        Edit:
                        If you’d like, I can send you my code that I used for the dBASE UDL installer, so you can see what I had to do to first identify if there is a standard system directory to install to, if there is no standard directory at which point they’d need to point to where the portable directory is, and if there is a cloud directory for either version. It’s in the dBASE language, but it’s a fairly easy language to read, to figure it out.

                        P 1 Reply Last reply Apr 3, 2025, 8:58 PM Reply Quote 0
                        • P
                          PeterJones @Lycan Thrope
                          last edited by PeterJones Apr 3, 2025, 8:58 PM Apr 3, 2025, 8:58 PM

                          @Coises ,

                          Consider using a List Box

                          I will keep the Category as a dropdown (since there are only 4), but yeah, it makes sense to make the file list a List Box.

                          @Lycan-Thrope,

                          it would make sense that the repository have some kind of mechanism for the plugin to be able to read that mechanism’s connection of the different files

                          Yeah, there’s the JSON which has the information for 3 of the 4 file types (because Themes are a separate repo and not attached to the UDL). So it should be doable to automatically download all the appropriate files for a UDL (though I might make that be an option, because someone might want to just grab the updated UDL, without overwriting their previously-customized FunctionList, for example).

                          If you’d like, I can send you my code that I used for the dBASE UDL installer, so you can see what I had to do to first identify if there is a standard system directory to install to, if there is no standard directory at which point they’d need to point to where the portable directory is, and if there is a cloud directory for either version. It’s in the dBASE language, but it’s a fairly easy language to read, to figure it out.

                          I don’t see a reason for that, for me. NPPM_GETNPPDIRECTORY tells you where notepad++.exe is for the current instance, which is the only parent directory for autoCompletion\. And NPPM_GETPLUGINSCONFIGDIR, which tells you where Notepad++ Plugins\Config is, which is relative to %AppData% for standard, relative to notepad++.exe for local, and should* be relative to CloudDirectory or -settingsDir if one of those options is chosen.

                          Your installer needs the more complicated code, because you are running outside of Notepad++ environment, but the plugin should have access to all the information it needs to put the files in the right location.

                          Lycan ThropeL 1 Reply Last reply Apr 3, 2025, 9:11 PM Reply Quote 1
                          • Lycan ThropeL
                            Lycan Thrope @PeterJones
                            last edited by Lycan Thrope Apr 3, 2025, 9:15 PM Apr 3, 2025, 9:11 PM

                            @PeterJones said in Need help with getting started using C++ Plugin Template:

                            Yeah, there’s the JSON which has the information for 3 of the 4 file types (because Themes are a separate repo and not attached to the UDL). So it should be doable to automatically download all the appropriate files for a UDL (though I might make that be an option, because someone might want to just grab the updated UDL, without overwriting their previously-customized FunctionList, for example).

                            Good point, as that would be an option, as I am probably going to need that for when I update the dBASE UDL definitions for all the versions that I’m working on now, to make more of the language color configurable for users via the UDL defintion dialog by including builtin functions/commands that they can custom color as well as, if I organize it well, leave a Keywords box open so they can put their own function definitions in it separate from the standard ones.
                            Just an FYI, the light and dark modes are actual languages in the different versions, not themes.

                            @PeterJones said in Need help with getting started using C++ Plugin Template:

                            I don’t see a reason for that, for me. NPPM_GETNPPDIRECTORY tells you where notepad++.exe is for the current instance, which is the only parent directory for autoCompletion. And NPPM_GETPLUGINSCONFIGDIR, which tells you where Notepad++ Plugins\Config is, which is relative to %AppData% for standard, relative to notepad++.exe for local, and should* be relative to CloudDirectory or -settingsDir if one of those options is chosen.

                            Your installer needs the more complicated code, because you are running outside of Notepad++ environment, but the plugin should have access to all the information it needs to put the files in the right location.

                            Which, if I was somewhat able to code in C++, using the NPP plugin would have made my life simpler then, at least from the installer perspective. :-)

                            1 Reply Last reply Reply Quote 0
                            • C
                              Coises @PeterJones
                              last edited by Apr 3, 2025, 9:22 PM

                              @PeterJones said in Need help with getting started using C++ Plugin Template:

                              would you prefer:

                              1. After hitting DOWNLOAD for the first file, the dialog closes itself, so you have to re-run the Plugin command to get the next file
                              2. After hitting DOWNLOAD for the first file, when it’s done, it pops up a MessageBox to inform you it’s done, and you can go immediately get another file from the same dialog
                              3. After hitting DOWNLOAD for the first file, when it’s done, it changes a status bar on that dialog to indicate that it’s complete
                              4. Other ideas (the less complicated, the better)

                              I would do the reverse of 2: raise a dialog box while the content is downloading, then close it when the download is finished. I looked just briefly at your project; since you’re using an asynchronous interface (wininet) you should be able to put a cancel button on the downloading dialog. (Progress would be more work; I’d guess these files are small enough that it wouldn’t be necessary?)

                              You could still put up a status message showing the last thing that happened (downloaded, or download cancelled or failed) and the item name.

                              Your button layout is non-standard. It’s allowed, but might confuse users. The rightmost button is usually Cancel or Close. (No real difference, but Cancel usually goes with a single-use OK, whereas Close usually goes with a dialog that has other options and stays open after one or more of them.)

                              The Restart button leaves me wondering if it means “Download what I have selected and then restart” or “Restart without downloading anything (more).”

                              If it means just Restart, I would put it to the far left and disable it until at least one file has been downloaded successfully, and put the Download button just to the left of the Close button, disabled until there is a valid selection.

                              If it means download and restart… then it’s more like an OK button. In that case, I suppose I would put Download to the far left, but really consider the multiple selection option.

                              A possibility would be to just have Download/Close (if you only want one selection at a time) or OK/Cancel (for multiple selections). Then, upon Close (if at least one file has been downloaded) or OK, raise another dialog asking whether the user wants to restart.

                              Lycan ThropeL P 2 Replies Last reply Apr 3, 2025, 9:28 PM Reply Quote 1
                              • Lycan ThropeL
                                Lycan Thrope @Coises
                                last edited by Lycan Thrope Apr 3, 2025, 9:29 PM Apr 3, 2025, 9:28 PM

                                @Coises said in Need help with getting started using C++ Plugin Template:

                                The Restart button leaves me wondering if it means “Download what I have selected and then restart” or “Restart without downloading anything (more).”

                                If it means just Restart, I would put it to the far left and disable it until at least one file has been downloaded successfully, and put the Download button just to the left of the Close button, disabled until there is a valid selection.

                                I believe it’s to restart Notepad++, to allow for the UDL/Themes to be able to be active, is what it means, this of course would mean that it’s going to close the dialog of the Plugin as well.

                                1 Reply Last reply Reply Quote 0
                                • Lycan ThropeL
                                  Lycan Thrope @PeterJones
                                  last edited by Apr 3, 2025, 9:50 PM

                                  @PeterJones said in Need help with getting started using C++ Plugin Template:

                                  alpha testing

                                  For those interested in alpha testing, the copy at https://github.com/pryrt/NppPlugin-CollectionInterface should now have all features implemented, though it definitely needs error handling improvements (right now, it will throw uncaught exceptions)

                                  Well, I probably did something wrong, but this is what I got after building your .dll in VS2022, and then creating the directory in the Programs\Notepad++\Plugins\CollectionInterface directory and copying the CollectionInterface.dll into it and trying to start NPP.

                                  StartNPPErrorAfterInstall.PNG

                                  StartNPPErrorAfterInstall2.PNG

                                  Like I said, it might be me, all I did was clone your github directory to my github desktop directories and ran VS 2022, went to that directory as a project in it and then hit build. Not sure if it’s a program error, mine or not compatible with 8.7.7, which my current standard install is at. I’ll try it in one of my portable RC’s if that matters.

                                  P 2 Replies Last reply Apr 3, 2025, 9:56 PM Reply Quote 1
                                  • P
                                    PeterJones @Lycan Thrope
                                    last edited by PeterJones Apr 3, 2025, 10:02 PM Apr 3, 2025, 9:56 PM

                                    @Lycan-Thrope ,

                                    Per MS Learn > GetTempPath2W(), that function is in Kernel32.dll, so I cannot see why it wouldn’t be found for you. [update: see next reply]

                                    Are you sure you were building the 64bit DLL for the 64bit Notepad++?

                                    Because I didn’t do anything special other than linking the Plugins\CollectionInterface directory to the VS build output (as described above), along with setting the run command to use my normal Notepad++ (also mentioned above). It works for me when I run it either from the VS Run button, or when I just manually run Notepad++ normally.

                                    Mine is v8.7.5, but I don’t see how anything I’ve coded would be NPP-version dependent

                                    1 Reply Last reply Reply Quote 0
                                    • P
                                      PeterJones @Lycan Thrope
                                      last edited by Apr 3, 2025, 10:02 PM

                                      @Lycan-Thrope ,

                                      The same MS Learn page mentioned at the bottom:

                                      Requirement	Value
                                      Minimum supported client	Windows 11 Build 22000
                                      Minimum supported server	Windows Server 2022 Build 20348
                                      Header	fileapi.h (include Windows.h)
                                      Library	Kernel32.lib
                                      DLL	Kernel32.dll
                                      

                                      I hadn’t previously noticed that. I just saw that GetTempPathW told me to use GetTempPath2W instead.

                                      Try changing from GetTempPath2() to GetTempPath() (which has been around since WinXP, If that fixes it, I will update the repo tomorrow.

                                      Lycan ThropeL 4 Replies Last reply Apr 3, 2025, 10:17 PM Reply Quote 0
                                      • Lycan ThropeL
                                        Lycan Thrope @PeterJones
                                        last edited by Apr 3, 2025, 10:17 PM

                                        @PeterJones ,
                                        Looking for it now, but it appears to only show up in system files using the Code Search, and I don’t want to change VS2022 files…will change it when I find it in your code.

                                        1 Reply Last reply Reply Quote 0
                                        • Lycan ThropeL
                                          Lycan Thrope @PeterJones
                                          last edited by Apr 3, 2025, 10:39 PM

                                          @PeterJones ,
                                          Okay, that fixed it.
                                          ROFLMAO, I couldn’t find out how to use VS 2022 search to just find the file it was in, so I had to use Notepad++ Search in file feature to find it in the right .cpp file. God you got to love Notepad++ for it’s simplicity and funtionality.

                                          I may not be familar with VS 2022…but searching for code shouldn’t start at the libraries and never mention the opened code folder where it is. Sheesh.

                                          Now to check out your handy work…remember, we all aren’t using Win 11. :-)

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