1、Notepad++介绍
Notepad++是一个台湾人使用C++开发的开源免费的文本编辑器,它是一个多国语言版的编辑器,包含简体中文,使用它可以方便地编辑C、C++、Java、C#、XML、HTML、PHP、CSS等等纯文本文件,支持正则搜索、文件夹搜索、编码转换、文件比较等,可以媲美UltraEdit;关键的支持插件开发。
官方网站的地址是:http://notepad-plus-plus.org/
Sourceforge地址:http://sourceforge.net/apps/mediawiki/notepad-plus
另外,Npp是基于开源控件Scintilla 开发的。
Scintilla官网地址:http://www.scintilla.org/
2、Notepad++插件实现
之前开发的一个自动测试的项目,由于各种流程、界面以及报告都是以XML脚本的方式定义的,项目实施时需要经常编辑脚本,就个实施工程师推荐这个小巧方便的编辑工具,评价还不错。
最近实施的一个项目中需要把大量的格式不一致的excel和word文档编辑成项目格式的XML文档,一个一个的编辑实在麻烦、工作量大,为了减轻实施的工作量,决定给Notepad++开发一个插件。
在Sourceforge中,相关文档已经详细的说明了插件开发的方式,基本都是英文的。Npp提供了对多种语言开发的插件的支持,包括C#、VC++/MFC、DELPHI等。看了C#的比较麻烦,MFC的简单易开发,就选了用VC做。
插件开发说明地址:
http://sourceforge.net/apps/mediawiki/notepad-plus/index.php?title=Plugin_Resources
其中有plus-demo可下载,详细介绍页面地址:
http://sourceforge.net/apps/mediawiki/notepad-plus/index.php?title=Plugin_Development
主要Scintilla控件接口介绍页面:
http://www.scintilla.org/ScintillaDoc.html
插件接入方式主要是消息和函数指针。主要包含四个头文件:Notepad_plus_msgs.h(npp消息定义)、menuCmdID.h(菜单项ID定义)、 Scintilla.h(Scintilla控件消息定义)、PluginDefinition.h(插件接口定义);
插件接口定义如下:
其中主要需要实现setInfo、getName、getFuncsArray、isUnicode,如有需要消息反馈可实现messageProc;另外,在插件dll加载时还需要一些初始化操作以及x卸载时的释放操作,所有添加有XmlEditorInit函数和XmlEditorCleanUp函数,该两函数在dll的CWinApp的InitInstance和ExitInstance函数中分别调用即可。
主体功能实现在接口指针结构体数组的实现,一下为功能主体实现接入部分源代码。
头文件:
实现文件:
* NppPlugin_XmlEditor.cpp
*
* Copyright (c)2012,
*
* 2012-10-10 V1.0 lizhi<msn:[email protected]> created
*
*/
#include "StdAfx.h"
#include "NppPlugin_XmlEditor.h"
#include "XmlEditor_Function.h"
#include "NppPlugin_StdApi.h"
// 插件名称
TCHAR* thePluginName = _T("XML Editor");
// 函数表指针
FuncItem* theFuncArray = NULL;
// 数据指针
NppData* theNppData = NULL;
// 快捷键表
ShortcutKey* theShortcutArray = NULL;
// 设置快捷键
void XmlEditorSetShortcutKey(int nID, bool bCtrl, bool bAlt, bool bShift, UCHAR key)
{
if (nID < FUNC_COUNT)
{
theShortcutArray[nID]._isCtrl = bCtrl;
theShortcutArray[nID]._isAlt = bAlt;
theShortcutArray[nID]._isShift = bShift;
theShortcutArray[nID]._key = key;
}
}
// 设置函数
void XmlEditorSetCommand(int nID, TCHAR *strCmdName, PFUNCPLUGINCMD pFunc, bool bCheck0nInit)
{
if (nID < FUNC_COUNT)
{
lstrcpy(theFuncArray[nID]._itemName, strCmdName);
theFuncArray[nID]._pFunc = pFunc;
theFuncArray[nID]._init2Check = bCheck0nInit;
theFuncArray[nID]._pShKey = theShortcutArray+nID;
}
}
// 添加菜单
void XmlEditorInitCommandMenu(void)
{
XmlEditorSetShortcutKey(FUNC_PASTE_SHEET_HEADER, true, false, false, 103); //7
XmlEditorSetShortcutKey(FUNC_PASTE_SHEET_ATTENTION, true, false, false, 104); //8
XmlEditorSetShortcutKey(FUNC_PASTE_SHEET_CONTENT, true, false, false, 105); //9
XmlEditorSetCommand(FUNC_PASTE_SHEET_HEADER, _T("Paste Sheet Header"), XmlEditorPasteSheetHeader, false);
XmlEditorSetCommand(FUNC_PASTE_SHEET_ATTENTION, _T("Paste Sheet Attention"), XmlEditorPasteSheetAttention, false);
XmlEditorSetCommand(FUNC_PASTE_SHEET_CONTENT, _T("Paste Sheet Content"), XmlEditorPasteSheetContent, false);
}
// 初始化
void XmlEditorInit(HANDLE hModule)
{
theFuncArray = (FuncItem *)malloc(sizeof(FuncItem) * FUNC_COUNT);
memset(theFuncArray, 0, sizeof(FuncItem) * FUNC_COUNT);
theNppData = (NppData *)malloc(sizeof(NppData));
memset(theNppData, 0, sizeof(NppData));
theShortcutArray = (ShortcutKey *)malloc(sizeof(ShortcutKey) * FUNC_COUNT);
memset(theShortcutArray, 0, sizeof(ShortcutKey) * FUNC_COUNT);
XmlEditorInitCommandMenu();
}
// 清除
void XmlEditorCleanUp(void)
{
if (theFuncArray != NULL)
{
free(theFuncArray);
theFuncArray = NULL;
}
if (theShortcutArray != NULL)
{
free(theShortcutArray);
theShortcutArray = NULL;
}
if (theNppData != NULL)
{
free(theNppData);
theNppData = NULL;
}
}
3、插件Demo代码