Notepad++插件开发实战
Notepad++插件开发实战:核心功能开发详解
1. 获取当前编辑窗口内容
// 获取当前编辑窗口句柄
HWND hScintilla = (HWND)::SendMessage(nppData._nppHandle, NPPM_GETCURRENTSCINTILLA, 0, 0);
int which = -1;
::SendMessage(nppData._nppHandle, NPPM_GETCURRENTSCINTILLA, 0, (LPARAM)&which);
hScintilla = (which == 0) ? nppData._scintillaMainHandle : nppData._scintillaSecondHandle;// 获取当前文档内容
int length = ::SendMessage(hScintilla, SCI_GETLENGTH, 0, 0);
char* buffer = new char[length + 1];
::SendMessage(hScintilla, SCI_GETTEXT, length + 1, (LPARAM)buffer);// 使用后释放内存
delete[] buffer;
2. 文本查找与替换API
// 设置搜索参数
Sci_TextToFind ttf;
ttf.chrg.cpMin = 0;
ttf.chrg.cpMax = -1;
ttf.lpstrText = "search_text";// 执行查找
int pos = ::SendMessage(hScintilla, SCI_FINDTEXT, SCFIND_MATCHCASE, (LPARAM)&ttf);// 替换文本
if (pos != -1) {::SendMessage(hScintilla, SCI_SETTARGETRANGE, ttf.chrgText.cpMin, ttf.chrgText.cpMax);::SendMessage(hScintilla, SCI_REPLACETARGET, -1, (LPARAM)"new_text");
}
3. 正则表达式处理示例
// 设置正则表达式搜索
::SendMessage(hScintilla, SCI_SETSEARCHFLAGS, SCFIND_REGEXP | SCFIND_MATCHCASE, 0);// 编译正则表达式
TCHAR pattern[] = _T("\\b\\w+\\b");
::SendMessage(hScintilla, SCI_SETTARGETSTART, 0, 0);
::SendMessage(hScintilla, SCI_SETTARGETEND, -1, 0);// 循环匹配
int pos = 0;
while ((pos = ::SendMessage(hScintilla, SCI_SEARCHINTARGET, _tcslen(pattern), (LPARAM)pattern)) != -1)
{int start = ::SendMessage(hScintilla, SCI_GETTARGETSTART, 0, 0);int end = ::SendMessage(hScintilla, SCI_GETTARGETEND, 0, 0);// 处理匹配结果...::SendMessage(hScintilla, SCI_SETTARGETSTART, end, 0);::SendMessage(hScintilla, SCI_SETTARGETEND, -1, 0);
}
4. 自定义对话框设计实现
// 对话框资源ID定义
#define IDD_MY_DIALOG 101
#define IDC_EDIT_BOX 1001// 对话框过程函数
INT_PTR CALLBACK DialogProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{switch (msg) {case WM_INITDIALOG:return TRUE;case WM_COMMAND:if (LOWORD(wParam) == IDOK) {TCHAR text[256];GetDlgItemText(hwnd, IDC_EDIT_BOX, text, 255);// 处理输入文本...EndDialog(hwnd, IDOK);}break;}return FALSE;
}// 显示对话框
void showDialog() {DialogBoxParam(hInstance, MAKEINTRESOURCE(IDD_MY_DIALOG),nppData._nppHandle,DialogProc,0);
}
关键开发技巧
-
Scintilla消息机制
- 使用
SCI_
前缀消息操作编辑器 - 位置参数使用字节偏移量而非行号
- 文本处理注意UTF-8编码转换
- 使用
-
线程安全注意事项
// GUI操作必须在主线程执行 ::PostMessage(nppData._nppHandle, NPPM_MSGTOPLUGIN, (WPARAM)_T("MyPlugin"), (LPARAM)&myNotification);
-
高效文本处理
- 大文件处理使用分块读取
- 避免频繁的整文档获取
- 使用
SCI_GETLINECHARACTERPTR
直接访问行缓冲
-
跨版本兼容性
// 通过NPPM_GETNPPVERSION获取版本 int nppVersion = ::SendMessage(nppData._nppHandle, NPPM_GETNPPVERSION, 0, 0); int major = (nppVersion >> 16) & 0xFFFF; int minor = nppVersion & 0xFFFF;
调试技巧
// 输出调试信息到控制台
void debugLog(const char* message) {char buffer[1024];sprintf_s(buffer, "[MyPlugin] %s\n", message);::OutputDebugStringA(buffer);
}// 内存泄漏检测(MSVC)
#define _CRTDBG_MAP_ALLOC
#include <crtdbg.h>int APIENTRY DllMain(HANDLE hModule, DWORD reason, LPVOID reserved) {if (reason == DLL_PROCESS_ATTACH) {_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);}return TRUE;
}
实战示例:全文批注插件
void addComments() {HWND hScintilla = getCurrentScintilla();// 获取选中文本范围int start = ::SendMessage(hScintilla, SCI_GETSELECTIONSTART, 0, 0);int end = ::SendMessage(hScintilla, SCI_GETSELECTIONEND, 0, 0);// 逐行处理int lineStart = ::SendMessage(hScintilla, SCI_LINEFROMPOSITION, start, 0);int lineEnd = ::SendMessage(hScintilla, SCI_LINEFROMPOSITION, end, 0);for (int line = lineStart; line <= lineEnd; ++line) {int pos = ::SendMessage(hScintilla, SCI_POSITIONFROMLINE, line, 0);::SendMessage(hScintilla, SCI_INSERTTEXT, pos, (LPARAM)"// ");}
}
开发注意事项:
- 使用
SCI_BEGINUNDOACTION
/SCI_ENDUNDOACTION
包裹批量操作 - 跨平台兼容性避免Windows API硬编码
- 插件初始化时注册
NPPN_READY
通知 - 多视图场景区分主/副编辑窗口
通过以上核心功能实现,开发者可构建:
- 代码格式化工具
- 自定义语法检查器
- 文档分析插件
- 文本处理工作流自动化工具
提示:官方插件模板可从Notepad++仓库获取(Plugins->Plugin Template),建议基于模板开发确保结构规范