A Notepad++ egy rendkívül népszerű, ingyenes és nyílt forráskódú szövegszerkesztő, amelyet fejlesztők és általános felhasználók egyaránt előszeretettel használnak. Könnyedén kezelhető felülete, számos beépített funkciója és nem utolsósorban a pluginok általi bővíthetősége teszi nélkülözhetetlenné sokak számára. De mi van akkor, ha van egy olyan funkció, amire szükséged lenne, de még senki sem írta meg hozzá a plugint? Vagy egyszerűen csak szeretnéd automatizálni egyedi munkafolyamataidat? Akkor itt az ideje, hogy belevágj a saját Notepad++ plugin fejlesztésbe!
Ez az átfogó útmutató lépésről lépésre végigvezet téged a Notepad++ pluginok elkészítésének folyamatán. Megismerkedhetsz az alapvető koncepciókkal, a fejlesztői környezet beállításával, a kód struktúrájával és a fordítás, tesztelés lépéseivel. Célunk, hogy még ha nem is vagy tapasztalt C++ fejlesztő, akkor is képes legyél elindítani a saját projektet, és létrehozd az első egyéni funkcióidat a kedvenc szövegszerkesztődbe.
Miért érdemes saját Notepad++ Plugint fejleszteni?
A Notepad++ már önmagában is rendkívül sokoldalú, de a pluginok adják az igazi erejét. Íme néhány ok, amiért érdemes saját bővítményt írnod:
- Egyéni munkafolyamatok automatizálása: Számos ismétlődő feladatot automatizálhatsz, amelyekkel időt takaríthatsz meg.
- Hiányzó funkciók pótlása: Ha van egy specifikus igényed, amit a meglévő pluginok nem fednek le, elkészítheted a sajátodat.
- Integráció más rendszerekkel: Lehetőséged van a Notepad++-t külső alkalmazásokkal, API-kkal vagy szolgáltatásokkal összekapcsolni.
- Tanulás és fejlődés: A plugin fejlesztés kiváló módja a C++ ismeretek elmélyítésének és a Windows API-val való ismerkedésnek.
- Közösségi hozzájárulás: Ha hasznos plugint készítesz, megoszthatod másokkal, és hozzájárulhatsz a Notepad++ közösségéhez.
Vágjunk is bele!
A Notepad++ Pluginok Alapjai: Hogyan működnek?
A Notepad++ pluginok lényegében dinamikusan linkelt könyvtárak (DLL-ek), amelyeket a Notepad++ betölt induláskor. Ezek a DLL-ek speciális függvényeket exportálnak, amelyeket a Notepad++ meghív, hogy lekérdezze a plugin adatait, a menüpontokat, és értesítéseket küldjön bizonyos eseményekről. A Notepad++ egy Scintilla komponensen alapul, amely maga is egy rendkívül rugalmas szövegszerkesztő komponens. A pluginok közvetlenül a Scintilla-val és a Notepad++ magjával is kommunikálhatnak üzeneteken keresztül.
Főbb alkotóelemek:
NppPlugin.h
ésPluginInterface.h
: Ezek a header fájlok tartalmazzák azokat a struktúrákat és függvényprototípusokat, amelyeket a pluginodnak implementálnia kell a Notepad++-szal való kommunikációhoz.NppData
: Ez a struktúra tárolja a Notepad++ fő ablakának és a Scintilla ablakoknak a handle-jeit, amelyek segítségével üzeneteket küldhetsz a szerkesztőnek.FuncItem
: Ez a struktúra írja le a menüpontokat, amelyeket a pluginod hozzáad a Notepad++ menüjéhez.- Eseménykezelő függvények: A pluginodnak képesnek kell lennie kezelni a Notepad++ eseményeit (pl. fájl megnyitása, mentése, szerkesztő bezárása).
Előkészületek: Mire lesz szükséged?
Mielőtt belevágnánk a kódolásba, győződj meg róla, hogy minden szükséges eszközzel rendelkezel:
1. Fejlesztői Környezet: Visual Studio
A legkényelmesebb és legelterjedtebb választás a C++ plugin fejlesztéshez a Microsoft Visual Studio. A Visual Studio Community Edition ingyenesen letölthető és használható magánszemélyek és kis csapatok számára. Győződj meg róla, hogy telepítéskor kiválasztottad a „Desktop development with C++” munkaterhelést.
2. Notepad++ SDK (Software Development Kit)
Ez a legfontosabb komponens. Az SDK tartalmazza a szükséges header fájlokat és a példaprojekteket. Letöltheted a Notepad++ hivatalos GitHub oldaláról, általában a „nppPluginList” repositoryban találod meg a plugin_template
mappát vagy egy különálló nppsdk
repositoryt.
Keresd meg a Notepad++ plugin template
repositoryt, amely egy működő kiindulási alapot biztosít a plugin fejlesztéshez. Erősen ajánlott ebből kiindulni, mivel már tartalmazza a minimális szükséges kódot és a projektbeállításokat.
3. Notepad++ Telepítés
Természetesen szükséged lesz egy működő Notepad++ telepítésre a plugin teszteléséhez. Fontos, hogy a pluginod architektúrája (32-bit vagy 64-bit) megegyezzen a Notepad++ telepítésed architektúrájával.
4. C/C++ Alapismeretek
Bár ez az útmutató igyekszik minél részletesebben mindent elmagyarázni, a C++ nyelv alapszintű ismerete, beleértve a mutatókat, struktúrákat és a Windows API alapjait, nagyban megkönnyíti a dolgodat.
Projekt Beállítása Visual Studióban
A projekt beállítása az egyik legkritikusabb lépés. Kövesd az alábbi utasításokat:
1. Új projekt létrehozása
- Nyisd meg a Visual Studiót.
- Válassz „Create a new project”-et.
- Keresd a „Dynamic Link Library (DLL)” projektet C++ nyelven, és válaszd a „Empty Project” sablont. (Ha a template-ből indulsz, akkor egyszerűen nyisd meg a .sln fájlt a template mappájából.)
- Adj nevet a projektnek (pl. „MyNppPlugin”) és válaszd ki a mentési helyet.
- Kattints a „Create” gombra.
2. Projekt Konfigurációk
A Visual Studio felül, a toolbaron válaszd ki a megfelelő architektúrát (x64 vagy Win32) a Notepad++ telepítésednek megfelelően, valamint a „Release” vagy „Debug” konfigurációt.
3. C++ Include Könyvtárak hozzáadása
Ez elengedhetetlen, hogy a projekt megtalálja az SDK header fájljait:
- Kattints jobb gombbal a projektre a Solution Explorerben, és válaszd a „Properties” lehetőséget.
- Navigálj a „Configuration Properties” -> „C/C++” -> „General” menüpontra.
- Az „Additional Include Directories” mezőbe add hozzá a Notepad++ SDK mappájának elérési útját (pl.
C:NotepadPP_SDKnppsdkinclude
vagy ahova letöltötted a template-et és az include mappát).
4. Linker Beállítások
Szükségünk lehet bizonyos függvénykönyvtárakra a fordításhoz:
- Még mindig a „Project Properties” ablakban, navigálj a „Linker” -> „Input” menüpontra.
- Az „Additional Dependencies” mezőbe add hozzá a
SciLexer.lib
fájlt (ez a Scintilla komponens könyvtára, gyakran hasznos, ha a szerkesztő tartalmával akarsz interakcióba lépni). Lehet, hogy meg kell adnod az elérési útját is, ha nincs a Visual Studio default lib mappáiban (pl.C:NotepadPP_SDKnppsdklibSciLexer.lib
).
5. Kimeneti könyvtár beállítása
Ez egy kényelmi funkció, amely automatikusan a megfelelő helyre másolja a lefordított DLL-t:
- Navigálj a „Configuration Properties” -> „General” menüpontra.
- A „Output Directory” mezőben add meg a Notepad++ plugins mappájának elérési útját (pl.
C:Program FilesNotepad++pluginsMyNppPlugin
, vagy a 64-bites verzió eseténC:Program FilesNotepad++pluginsMyNppPlugin
. Fontos, hogy a DLL-nek a plugin saját almappájában kell lennie a Notepad++ 7.6.x verzióitól kezdve!). - A „Target Name” mezőben add meg a DLL nevének előtagját (pl.
MyNppPlugin
), ekkor a kimenetMyNppPlugin.dll
lesz.
6. SDK fájlok hozzáadása a projekthez (ha nem template-ből indulsz)
Ha üres projektet hoztál létre, manuálisan hozzá kell adnod az SDK legfontosabb fájljait a projektedhez. Ezeket általában az SDK src
mappájában találod:
NppPlugin.cpp
NppPlugin.h
PluginInterface.h
menuCmdID.h
(opcionális, de jó, ha kéznél van az egyedi menü ID-k definiálásához)
Másold ezeket a fájlokat a projektmappádba, majd kattints jobb gombbal a projektre a Solution Explorerben, és válaszd az „Add” -> „Existing Item…” lehetőséget, majd válaszd ki a másolt fájlokat.
A Plugin Lelke: Alapvető Kód Struktúra
Most, hogy a projekt beállításra került, nézzük meg, hogyan épül fel egy minimális Notepad++ plugin kódja. A NppPlugin.cpp
fájl a pluginod fő forráskódja.
1. Globális változók és inicializálás
Szükségünk lesz egy globális NppData
változóra, ami tárolja a Notepad++ fő adatstruktúráját, és egy FuncItem
tömbre, ami a menüparancsokat tartalmazza.
#include <windows.h>
#include "NppPlugin.h"
#include "PluginInterface.h"
// Globális NppData struktúra a Notepad++ kommunikációhoz
NppData nppData;
// A plugin menüparancsai
FuncItem funcItems[MAX_FUNC];
// Plugin neve
TCHAR pluginName[] = TEXT("MyNppPlugin");
// A parancsok száma
int nbFunc = 0;
2. DllMain függvény
Ez a DLL belépési pontja. Itt nincs szükség bonyolult logikára, csak az alapvető inicializálásra.
BOOL APIENTRY DllMain(HMODULE hModule, DWORD reasonForCall, LPVOID lpReserved)
{
UNREFERENCED_PARAMETER(lpReserved);
switch (reasonForCall)
{
case DLL_PROCESS_ATTACH:
// Plugin betöltésekor
break;
case DLL_PROCESS_DETACH:
// Plugin leállásakor
break;
case DLL_THREAD_ATTACH:
// Szál indításakor
break;
case DLL_THREAD_DETACH:
// Szál leállásakor
break;
}
return TRUE;
}
3. setInfo(NppData npd)
Ezt a függvényt hívja meg a Notepad++ közvetlenül a plugin betöltése után. Itt kapjuk meg az NppData
struktúrát, amit el kell mentenünk a globális változónkba.
extern "C" __declspec(dllexport) void setInfo(NppData npd)
{
nppData = npd;
}
4. isUnicode()
Ez a függvény jelzi a Notepad++-nak, hogy a plugin Unicode-ot használ. A modern pluginoknak mindig true
-t kell visszaadniuk.
extern "C" __declspec(dllexport) BOOL isUnicode()
{
return TRUE;
}
5. getName()
Ez adja vissza a plugin nevét, ami a Notepad++ menüjében fog megjelenni.
extern "C" __declspec(dllexport) TCHAR * getName()
{
return pluginName;
}
6. setCommand(size_t index, TCHAR *cmdName, PFUNCPLUGINCMD pFunc, BOOL checkOnInit, ShortcutKey *sk)
Ez a segédfüggvény a menüparancsok hozzáadására szolgál.
void addCommand(TCHAR *cmdName, PFUNCPLUGINCMD pFunc, BOOL checkOnInit, ShortcutKey *sk)
{
if (nbFunc >= MAX_FUNC) return;
// Inicializáld a FuncItem struktúrát
funcItems[nbFunc]._cmdID = nbFunc;
_tcsncpy_s(funcItems[nbFunc]._itemName, cmdName, _countof(funcItems[nbFunc]._itemName) - 1);
funcItems[nbFunc]._pFunc = pFunc;
funcItems[nbFunc]._init2Check = checkOnInit;
funcItems[nbFunc]._pShKey = sk;
funcItems[nbFunc]._tMenu = NULL;
funcItems[nbFunc]._pszModuleName = pluginName;
nbFunc++;
}
7. getFuncArray(int *nbItems)
Ezt a függvényt hívja meg a Notepad++, hogy lekérdezze a plugin által biztosított menüparancsokat. Itt kell feltölteni a funcItems
tömböt a saját parancsaiddal.
void command1()
{
MessageBox(nppData._nppHandle, TEXT("Szia, Notepad++! Ez az első pluginom!"), TEXT("MyNppPlugin"), MB_OK);
}
extern "C" __declspec(dllexport) FuncItem * getFuncArray(int *nbItems)
{
*nbItems = nbFunc;
return funcItems;
}
// Ezt a DllMain-ben vagy egy külön inicializáló függvényben hívhatod meg
extern "C" __declspec(dllexport) void beNotified(SCNotification *notifyCode)
{
// Események kezelése, lásd később
}
// Ezt a setInfo után, de a getFuncArray előtt kell meghívni
void doInit()
{
// Itt definiáljuk a menüparancsainkat
addCommand(TEXT("Üdvözlő üzenet"), command1, FALSE, NULL);
// addCommand(TEXT("Másik parancs"), anotherCommandFunc, FALSE, NULL);
}
// Notepad++ 8.x-től a beNotified előtt van egy "pluginInit" függvény hívva
extern "C" __declspec(dllexport) void pluginInit(HANDLE hModule)
{
doInit(); // Hívjuk meg az inicializáló függvényünket
}
Megjegyzés: A Notepad++ 8.x verzióitól kezdve a pluginInit
függvényt hívják meg a menüparancsok inicializálására, mielőtt a getFuncArray
-t meghívnák. A régebbi verziókhoz a setInfo
függvényben is inicializálhatod a parancsokat, de a pluginInit
a preferált módszer.
Interakció a Notepad++-szal: Üzenetek küldése
A plugin lényege, hogy interakcióba lépjen a Notepad++-szal és a Scintilla szerkesztőkomponenssel. Ezt Windows üzenetek küldésével tehetjük meg a ::SendMessage
függvény segítségével.
1. Notepad++ üzenetek (NPPW_*, NPPM_*)
Ezek az üzenetek a Notepad++ fő ablakának funkcióit vezérlik (pl. fájlok megnyitása, mentése, aktuális fájl elérési útjának lekérése).
// Aktuális fájl elérési útjának lekérése
TCHAR filePath[MAX_PATH];
::SendMessage(nppData._nppHandle, NPPM_GETFULLCURRENTPATH, 0, (LPARAM)filePath);
MessageBox(nppData._nppHandle, filePath, TEXT("Aktuális fájl"), MB_OK);
// Szöveg beillesztése a kurzor pozíciójára (Scintilla üzenettel)
::SendMessage(nppData._scintillaMainHandle, SCI_INSERTTEXT, -1, (LPARAM)TEXT("Hello from plugin!"));
2. Scintilla üzenetek (SCI_*)
Ezek az üzenetek a szövegszerkesztő tartalmát és viselkedését befolyásolják (pl. szöveg beszúrása, kijelölés, színek beállítása).
// Aktuálisan kijelölt szöveg lekérése
int selLength = ::SendMessage(nppData._scintillaMainHandle, SCI_GETSELTEXTLENGTH, 0, 0);
if (selLength > 0)
{
char* selectedText = new char[selLength + 1];
::SendMessage(nppData._scintillaMainHandle, SCI_GETSELTEXT, 0, (LPARAM)selectedText);
selectedText[selLength] = ' '; // Null-terminátor
MessageBoxA(nppData._nppHandle, selectedText, "Kijelölt szöveg", MB_OK);
delete[] selectedText;
}
// Szöveg cseréje
::SendMessage(nppData._scintillaMainHandle, SCI_REPLACERANGE, 0, (LPARAM)TEXT("Új szöveg"));
A Notepad++ SDK dokumentációja és a Scintilla dokumentációja tartalmazza az összes elérhető üzenetet és paramétereiket. Ez a te „bibliaod” a fejlesztés során.
Eseménykezelés: beNotified(SCNotification *notifyCode)
A beNotified
függvényt hívja meg a Notepad++, amikor különböző események történnek (pl. fájl megnyitása, mentése, a felhasználó vált dokumentumot). Itt tudsz reagálni ezekre az eseményekre.
extern "C" __declspec(dllexport) void beNotified(SCNotification *notifyCode)
{
switch (notifyCode->_header.code)
{
case NPPN_FILEOPENED:
// Fájl megnyitásakor
MessageBox(nppData._nppHandle, TEXT("Egy fájl megnyílt!"), TEXT("Esemény"), MB_OK);
break;
case NPPN_FILESAVED:
// Fájl mentésekor
break;
case NPPN_SHUTDOWN:
// Notepad++ bezárásakor (fontos a cleanuphoz)
// Itt szabadítsd fel az erőforrásaidat
break;
// ... további események (NPPN_BUFFERACTIVATED, NPPN_WORDSTYLEUPDATED stb.)
}
}
Felhasználói Felület (UI) Készítése
A legegyszerűbb UI a MessageBox
, de komplexebb interakciókhoz szükség lehet párbeszédpanelekre vagy dokkolható ablakokra.
1. Párbeszédpanelek (Dialogs)
A Windows API lehetővé teszi egyedi párbeszédpanelek létrehozását. Ehhez szükség van egy .rc fájlra (resource script), ahol definiálhatod a dialog box layoutját (gombok, szövegmezők stb.), majd a DialogBoxParam
függvényt használva jelenítheted meg.
// DialogBoxParam függvény hívása
INT_PTR CALLBACK MyDialogProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_INITDIALOG:
// Dialógus inicializálása
return TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
{
EndDialog(hDlg, LOWORD(wParam));
return TRUE;
}
break;
}
return FALSE;
}
void showMyDialog()
{
DialogBoxParam(nppData._hInst, MAKEINTRESOURCE(IDD_MY_DIALOG), nppData._nppHandle, MyDialogProc, 0);
}
2. Dokkolható panelek (Dockable Panels)
Ez egy komplexebb téma, de a Notepad++ lehetővé teszi, hogy saját dokkolható ablakokat hozz létre (pl. a „Keresés eredményei” ablakhoz hasonlóan). Ehhez a NPPM_DMMREGASDCKDLG
üzenetet kell elküldeni a Notepad++-nak, és be kell állítani egy ablak procedúrát a panelhez.
Fordítás és Tesztelés
A kód elkészítése után jöhet a fordítás és tesztelés.
1. Projekt fordítása
- A Visual Studióban válassza a „Build” -> „Build Solution” menüpontot (vagy nyomd meg az F7 billentyűt).
- Ha minden rendben van, létrejön a
.dll
fájl a beállított kimeneti mappában (pl.C:Program FilesNotepad++pluginsMyNppPluginMyNppPlugin.dll
).
2. Tesztelés
- Győződj meg róla, hogy a Notepad++ be van zárva.
- Ha nem állítottad be az automatikus kimeneti mappát, másold be manuálisan a lefordított
MyNppPlugin.dll
fájlt a Notepad++plugins
mappájába, egy új, saját almappába (pl.C:Program FilesNotepad++pluginsMyNppPluginMyNppPlugin.dll
). - Indítsd el a Notepad++-t.
- Navigálj a „Beépülő modulok” (Plugins) menüponthoz. Látnod kell a pluginod nevét (pl. „MyNppPlugin”), és alatta a hozzáadott menüparancsokat (pl. „Üdvözlő üzenet”).
- Kattints a parancsra, és győződj meg róla, hogy megfelelően működik.
3. Hibakeresés (Debugging)
A hibakeresés Visual Studióval elengedhetetlen a fejlesztés során:
- Indítsd el a Notepad++-t.
- A Visual Studióban válaszd a „Debug” -> „Attach to Process…” menüpontot.
- Keresd meg a
notepad++.exe
folyamatot, és csatold hozzá a debugger-t. - Mostantól breakpointokat helyezhetsz el a pluginod kódjában, és lépésenként futtathatod azt, miközben a Notepad++-t használod.
Gyakori Hibák és Tippek
- 32-bit vs. 64-bit: A leggyakoribb hiba. A pluginodnak pontosan meg kell egyeznie a Notepad++ verziójával. Ha 64-bites Notepad++-t használsz, 64-bites DLL-t kell fordítanod.
- DLL helye: Ne feledd, a Notepad++ 7.6.x verziójától kezdve a pluginoknak saját almappában kell lenniük a
plugins
könyvtárban! - Linker hibák: Győződj meg róla, hogy minden szükséges
.lib
fájl (pl.SciLexer.lib
) hozzá van adva a linker beállításaihoz. - Memória kezelés: Légy óvatos a memória foglalásával és felszabadításával. Használj
new/delete
párokat, és szabadítsd fel az erőforrásokat aNPPN_SHUTDOWN
eseményben. - Unicode: Mindig Unicode-ot használj (
TCHAR
,_tcsncpy_s
,TEXT()
makrók), mivel a modern Notepad++ verziók Unicode-ot várnak. - Naplózás: Hiba esetén írj ki információkat egy log fájlba (pl.
OutputDebugString
vagy egyszerű fájlba írás), ha a debugger nem elérhető. - Kezdj template-ből: A
plugin_template
projekt a Notepad++ SDK-ban egy kiváló kiindulópont, minden alapvető beállítással és kódstruktúrával.
További Fejlesztési Lehetőségek
Miután elsajátítottad az alapokat, számos irányba fejlesztheted a pluginodat:
- Komplex szövegmanipuláció: Regexp alapú keresés és csere, formázás, kódgenerálás.
- Hálózati kérések: Integráció webes API-kkal, adatok lekérése vagy feltöltése.
- Fájlrendszer műveletek: Fájlok kezelése, könyvtárak létrehozása.
- Egyéni szintaxis kiemelés: Bár a Notepad++ rendelkezik felhasználó által definiálható nyelvekkel, C++-ban még részletesebb kiemelést valósíthatsz meg.
- Git integráció: Egyszerű Git parancsok futtatása a szerkesztőből.
Konklúzió
A saját Notepad++ plugin készítése izgalmas és rendkívül hasznos feladat lehet. Lehetővé teszi, hogy a kedvenc szövegszerkesztődet pontosan a saját igényeidre szabd, automatizáld a munkafolyamataidat, és bővítsd a képességeit. Reméljük, ez a részletes útmutató segített neked elindulni ezen az úton. Ne habozz kísérletezni, olvasd el az SDK dokumentációját, és fedezd fel a Notepad++ plugin fejlesztésben rejlő végtelen lehetőségeket. Sok sikert a kódoláshoz!
Leave a Reply