1 //this file is part of notepad++ 2 //Copyright (C)2003 Don HO <donho@altern.org> 3 // 4 //This program is free software; you can redistribute it and/or 5 //modify it under the terms of the GNU General Public License 6 //as published by the Free Software Foundation; either 7 //version 2 of the License, or (at your option) any later version. 8 // 9 //This program is distributed in the hope that it will be useful, 10 //but WITHOUT ANY WARRANTY; without even the implied warranty of 11 //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 //GNU General Public License for more details. 13 // 14 //You should have received a copy of the GNU General Public License 15 //along with this program; if not, write to the Free Software 16 //Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 17 /** 18 * plugin demo 19 * 20 * License: GPL-2.0 or later 21 */ 22 module npp_demo.commands; 23 24 25 private static import core.stdc.stdint; 26 private static import core.stdc.stdio; 27 private static import core.stdc.stdlib; 28 private static import core.stdc.string; 29 private static import core.stdc.time; 30 private static import core.sys.windows.basetsd; 31 private static import core.sys.windows.winbase; 32 private static import core.sys.windows.windef; 33 private static import core.sys.windows.winnls; 34 private static import core.sys.windows.winnt; 35 private static import core.sys.windows.winuser; 36 private static import npp_api.PowerEditor.MISC.PluginsManager.Notepad_plus_msgs; 37 private static import npp_api.PowerEditor.MISC.PluginsManager.PluginInterface; 38 private static import npp_api.PowerEditor.ScitillaComponent.GoToLineDlg; 39 private static import npp_api.PowerEditor.WinControls.DockingWnd.Docking; 40 private static import npp_api.PowerEditor.menuCmdID; 41 private static import npp_api.pluginfunc.npp_msgs; 42 private static import npp_api.pluginfunc.path; 43 private static import npp_api.pluginfunc.scintilla_msg; 44 private static import npp_api.pluginfunc.string; 45 private static import npp_api.scintilla.Scintilla; 46 private static import npp_demo.GoToLineDlg; 47 private static import npp_demo.plugin_dll; 48 private static import std.path; 49 private static import std.string; 50 51 version (Windows): 52 53 //pragma(lib, "kernel32"); 54 //pragma(lib, "user32"); 55 56 enum DOCKABLE_DEMO_INDEX = 15; 57 enum bool shortDate = true; 58 enum bool longDate = false; 59 60 extern (C) 61 extern npp_api.PowerEditor.MISC.PluginsManager.PluginInterface.NppData nppData; 62 63 extern (C) 64 extern __gshared npp_api.PowerEditor.MISC.PluginsManager.PluginInterface.NppData gshared_nppData; 65 66 /** 67 * 68 */ 69 extern (Windows) 70 nothrow @nogc 71 package core.sys.windows.windef.DWORD threadZoomer(void*) 72 73 in 74 { 75 } 76 77 do 78 { 79 // Get the current scintilla 80 int currentEdit = -1; 81 npp_api.pluginfunc.npp_msgs.send_NPPM_GETCURRENTSCINTILLA(.gshared_nppData._nppHandle, currentEdit); 82 83 if (currentEdit == -1) { 84 return core.sys.windows.windef.FALSE; 85 } 86 87 core.sys.windows.windef.HWND curScintilla = (currentEdit == 0) ? (.gshared_nppData._scintillaMainHandle) : (.gshared_nppData._scintillaSecondHandle); 88 89 core.stdc.stdint.intptr_t currentZoomLevel = npp_api.pluginfunc.scintilla_msg.send_SCI_GETZOOM(curScintilla); 90 91 core.stdc.stdint.intptr_t i = currentZoomLevel; 92 93 for (size_t j = 0 ; j < 4 ; ++j) { 94 for ( ; i >= -10 ; i--) { 95 npp_api.pluginfunc.scintilla_msg.send_SCI_SETZOOM(curScintilla, i); 96 core.sys.windows.winbase.Sleep(30); 97 } 98 99 core.sys.windows.winbase.Sleep(100); 100 101 for ( ; i <= 20 ; ++i) { 102 core.sys.windows.winbase.Sleep(30); 103 npp_api.pluginfunc.scintilla_msg.send_SCI_SETZOOM(curScintilla, i); 104 } 105 106 core.sys.windows.winbase.Sleep(100); 107 } 108 109 core.sys.windows.winbase.Sleep(100); 110 111 for ( ; i >= currentZoomLevel ; i--) { 112 core.sys.windows.winbase.Sleep(30); 113 npp_api.pluginfunc.scintilla_msg.send_SCI_SETZOOM(curScintilla, i); 114 } 115 116 return core.sys.windows.windef.TRUE; 117 } 118 119 /** 120 * 121 */ 122 extern (Windows) 123 nothrow @nogc 124 package core.sys.windows.windef.DWORD threadTextPlayer(void* text2display) 125 126 in 127 { 128 } 129 130 do 131 { 132 enum RAND_MAX = 0x7FFF; 133 134 // Open a new document 135 npp_api.pluginfunc.npp_msgs.send_NPPM_MENUCOMMAND(.gshared_nppData._nppHandle, npp_api.PowerEditor.menuCmdID.IDM_FILE_NEW); 136 137 // Get the current scintilla 138 int currentEdit = -1; 139 npp_api.pluginfunc.npp_msgs.send_NPPM_GETCURRENTSCINTILLA(.gshared_nppData._nppHandle, currentEdit); 140 141 if (currentEdit == -1) { 142 return core.sys.windows.windef.FALSE; 143 } 144 145 core.sys.windows.windef.HWND curScintilla = (currentEdit == 0) ? (.gshared_nppData._scintillaMainHandle) : (.gshared_nppData._scintillaSecondHandle); 146 core.stdc.stdlib.srand(cast(uint)(core.stdc.time.time(core.sys.windows.windef.NULL))); 147 int rangeMin = 0; 148 int rangeMax = 250; 149 size_t length = core.stdc..string.strlen(cast(char*)(text2display)); 150 151 for (size_t i = 0 ; i < length; ++i) { 152 char[2] charToShow = [*((cast(char*)(text2display)) + i), '\0']; 153 154 version (none) { 155 int ranNum = rangeMin + cast(int)(cast(double)(core.stdc.stdlib.rand()) / (cast(double)(RAND_MAX) + 1) * rangeMax); 156 core.sys.windows.winbase.Sleep(ranNum + 30); 157 } 158 159 npp_api.pluginfunc.scintilla_msg.send_SCI_APPENDTEXT(curScintilla, 1, &(charToShow[0])); 160 npp_api.pluginfunc.scintilla_msg.send_SCI_GOTOPOS(curScintilla, npp_api.pluginfunc.scintilla_msg.send_SCI_GETLENGTH(curScintilla)); 161 } 162 163 return core.sys.windows.windef.TRUE; 164 } 165 166 /** 167 * plugin command 168 */ 169 extern (C) 170 nothrow @nogc 171 void hello() 172 173 do 174 { 175 // Open a new document 176 npp_api.pluginfunc.npp_msgs.send_NPPM_MENUCOMMAND(.nppData._nppHandle, npp_api.PowerEditor.menuCmdID.IDM_FILE_NEW); 177 178 // Get the current scintilla 179 int currentEdit = -1; 180 npp_api.pluginfunc.npp_msgs.send_NPPM_GETCURRENTSCINTILLA(.nppData._nppHandle, currentEdit); 181 182 if (currentEdit == -1) { 183 return; 184 } 185 186 core.sys.windows.windef.HWND curScintilla = (currentEdit == 0) ? (.nppData._scintillaMainHandle) : (.nppData._scintillaSecondHandle); 187 188 // Say hello now : 189 // Scintilla control has no Unicode mode, so we use (char*) here 190 enum string msg_text = "Hello, Notepad++!\0"; 191 npp_api.pluginfunc.scintilla_msg.send_SCI_SETTEXT(curScintilla, &(msg_text[0])); 192 } 193 194 /** 195 * plugin command 196 */ 197 extern (C) 198 nothrow @nogc 199 void helloFX() 200 201 do 202 { 203 hello(); 204 core.sys.windows.basetsd.HANDLE hThread = core.sys.windows.winbase.CreateThread(core.sys.windows.windef.NULL, 0, &threadZoomer, core.sys.windows.windef.NULL, 0, core.sys.windows.windef.NULL); 205 core.sys.windows.winbase.CloseHandle(hThread); 206 } 207 208 /** 209 * plugin command 210 */ 211 extern (C) 212 nothrow @nogc 213 void WhatIsNpp() 214 215 do 216 { 217 string text2display = `Notepad++ is a free (as in "free speech" and also as in "free beer") source code editor and Notepad replacement that supports several languages. 218 Running in the MS Windows environment, its use is governed by GPL License. 219 220 Based on a powerful editing component Scintilla, Notepad++ is written in C++ and uses pure Win32 API and STL which ensures a higher execution speed and smaller program size. 221 By optimizing as many routines as possible without losing user friendliness, Notepad++ is trying to reduce the world carbon dioxide emissions. When using less CPU power, the PC can throttle down and reduce power consumption, resulting in a greener environment.` ~ "\0"; 222 core.sys.windows.basetsd.HANDLE hThread = core.sys.windows.winbase.CreateThread(core.sys.windows.windef.NULL, 0, &.threadTextPlayer, cast(core.sys.windows.winnt.LPVOID*)(&(text2display[0])), 0, core.sys.windows.windef.NULL); 223 core.sys.windows.winbase.CloseHandle(hThread); 224 } 225 226 /** 227 * 228 */ 229 nothrow @nogc 230 void insertCurrentPath(int which) 231 232 do 233 { 234 int msg; 235 236 switch (which) { 237 case npp_api.PowerEditor.MISC.PluginsManager.Notepad_plus_msgs.FILE_NAME: 238 msg = npp_api.PowerEditor.MISC.PluginsManager.Notepad_plus_msgs.NPPM_GETFILENAME; 239 240 break; 241 242 case npp_api.PowerEditor.MISC.PluginsManager.Notepad_plus_msgs.CURRENT_DIRECTORY: 243 msg = npp_api.PowerEditor.MISC.PluginsManager.Notepad_plus_msgs.NPPM_GETCURRENTDIRECTORY; 244 245 break; 246 247 default: 248 msg = npp_api.PowerEditor.MISC.PluginsManager.Notepad_plus_msgs.NPPM_GETFULLCURRENTPATH; 249 250 break; 251 } 252 253 int currentEdit; 254 core.sys.windows.winnt.WCHAR[npp_api.pluginfunc.path.OS_MAX_PATH] path = '\0'; 255 256 // A message to Notepad++ to get a multibyte string (if ANSI mode) or a wide char string (if Unicode mode) 257 core.sys.windows.winuser.SendMessageW(.nppData._nppHandle, msg, path.length, cast(core.sys.windows.windef.LPARAM)(&(path[0]))); 258 259 // 260 npp_api.pluginfunc.npp_msgs.send_NPPM_GETCURRENTSCINTILLA(.nppData._nppHandle, currentEdit); 261 core.sys.windows.windef.HWND curScint = (currentEdit == 0) ? (.nppData._scintillaMainHandle) : (.nppData._scintillaSecondHandle); 262 263 int encoding = cast(int)(npp_api.pluginfunc.scintilla_msg.send_SCI_GETCODEPAGE(curScint)); 264 char[core.sys.windows.windef.MAX_PATH] pathA; 265 core.sys.windows.winnls.WideCharToMultiByte(encoding, 0, &(path[0]), -1, &(pathA[0]), core.sys.windows.windef.MAX_PATH, core.sys.windows.windef.NULL, core.sys.windows.windef.NULL); 266 npp_api.pluginfunc.scintilla_msg.send_SCI_REPLACESEL(curScint, &(pathA[0])); 267 } 268 269 /** 270 * plugin command 271 */ 272 extern (C) 273 nothrow @nogc 274 void insertCurrentFullPath() 275 276 do 277 { 278 .insertCurrentPath(npp_api.PowerEditor.MISC.PluginsManager.Notepad_plus_msgs.FULL_CURRENT_PATH); 279 } 280 281 /** 282 * plugin command 283 */ 284 extern (C) 285 nothrow @nogc 286 void insertCurrentFileName() 287 288 do 289 { 290 .insertCurrentPath(npp_api.PowerEditor.MISC.PluginsManager.Notepad_plus_msgs.FILE_NAME); 291 } 292 293 /** 294 * plugin command 295 */ 296 extern (C) 297 nothrow 298 void insertCurrentDirectory() 299 300 do 301 { 302 .insertCurrentPath(npp_api.PowerEditor.MISC.PluginsManager.Notepad_plus_msgs.CURRENT_DIRECTORY); 303 } 304 305 /** 306 * 307 */ 308 nothrow @nogc 309 void insertDateTime(bool format) 310 311 do 312 { 313 core.sys.windows.winnt.WCHAR[128] date; 314 core.sys.windows.winnt.WCHAR[128] time; 315 core.sys.windows.winnt.WCHAR[256] dateTime; 316 317 core.sys.windows.winbase.SYSTEMTIME st; 318 core.sys.windows.winbase.GetLocalTime(&st); 319 core.sys.windows.winnls.GetDateFormatW(core.sys.windows.winnls.LOCALE_USER_DEFAULT, ((format == .shortDate) ? (core.sys.windows.winnls.DATE_SHORTDATE) : (core.sys.windows.winnls.DATE_LONGDATE)), &st, core.sys.windows.windef.NULL, &(date[0]), 128); 320 core.sys.windows.winnls.GetTimeFormatW(core.sys.windows.winnls.LOCALE_USER_DEFAULT, core.sys.windows.winnls.TIME_NOSECONDS, &st, core.sys.windows.windef.NULL, &(time[0]), 128); 321 322 core.sys.windows.winuser.wsprintfW(&(dateTime[0]), &(npp_api.pluginfunc..string.c_wstring!("%s %s"w)[0]), &(time[0]), &(date[0])); 323 324 int currentEdit; 325 npp_api.pluginfunc.npp_msgs.send_NPPM_GETCURRENTSCINTILLA(.nppData._nppHandle, currentEdit); 326 core.sys.windows.windef.HWND curScint = (currentEdit == 0) ? (.nppData._scintillaMainHandle) : (.nppData._scintillaSecondHandle); 327 int encoding = cast(int)(npp_api.pluginfunc.scintilla_msg.send_SCI_GETCODEPAGE(curScint)); 328 char[core.sys.windows.windef.MAX_PATH] dateTimeA; 329 core.sys.windows.winnls.WideCharToMultiByte(encoding, 0, &(dateTime[0]), -1, &(dateTimeA[0]), core.sys.windows.windef.MAX_PATH, core.sys.windows.windef.NULL, core.sys.windows.windef.NULL); 330 npp_api.pluginfunc.scintilla_msg.send_SCI_REPLACESEL(curScint, &(dateTimeA[0])); 331 } 332 333 /** 334 * plugin command 335 */ 336 extern (C) 337 nothrow @nogc 338 void insertShortDateTime() 339 340 do 341 { 342 .insertDateTime(.shortDate); 343 } 344 345 /** 346 * plugin command 347 */ 348 extern (C) 349 nothrow @nogc 350 void insertLongDateTime() 351 352 do 353 { 354 .insertDateTime(.longDate); 355 } 356 357 /** 358 * plugin command 359 */ 360 extern (C) 361 nothrow @nogc 362 void getFileNamesDemo() 363 364 do 365 { 366 size_t malloc_count = 0; 367 int nbFile = cast(int)(npp_api.pluginfunc.npp_msgs.send_NPPM_GETNBOPENFILES(.nppData._nppHandle, npp_api.PowerEditor.MISC.PluginsManager.Notepad_plus_msgs.ALL_OPEN_FILES)); 368 char[16] temp = '\0'; 369 370 if (nbFile > 1) { 371 nbFile--; 372 } 373 374 core.stdc.stdio.snprintf(&(temp[0]), 4, &("%d\0"[0]), nbFile); 375 core.sys.windows.winuser.MessageBoxA(.nppData._nppHandle, &(temp[0]), &("Notepad++ opened files\0"[0]), core.sys.windows.winuser.MB_OK); 376 377 core.sys.windows.winnt.WCHAR** fileNames = cast(core.sys.windows.winnt.WCHAR**)(core.stdc.stdlib.malloc((core.sys.windows.winnt.WCHAR*).sizeof * nbFile)); 378 379 if (fileNames == null) { 380 return; 381 } 382 383 scope (exit) { 384 core.stdc.stdlib.free(fileNames); 385 fileNames = null; 386 } 387 388 for (size_t i = 0 ; i < nbFile; ++i) { 389 *(fileNames + i) = cast(core.sys.windows.winnt.WCHAR*)(core.stdc.stdlib.malloc(core.sys.windows.winnt.WCHAR.sizeof * core.sys.windows.windef.MAX_PATH)); 390 391 if ((*(fileNames + i)) == null) { 392 for (size_t j; j < malloc_count; ++j) { 393 core.stdc.stdlib.free(*(fileNames + j)); 394 } 395 396 return; 397 } 398 399 ++malloc_count; 400 } 401 402 scope (exit) { 403 for (size_t j; j < malloc_count; ++j) { 404 core.stdc.stdlib.free(*(fileNames + j)); 405 fileNames[j] = null; 406 } 407 } 408 409 if (npp_api.pluginfunc.npp_msgs.send_NPPM_GETOPENFILENAMES(.nppData._nppHandle, fileNames, nbFile)) { 410 for (size_t i = 0 ; i < nbFile; ++i) { 411 core.sys.windows.winuser.MessageBoxW(.nppData._nppHandle, *(fileNames + i), &("\0"w[0]), core.sys.windows.winuser.MB_OK); 412 } 413 } 414 } 415 416 /** 417 * plugin command 418 */ 419 extern (C) 420 nothrow @nogc 421 void getSessionFileNamesDemo() 422 423 do 424 { 425 size_t malloc_count = 0; 426 const core.sys.windows.winnt.WCHAR[] sessionFullPath = npp_api.pluginfunc..string.c_wstring!("c:\\test.session"w); 427 char[16] temp = '\0'; 428 size_t nbFile = npp_api.pluginfunc.npp_msgs.send_NPPM_GETNBSESSIONFILES(.nppData._nppHandle, &(sessionFullPath[0])); 429 430 if (nbFile == 0) { 431 core.sys.windows.winuser.MessageBoxW(.nppData._nppHandle, &(npp_api.pluginfunc..string.c_wstring!("Please modify \"sessionFullPath\" in \"NppInsertPlugin.cpp\" in order to point to a valide session file")[0]), &(npp_api.pluginfunc..string.c_wstring!("Error :"w)[0]), core.sys.windows.winuser.MB_OK); 432 433 return; 434 } 435 436 core.stdc.stdio.snprintf(&(temp[0]), 4, &("%d\0"[0]), nbFile); 437 core.sys.windows.winuser.MessageBoxA(.nppData._nppHandle, &(temp[0]), &("Notepad++ session files\0"[0]), core.sys.windows.winuser.MB_OK); 438 439 core.sys.windows.winnt.WCHAR** fileNames = cast(core.sys.windows.winnt.WCHAR**)(core.stdc.stdlib.malloc((core.sys.windows.winnt.WCHAR*).sizeof * nbFile)); 440 441 if (fileNames == null) { 442 return; 443 } 444 445 scope (exit) { 446 core.stdc.stdlib.free(fileNames); 447 fileNames = null; 448 } 449 450 for (size_t i = 0 ; i < nbFile; ++i) { 451 *(fileNames + i) = cast(core.sys.windows.winnt.WCHAR*)(core.stdc.stdlib.malloc(core.sys.windows.winnt.WCHAR.sizeof * core.sys.windows.windef.MAX_PATH)); 452 453 if ((*(fileNames + i)) == null) { 454 for (size_t j; j < malloc_count; ++j) { 455 core.stdc.stdlib.free(*(fileNames + j)); 456 } 457 458 return; 459 } 460 461 ++malloc_count; 462 } 463 464 scope (exit) { 465 for (size_t j; j < malloc_count; ++j) { 466 core.stdc.stdlib.free(*(fileNames + j)); 467 fileNames[j] = null; 468 } 469 } 470 471 if (npp_api.pluginfunc.npp_msgs.send_NPPM_GETSESSIONFILES(.nppData._nppHandle, fileNames, &(sessionFullPath[0]))) { 472 for (size_t i = 0 ; i < nbFile ; ++i) { 473 core.sys.windows.winuser.MessageBoxW(.nppData._nppHandle, *(fileNames + i), &(npp_api.pluginfunc..string.c_wstring!("session file name :"w)[0]), core.sys.windows.winuser.MB_OK); 474 } 475 } 476 } 477 478 /** 479 * plugin command 480 */ 481 extern (C) 482 nothrow @nogc 483 void saveCurrentSessionDemo() 484 485 do 486 { 487 const (core.sys.windows.winnt.WCHAR)* sessionPath = npp_api.pluginfunc.npp_msgs.send_NPPM_SAVECURRENTSESSION(.nppData._nppHandle, core.sys.windows.windef.NULL); 488 489 if (sessionPath != null) { 490 core.sys.windows.winuser.MessageBoxW(.nppData._nppHandle, sessionPath, &(npp_api.pluginfunc..string.c_wstring!("Saved Session File :"w)[0]), core.sys.windows.winuser.MB_OK); 491 } 492 } 493 494 /** 495 * plugin command 496 * Dockable Dialog Demo 497 * 498 * This demonstration shows you how to do a dockable dialog. 499 * You can create your own non dockable dialog - in this case you don't nedd this demonstration. 500 * You have to create your dialog by inherented DockingDlgInterface class in order to make your dialog dockable 501 * - please see DemoDlg.h and DemoDlg.cpp to have more informations. 502 */ 503 extern (C) 504 nothrow 505 void DockableDlgDemo() 506 507 do 508 { 509 npp_demo.GoToLineDlg._goToLine.setParent(.gshared_nppData._nppHandle); 510 npp_api.PowerEditor.WinControls.DockingWnd.Docking.tTbData data; 511 512 try { 513 if (!npp_demo.GoToLineDlg._goToLine.isCreated()) { 514 npp_demo.GoToLineDlg._goToLine.create(&npp_demo.GoToLineDlg._goToLine, data); 515 516 // define the default docking behaviour 517 data.uMask = npp_api.PowerEditor.WinControls.DockingWnd.Docking.DWS_DF_CONT_RIGHT; 518 519 data.pszModuleName = npp_demo.GoToLineDlg._goToLine.getPluginFileName(); 520 521 // the dlgDlg should be the index of func_list where the current function pointer is 522 // in this case is DOCKABLE_DEMO_INDEX 523 data.dlgID = .DOCKABLE_DEMO_INDEX; 524 npp_api.pluginfunc.npp_msgs.send_NPPM_DMMREGASDCKDLG(.gshared_nppData._nppHandle, &data); 525 } 526 527 npp_demo.GoToLineDlg._goToLine.display(); 528 } catch (Exception e) { 529 //ToDo: 530 core.sys.windows.winuser.MessageBoxW(.nppData._nppHandle, &("Exception\0"w[0]), &(npp_demo.plugin_dll.plugin_name[0]), core.sys.windows.winuser.MB_OK); 531 } 532 }