Notepad++插件开发

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(插件接口定义);

插件接口定义如下: 

复制代码
  // this file is part of notepad++ 
 // Copyright (C)2003 Don HO <[email protected]>
 
//
 
// This program is free software; you can redistribute it and/or
 
// modify it under the terms of the GNU General Public License
 
// as published by the Free Software Foundation; either
 
// version 2 of the License, or (at your option) any later version.
 
//
 
// This program is distributed in the hope that it will be useful,
 
// but WITHOUT ANY WARRANTY; without even the implied warranty of
 
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
// GNU General Public License for more details.
 
//
 
// You should have received a copy of the GNU General Public License
 
// along with this program; if not, write to the Free Software
 
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
 #ifndef PLUGININTERFACE_H
  #define PLUGININTERFACE_H
 
 #include <windows.h>
 #include  " NppPlugin_Scintilla.h "
 #include  " NppPlugin_Msgs.h "
 #include  " NppPlugin_MenuCmdID.h "
 
  const  int nbChar =  64;
 
 typedef  const TCHAR * (__cdecl * PFUNCGETNAME)();
 
 typedef  struct _NppData {
     HWND _nppHandle;            
     HWND _scintillaMainHandle;
     HWND _scintillaSecondHandle;
 } NppData;
 
 typedef  void (__cdecl * PFUNCSETINFO)(NppData);
 typedef  void (__cdecl * PFUNCPLUGINCMD)();
 typedef  void (__cdecl * PBENOTIFIED)(SCNotification *);
 typedef LRESULT (__cdecl * PMESSAGEPROC)(UINT Message, WPARAM wParam, LPARAM lParam);
 
 typedef  struct _ShortcutKey {
      bool _isCtrl;
      bool _isAlt;
      bool _isShift;
     UCHAR _key;
 } ShortcutKey;
 
 typedef  struct _FuncItem {
     TCHAR _itemName[nbChar];
     PFUNCPLUGINCMD _pFunc;
      int _cmdID;
      bool _init2Check;
     ShortcutKey *_pShKey;
 } FuncItem;
 
 typedef FuncItem * (__cdecl * PFUNCGETFUNCSARRAY)( int *);
 
  //  You should implement (or define an empty function body) those functions which are called by Notepad++ plugin manager
  extern  " C " __declspec(dllexport)  void setInfo(NppData);
  extern  " C " __declspec(dllexport)  const TCHAR * getName();
  extern  " C " __declspec(dllexport) FuncItem * getFuncsArray( int *);
  extern  " C " __declspec(dllexport)  void beNotified(SCNotification *);
  extern  " C " __declspec(dllexport) LRESULT messageProc(UINT Message, WPARAM wParam, LPARAM lParam);
  extern  " C " __declspec(dllexport) BOOL isUnicode();
 
  #endif  // PLUGININTERFACE_H
 插件接口实现如下:
 #include  " StdAfx.h "
 #include  " NppPlugin_StdApi.h "
 #include  " NppPlugin_XmlEditor.h "
  //  插件名称
  extern TCHAR* thePluginName;
  //  函数表指针
  extern FuncItem* theFuncArray;
  //  数据指针
  extern NppData* theNppData;
 
  //  api setInfo
  extern  " C " __declspec(dllexport) 
  void setInfo(NppData notpadPlusData)
 {
     (*theNppData) = notpadPlusData;
 }
 
  //  api getName
  extern  " C " __declspec(dllexport) 
  const TCHAR * getName()
 {
      return thePluginName;
 }
 
  //  api getFuncsArray
  extern  " C " __declspec(dllexport) 
 FuncItem * getFuncsArray( int *nbF)
 {
     *nbF = FUNC_COUNT;
      return theFuncArray;
 }
 
  //  api beNotified
  extern  " C " __declspec(dllexport) 
  void beNotified(SCNotification *notifyCode)
 {
 }
 
  //  api messageProc
  extern  " C " __declspec(dllexport) 
 LRESULT messageProc(UINT nMessage, WPARAM wParam, LPARAM lParam)
 {
      if (nMessage == WM_MOVE)
     {
          // ::MessageBox(NULL, "move", "", MB_OK);
     }
      return TRUE;
 }
 
  //  api isUnicode
  extern  " C " __declspec(dllexport) 
 BOOL isUnicode()
 {
      return TRUE;
 }
复制代码

  

其中主要需要实现setInfogetNamegetFuncsArrayisUnicode,如有需要消息反馈可实现messageProc;另外,在插件dll加载时还需要一些初始化操作以及x卸载时的释放操作,所有添加有XmlEditorInit函数和XmlEditorCleanUp函数,该两函数在dllCWinAppInitInstanceExitInstance函数中分别调用即可。

主体功能实现在接口指针结构体数组的实现,一下为功能主体实现接入部分源代码。

头文件:

复制代码
/*
  * NppPlugin_XmlEditor.h
  *
  * Copyright (c)2012,
  *
  * 2012-10-10 V1.0 lizhi<msn:[email protected]> created
  *
  
*/ 
  #pragma once
 
  //  枚举API ID
  enum FUNCITEM_ID
 {
     FUNC_PASTE_SHEET_HEADER =  0,
     FUNC_PASTE_SHEET_ATTENTION,
     FUNC_PASTE_SHEET_CONTENT,
     FUNC_COUNT,
 };
 
  //  初始化
  void XmlEditorInit(HANDLE hModule);
  //  清除
   void XmlEditorCleanUp( void); 
复制代码


实现文件: 

复制代码
  /*   

  * 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, truefalsefalse103); //7
     XmlEditorSetShortcutKey(FUNC_PASTE_SHEET_ATTENTION, truefalsefalse104); //8
     XmlEditorSetShortcutKey(FUNC_PASTE_SHEET_CONTENT, truefalsefalse105); //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, 0sizeof(FuncItem) * FUNC_COUNT);
 
     theNppData = (NppData *)malloc(sizeof(NppData));
     memset(theNppData, 0sizeof(NppData));
 
     theShortcutArray = (ShortcutKey *)malloc(sizeof(ShortcutKey) * FUNC_COUNT);
     memset(theShortcutArray, 0sizeof(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代码

[email protected]

你可能感兴趣的:(Notepad++插件开发)