Demo.cs 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381
  1. using System;
  2. using System.Drawing;
  3. using System.Drawing.Imaging;
  4. using System.IO;
  5. using System.Runtime.InteropServices;
  6. using System.Text;
  7. using System.Text.RegularExpressions;
  8. using System.Threading;
  9. using System.Windows.Forms;
  10. using Demo.Forms;
  11. namespace Demo
  12. {
  13. partial class PluginBase
  14. {
  15. #region " Fields "
  16. internal const string PluginName = "Offical .Net Demo";
  17. static string _iniFilePath;
  18. static readonly string SectionName = "Insert Extension";
  19. static readonly string KeyName = "doCloseTag";
  20. static bool _doCloseTag;
  21. static readonly string SessionFilePath = @"C:\text.session";
  22. static FrmGoToLine _frmGoToLine;
  23. internal static int IdFrmGotToLine = -1;
  24. static readonly Bitmap TbBmp = Properties.Resources.star;
  25. static readonly Bitmap TbBmpTbTab = Properties.Resources.star_bmp;
  26. static Icon _tbIcon;
  27. #endregion
  28. #region " Startup/CleanUp "
  29. internal static void CommandMenuInit()
  30. {
  31. // Initialization of your plugin commands
  32. // You should fill your plugins commands here
  33. //
  34. // Firstly we get the parameters from your plugin config file (if any)
  35. //
  36. // get path of plugin configuration
  37. var sbIniFilePath = new StringBuilder(Win32.MAX_PATH);
  38. Win32.SendMessage(NppData._nppHandle, NppMsg.NPPM_GETPLUGINSCONFIGDIR, Win32.MAX_PATH, sbIniFilePath);
  39. _iniFilePath = sbIniFilePath.ToString();
  40. // if config path doesn't exist, we create it
  41. if (!Directory.Exists(_iniFilePath))
  42. {
  43. Directory.CreateDirectory(_iniFilePath);
  44. }
  45. // make your plugin config file full file path name
  46. _iniFilePath = Path.Combine(_iniFilePath, PluginName + ".ini");
  47. // get the parameter value from plugin config
  48. _doCloseTag = (Win32.GetPrivateProfileInt(SectionName, KeyName, 0, _iniFilePath) != 0);
  49. // with function :
  50. // SetCommand(int index, // zero based number to indicate the order of command
  51. // string commandName, // the command name that you want to see in plugin menu
  52. // NppFuncItemDelegate functionPointer, // the symbol of function (function pointer) associated with this command. The body should be defined below. See Step 4.
  53. // ShortcutKey *shortcut, // optional. Define a shortcut to trigger this command
  54. // bool check0nInit // optional. Make this menu item be checked visually
  55. // );
  56. SetCommand(0, "Hello Notepad++", Hello);
  57. SetCommand(1, "Hello (with FX)", HelloFx);
  58. SetCommand(2, "What is Notepad++?", WhatIsNpp);
  59. // Here you insert a separator
  60. SetCommand(3, "---", null);
  61. // Shortcut :
  62. // Following makes the command bind to the shortcut Alt-F
  63. SetCommand(4, "Current Full Path", InsertCurrentFullPath, new ShortcutKey(false, true, false, Keys.F));
  64. SetCommand(5, "Current File Name", InsertCurrentFileName);
  65. SetCommand(6, "Current Directory", InsertCurrentDirectory);
  66. SetCommand(7, "Date && Time - short format", InsertShortDateTime);
  67. SetCommand(8, "Date && Time - long format", InsertLongDateTime);
  68. SetCommand(9, "Close HTML/XML tag automatically", CheckInsertHtmlCloseTag, new ShortcutKey(false, true, false, Keys.Q), _doCloseTag);
  69. SetCommand(10, "---", null);
  70. SetCommand(11, "Get File Names Demo", GetFileNamesDemo);
  71. SetCommand(12, "Get Session File Names Demo", GetSessionFileNamesDemo);
  72. SetCommand(13, "Save Current Session Demo", SaveCurrentSessionDemo);
  73. SetCommand(14, "---", null);
  74. SetCommand(15, "Dockable Dialog Demo", DockableDlgDemo); IdFrmGotToLine = 15;
  75. }
  76. internal static void SetToolBarIcon()
  77. {
  78. var tbIcons = new ToolbarIcons();
  79. tbIcons.hToolbarBmp = TbBmp.GetHbitmap();
  80. var pTbIcons = Marshal.AllocHGlobal(Marshal.SizeOf(tbIcons));
  81. Marshal.StructureToPtr(tbIcons, pTbIcons, false);
  82. Win32.SendMessage(NppData._nppHandle, NppMsg.NPPM_ADDTOOLBARICON, FuncItems.Items[IdFrmGotToLine]._cmdID, pTbIcons);
  83. Marshal.FreeHGlobal(pTbIcons);
  84. }
  85. internal static void PluginCleanUp()
  86. {
  87. Win32.WritePrivateProfileString(SectionName, KeyName, _doCloseTag ? "1" : "0", _iniFilePath);
  88. }
  89. #endregion
  90. #region " Menu functions "
  91. static void Hello()
  92. {
  93. // Open a new document
  94. Win32.SendMessage(NppData._nppHandle, NppMsg.NPPM_MENUCOMMAND, 0, NppMenuCmd.IDM_FILE_NEW);
  95. // Say hello now :
  96. // Scintilla control has no Unicode mode, so we use ANSI here (marshalled as ANSI by default)
  97. Win32.SendMessage(GetCurrentScintilla(), SciMsg.SCI_SETTEXT, 0, "Hello, Notepad++... from .NET!");
  98. }
  99. static void HelloFx()
  100. {
  101. Hello();
  102. new Thread(CallbackHelloFx).Start();
  103. }
  104. static void CallbackHelloFx()
  105. {
  106. var curScintilla = GetCurrentScintilla();
  107. var currentZoomLevel = (int)Win32.SendMessage(curScintilla, SciMsg.SCI_GETZOOM, 0, 0);
  108. var i = currentZoomLevel;
  109. for (var j = 0 ; j < 4 ; j++)
  110. {
  111. for ( ; i >= -10; i--)
  112. {
  113. Win32.SendMessage(curScintilla, SciMsg.SCI_SETZOOM, i, 0);
  114. Thread.Sleep(30);
  115. }
  116. Thread.Sleep(100);
  117. for ( ; i <= 20 ; i++)
  118. {
  119. Thread.Sleep(30);
  120. Win32.SendMessage(curScintilla, SciMsg.SCI_SETZOOM, i, 0);
  121. }
  122. Thread.Sleep(100);
  123. }
  124. for ( ; i >= currentZoomLevel ; i--)
  125. {
  126. Thread.Sleep(30);
  127. Win32.SendMessage(curScintilla, SciMsg.SCI_SETZOOM, i, 0);
  128. }
  129. }
  130. static void WhatIsNpp()
  131. {
  132. var text2Display = "Notepad++ is a free (as in \"free speech\" and also as in \"free beer\") " +
  133. "source code editor and Notepad replacement that supports several languages.\n" +
  134. "Running in the MS Windows environment, its use is governed by GPL License.\n\n" +
  135. "Based on a powerful editing component Scintilla, Notepad++ is written in C++ and " +
  136. "uses pure Win32 API and STL which ensures a higher execution speed and smaller program size.\n" +
  137. "By optimizing as many routines as possible without losing user friendliness, Notepad++ is trying " +
  138. "to reduce the world carbon dioxide emissions. When using less CPU power, the PC can throttle down " +
  139. "and reduce power consumption, resulting in a greener environment.";
  140. new Thread(CallbackWhatIsNpp).Start(text2Display);
  141. }
  142. static void CallbackWhatIsNpp(object data)
  143. {
  144. var text2Display = (string)data;
  145. // Open a new document
  146. Win32.SendMessage(NppData._nppHandle, NppMsg.NPPM_MENUCOMMAND, 0, NppMenuCmd.IDM_FILE_NEW);
  147. // Get the current scintilla
  148. var curScintilla = GetCurrentScintilla();
  149. var srand = new Random(DateTime.Now.Millisecond);
  150. var rangeMin = 0;
  151. var rangeMax = 250;
  152. for (var i = 0; i < text2Display.Length; i++)
  153. {
  154. var charToShow = new StringBuilder(text2Display[i].ToString());
  155. var ranNum = srand.Next(rangeMin, rangeMax);
  156. Thread.Sleep(ranNum + 30);
  157. Win32.SendMessage(curScintilla, SciMsg.SCI_APPENDTEXT, 1, charToShow);
  158. Win32.SendMessage(curScintilla, SciMsg.SCI_GOTOPOS, (int)Win32.SendMessage(curScintilla, SciMsg.SCI_GETLENGTH, 0, 0), 0);
  159. }
  160. }
  161. static void InsertCurrentFullPath()
  162. {
  163. InsertCurrentPath(NppMsg.FULL_CURRENT_PATH);
  164. }
  165. static void InsertCurrentFileName()
  166. {
  167. InsertCurrentPath(NppMsg.FILE_NAME);
  168. }
  169. static void InsertCurrentDirectory()
  170. {
  171. InsertCurrentPath(NppMsg.CURRENT_DIRECTORY);
  172. }
  173. static void InsertCurrentPath(NppMsg which)
  174. {
  175. var msg = NppMsg.NPPM_GETFULLCURRENTPATH;
  176. if (which == NppMsg.FILE_NAME)
  177. msg = NppMsg.NPPM_GETFILENAME;
  178. else if (which == NppMsg.CURRENT_DIRECTORY)
  179. msg = NppMsg.NPPM_GETCURRENTDIRECTORY;
  180. var path = new StringBuilder(Win32.MAX_PATH);
  181. Win32.SendMessage(NppData._nppHandle, msg, 0, path);
  182. Win32.SendMessage(GetCurrentScintilla(), SciMsg.SCI_REPLACESEL, 0, path);
  183. }
  184. static void InsertShortDateTime()
  185. {
  186. InsertDateTime(false);
  187. }
  188. static void InsertLongDateTime()
  189. {
  190. InsertDateTime(true);
  191. }
  192. static void InsertDateTime(bool longFormat)
  193. {
  194. var dateTime = string.Format("{0} {1}",
  195. DateTime.Now.ToShortTimeString(),
  196. longFormat ? DateTime.Now.ToLongDateString() : DateTime.Now.ToShortDateString());
  197. Win32.SendMessage(GetCurrentScintilla(), SciMsg.SCI_REPLACESEL, 0, dateTime);
  198. }
  199. static void CheckInsertHtmlCloseTag()
  200. {
  201. _doCloseTag = !_doCloseTag;
  202. var i = Win32.CheckMenuItem(Win32.GetMenu(NppData._nppHandle), FuncItems.Items[9]._cmdID,
  203. Win32.MF_BYCOMMAND | (_doCloseTag ? Win32.MF_CHECKED : Win32.MF_UNCHECKED));
  204. }
  205. internal static void DoInsertHtmlCloseTag(char newChar)
  206. {
  207. var docType = LangType.L_TEXT;
  208. Win32.SendMessage(NppData._nppHandle, NppMsg.NPPM_GETCURRENTLANGTYPE, 0, ref docType);
  209. var isDocTypeHtml = (docType == LangType.L_HTML || docType == LangType.L_XML || docType == LangType.L_PHP);
  210. if (_doCloseTag && isDocTypeHtml)
  211. {
  212. if (newChar == '>')
  213. {
  214. var bufCapacity = 512;
  215. var hCurrentEditView = GetCurrentScintilla();
  216. var currentPos = (int)Win32.SendMessage(hCurrentEditView, SciMsg.SCI_GETCURRENTPOS, 0, 0);
  217. var beginPos = currentPos - (bufCapacity - 1);
  218. var startPos = (beginPos > 0) ? beginPos : 0;
  219. var size = currentPos - startPos;
  220. if (size >= 3)
  221. {
  222. using (var tr = new SciTextRange(startPos, currentPos, bufCapacity))
  223. {
  224. Win32.SendMessage(hCurrentEditView, SciMsg.SCI_GETTEXTRANGE, 0, tr.NativePointer);
  225. var buf = tr.LpstrText;
  226. if (buf[size - 2] != '/')
  227. {
  228. var insertString = new StringBuilder("</");
  229. var pCur = size - 2;
  230. for (; (pCur > 0) && (buf[pCur] != '<') && (buf[pCur] != '>'); )
  231. pCur--;
  232. if (buf[pCur] == '<')
  233. {
  234. pCur++;
  235. var regex = new Regex(@"[\._\-:\w]");
  236. while (regex.IsMatch(buf[pCur].ToString()))
  237. {
  238. insertString.Append(buf[pCur]);
  239. pCur++;
  240. }
  241. insertString.Append('>');
  242. if (insertString.Length > 3)
  243. {
  244. Win32.SendMessage(hCurrentEditView, SciMsg.SCI_BEGINUNDOACTION, 0, 0);
  245. Win32.SendMessage(hCurrentEditView, SciMsg.SCI_REPLACESEL, 0, insertString);
  246. Win32.SendMessage(hCurrentEditView, SciMsg.SCI_SETSEL, currentPos, currentPos);
  247. Win32.SendMessage(hCurrentEditView, SciMsg.SCI_ENDUNDOACTION, 0, 0);
  248. }
  249. }
  250. }
  251. }
  252. }
  253. }
  254. }
  255. }
  256. static void GetFileNamesDemo()
  257. {
  258. var nbFile = (int)Win32.SendMessage(NppData._nppHandle, NppMsg.NPPM_GETNBOPENFILES, 0, 0);
  259. MessageBox.Show(nbFile.ToString(), "Number of opened files:");
  260. using (var cStrArray = new ClikeStringArray(nbFile, Win32.MAX_PATH))
  261. {
  262. if (Win32.SendMessage(NppData._nppHandle, NppMsg.NPPM_GETOPENFILENAMES, cStrArray.NativePointer, nbFile) != IntPtr.Zero)
  263. foreach (var file in cStrArray.ManagedStringsUnicode) MessageBox.Show(file);
  264. }
  265. }
  266. static void GetSessionFileNamesDemo()
  267. {
  268. var nbFile = (int)Win32.SendMessage(NppData._nppHandle, NppMsg.NPPM_GETNBSESSIONFILES, 0, SessionFilePath);
  269. if (nbFile < 1)
  270. {
  271. MessageBox.Show("Please modify \"sessionFilePath\" in \"Demo.cs\" in order to point to a valid session file", "Error");
  272. return;
  273. }
  274. MessageBox.Show(nbFile.ToString(), "Number of session files:");
  275. using (var cStrArray = new ClikeStringArray(nbFile, Win32.MAX_PATH))
  276. {
  277. if (Win32.SendMessage(NppData._nppHandle, NppMsg.NPPM_GETSESSIONFILES, cStrArray.NativePointer, SessionFilePath) != IntPtr.Zero)
  278. foreach (var file in cStrArray.ManagedStringsUnicode) MessageBox.Show(file);
  279. }
  280. }
  281. static void SaveCurrentSessionDemo()
  282. {
  283. var sessionPath = Marshal.PtrToStringUni(Win32.SendMessage(NppData._nppHandle, NppMsg.NPPM_SAVECURRENTSESSION, 0, SessionFilePath));
  284. if (!string.IsNullOrEmpty(sessionPath))
  285. MessageBox.Show(sessionPath, "Saved Session File :", MessageBoxButtons.OK);
  286. }
  287. static void DockableDlgDemo()
  288. {
  289. // Dockable Dialog Demo
  290. //
  291. // This demonstration shows you how to do a dockable dialog.
  292. // You can create your own non dockable dialog - in this case you don't nedd this demonstration.
  293. if (_frmGoToLine == null)
  294. {
  295. _frmGoToLine = new FrmGoToLine();
  296. using (var newBmp = new Bitmap(16, 16))
  297. {
  298. var g = Graphics.FromImage(newBmp);
  299. var colorMap = new ColorMap[1];
  300. colorMap[0] = new ColorMap();
  301. colorMap[0].OldColor = Color.Fuchsia;
  302. colorMap[0].NewColor = Color.FromKnownColor(KnownColor.ButtonFace);
  303. var attr = new ImageAttributes();
  304. attr.SetRemapTable(colorMap);
  305. g.DrawImage(TbBmpTbTab, new Rectangle(0, 0, 16, 16), 0, 0, 16, 16, GraphicsUnit.Pixel, attr);
  306. _tbIcon = Icon.FromHandle(newBmp.GetHicon());
  307. }
  308. var nppTbData = new NppTbData();
  309. nppTbData.hClient = _frmGoToLine.Handle;
  310. nppTbData.pszName = "Go To Line #";
  311. // the dlgDlg should be the index of funcItem where the current function pointer is in
  312. // this case is 15.. so the initial value of funcItem[15]._cmdID - not the updated internal one !
  313. nppTbData.dlgID = IdFrmGotToLine;
  314. // define the default docking behaviour
  315. nppTbData.uMask = NppTbMsg.DWS_DF_CONT_RIGHT | NppTbMsg.DWS_ICONTAB | NppTbMsg.DWS_ICONBAR;
  316. nppTbData.hIconTab = (uint)_tbIcon.Handle;
  317. nppTbData.pszModuleName = PluginName;
  318. var ptrNppTbData = Marshal.AllocHGlobal(Marshal.SizeOf(nppTbData));
  319. Marshal.StructureToPtr(nppTbData, ptrNppTbData, false);
  320. Win32.SendMessage(NppData._nppHandle, NppMsg.NPPM_DMMREGASDCKDLG, 0, ptrNppTbData);
  321. // Following message will toogle both menu item state and toolbar button
  322. Win32.SendMessage(NppData._nppHandle, NppMsg.NPPM_SETMENUITEMCHECK, FuncItems.Items[IdFrmGotToLine]._cmdID, 1);
  323. }
  324. else
  325. {
  326. if (!_frmGoToLine.Visible)
  327. {
  328. Win32.SendMessage(NppData._nppHandle, NppMsg.NPPM_DMMSHOW, 0, _frmGoToLine.Handle);
  329. Win32.SendMessage(NppData._nppHandle, NppMsg.NPPM_SETMENUITEMCHECK, FuncItems.Items[IdFrmGotToLine]._cmdID, 1);
  330. }
  331. else
  332. {
  333. Win32.SendMessage(NppData._nppHandle, NppMsg.NPPM_DMMHIDE, 0, _frmGoToLine.Handle);
  334. Win32.SendMessage(NppData._nppHandle, NppMsg.NPPM_SETMENUITEMCHECK, FuncItems.Items[IdFrmGotToLine]._cmdID, 0);
  335. }
  336. }
  337. _frmGoToLine.textBox1.Focus();
  338. }
  339. #endregion
  340. }
  341. }