Need help with getting started using C++ Plugin Template
-
This post is deleted! -
@PeterJones said in Need help with getting started using C++ Plugin Template:
if you know of a “best practices” C++ plugin I can use as a reference
For some reason, I thought that @Coises was one of the C# programmers so I didn’t think of looking at Columns++; but I now see it is, in fact, in C++, so I’ll probably at least use it for reference. :-)
-
I was working on a personal project to create a Visual Studio Template for C++ plugins for Notepad++. I put that on hold while I’m working on improving the regular expression search for Unicode files in Columns++.
If you would like to try it as a starting point, I put a copy here:
https://www.coises.com/extrn/SampleNppPlugin1.zip
I don’t have it packaged as a template yet, so the included instructions for installing it don’t apply. Just unzip, put it somewhere you’ll leave it, and double-click the Waiting for Godot.sln file to open it in Visual Studio.
It is a working (though useless) plugin that includes an About dialog, a Settings dialog, a non-modal dialog, a docking panel and a mechanism for saving settings as a JSON file.
The included help file is somewhat out of date, but it will still give you an idea how the thing is organized. As noted at the start of that file:
This project is not a part of Notepad++ and is not endorsed by the author of Notepad++.
This template includes framework code for making a Notepad++ plugin in C++, along with various utility functions and examples.
I have constructed it to give myself and others a useful starting point when developing a Notepad++ plugin in C++.
It necessarily reflects my own idiosyncrasies as a programmer. I hope it may prove useful to others, and I welcome comments, suggestions and problem reports in the Issues; however, I make no apologies for its incorporation of my personal choices and styles — which might not meet with universal approval — and I do not promise to make changes to accommodate all plausible programming styles and use cases. So be it.
-
@PeterJones said in Need help with getting started using C++ Plugin Template:
For some reason, I thought that @Coises was one of the C# programmers so I didn’t think of looking at Columns++; but I now see it is, in fact, in C++, so I’ll probably at least use it for reference. :-)
See my previous post about a template I have in progress. Even though it is not finished yet, it is probably a better model than Columns++. It does load and open dialogs.
Columns++ was my first plugin, and I made a few design decisions I would do differently now. It also has a lot of complexity because of what it does… untangling that from what parts are needed to work as a plugin could be confusing.
In the template-in-progress, I’m making an effort to separate the code that needs to be there for a plugin to work from the code that does what your plugin does. If you try it, you can tell me to what extent I’ve succeeded. ;-)
-
A Alan Kilborn referenced this topic on
-
@Coises said in Need help with getting started using C++ Plugin Template:
See my previous post about a template I have in progress.
👍 Looks like a promising object-oriented replacement for Don HO’s mostly C-like template (with its global variables, constants declared with
#define
instead ofconstexpr
, raw pointers, etc.).One small tip: if you don’t want the Win API’s
min()
/max()
macros to shadowstd::min
/*::max
, simply put#define NOMINMAX
before you include<windows.h>
(to hide the macros from the current file), or addNOMINMAX
to the project’s compiler definitions (to hide them everywhere). That will slightly clean up the preprocessor kludge at the top of.../src/Framework/PluginFramework.h
, i.e.,// ... #include <windows.h> // ... #undef min #undef max
-
@rdipardo said in Need help with getting started using C++ Plugin Template:
#define NOMINMAX
Thanks! I didn’t know about that.
And thank you for the encouragement. I hope it might be helpful. 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.)
-
Picking up from where my previous post in this thread ended…
Hmm, I submitted that post, then I edited it to add more info, and…somehow never submitted that. :-( Maybe there were gremlins in the machine (or the user!)…the same ones that caused my screenshot to somehow be dark…
OK, well, I meant to say that what I’ve done to debug/step a plugin code is “what I said earlier” plus I do some “trickery” to get things in the correct folder scheme so that Notepad++ finds the plugin when it starts up. That trickery involves a symbolic link, so that the plugin development folder can be anywhere but yet also maps to being in the plugins folder underneath Notepad++.
Thus:
In the plugins folder under Notepad++, from a cmd prompt, create the folder for the plugin (
md PluginName
), and then executemklink /D PluginName PathToDebugFolderOfPlugin
-
@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.
-
@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.
-
@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. -
@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 themklink
, themklink
complains; doing themklink
from theplugins\
directory without doing themkdir
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 inblah.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 runc:\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 appropriateplugins\
directory pointing to their local<arch>\Debug
directory with the appropriate DLL and meta-information seems to make good logical sense to me -
@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:
-
@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? :-)
-
@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. -
@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.