Notepad++插件开发实战

发布于:2025-08-14 ⋅ 阅读:(14) ⋅ 点赞:(0)

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
    );
}

关键开发技巧

  1. Scintilla消息机制

    • 使用SCI_前缀消息操作编辑器
    • 位置参数使用字节偏移量而非行号
    • 文本处理注意UTF-8编码转换
  2. 线程安全注意事项

    // GUI操作必须在主线程执行
    ::PostMessage(nppData._nppHandle, NPPM_MSGTOPLUGIN, 
                 (WPARAM)_T("MyPlugin"), 
                 (LPARAM)&myNotification);
    
  3. 高效文本处理

    • 大文件处理使用分块读取
    • 避免频繁的整文档获取
    • 使用SCI_GETLINECHARACTERPTR直接访问行缓冲
  4. 跨版本兼容性

    // 通过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)"// ");
    }
}

开发注意事项:

  1. 使用SCI_BEGINUNDOACTION/SCI_ENDUNDOACTION包裹批量操作
  2. 跨平台兼容性避免Windows API硬编码
  3. 插件初始化时注册NPPN_READY通知
  4. 多视图场景区分主/副编辑窗口

通过以上核心功能实现,开发者可构建:

  • 代码格式化工具
  • 自定义语法检查器
  • 文档分析插件
  • 文本处理工作流自动化工具

提示:官方插件模板可从Notepad++仓库获取(Plugins->Plugin Template),建议基于模板开发确保结构规范


网站公告

今日签到

点亮在社区的每一天
去签到