近期发现NotePad++不支持按行号区间的文本复制,就想自己动手开发一个NotePad++插件,支持输入起始行号和结束行号,然后复制该区域的文本到新文档或者拷贝到系统剪切板,方便文本的操作。

效果例如以下图:

本文主要介绍NotePad++插件开发的基本流程以及相关的注意点。

1、Notepad++介绍

Notepad++是使用C++开发的开源免费的文本编辑器,它是一个多国语言版的编辑器,包括中文简体。使用它能够方便地编辑C、C++、Java、C#、XML、HTML、PHP、CSS等等纯文本文件,支持正则搜索、目录搜索、编码转换、文件比較等,能够媲美UltraEdit,最重要的是支持自己扩展插件的开发。

NotePad++官方站点的地址是:http://notepad-plus-plus.org/

Sourceforge地址:http://sourceforge.net/apps/mediawiki/notepad-plus

另外,Npp是基于开源控件Scintilla 开发的。Scintilla官网地址:http://www.scintilla.org/

插件中心:http://docs.notepad-plus-plus.org/index.php/Plugin_Central

2、NotePad++开发过程

开发一个NotePad++插件大概须要六步:

第一。下载Np++插件模板project(http://notepad-plus.sourceforge.net/commun/pluginDemoTemplate/NppPluginTemplate.zip),而且解压到本地。

第二,用VS打开project中的NppPluginTemplate.vcproj 项目,能够重命名该project。

第三,在PluginDefinition.h头文件里定义插件名字,即

const TCHAR NPP_PLUGIN_NAME[] = TEXT("Notepad++
plugin template");

第四,定义插件中菜单的个数const int nbFunc = 2;

第五,在PluginDefinition.cpp中将菜单名字和回调函数绑定。

第六。实现相关菜单的回调函数。

3、与NotePad++主界面交互的主要数据结构

a.交互句柄

struct NppData {
HWND _nppHandle;
HWND _scintillaMainHandle;
HWND _scintillaSecondHandle;
};

该数据结构包括和NP++的交互的句柄,当中包括主窗体和次窗体句柄。

该数据成员在载入插件的时候传入,以供插件和NP++主界面进行消息交互。

通过接口extern "C" __declspec(dllexport) void setInfo(NppData
notpadPlusData)传入到插件,编写插件时。须要保存传过来的 notpadPlusData的值。

b.菜单与回调函数绑定

struct FuncItem {
TCHAR _itemName[nbChar];
PFUNCPLUGINCMD _pFunc;
int _cmdID;
bool _init2Check;
ShortcutKey *_pShKey;
};

该结构定义了插件菜单名与相应的回调函数的相应关系。如

//注冊菜单回调函数
FuncItem CRunlogMenu::arrFuncItems[N_NBFUNCITEMS] = {
{ TEXT("Line Range Copy"), funcRangeCopy, 0, false, NULL },
//{ TEXT("Statistics"), funcStatistics, 0, false, NULL },
{ TEXT(""), NULL, 0, false, NULL }, // separator
{ TEXT("About"), funcAbout, 0, false, NULL }
};

4、与NotePad++的消息交互

与主界面的交互都是通过发送NPPM_开头的消息进行的,如获取当前文件的全路径名:

TCHAR str[100];
int strLen = 100;
::SendMessage(m_nppData._nppHandle, NPPM_GETNPPDIRECTORY, (WPARAM) strLen, (LPARAM) str);

其它相关的NPPM_消息的介绍见:http://docs.notepad-plus-plus.org/index.php/Messages_And_Notifications

5.获取当前文档文本相关属性

 
操作当前文本都是通过SCI消息来获取,如获取选择的文本内容

首先获取当前文档句柄:

int currentView = 0;
SendNppMsg( NPPM_GETCURRENTSCINTILLA, 0, (LPARAM) ¤tView );
return ( (currentView == 0) ?
m_nppData._scintillaMainHandle : m_nppData._scintillaSecondHandle );

然后採用该句柄发送SCI_GETSELTEXT消息

::SendMessage(m_hSciWnd, uMsg, wParam, lParam);

以下给出几个比較重要的SCI消息。用于在开发插件的过程中參考:

SCI_GETTEXTRANGE(<unused>, Sci_TextRange *tr)

This collects the text between the positions cpMin and cpMax and copies it to lpstrText (see structSci_TextRange in Scintilla.h).
If cpMax is -1, text isreturned to the end of the document. The text is 0 terminated, so you mustsupply a buffer that is at least 1 character longer than the number ofcharacters you wish to read. The return value is the length
of the returnedtext not including the terminating 0.

 

获取总行

SCI_GETLINECOUNT

This returns the number of lines in thedocument. An empty document contains 1 line. A document holding only an end ofline sequence has 2 lines.

获取文档总字节数SCI_GETTEXTLENGTH

SCI_GETLENGTH


Both these messages return the length of thedocument in byte

获取文档是否改动

SCI_GETMODIFY

This returns non-zero if the document ismodified and 0 if it is unmodified. The modified status of a document is determinedby the undo position relative to the save point. The save point is set by SCI_SETSAVEPOINT,
usually when you have saved data to a file.

选择文本

SCI_SETSEL(int anchorPos, intcurrentPos)

This message sets both the anchor and the currentposition. If currentPos is negative, itmeans the end of the document. If anchorPos is negative, itmeans remove any selection (i.e. set the anchor
to the same position as currentPos). The caret is scrolled into view after this operation.

跳到某一行

SCI_GOTOLINE(int line)

This removes any selection and sets the caret atthe start of line number line and scrolls the view(if needed) to make it visible. The anchor position is set the same as thecurrent position. If line is
outside the linesin the document (first line is 0), the line set is the first or last.

获取当前的位置

SCI_GETCURRENTPOS

This returns the current position.

获取鼠标位置SCI_GETANCHOR

This returns the current anchor position.

选择全部文本

SCI_SELECTALL

This selects all the text in the document. Thecurrent position is not scrolled into view.

获取某行的首位置

SCI_POSITIONFROMLINE(int line)

This returns the document position thatcorresponds with the start of the line. If line is negative, the positionof the line holding the start of the selection is returned. If line is greater than the
lines in the document, the return valueis -1. If line is equal to thenumber of lines in the document (i.e. 1 line past the last line), the returnvalue is the end of the document.

获取某行的长度

SCI_LINELENGTH(int line)

This returns the length of the line, includingany line end characters. If line is negative orbeyond the last line in the document, the result is 0. If you want the lengthof the line not including any end of line characters, use SCI_GETLINEENDPOSITION(line) - SCI_POSITIONFROMLINE(line).

拷贝当前选择的文本

SCI_GETSELTEXT(<unused>,char *text NUL-terminated)

This copies the currently selected text and aterminating 0 byte to the text buffer. The buffersize should be determined by calling with a NULL pointer for the textargument SCI_GETSELTEXT(0,0).
This allowsfor rectangular and discontiguous selections as well as simple selections. See MultipleSelection for information on how multipleand rectangular
selections and virtual space are copied.

6、注意事项

对于Unicode模式下文本的操作须要转换,否则会出现乱码:

#ifdef UNICODE
WCHAR wText[65];
ListView_GetItemText(_hListCtrl, _pCurProp->cursorItem, _pCurProp->cursorSubItem, wText, SUBITEM_LENGTH);
wText[_pCurProp->cursorPos] = (TCHAR)wParam;
::WideCharToMultiByte(CP_ACP, 0, wText, -1, text, SUBITEM_LENGTH, NULL, NULL);
#else
ListView_GetItemText(_hListCtrl, _pCurProp->cursorItem, _pCurProp->cursorSubItem, text, SUBITEM_LENGTH);
#endif

PS:附本次开发的基于行号文本区域复制的插件下载地址,解压后将NppPluginTextSelect.dll放在NotePad++的安装文件夹Notepad++\plugins下就可以,然后又一次启动NotePad++软件,在【插件】菜单中查找【Text
Selection Helper】菜单项。

http://download.csdn.net/detail/xiaoding133/8912559

支持按行号区域文本选择的NotePad++插件开发的更多相关文章

  1. PyCharm 教程(四)显示行号

    PyCharm 教程(四)显示行号 在PyCharm 里,显示行号有两种办法: 1,临时设置.右键单击行号处,选择 Show Line Numbers. 但是这种方法,只对一个文件有效,并且,重启Py ...

  2. pycharm显示行号

    在PyCharm 里,显示行号有两种办法: 1,临时设置.右键单击行号处,选择 Show Line Numbers. 但是这种方法,只对一个文件有效,并且,重启PyCharm 后消失. 2,永久设置. ...

  3. notepad++ 如何选择10000行-20000行之间的文本?

    最近要上传导入一批数据,但是数据太多,一次上传不了,所以就要分批上传,而且数据全部在一个txt里面,这时就想一次复制一部分出来导入,直到导入完成,但是问题来了,数据太多,选择1到10000行,鼠标要拉 ...

  4. ExtJS表格——行号、复选框、选择模型

    本篇的内容是为表格添加行号,和复选框,最后谈一下Ext的选择模型.内容比较简单,就直接上代码了.一. 设置行号   行号的设置主要问题在于删除某一行后需要重新计算行号  Ext.onReady(fun ...

  5. 打印文本中的所有单词,并且打印每个单词出现的行号,非实义单词不考虑(TCPL,练习6-3)

    建立一棵二叉树,每个接单存放单词以及指向一个链表的指针,以及指向左右节点的指针.链表内存放行号以及指向下一个链表节点的指针. 每录入一个单词,先寻找二叉树,再寻找它的链表,分别将单词和行号插入二叉树和 ...

  6. Linux vi 文本代码时显示行号或不显示行号

    Linux vi 文本代码时显示行号或不显示行号 前提  安装了vim $vi ~/.vimrc 显示的话加上 set nu 不想显示的话可以注释掉 "set nu 之后 $source ~ ...

  7. 文本编辑器vim——三种模式、显示行号、插入命令、行快速定位、行内定位

    1.vim的三种工作模式: (1)利用vim命令新建文件: 点击entre键执行命令后,开始向文本中输入想要写入的内容: (2)命令行模式(ESC): 不管用户处于何种模式,只要单击Esc键,即可进入 ...

  8. excel VBA返回选中单元格区域的行数、列数,以及活动单元格的行号和列号

    Private Sub Worksheet_SelectionChange(ByVal Target As Range) '可以直接sub(),不然选择就会触发vba    Dim rows_coun ...

  9. linux vim 配置文件(高亮+自动缩进+行号+折叠+优化)

    点评:将一下代码copy到 用户目录下 新建文件为 .vimrc保存即可生效 如果想所有用户生效 请修改 /etc/vimrc (建议先cp一份)"===================== ...

随机推荐

  1. python获取文件属性

    提供三段代码 1.os模块 import os def TestFileAttributes(): # This function is platform indepedent. statinfo = ...

  2. HAproxy 代理技术原理探究

    HAproxy 技术分享 简介 HAProxy是一款提供高可用性.负载均衡以及基于TCP(第四层)和HTTP(第七层)应用的代理软件 Features 1.免费 2.能够做到4层以上代理 3.高性能 ...

  3. Django 模板中使用css, javascript

    Django 模板中使用css, javascript (r'^css/(?Ppath.*)$', 'django.views.static.serve', {'document_root': '/v ...

  4. CodeForces 1070J Streets and Avenues in Berhattan 性质+动态规划

    题目大意: 你有$k$个数,分为$26$种 对于每个数,你可以选择选进$A$集合或者$B$集合或者不选 要求$A$集合中必须有$n$个数,$B$集合中必须有$m$个数 记第$i$种数在$A$集合中的个 ...

  5. Contest Reviews(Updating)

    现在每天至少一套题又不太想写题解…… 那就开个坑总结下每场的失误和特定题目的技巧吧 2018.8.25[ZROI] T3传送门 T1:找规律找崩了…… 最好不要一上来就钻进大讨论,先想有没有普适规律 ...

  6. hdu 5248 贪心

    题意:

  7. IntelliJ IDEA代码分屏显示

  8. jQuery制作水平多级下拉菜单

    本篇体验使用jQuery制作水平的.多级的.下拉菜单. 下拉菜单的html部分如下. <body> <nav class="main-nav"> <u ...

  9. datagrid在MVC中的运用02-结合搜索

    本文接着上一篇,来体验给datagrid加上搜索功能.主要涉及到: ※ 把一个div与datagrid相关起来 ※ datagrid接收查询参数 ※ 查询参数的封装 效果图: 查询参数封装 分页相关的 ...

  10. MVC客户端使用 Mustache.js把json数据填充到模版中

    使用Mustache的好处是:可以把一些反复用到的html部分定义成Mustache模版,以便多次使用.使用Mustache的大致步骤是: →从后台拿到json数据 →获取前台页面预先定义好Musta ...