近期发现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. 【基础知识】Dom基础

    [学习日记]Dom基础 1.   内容:使用JavaScript操作Dom进行DHTML开发 2.   目标:能共使用JavaScript操作Dom实现常见的DHTML效果 3.   DHTML= C ...

  2. Highmaps网页图表教程之数据标签与标签文本

    Highmaps网页图表教程之数据标签与标签文本 Highmaps数据标签 数据标签用于在地图图表上展现节点对应的数据.数据标签展现数据是静态的,只要节点一加载,数据标签就会出现在节点附近.在High ...

  3. 1015 Reversible Primes (20)(20 point(s))

    problem A reversible prime in any number system is a prime whose "reverse" in that number ...

  4. opencv 掩膜操作 滤波 卷积核定义 增强对比度 掩膜运算

    /* 矩阵的掩膜操作 0 掩膜mask 在这里进行增强对比度: [ [ 0,-1, 0 ], [-1, 5, -1], [ 0,-1, 0 ] ] 使用mask滑动图片每一个位置,进行卷积运算 这里这 ...

  5. JavaScript惰性函数定义

    函数是js世界的一等公民,js的动态性.易变性在函数的应用上,体现的淋漓尽致.做为参数,做为返回值等,正是函数这些特性,使得js开发变的有趣. 下面就阐述一下,js一个有趣的应用--惰性函数定义(La ...

  6. no device found for connection ‘ System eth0′

    解决办法: 1.删除/etc/udev/rules.d/70-persistent-net.rules文件,重启系统. 2.如果上面的不起作用,那么去看ifcfg-eth0文件中的HWADDR是否正确 ...

  7. js中什么是对象,对象的概念是什么?

    我们一直在用对象 可是你真的理解对象吗,js中有一个说法是一切皆对象,其实这里说的应该是 一切皆可看作对象 对象就是可以拥有属性和方法的一个集合 士兵就是一个对象,它拥有身高体重的属性,保家卫国,吃饭 ...

  8. php-curl小记

    用jQuery: $.ajax({ url:url, type:"POST", data:data, contentType:"application/json; cha ...

  9. C#线程安全的那些事

    还是上一次,面试的时候提到了C#线程安全的问题,当时回答的记不太清了,大概就是多线程同是调用某一个函数时可能会照成数据发生混乱,运行到最后发现产生的结果或数据并不是自己想要的,或是跨线程调用属性或方法 ...

  10. Linux shell命令中expr

    在Linux shell命令中expr虽然不是很起眼,但是它的作用是非常大的!到目前为止,我个人看来最大的作用就是两个——四则运算和字符串的操作. 先说四则运算,在Shell中四则运算不能简简单单的加 ...