Scripts discussion (3)

Discuss and announce AkelPad plugins
Locked
  • Author
  • Message
Offline
Posts: 202
Joined: Sat Mar 28, 2015 2:36 pm
Location: Russia

Post by Kley »

Lenchik
Восстановление пометок Coder::HighLight
Восстановление закладок LineBoard::Main::SetBookmark
И при изменении расширения файла
Наглядное изменение расширения файла
Нет "Сперва сохраните файл."
Два в одном. Может еще что-то...
Терпеть не могу Win диалоги. Чёт они как-то не сразу "выскакивают" :)

Offline
Posts: 3217
Joined: Wed Nov 29, 2006 1:19 pm
Location: Киев, Русь
Contact:

Post by VladSh »

ewild, Cuprum

Залил новые версии скриптов, пробуйте (через AkelUpdater).
Предупреждаю - многое поменялось! Простите за неудобства, если сможете)
• Много изменений в ShowMenuEx.js: как просил когда-то Lenchik, - теперь аргументы можно задавать в json-файле. Т.е. можно задавать общие аргументы в ini-файле скрипта, можно в json-файле, а можно в аргументах, причём задание в аргументах самое приоритетное (такая структура логична, а также удобна для отладки).
• Соответственно изменился принцип работы с параметрами (каталог Params), к примеру FileDialogExtentions теперь в ini (всем, кто использует, надо откорректировать).
• Соответственно поменялись зависимые скрипты, а также их аргументы (всё унифицировано под новый ShowMenuEx.js).
Проверьте вызовы для всех изменившихся скриптов.

Примеры см. скрипты tidy.js и pack7zip.js (там есть кое-какие комменты), а также примеры вызовов (меню "Плагины" -> "Управление файлами" -> "Упаковка") и ini-, json-файлы к ним в моей сборке 4.9.4. Доку может быть когда-нибудь и напишу.

Offline
Posts: 381
Joined: Wed Sep 28, 2011 3:05 pm

Post by Cuprum »

VladSh
Спасибо!

KDJ
Offline
Posts: 1949
Joined: Sat Mar 06, 2010 7:40 pm
Location: Poland

Post by KDJ »

AkelPadDocsView.js
AkelPadMethodsView.js
Changed: now in edit window beep is disabled.
Added: detect url links in edit window, double click - opens link.

KDJ
Offline
Posts: 1949
Joined: Sat Mar 06, 2010 7:40 pm
Location: Poland

Post by KDJ »

Kley
Check what RenameFileAs.js is doing if there is no edit window (in MDI mode).


Offline
Posts: 202
Joined: Sat Mar 28, 2015 2:36 pm
Location: Russia

Post by Kley »

KDJ
Thank you.
RenameFileAs.js

Instructor
KDJ wrote:Check what RenameFileAs.js is doing if there is no edit window (in MDI mode).
Падение AkelPad происходит при вызове функций

Code: Select all

var pFileFullName = AkelPad.GetEditFile(0);
var pFileBaseName = AkelPad.GetFilePath(pFileFullName, 3 /*CPF_FILEBASENAME*/);
если нет открытых окон.
Нельзя ли это исправить (игнорировать "пустой" параметр) в программе?

Offline
Site Admin
Posts: 6311
Joined: Thu Jul 06, 2006 7:20 am

Post by Instructor »

KDJ wrote:AkelPadDocsView.js
AkelPadMethodsView.js
Added: detect url links in edit window, double click - opens link.
JFI: it is possible to open link via AEN_LINK or EN_LINK without edit window subclass.

Kley
Scripts плагин v17.2

Offline
Posts: 3217
Joined: Wed Nov 29, 2006 1:19 pm
Location: Киев, Русь
Contact:

Post by VladSh »

KDJ
Имеется пара предложений по AkelPadDocsView.js.

Можете добавить возможность задавать sDocsDir через аргументы?

И, если можно, задавать var aDoc = [...] в настроечном файле скрипта (json в этом случае было бы удобнее всего).

KDJ
Offline
Posts: 1949
Joined: Sat Mar 06, 2010 7:40 pm
Location: Poland

Post by KDJ »

Instructor wrote:JFI: it is possible to open link via AEN_LINK or EN_LINK without edit window subclass.
Example:

Code: Select all

var oSys     = AkelPad.SystemFunction();
var sClass   = "AkelPad::Scripts::" + WScript.ScriptName + "::" + AkelPad.GetInstanceDll();
var hMainWnd = AkelPad.GetMainWnd();
var IDTEXT   = 2000;
var IDCLOSE  = 2001;
var hDlg;

AkelPad.WindowRegisterClass(sClass);

AkelPad.CreateDialog(0, sClass, "AkelEdit link", 0x90CA0040, 200, 100, 270, 153, hMainWnd, DialogCallback, 0x3 /*CDF_PIXELS|CDF_MODAL*/, 0, 0, "MS Shell Dlg", 1, 8, "|",
  0x0000, "AkelEditW", "",      0x50B11004,  10,  10, 250, 100, IDTEXT,  0, "|",
  0x0000, "BUTTON",    "Close", 0x50010000, 100, 120,  70,  23, IDCLOSE, 0, "|"
  );

AkelPad.WindowUnregisterClass(sClass);

function DialogCallback(hWnd, uMsg, wParam, lParam)
{
  var nID;

  if (uMsg == 272 /*WM_INITDIALOG*/)
  {
    hDlg = hWnd;
    oSys.Call("User32::SendDlgItemMessageW", hDlg, IDTEXT, 3234 /*AEM_EXSETOPTIONS*/, 2 /*AECOOP_OR*/, 0x00000001 /*AECOE_DETECTURL*/);
    oSys.Call("User32::SendDlgItemMessageW", hDlg, IDTEXT, 3226 /*AEM_SETEVENTMASK*/, 0, 0x00040000 /*AENM_LINK*/);
    oSys.Call("User32::SetDlgItemTextW", hDlg, IDTEXT, "Double click on link:\n\nhttp://akelpad.sourceforge.net\n");
  }

  else if (uMsg == 78 /*WM_NOTIFY*/)
  {
    if (wParam == IDTEXT)
    {
      if (AkelPad.MemRead(_PtrAdd(lParam, _X64 ? 16 : 8), 3 /*DT_DWORD*/) == 2103 /*AEN_LINK*/)
      {
        if (AkelPad.MemRead(_PtrAdd(lParam, _X64 ? 32 : 16) /*AENLINK.uMsg*/, 3 /*DT_DWORD*/) == 515 /*WM_LBUTTONDBLCLK*/)
          OpenAELink(lParam);
      }
    }
  }

  else if (uMsg == 273 /*WM_COMMAND*/)
  {
    nID = wParam & 0xFFFF;

    if ((nID == IDCLOSE) || (nID == 2 /*IDCANCEL*/))
      oSys.Call("User32::EndDialog", hDlg, 0);
  }

  return 0;
}

function OpenAELink(lpAENLINK)
{
  var nOffset1 = oSys.Call("User32::SendDlgItemMessageW", hDlg, IDTEXT, 3136 /*AEM_INDEXTORICHOFFSET*/, 0, _PtrAdd(lpAENLINK, _X64 ? 56 : 28));
  var nOffset2 = oSys.Call("User32::SendDlgItemMessageW", hDlg, IDTEXT, 3136 /*AEM_INDEXTORICHOFFSET*/, 0, _PtrAdd(lpAENLINK, _X64 ? 80 : 40));
  var sLink;

  AkelPad.SetEditWnd(oSys.Call("User32::GetDlgItem", hDlg, IDTEXT));
  sLink = AkelPad.GetTextRange(nOffset1, nOffset2);
  AkelPad.SetEditWnd(0);

  oSys.Call("Shell32::ShellExecuteW", 0, "open", sLink, 0, 0, 1 /*SW_SHOWNORMAL*/);
}


But how to avoid selection of the whole word after double-click on the link?
Subclassing or is there another way?

-----
AkelPadDocsView.js
AkelPadMethodsView.js
Fixed: open url link on Win7.

Offline
Site Admin
Posts: 6311
Joined: Thu Jul 06, 2006 7:20 am

Post by Instructor »

KDJ wrote:But how to avoid selection of the whole word after double-click on the link?

Code: Select all

        {
          OpenAELink(lParam);
          oSys.Call("user32::SetWindowLong" + _TCHAR, hDlg, 0 /*DWL_MSGRESULT*/, true);
          return 1;
        }

KDJ
Offline
Posts: 1949
Joined: Sat Mar 06, 2010 7:40 pm
Location: Poland

Post by KDJ »

Instructor
Thank you very much.
Used in: AkelPadDocsView.js.

Offline
Posts: 176
Joined: Sat Dec 24, 2011 4:05 pm

Post by F. Phoenix »

KDJ, I translated your PluginText.js script, but for larger window size:

Code: Select all

/********************************
PluginText.js - ver. 2015-01-07a
Interface language
Language:      English (1033)
Translated by: KDJ
********************************/
sTxtScriptName   = "Plugin Text";
sTxtOnlyMDI      = "This script does work in MDI/PMDI mode only.";
sTxtNoTexts      = "There are no any texts in plugins settings.";
sTxtSetInReg     = "Settings stored in registry";
sTxtSetInIni     = "Settings stored in file AkelPad.ini";
sTxtDir          = "Directory for text files: ";
sTxtPlugin       = "Plugin";
sTxtKeyTextName  = "Key - text name";
sTxtTextFile     = "Text file associated with the key";
sTxtEditText     = "Edit plugin text";
sTxtLoadText     = "Load text to plugin key";
sTxtSaveTextFile = "Save plugin text in text file";
sTxtEditTextFile = "Edit text file";
sTxtLoadTextFile = "Load text file to plugin key";
sTxtRenameFile   = "Rename text file";
sTxtDeleteFile   = "Delete text file";
sTxtChangeDir    = "Change dir for text files";
sTxtEditIniFile  = "Edit .ini file";
sTxtOpenRegEdit  = "Open in RegEdit";
sTxtLoaded       = "Loaded:";
sTxtNotLoaded    = "Not loaded:";
sTxtSaved        = "Saved:";
sTxtNotSaved     = "Not saved:";
sTxtNoFiles      = "No file(s):";
sTxtWantSave     = "Do you want to extract selected plugin keys and save in text files?";
sTxtWantLoad     = "Do you want to load selected text files to plugin keys?";
sTxtNewName      = "new name:";
sTxtBadName      = "Illegal name.";
sTxtBadChar      = "Illegal character in the name.";
sTxtWantDelete   = "Do you want to delete selected text files?";
sTxtDeleted      = "Deleted:";
sTxtNotDeleted   = "Not deleted:";
sTxtEnvVar       = "environment variable";
sTxtAkelDir      = "AkelPad directory";
sTxtPlugDir      = "plugins directory";
sTxtDirNoExists  = "This directory does not exist. Do you want to create it?";
sTxtDirCreFail   = "Failed to create this directory.";


Code: Select all

/********************************
PluginText.js - ver. 2015-01-07a
Interface language
Language:      Russian (1049)
Translated by: F.Phoenix
********************************/
nWndPosW=620;
nWndPosH=400;
sTxtScriptName   = "Текстовая конфигурация плагинов";
sTxtOnlyMDI      = "Данный скрипт работает только в режиме MDI/PMDI.";
sTxtNoTexts      = "В настройках плагинов не обнаружено подходящих текстовых ключей.";
sTxtSetInReg     = "Параметры сохранены в реестре";
sTxtSetInIni     = "Параметры сохранены в файле AkelPad.ini";
sTxtDir          = "Папка текстовых файлов: ";
sTxtPlugin       = "Плагин";
sTxtKeyTextName  = "Ключ";
sTxtTextFile     = "Файл, связанный с ключем";
sTxtEditText     = "Править текст ключа";
sTxtLoadText     = "Загрузить ключ из текста";
sTxtSaveTextFile = "Сохранить текст ключа в файл";
sTxtEditTextFile = "Править текстовый файл";
sTxtLoadTextFile = "Загрузить ключ из файла";
sTxtRenameFile   = "Переименовать файл";
sTxtDeleteFile   = "Удалить текстовый файл";
sTxtChangeDir    = "Сменить рабочую папку";
sTxtEditIniFile  = "Править .ini файл";
sTxtOpenRegEdit  = "Открыть в RegEdit";
sTxtLoaded       = "Загружено:";
sTxtNotLoaded    = "Не загружено:";
sTxtSaved        = "Сохранено:";
sTxtNotSaved     = "Не сохранено:";
sTxtNoFiles      = "Файла(ов) не существует:";
sTxtWantSave     = "Вы  хотите извлечь выделенные ключи конфигурации плагинов и сохранить их в текстовых файлах?";
sTxtWantLoad     = "Вы хотите загрузить выделенные текстовые файлы в ключи конфигурации плагинов?";
sTxtNewName      = "Новое имя файла:";
sTxtBadName      = "Недопустимое имя.";
sTxtBadChar      = "Недопустимый символ в имени файла.";
sTxtWantDelete   = "Вы действительно хотите удалить выделенные текстовые файлы?";
sTxtDeleted      = "Удалено:";
sTxtNotDeleted   = "Не удалено:";
sTxtEnvVar       = "переменная среды";
sTxtAkelDir      = "папка AkelPad";
sTxtPlugDir      = "папка плагинов";
sTxtDirNoExists  = "Указанная папка не существует. Вы хотите ее создать?";
sTxtDirCreFail   = "Не удалось создать папку.";

Offline
Posts: 176
Joined: Sat Dec 24, 2011 4:05 pm

Post by F. Phoenix »

Code: Select all

// http://akelpad.sourceforge.net/forum/viewtopic.php?p=17303#p17303
// Version: 2015-01-07a
// Author: KDJ
//
// *** Operations on the text from plugins: Coder, ContextMenu, Hotkeys, SpecialChar and ToolBar* ***
//
// Usage:
//   Call("Scripts::Main", 1, "PluginText.js")
//
// Keyboard and mouse:
//   Ctrl+A - select all items on list
//   double click on list item - edit plugin text, if text is opened in current tab - close it
//
// Remarks:
//   The text is read from plugin settings (.ini file or registry).
//   For the syntax highlighting uses akelmenu.coder by Infocatcher: http://infocatcher.ucoz.net/akelpad/coder/_akelmenu.coder

var sTxtScriptName   = "Plugin Text";
var sTxtOnlyMDI      = "This script does work in MDI/PMDI mode only.";
var sTxtNoTexts      = "There are no any texts in plugins settings.";
var sTxtSetInReg     = "Settings stored in registry";
var sTxtSetInIni     = "Settings stored in file AkelPad.ini";
var sTxtDir          = "Directory for text files: ";
var sTxtPlugin       = "Plugin";
var sTxtKeyTextName  = "Key - text name";
var sTxtTextFile     = "Text file associated with the key";
var sTxtEditText     = "Edit plugin text";
var sTxtLoadText     = "Load text to plugin key";
var sTxtSaveTextFile = "Save plugin text in text file";
var sTxtEditTextFile = "Edit text file";
var sTxtLoadTextFile = "Load text file to plugin key";
var sTxtRenameFile   = "Rename text file";
var sTxtDeleteFile   = "Delete text file";
var sTxtChangeDir    = "Change dir for text files";
var sTxtEditIniFile  = "Edit .ini file";
var sTxtOpenRegEdit  = "Open in RegEdit";
var sTxtLoaded       = "Loaded:";
var sTxtNotLoaded    = "Not loaded:";
var sTxtSaved        = "Saved:";
var sTxtNotSaved     = "Not saved:";
var sTxtNoFiles      = "No file(s):";
var sTxtWantSave     = "Do you want to extract selected plugin keys and save in text files?";
var sTxtWantLoad     = "Do you want to load selected text files to plugin keys?";
var sTxtNewName      = "new name:";
var sTxtBadName      = "Illegal name.";
var sTxtBadChar      = "Illegal character in the name.";
var sTxtWantDelete   = "Do you want to delete selected text files?";
var sTxtDeleted      = "Deleted:";
var sTxtNotDeleted   = "Not deleted:";
var sTxtEnvVar       = "environment variable";
var sTxtAkelDir      = "AkelPad directory";
var sTxtPlugDir      = "plugins directory";
var sTxtDirNoExists  = "This directory does not exist. Do you want to create it?";
var sTxtDirCreFail   = "Failed to create this directory.";

var oSys     = AkelPad.SystemFunction();
var hMainWnd = AkelPad.GetMainWnd();
var hInstDLL = AkelPad.GetInstanceDll();
var sClass   = "AkelPad::Scripts::" + WScript.ScriptName + "::" + hInstDLL;

if (IsScriptRunning() || IsSDI())
  WScript.Quit();

var DT_UNICODE = 1;
var DT_QWORD   = 2;
var DT_DWORD   = 3;
var DT_WORD    = 4;
var DT_BYTE    = 5;

var oFSO      = new ActiveXObject("Scripting.FileSystemObject");
var bSetInReg = (AkelPad.SendMessage(hMainWnd, 1222 /*AKD_GETMAININFO*/, 5 /*MI_SAVESETTINGS*/, 0) == 1 /*SS_REGISTRY*/);
var nBufSize  = 1024;
var lpBuffer  = AkelPad.MemAlloc(nBufSize);
var lpLVITEM  = AkelPad.MemAlloc(_X64 ? 72 : 60); //sizeof(LVITEM)

AkelPad.MemCopy(lpLVITEM, 0x0001 /*LVIF_TEXT*/, DT_DWORD);
AkelPad.MemCopy(_PtrAdd(lpLVITEM, _X64 ? 24 : 20), lpBuffer, DT_QWORD);
AkelPad.MemCopy(_PtrAdd(lpLVITEM, _X64 ? 32 : 24), nBufSize, DT_DWORD);

var nWndMinW  = 500;
var nWndMinH  = 262;
var nWndPosX  = 240;
var nWndPosY  = 160;
var nWndPosW  = 0;
var nWndPosH  = 0;
var oPlugText = {};
var aFrame    = [];
var sTextDirS;
var hDlg;

ReadIni();

var CLASS = 0;
var HWND  = 1;
var STYLE = 2;
var TXT   = 3;

var aDlg   = [];
var IDSET  = 2000;
var IDDIR  = 2001;
var IDPLUG = 2002;
var IDB1   = 2003;
var IDB2   = 2004;
var IDB3   = 2005;
var IDB4   = 2006;
var IDB5   = 2007;
var IDB6   = 2008;
var IDB7   = 2009;
var IDB8   = 2010;
var IDB9   = 2011;

//0x50000000 - WS_VISIBLE|WS_CHILD
//0x50000080 - WS_VISIBLE|WS_CHILD|SS_NOPREFIX
//0x50818009 - WS_VISIBLE|WS_CHILD|WS_BORDER|WS_TABSTOP|LVS_NOSORTHEADER|LVS_SHOWSELALWAYS|LVS_REPORT
//Windows     CLASS,        HWND,      STYLE, TXT
aDlg[IDSET ]=["STATIC",        0, 0x50000080, bSetInReg ? sTxtSetInReg : sTxtSetInIni];
aDlg[IDDIR ]=["STATIC",        0, 0x50000080, sTxtDir + ExpandDirName(sTextDirS)];
aDlg[IDPLUG]=["SysListView32", 0, 0x50818009, ""];
aDlg[IDB1  ]=["BUTTON",        0, 0x50000000, sTxtEditText + " (F1)"];
aDlg[IDB2  ]=["BUTTON",        0, 0x50000000, sTxtLoadText + " (F2)"];
aDlg[IDB3  ]=["BUTTON",        0, 0x50000000, sTxtSaveTextFile + " (F3)"];
aDlg[IDB4  ]=["BUTTON",        0, 0x50000000, sTxtEditTextFile + " (F4)"];
aDlg[IDB5  ]=["BUTTON",        0, 0x50000000, sTxtLoadTextFile + " (F5)"];
aDlg[IDB6  ]=["BUTTON",        0, 0x50000000, sTxtRenameFile + " (F7)"];
aDlg[IDB7  ]=["BUTTON",        0, 0x50000000, sTxtDeleteFile + " (F8)"];
aDlg[IDB8  ]=["BUTTON",        0, 0x50000000, sTxtChangeDir + " (F9)"];
aDlg[IDB9  ]=["BUTTON",        0, 0x50000000, (bSetInReg ? sTxtOpenRegEdit : sTxtEditIniFile) + " (Shift+F4)"];

if (AkelPad.WindowSubClass(1 /*WSC_MAINPROC*/, MainCallback, 1048 /*AKDN_FRAME_DESTROY*/, 1078 /*AKDN_OPENDOCUMENT_FINISH*/))
{
  AkelPad.ScriptNoMutex();
  AkelPad.WindowRegisterClass(sClass);

  hDlg = oSys.Call("User32::CreateWindowExW",
    0,              //dwExStyle
    sClass,         //lpClassName
    sTxtScriptName, //lpWindowName
    0x90CE0000,     //WS_POPUP|WS_VISIBLE|WS_CAPTION|WS_MINIMIZEBOX|WS_SYSMENU|WS_SIZEBOX
    nWndPosX,       //x
    nWndPosY,       //y
    nWndPosW,       //nWidth
    nWndPosH,       //nHeight
    hMainWnd,       //hWndParent
    0,              //ID
    hInstDLL,       //hInstance
    DialogCallback);//Script function callback. To use it class must be registered by WindowRegisterClass.

  AkelPad.WindowGetMessage();
  AkelPad.WindowUnregisterClass(sClass);
  AkelPad.WindowUnsubClass(1 /*WSC_MAINPROC*/);
}

AkelPad.MemFree(lpBuffer);
AkelPad.MemFree(lpLVITEM);

function MainCallback(hWnd, uMsg, wParam, lParam)
{
  if ((uMsg == 1048 /*AKDN_FRAME_DESTROY*/) || (uMsg == 1078 /*AKDN_OPENDOCUMENT_FINISH*/) && (lParam == 0 /*EOD_SUCCESS*/))
  {
    var lpFrame = (uMsg == 1048 /*AKDN_FRAME_DESTROY*/) ? lParam : AkelPad.SendMessage(hMainWnd, 1290 /*AKD_FRAMEFINDW*/, 1 /*FWF_CURRENT*/, 0);

    for (var i = 0; i < aFrame.length; ++i)
    {
      if (aFrame[i] == lpFrame)
      {
        aFrame[i] = 0;
        break;
      }
    }
  }

  return 0;
}

function DialogCallback(hWnd, uMsg, wParam, lParam)
{
  if (uMsg == 1) //WM_CREATE
  {
    var hGuiFont = oSys.Call("Gdi32::GetStockObject", 17 /*DEFAULT_GUI_FONT*/);
    var i;

    for (i = IDSET; i < aDlg.length; ++i)
    {
      aDlg[i][HWND] = oSys.Call("User32::CreateWindowExW",
        0,              //dwExStyle
        aDlg[i][CLASS], //lpClassName
        0,              //lpWindowName
        aDlg[i][STYLE], //dwStyle
        0,              //x
        0,              //y
        0,              //nWidth
        0,              //nHeight
        hWnd,           //hWndParent
        i,              //ID
        hInstDLL,       //hInstance
        0);             //lpParam

      AkelPad.SendMessage(aDlg[i][HWND], 48 /*WM_SETFONT*/, hGuiFont, true);
      oSys.Call("User32::SetWindowTextW", aDlg[i][HWND], aDlg[i][TXT]);
    }

    FillPlugList();

    if (! GetItemCountLV())
    {
      AkelPad.MessageBox(hWnd, sTxtNoTexts, sTxtScriptName, 0x30 /*MB_ICONWARNING*/);
      oSys.Call("User32::DestroyWindow", hWnd);
    }
  }

  else if (uMsg == 7) //WM_SETFOCUS
    oSys.Call("User32::SetFocus", aDlg[IDPLUG][HWND]);

  else if (uMsg == 36) //WM_GETMINMAXINFO
  {
    AkelPad.MemCopy(_PtrAdd(lParam, 24), nWndMinW, DT_DWORD); //ptMinTrackSize_x
    AkelPad.MemCopy(_PtrAdd(lParam, 28), nWndMinH, DT_DWORD); //ptMinTrackSize_y
  }

  else if (uMsg == 5) //WM_SIZE
    ResizeDlg(LoWord(lParam), HiWord(lParam));

  else if (uMsg == 15) //WM_PAINT
    PaintSizeGrip();

  else if (uMsg == 256) //WM_KEYDOWN
  {
    if ((wParam == 0x70 /*VK_F1*/) && (! Ctrl()) && (! Shift()) && (! Alt()))
      EditText(0);
    else if ((wParam == 0x71 /*VK_F2*/) && (! Ctrl()) && (! Shift()) && (! Alt()))
      LoadTextToPlugin();
    else if ((wParam == 0x72 /*VK_F3*/) && (! Ctrl()) && (! Shift()) && (! Alt()))
      EditText(1);
    else if ((wParam == 0x73 /*VK_F4*/) && (! Ctrl()) && (! Alt()))
    {
      if (Shift())
        bSetInReg ? OpenInRegEdit() : EditIniFile();
      else      
        EditTextFile();
    }
    else if ((wParam == 0x74 /*VK_F5*/) && (! Ctrl()) && (! Shift()) && (! Alt()))
      LoadTextToPlugin(1);
    else if ((wParam == 0x76 /*VK_F7*/) && (! Ctrl()) && (! Shift()) && (! Alt()))
      RenameTextFile();
    else if (((wParam == 0x77 /*VK_F8*/) || (wParam == 0x2E /*VK_DELETE*/)) && (! Ctrl()) && (! Alt()))
      DeleteTextFile();
    else if ((wParam == 0x78 /*VK_F9*/) && (! Ctrl()) && (! Shift()) && (! Alt()))
      ChangeTextsDir();
    else if ((wParam == 0x41 /*A key*/) && Ctrl() && (! Shift()) && (! Alt()))
    {
      for (var i = 0; i < GetItemCountLV(); ++i)
        SetSelLV(i);
    }
  }

  else if ((uMsg == 0x004E /*WM_NOTIFY*/) && (wParam == IDPLUG))
  {
    switch (AkelPad.MemRead(_PtrAdd(lParam, _X64 ? 16 : 8), DT_DWORD))
    {
      case -3 : //NM_DBLCLK
        if (AkelPad.MemRead(_PtrAdd(lParam, _X64 ? 24 : 12) /*NMITEMACTIVATE.iItem*/, DT_DWORD) > -1)
        {
          EditText(0, 1);
          break;
        }
      case -2 : //NM_CLICK
      case -5 : //NM_RCLICK
      case -6 : //NM_RDBLCLK
        if (AkelPad.MemRead(_PtrAdd(lParam, _X64 ? 24 : 12) /*NMITEMACTIVATE.iItem*/, DT_DWORD) == -1)
          SetSelLV(AkelPad.SendMessage(aDlg[IDPLUG][HWND], 0x100C /*LVM_GETNEXTITEM*/, -1, 0x0001 /*LVNI_FOCUSED*/));
        break;
    }
  }

  else if (uMsg == 273) //WM_COMMAND
  {
    var nLowParam = LoWord(wParam);

    if ((nLowParam >= IDB1) && (nLowParam <= IDB9))
    {
      AkelPad.SendMessage(lParam, 0x00F4 /*BM_SETSTYLE*/, 0 /*BS_PUSHBUTTON*/, 0);

      if (nLowParam == IDB1)
        EditText(0);
      else if (nLowParam == IDB2)
        LoadTextToPlugin();
      else if (nLowParam == IDB3)
        EditText(1);
      else if (nLowParam == IDB4)
        EditTextFile();
      else if (nLowParam == IDB5)
        LoadTextToPlugin(1);
      else if (nLowParam == IDB6)
        RenameTextFile();
      else if (nLowParam == IDB7)
        DeleteTextFile();
      else if (nLowParam == IDB8)
        ChangeTextsDir();
      else if (nLowParam == IDB9)
        bSetInReg ? OpenInRegEdit() : EditIniFile();

      oSys.Call("User32::SetFocus", aDlg[IDPLUG][HWND]);
    }

    else if (nLowParam == 2 /*IDCANCEL*/)
      AkelPad.SendMessage(hWnd, 16 /*WM_CLOSE*/, 0, 0);
  }

  else if (uMsg == 16) //WM_CLOSE
  {
    WriteIni();
    oSys.Call("User32::DestroyWindow", hWnd);
  }

  else if (uMsg == 2) //WM_DESTROY
    oSys.Call("User32::PostQuitMessage", 0);

  return 0;
}

function LoWord(nDwNum)
{
  return nDwNum & 0xFFFF;
}

function HiWord(nDwNum)
{
  return (nDwNum >> 16) & 0xFFFF;
}

function Ctrl()
{
  return oSys.Call("User32::GetKeyState", 0x11 /*VK_CONTROL*/) & 0x8000;
}

function Shift()
{
  return oSys.Call("User32::GetKeyState", 0x10 /*VK_SHIFT*/) & 0x8000;
}

function Alt()
{
  return oSys.Call("user32::GetKeyState", 0x12 /*VK_MENU*/) & 0x8000;
}

function ResizeDlg(nW, nH)
{
  var nFlags = 0x14; //SWP_NOACTIVATE|SWP_NOZORDER
  var nBW    = Math.round((nW - 4 * 8) / 3);
  var i;

  for (i = 0; i < 2; ++i)
  {
    oSys.Call("User32::SetWindowPos",
      aDlg[IDSET + i][HWND], 0,
      8,
      10 + 15 * i,
      nW - 2 * 8,
      13,
      nFlags);
  }
  oSys.Call("User32::SetWindowPos",
    aDlg[IDPLUG][HWND], 0,
    8,
    45,
    nW - 2 * 8,
    nH - 3 * 23 - 2 * 2 - 2 * 8 - 45,
    nFlags);
  for (i = 0; i < 3; ++i)
  {
    oSys.Call("User32::SetWindowPos",
      aDlg[IDB1 + i][HWND], 0,
      8,
      nH - 3 * 23 - 2 * 2 - 8 + 25 * i,
      nBW,
      23,
      nFlags);
    oSys.Call("User32::SetWindowPos",
      aDlg[IDB4 + i][HWND], 0,
      nBW + 2 * 8,
      nH - 3 * 23 - 2 * 2 - 8 + 25 * i,
      nBW,
      23,
      nFlags);
    oSys.Call("User32::SetWindowPos",
      aDlg[IDB7 + i][HWND], 0,
      nW - nBW - 8,
      nH - 3 * 23 - 2 * 2 - 8 + 25 * i,
      nBW,
      23,
      nFlags);
  }

  for (i = 0; i < 3; ++i)
    AkelPad.SendMessage(aDlg[IDPLUG][HWND], 0x101E /*LVM_SETCOLUMNWIDTH*/, i, -2 /*LVSCW_AUTOSIZE_USEHEADER*/);

  AkelPad.SendMessage(aDlg[IDPLUG][HWND], 0x1013 /*LVM_ENSUREVISIBLE*/, GetNextSelLV(-1), false);
  oSys.Call("user32::InvalidateRect", hDlg, 0, true);
}

function PaintSizeGrip()
{
  var lpPaint = AkelPad.MemAlloc(_X64 ? 72 : 64); //sizeof(PAINTSTRUCT)
  var lpRect  = AkelPad.MemAlloc(16); //sizeof(RECT)
  var hDC;

  if (hDC = oSys.Call("User32::BeginPaint", hDlg, lpPaint))
  {
    oSys.Call("User32::GetClientRect", hDlg, lpRect);

    AkelPad.MemCopy(_PtrAdd(lpRect, 0), AkelPad.MemRead(_PtrAdd(lpRect,  8), DT_DWORD) - oSys.Call("User32::GetSystemMetrics",  2 /*SM_CXVSCROLL*/), DT_DWORD);
    AkelPad.MemCopy(_PtrAdd(lpRect, 4), AkelPad.MemRead(_PtrAdd(lpRect, 12), DT_DWORD) - oSys.Call("User32::GetSystemMetrics", 20 /*SM_CYVSCROLL*/), DT_DWORD);

    oSys.Call("User32::DrawFrameControl", hDC, lpRect, 3 /*DFC_SCROLL*/, 0x8 /*DFCS_SCROLLSIZEGRIP*/);
    oSys.Call("User32::EndPaint", hDlg, lpPaint);
  }

  AkelPad.MemFree(lpPaint);
  AkelPad.MemFree(lpRect);
}

function GetItemCountLV()
{
  return AkelPad.SendMessage(aDlg[IDPLUG][HWND], 0x1004 /*LVM_GETITEMCOUNT*/, 0, 0);
}

function GetItemTextLV(nItem, nSubItem)
{
  AkelPad.MemCopy(_PtrAdd(lpLVITEM, 8), nSubItem, DT_DWORD);
  AkelPad.SendMessage(aDlg[IDPLUG][HWND], 0x1073 /*LVM_GETITEMTEXTW*/, nItem, lpLVITEM);
  return AkelPad.MemRead(lpBuffer, DT_UNICODE);
}

function SetItemTextLV(nItem, nSubItem, sText)
{
  AkelPad.MemCopy(_PtrAdd(lpLVITEM, 4), nItem,    DT_DWORD);
  AkelPad.MemCopy(_PtrAdd(lpLVITEM, 8), nSubItem, DT_DWORD);
  AkelPad.MemCopy(lpBuffer, sText, DT_UNICODE);

  AkelPad.SendMessage(aDlg[IDPLUG][HWND], 0x1074 /*LVM_SETITEMTEXTW*/, nItem, lpLVITEM);
}

function GetNextSelLV(nItem)
{
  return AkelPad.SendMessage(aDlg[IDPLUG][HWND], 0x100C /*LVM_GETNEXTITEM*/, nItem, 0x0002 /*LVNI_SELECTED*/);
}

function GetSelArrayLV()
{
  var aSel  = [];
  var nItem = -1;

  while (true)
  {
    nItem = GetNextSelLV(nItem);

    if (nItem < 0)
      break;

    aSel.push(nItem);
  }

  return aSel;
}

function SetSelLV(nItem)
{
  AkelPad.MemCopy(_PtrAdd(lpLVITEM, 12), 0x0003 /*LVIS_SELECTED|LVIS_FOCUSED*/, DT_DWORD);
  AkelPad.MemCopy(_PtrAdd(lpLVITEM, 16), 0x0003 /*LVIS_SELECTED|LVIS_FOCUSED*/, DT_DWORD);
  AkelPad.SendMessage(aDlg[IDPLUG][HWND], 0x102B /*LVM_SETITEMSTATE*/, nItem, lpLVITEM);
  AkelPad.SendMessage(aDlg[IDPLUG][HWND], 0x1013 /*LVM_ENSUREVISIBLE*/, nItem, false);
}

function InsertItemLV(nItem, aItems)
{
  var i;

  AkelPad.MemCopy(_PtrAdd(lpLVITEM, 4), nItem, DT_DWORD);
  AkelPad.MemCopy(_PtrAdd(lpLVITEM, 8),     0, DT_DWORD);
  AkelPad.MemCopy(lpBuffer, aItems[0], DT_UNICODE);
  AkelPad.SendMessage(aDlg[IDPLUG][HWND], 0x104D /*LVM_INSERTITEMW*/, 0, lpLVITEM);

  for (i = 1; i < aItems.length; ++i)
  {
    AkelPad.MemCopy(_PtrAdd(lpLVITEM, 8), i, DT_DWORD);
    AkelPad.MemCopy(lpBuffer, aItems[i], DT_UNICODE);
    AkelPad.SendMessage(aDlg[IDPLUG][HWND], 0x1074 /*LVM_SETITEMTEXTW*/, nItem, lpLVITEM);
  }
}

function FillPlugList()
{
  var aPlugList  = [];
  var lpLVCOLUMN = AkelPad.MemAlloc(_X64 ? 56 : 44); //sizeof(LVCOLUMN)
  var nMask      = 5; //LVCF_FMT|LVCF_TEXT
  var aFmt       = [0 /*LVCFMT_LEFT*/, 0, 0]; //Alignment of the column header
  var aText      = [AkelPad.MemStrPtr(sTxtPlugin), AkelPad.MemStrPtr(sTxtKeyTextName), AkelPad.MemStrPtr(sTxtTextFile)];
  var i;

  if (bSetInReg)
    GetPluginsFromReg(aPlugList);
  else
    GetPluginsFromIni(aPlugList);

  AkelPad.SendMessage(aDlg[IDPLUG][HWND], 0x1036 /*LVM_SETEXTENDEDLISTVIEWSTYLE*/, 0, 0x0021 /*LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES*/);
  AkelPad.MemCopy(lpLVCOLUMN, nMask, DT_DWORD);

  for (i = 0; i < aFmt.length; ++i)
  {
    AkelPad.MemCopy(_PtrAdd(lpLVCOLUMN, 4), aFmt[i], DT_DWORD);
    AkelPad.MemCopy(_PtrAdd(lpLVCOLUMN, _X64 ? 16 : 12), aText[i], DT_QWORD);
    AkelPad.SendMessage(aDlg[IDPLUG][HWND], 0x1061 /*LVM_INSERTCOLUMNW*/, i, lpLVCOLUMN);
  }
  AkelPad.MemFree(lpLVCOLUMN);

  for (i = 0; i < aPlugList.length; ++i)
  {
    if (oPlugText[aPlugList[i][0]] &&
        oPlugText[aPlugList[i][0]][aPlugList[i][1]] &&
        oPlugText[aPlugList[i][0]][aPlugList[i][1]].File)
      aPlugList[i].push(oPlugText[aPlugList[i][0]][aPlugList[i][1]].File);
    else
      aPlugList[i].push(aPlugList[i][0] + "." + aPlugList[i][1].replace(/[<>:"/\\|?*]/g, "_") + ".akelmenu");

    InsertItemLV(i, aPlugList[i]);
    aFrame[i] = 0;

    if (oPlugText[aPlugList[i][0]] &&
        oPlugText[aPlugList[i][0]][aPlugList[i][1]] &&
        oPlugText[aPlugList[i][0]][aPlugList[i][1]].Sel)
      SetSelLV(i);
  }

  if (GetNextSelLV(-1) < 0)
    SetSelLV(0);
}

function GetPluginsFromIni(aPlugList)
{
  var oRE1      = /^\/.+(?==)/gm;
  var oRE2      = /^.+Text(?==)/gm;
  var aPlugName = [["Coder", oRE1], ["ContextMenu", oRE2], ["Hotkeys", oRE2], ["SpecialChar", oRE2]];
  var sPlugDir  = AkelPad.GetAkelDir(4 /*ADTYPE_PLUGS*/) + "\\";
  var hFindFile = oSys.Call("Kernel32::FindFirstFileW", sPlugDir + "ToolBar*.ini", lpBuffer);
  var sToolBarName;
  var aText;
  var i, n;

  if (hFindFile != -1) //INVALID_HANDLE_VALUE
  {
    do
    {
      if (! (AkelPad.MemRead(lpBuffer, DT_DWORD) & 16 /*FILE_ATTRIBUTE_DIRECTORY*/))
      {
        sToolBarName = AkelPad.MemRead(_PtrAdd(lpBuffer, 44 /*offsetof(WIN32_FIND_DATAW, cFileName)*/), DT_UNICODE);
        sToolBarName = sToolBarName.substring(sToolBarName.lastIndexOf("\\") + 1, sToolBarName.lastIndexOf("."));
        aPlugName.push([sToolBarName, oRE2]);
      }
    }
    while (oSys.Call("Kernel32::FindNextFileW", hFindFile, lpBuffer));

    oSys.Call("Kernel32::FindClose", hFindFile);
  }

  for (i = 0; i < aPlugName.length; ++i)
  {
    if ((oFSO.FileExists(sPlugDir + aPlugName[i][0] + ".ini")) &&
        (aText = AkelPad.ReadFile(sPlugDir + aPlugName[i][0] + ".ini", 0x10 /*OD_ADT_NOMESSAGES*/, 1200 /*UTF-16LE*/, 1 /*bBOM*/).match(aPlugName[i][1])))
    {
      for (n = 0; n < aText.length; ++n)
        aPlugList.push([aPlugName[i][0], aText[n]]);
    }
  }
}

function GetPluginsFromReg(aPlugList)
{
  var oRE1       = /^\/.+/;
  var oRE2       = /.+Text$/;
  var aPlugName  = [["Coder", oRE1], ["ContextMenu", oRE2], ["Hotkeys", oRE2], ["SpecialChar", oRE2]];
  var sPlugKey   = "Software\\Akelsoft\\AkelPad\\Plugs";
  var lpCount    = AkelPad.MemAlloc(4);
  var lpNameLen  = AkelPad.MemAlloc(4);
  var lpType     = AkelPad.MemAlloc(4);
  var lpName;
  var nNameLen;
  var sToolBarName;
  var sValueName;
  var hKey;
  var i;

  if (hKey = GetRegKeyHandle(0x80000001 /*HKEY_CURRENT_USER*/, sPlugKey, 0x0009 /*KEY_ENUMERATE_SUB_KEYS|KEY_QUERY_VALUE*/))
  {
    if (! oSys.Call("Advapi32::RegQueryInfoKeyW",
            hKey,      //hKey
            0,         //lpClass
            0,         //lpcClass
            0,         //lpReserved
            lpCount,   //lpcSubKeys
            lpNameLen, //lpcMaxSubKeyLen
            0,         //lpcMaxClassLen
            0,         //lpcValues
            0,         //lpcMaxValueNameLen
            0,         //lpcMaxValueLen
            0,         //lpcbSecurityDescri
            0))        //lpftLastWriteTime
    {
      nNameLen = AkelPad.MemRead(lpNameLen, DT_DWORD) + 1;
      lpName   = AkelPad.MemAlloc(nNameLen * 2);

      for (i = 0; i < AkelPad.MemRead(lpCount, DT_DWORD); ++i)
      {
        AkelPad.MemCopy(lpNameLen, nNameLen, DT_DWORD);
        if (! oSys.Call("Advapi32::RegEnumKeyExW",
                hKey,      //hKey
                i,         //dwIndex
                lpName,    //lpName
                lpNameLen, //lpcName
                0,         //lpReserved
                0,         //lpClass
                0,         //lpcClass
                0))        //lpftLastWriteTime
        {
          sToolBarName = AkelPad.MemRead(lpName, DT_UNICODE);
          if (sToolBarName.indexOf("ToolBar") == 0)
            aPlugName.push([sToolBarName, oRE2]);
        }
      }
      AkelPad.MemFree(lpName);
    }
    oSys.Call("Advapi32::RegCloseKey", hKey);
  }

  for (i = 0; i < aPlugName.length; ++i)
  {
    if (hKey = GetRegKeyHandle(0x80000001 /*HKEY_CURRENT_USER*/, sPlugKey + "\\" + aPlugName[i][0], 0x0001 /*KEY_QUERY_VALUE*/))
    {
      if (! oSys.Call("Advapi32::RegQueryInfoKeyW",
              hKey,      //hKey
              0,         //lpClass
              0,         //lpcClass
              0,         //lpReserved
              0,         //lpcSubKeys
              0,         //lpcMaxSubKeyLen
              0,         //lpcMaxClassLen
              lpCount,   //lpcValues
              lpNameLen, //lpcMaxValueNameLen
              0,         //lpcMaxValueLen
              0,         //lpcbSecurityDescri
              0))        //lpftLastWriteTime
      {
        nNameLen = AkelPad.MemRead(lpNameLen, DT_DWORD) + 1;
        lpName   = AkelPad.MemAlloc(nNameLen * 2);

        for (n = 0; n < AkelPad.MemRead(lpCount, DT_DWORD); ++n)
        {
          AkelPad.MemCopy(lpNameLen, nNameLen, DT_DWORD);
          if (! oSys.Call("Advapi32::RegEnumValueW",
                  hKey,      //hKey
                  n,         //dwIndex
                  lpName,    //lpValueName
                  lpNameLen, //lpcchValueName
                  0,         //lpReserved
                  lpType,    //lpType
                  0,         //lpData
                  0))        //lpcbData
          {
            sValueName = AkelPad.MemRead(lpName, DT_UNICODE);
            if (aPlugName[i][1].test(sValueName) && (AkelPad.MemRead(lpType, DT_DWORD) == 3 /*REG_BINARY*/))
              aPlugList.push([aPlugName[i][0], sValueName]);
          }
        }
        AkelPad.MemFree(lpName);
      }
      oSys.Call("Advapi32::RegCloseKey", hKey);
    }
  }

  AkelPad.MemFree(lpCount);
  AkelPad.MemFree(lpNameLen);
  AkelPad.MemFree(lpType);
}

function GetRegKeyHandle(hParentKey, sSubKey, nAccess)
{
  var lpKey  = AkelPad.MemAlloc(_X64 ? 8 : 4);
  var hKey   = 0;
  var nError = oSys.Call("Advapi32::RegOpenKeyExW",
                 hParentKey, //hKey
                 sSubKey,    //lpSubKey
                 0,          //ulOptions
                 nAccess,    //samDesired
                 lpKey);     //phkResult

  if (! nError)
    hKey = AkelPad.MemRead(lpKey, DT_QWORD);

  AkelPad.MemFree(lpKey);

  return hKey;
}

function EditText(bSave, bMouseClick)
{
  var sTextDir  = ExpandDirName(sTextDirS);
  var sPlugDir  = AkelPad.GetAkelDir(4 /*ADTYPE_PLUGS*/) + "\\";
  var aSel      = GetSelArrayLV();
  var aSaved    = [];
  var aNotSaved = [];
  var sMessage  = "";
  var hKey;
  var lpType;
  var lpData;
  var lpDataLen;
  var sIniFile;
  var oRE;
  var bWasSaved;
  var i, n;

  if (bSave && (AkelPad.MessageBox(hDlg, sTxtWantSave, sTxtScriptName, 0x21 /*MB_DEFBUTTON1|MB_ICONQUESTION|MB_OKCANCEL*/) != 1 /*IDOK*/))
    return;

  if (bSetInReg)
  {
    lpType    = AkelPad.MemAlloc(4);
    lpDataLen = AkelPad.MemAlloc(4);

    for (i = 0; i < aSel.length; ++i)
    {
      bWasSaved = false;

      if (hKey = GetRegKeyHandle(0x80000001 /*HKEY_CURRENT_USER*/, "Software\\Akelsoft\\AkelPad\\Plugs\\" + GetItemTextLV(aSel[i], 0), 0x0001 /*KEY_QUERY_VALUE*/))
      {
        oSys.Call("Advapi32::RegQueryInfoKeyW",
          hKey,      //hKey
          0,         //lpClass
          0,         //lpcClass
          0,         //lpReserved
          0,         //lpcSubKeys
          0,         //lpcMaxSubKeyLen
          0,         //lpcMaxClassLen
          0,         //lpcValues
          0,         //lpcMaxValueNameLen
          lpDataLen, //lpcMaxValueLen
          0,         //lpcbSecurityDescri
          0);        //lpftLastWriteTime

        lpData = AkelPad.MemAlloc(AkelPad.MemRead(lpDataLen, DT_DWORD));

        if ((! oSys.Call("Advapi32::RegQueryValueExW",
                 hKey,                      //hKey
                 GetItemTextLV(aSel[i], 1), //lpValueName
                 0,                         //lpReserved
                 lpType,                    //lpType
                 lpData,                    //lpData
                 lpDataLen))                //lpcbData
            && (AkelPad.MemRead(lpType, DT_DWORD) == 3 /*REG_BINARY*/))
        {
          if (bSave)
          {
            if (AkelPad.WriteFile(sTextDir + GetItemTextLV(aSel[i], 2), AkelPad.MemRead(lpData, DT_UNICODE), -1, 1200 /*UTF-16LE*/, 1 /*bBOM*/) == 0 /*ESD_SUCCESS*/)
            {
              aSaved.push(aSel[i]);
              bWasSaved = true;
            }
          }
          else
            OpenText(lpData, aSel[i], bMouseClick);
        }

        oSys.Call("Advapi32::RegCloseKey", hKey);
        AkelPad.MemFree(lpData);
      }

      if (bSave && (! bWasSaved))
        aNotSaved.push(aSel[i]);
    }

    AkelPad.MemFree(lpType);
    AkelPad.MemFree(lpDataLen);
  }

  else
  {
    for (i = 0; i < aSel.length; ++i)
    {
      bWasSaved = false;
      sIniFile  = sPlugDir + GetItemTextLV(aSel[i], 0) + ".ini";

      if (oFSO.FileExists(sIniFile))
      {
        oRE = new RegExp(escapeRegExp(GetItemTextLV(aSel[i], 1)) + "=([\\dA-F]*)");

        if (oRE.test(AkelPad.ReadFile(sIniFile, 0x10 /*OD_ADT_NOMESSAGES*/, 1200 /*UTF-16LE*/, 1 /*bBOM*/)))
        {
          lpData = AkelPad.MemAlloc(RegExp.$1.length / 2);

          for (n = 0; n < RegExp.$1.length; n += 2)
            AkelPad.MemCopy(_PtrAdd(lpData, n / 2), parseInt(RegExp.$1.substr(n, 2), 16), DT_BYTE);

          if (bSave)
          {
            if (AkelPad.WriteFile(sTextDir + GetItemTextLV(aSel[i], 2), AkelPad.MemRead(lpData, DT_UNICODE), -1, 1200 /*UTF-16LE*/, 1 /*bBOM*/) == 0 /*ESD_SUCCESS*/)
            {
              aSaved.push(aSel[i]);
              bWasSaved = true;
            }
          }
          else
            OpenText(lpData, aSel[i], bMouseClick);

          AkelPad.MemFree(lpData);
        }
      }

      if (bSave && (! bWasSaved))
        aNotSaved.push(aSel[i]);
    }
  }

  if (bSave)
  {
    if (aSaved.length)
    {
      sMessage += sTxtSaved + "\n";
      for (i = 0; i < aSaved.length; ++i)
        sMessage += sTextDir + GetItemTextLV(aSaved[i], 2) + "\n";
    }

    if (aNotSaved.length)
    {
      sMessage += "\n" + sTxtNotSaved + "\n";
      for (i = 0; i < aNotSaved.length; ++i)
        sMessage += sTextDir + GetItemTextLV(aNotSaved[i], 2) + "\n";
    }

    AkelPad.MessageBox(hDlg, sMessage, sTxtScriptName, 0x40 /*MB_ICONINFORMATION*/);
  }
}

function OpenText(lpData, nSel, bMouseClick)
{
  if (aFrame[nSel])
  {
    if (bMouseClick && (aFrame[nSel] == AkelPad.SendMessage(hMainWnd, 1290 /*AKD_FRAMEFINDW*/, 1 /*FWF_CURRENT*/, 0)))
      AkelPad.Command(4318 /*IDM_WINDOW_FRAMECLOSE*/);
    else
      AkelPad.SendMessage(hMainWnd, 1285 /*AKD_FRAMEACTIVATE*/, 0, aFrame[nSel]);
  }
  else
  {
    var sTabText = GetItemTextLV(nSel, 0) + ": " + GetItemTextLV(nSel, 1);
    var lpText   = AkelPad.MemAlloc((sTabText.length + 1) * 2);
    var lpTCITEM = AkelPad.MemAlloc(_X64 ? 40 : 28 /*sizeof(TCITEM)*/);
    var hWndTab  = AkelPad.SendMessage(hMainWnd, 1222 /*AKD_GETMAININFO*/, 13 /*MI_WNDTAB*/, 0);
    var nTab;

    AkelPad.SendMessage(hMainWnd, 273 /*WM_COMMAND*/, 4101 /*IDM_FILE_NEW*/, 1 /*lParam=TRUE*/);
    AkelPad.Command(4125 /*IDM_FILE_REOPENAS_UTF16LE*/);
    AkelPad.Command(4186 /*IDM_EDIT_NEWLINE_MAC*/);
    oSys.Call("User32::SetWindowTextW", AkelPad.GetEditWnd(), lpData);

    if (AkelPad.IsPluginRunning("Coder::HighLight"))
      AkelPad.Call("Coder::Settings", 1, "akelmenu");

    aFrame[nSel] = AkelPad.SendMessage(hMainWnd, 1290 /*AKD_FRAMEFINDW*/, 1 /*FWF_CURRENT*/, 0);
    nTab         = AkelPad.SendMessage(hWndTab, 4875 /*TCM_GETCURSEL*/, 0, 0);

    AkelPad.MemCopy(lpText, sTabText, 1 /*DT_UNICODE*/);
    AkelPad.MemCopy(lpTCITEM, 1 /*TCIF_TEXT*/, 3 /*DT_DWORD*/); //mask
    AkelPad.MemCopy(_PtrAdd(lpTCITEM, _X64 ? 16 : 12), lpText, 2 /*DT_QWORD*/); //pszText

    AkelPad.SendMessage(hWndTab, 4925 /*TCM_SETITEMW*/, nTab, lpTCITEM);

    AkelPad.MemFree(lpTCITEM);
    AkelPad.MemFree(lpText);
  }
}

function LoadTextToPlugin(bFromFile)
{
  var nCurFrame  = AkelPad.SendMessage(hMainWnd, 1290 /*AKD_FRAMEFINDW*/, 1 /*FWF_CURRENT*/, 0);
  var sTextDir   = ExpandDirName(sTextDirS);
  var sPlugDir   = AkelPad.GetAkelDir(4 /*ADTYPE_PLUGS*/) + "\\";
  var aSel       = GetSelArrayLV();
  var aLoaded    = [];
  var aNotLoaded = [];
  var sMessage   = "";
  var sPrevPlug  = "";
  var hKey;
  var lpType;
  var sIniFile;
  var sBakFile;
  var sText;
  var sIniText;
  var nSize;
  var lpData;
  var oRE;
  var bWasLoaded;
  var i, n;

  if (AkelPad.MessageBox(hDlg, sTxtWantLoad, sTxtScriptName, 0x21 /*MB_DEFBUTTON1|MB_ICONQUESTION|MB_OKCANCEL*/) != 1 /*IDOK*/)
    return;

  if (bSetInReg)
  {
    lpType = AkelPad.MemAlloc(4);

    for (i = 0; i < aSel.length; ++i)
    {
      bWasLoaded = false;
      hKey       = GetRegKeyHandle(0x80000001 /*HKEY_CURRENT_USER*/, "Software\\Akelsoft\\AkelPad\\Plugs\\" + GetItemTextLV(aSel[i], 0), 0x0003 /*KEY_SET_VALUE|KEY_QUERY_VALUE*/);
      sText      = bFromFile ? AkelPad.ReadFile(sTextDir + GetItemTextLV(aSel[i], 2), 0x10 /*OD_ADT_NOMESSAGES*/, 1200 /*UTF-16LE*/, 1 /*bBOM*/) : GetTextAE(aSel[i]);

      if (hKey
          && (! oSys.Call("Advapi32::RegQueryValueExW",
                  hKey,                      //hKey
                  GetItemTextLV(aSel[i], 1), //lpValueName
                  0,                         //lpReserved
                  lpType,                    //lpType
                  0,                         //lpData
                  0))                        //lpcbData
          && (AkelPad.MemRead(lpType, DT_DWORD) == 3 /*REG_BINARY*/)
          && sText)
      {
        //create registry key backup file
        if (GetItemTextLV(aSel[i], 0) != sPrevPlug)
        {
          sBakFile = sTextDir + GetItemTextLV(aSel[i], 0) + ".reg.bak";
          DeleteFile(sBakFile);
          AkelPad.Exec("reg.exe export HKEY_CURRENT_USER\\Software\\Akelsoft\\AkelPad\\Plugs\\" + GetItemTextLV(aSel[i], 0) + " " + sBakFile, "", 1);
          sPrevPlug = GetItemTextLV(aSel[i], 0);
        }

        nSize  = (sText.length + 1) * 2;
        lpData = AkelPad.MemAlloc(nSize);
        AkelPad.MemCopy(lpData, sText, DT_UNICODE);

        if ((! oSys.Call("Advapi32::RegSetValueExW",
                 hKey,                      //hKey
                 GetItemTextLV(aSel[i], 1), //lpValueName
                 0,                         //Reserved
                 3,                         //dwType = REG_BINARY
                 lpData,                    //lpData
                 nSize)))                   //cbData
        {
          aLoaded.push(aSel[i]);
          bWasLoaded = true;
        }

        AkelPad.MemFree(lpData);
      }

      oSys.Call("Advapi32::RegCloseKey", hKey);
      if (! bWasLoaded)
        aNotLoaded.push(aSel[i]);
    }

    AkelPad.MemFree(lpType);
  }

  else
  {
    for (i = 0; i < aSel.length; ++i)
    {
      bWasLoaded = false;
      sIniFile   = sPlugDir + GetItemTextLV(aSel[i], 0) + ".ini";
      sText      = bFromFile ? AkelPad.ReadFile(sTextDir + GetItemTextLV(aSel[i], 2), 0x10 /*OD_ADT_NOMESSAGES*/, 1200 /*UTF-16LE*/, 1 /*bBOM*/) : GetTextAE(aSel[i]);

      if (oFSO.FileExists(sIniFile) && sText)
      {
        oRE      = new RegExp(escapeRegExp(GetItemTextLV(aSel[i], 1)) + "=[\\dA-F]*");
        sIniText = AkelPad.ReadFile(sIniFile, 0x10 /*OD_ADT_NOMESSAGES*/, 1200 /*UTF-16LE*/, 1 /*bBOM*/);
        nSize    = (sText.length + 1) * 2;
        lpData   = AkelPad.MemAlloc(nSize);
        AkelPad.MemCopy(lpData, sText, DT_UNICODE);

        sText = "";
        for (n = 0; n < nSize; ++n)
          sText += PadL0(AkelPad.MemRead(_PtrAdd(lpData, n), DT_BYTE).toString(16).toUpperCase());
        AkelPad.MemFree(lpData);

        if (sText && oRE.test(sIniText))
        {
          //create backup .ini file
          if (GetItemTextLV(aSel[i], 0) != sPrevPlug)
          {
            sBakFile = sTextDir + GetItemTextLV(aSel[i], 0) + ".ini.bak";
            CopyFile(sIniFile, sBakFile);
            sPrevPlug = GetItemTextLV(aSel[i], 0);
          }

          if (AkelPad.WriteFile(sIniFile, sIniText.replace(oRE, GetItemTextLV(aSel[i], 1) + "=" + sText), -1, 1200 /*UTF-16LE*/, 1 /*bBOM*/) == 0 /*ESD_SUCCESS*/)
          {
            aLoaded.push(aSel[i]);
            bWasLoaded = true;
          }
        }
      }

      if (! bWasLoaded)
        aNotLoaded.push(aSel[i]);
    }
  }

  if (aLoaded.length)
  {
    sMessage += sTxtLoaded + "\n";

    for (i = 0; i < aLoaded.length; ++i)
    {
      sMessage += GetItemTextLV(aLoaded[i], 0) + ": " + GetItemTextLV(aLoaded[i], 1) + "\n";
      RestartPlugin(GetItemTextLV(aLoaded[i], 0));
    }

    if ((! bFromFile) && AkelPad.IsPluginRunning("Coder::HighLight"))
    {
      for (i = 0; i < aFrame.length; ++i)
      {
        if (aFrame[i])
        {
          AkelPad.SendMessage(hMainWnd, 1285 /*AKD_FRAMEACTIVATE*/, 0, aFrame[i]);
          AkelPad.Call("Coder::Settings", 1, "akelmenu");
        }
      }
    }
  }

  if (aNotLoaded.length)
  {
    sMessage += "\n" + sTxtNotLoaded + "\n";

    for (i = 0; i < aNotLoaded.length; ++i)
      sMessage += GetItemTextLV(aNotLoaded[i], 0) + ": " + GetItemTextLV(aNotLoaded[i], 1) + "\n";
  }

  if (! bFromFile)
    AkelPad.SendMessage(hMainWnd, 1285 /*AKD_FRAMEACTIVATE*/, 0, nCurFrame);

  AkelPad.MessageBox(hDlg, sMessage, sTxtScriptName, 0x40 /*MB_ICONINFORMATION*/);
}

function GetTextAE(nSel)
{
  if (aFrame[nSel])
  {
    AkelPad.SendMessage(hMainWnd, 1285 /*AKD_FRAMEACTIVATE*/, 0, aFrame[nSel]);
    return AkelPad.GetTextRange(0, -1, 0 /*New line as is*/);
  }
}

function PadL0(sStr)
{
  if (sStr.length == 1)
    sStr = "0" + sStr;

  return sStr;
}

function RestartPlugin(sPlugName)
{
  var bCoderHL;
  var bCoderCF;
  var bCoderAC;

  if (sPlugName == "Coder")
  {
    if (AkelPad.IsPluginRunning(sPlugName + "::HighLight"))
    {
      bCoderHL = 1;
      AkelPad.Call(sPlugName + "::HighLight");
    }
    if (AkelPad.IsPluginRunning(sPlugName + "::CodeFold"))
    {
      bCoderCF = 1;
      AkelPad.Call(sPlugName + "::CodeFold");
    }
    if (AkelPad.IsPluginRunning(sPlugName + "::AutoComplete"))
    {
      bCoderAC = 1;
      AkelPad.Call(sPlugName + "::AutoComplete");
    }

    if (bCoderHL)
      AkelPad.Call(sPlugName + "::HighLight");
    if (bCoderCF)
      AkelPad.Call(sPlugName + "::CodeFold");
    if (bCoderAC)
      AkelPad.Call(sPlugName + "::AutoComplete");
  }
  else if ((sPlugName == "ContextMenu") || (sPlugName == "Hotkeys"))
  {
    if (AkelPad.IsPluginRunning(sPlugName + "::Main"))
    {
      AkelPad.Call(sPlugName + "::Main", 10);
      AkelPad.Call(sPlugName + "::Main", 10);
    }
  }
  //SpecialChar, ToolBar*
  else
  {
    if (AkelPad.IsPluginRunning(sPlugName + "::Main"))
    {
      AkelPad.Call(sPlugName + "::Main");
      AkelPad.Call(sPlugName + "::Main");
    }
  }
}

function EditTextFile()
{
  var sTextDir = ExpandDirName(sTextDirS);
  var aSel     = GetSelArrayLV();
  var aNoFile  = [];
  var sTextFile;
  var i;

  for (i = 0; i < aSel.length; ++i)
  {
    sTextFile = sTextDir + GetItemTextLV(aSel[i], 2);

    if (oFSO.FileExists(sTextFile))
      AkelPad.OpenFile(sTextFile);
    else
      aNoFile.push(aSel[i]);
  }

  if (aNoFile.length)
  {
    sMessage = sTxtNoFiles + "\n";
    for (i = 0; i < aNoFile.length; ++i)
      sMessage += sTextDir + GetItemTextLV(aNoFile[i], 2) + "\n";

    AkelPad.MessageBox(hDlg, sMessage, sTxtScriptName, 0x30 /*MB_ICONWARNING*/);
  }
}

function RenameTextFile()
{
  var aSel = GetSelArrayLV();
  var sOldName;
  var sNewName;

  for (i = 0; i < aSel.length; ++i)
  {
    sOldName = GetItemTextLV(aSel[i], 2);
    sNewName = GetFileName(sTxtRenameFile, sOldName + "\n\n" + sTxtNewName, sOldName);

    if (sNewName)
    {
      if (sNewName != sOldName)
      {
        SetItemTextLV(aSel[i], 2, sNewName);
        RenameFile(ExpandDirName(sTextDirS) + sOldName, ExpandDirName(sTextDirS) + sNewName);
      }
    }
    else
      break;
  }
}

function GetFileName(sCaption, sLabel, sName)
{
  while (true)
  {
    sName = AkelPad.InputBox(hDlg, sCaption, sLabel, sName);

    if (sName)
    {
      sName = sName.replace(/[ .]+$/, "");

      if (/^(CON|PRN|AUX|NUL|COM1|COM2|COM3|COM4|COM5|COM6|COM7|COM8|COM9|LPT1|LPT2|LPT3|LPT4|LPT5|LPT6|LPT7|LPT8|LPT9)$/i.test(sName))
        AkelPad.MessageBox(hDlg, sName + "\n\n" + sTxtBadName, sCaption, 0x30 /*MB_ICONWARNING*/);
      else if (/[<>:"/\\|?*]/.test(sName))
        AkelPad.MessageBox(hDlg, sName + "\n\n" + sTxtBadChar, sCaption, 0x30 /*MB_ICONWARNING*/);
      else
        break;
    }
    else
      break;
  }

  return sName;
}

function DeleteTextFile()
{
  var sTextDir    = ExpandDirName(sTextDirS);
  var aSel        = GetSelArrayLV();
  var aDeleted    = [];
  var aNotDeleted = [];
  var sMessage    = "";

  if (AkelPad.MessageBox(hDlg, sTxtWantDelete, sTxtScriptName, 0x21 /*MB_DEFBUTTON1|MB_ICONQUESTION|MB_OKCANCEL*/) == 1 /*IDOK*/)
  {
    for (i = 0; i < aSel.length; ++i)
    {
      if (DeleteFile(sTextDir + GetItemTextLV(aSel[i], 2)))
        aDeleted.push(aSel[i]);
      else
        aNotDeleted.push(aSel[i]);
    }

    if (aDeleted.length)
    {
      sMessage += sTxtDeleted + "\n";
      for (i = 0; i < aDeleted.length; ++i)
        sMessage += sTextDir + GetItemTextLV(aDeleted[i], 2) + "\n";
    }

    if (aNotDeleted.length)
    {
      sMessage += "\n" + sTxtNotDeleted + "\n";
      for (i = 0; i < aNotDeleted.length; ++i)
        sMessage += sTextDir + GetItemTextLV(aNotDeleted[i], 2) + "\n";
    }

    AkelPad.MessageBox(hDlg, sMessage, sTxtScriptName, 0x40 /*MB_ICONINFORMATION*/);
  }
}

//function written by Infocatcher
function escapeRegExp(str)
{
  return str.replace(/[\\\/.^$+*?|()\[\]{}]/g, "\\$&");
}

function ChangeTextsDir()
{
  var sLabel  = "%a - " + sTxtAkelDir + "\n%p - " + sTxtPlugDir + "\n%variable% - " + sTxtEnvVar;
  var sDirS   = sTextDirS;
  var bChange = 0;
  var sDirE;

  while (true)
  {
    sDirS = AkelPad.InputBox(hDlg, sTxtChangeDir, sLabel, sDirS);

    if (sDirS)
    {
      if (sDirS.slice(-1) != "\\")
        sDirS += "\\";

      sDirE = ExpandDirName(sDirS);

      if (oFSO.FolderExists(sDirE))
      {
        bChange = 1;
        break;
      }
      else if (AkelPad.MessageBox(hDlg, sDirE + "\n\n" + sTxtDirNoExists, sTxtScriptName, 0x21 /*MB_DEFBUTTON1|MB_ICONQUESTION|MB_OKCANCEL*/) == 1 /*IDOK*/)
      {
        if (oSys.Call("Kernel32::CreateDirectoryW", sDirE, 0))
        {
          bChange = 1;
          break;
        }
        else
          AkelPad.MessageBox(hDlg, sDirE + "\n\n" + sTxtDirCreFail, sTxtScriptName, 0x30 /*MB_ICONWARNING*/);
      }
    }
    else
      break;
  }

  if (bChange)
  {
    sTextDirS = sDirS;
    oSys.Call("User32::SetWindowTextW", aDlg[IDDIR][HWND], sTxtDir + sDirE);
  }
}

function ExpandDirName(sDir)
{
  sDir = sDir.replace(/%a\\/g, AkelPad.GetAkelDir() + "\\");
  sDir = sDir.replace(/%p\\/g, AkelPad.GetAkelDir(4 /*ADTYPE_PLUGS*/) + "\\");
  sDir = sDir.replace(/%.+?%/g, ExpandEnvironmentString);

  if (oSys.Call("Kernel32::GetFullPathNameW", sDir, nBufSize / 2, lpBuffer, 0))
    sDir = AkelPad.MemRead(lpBuffer, DT_UNICODE);

  return sDir;
}

function ExpandEnvironmentString(sStr)
{
  if (oSys.Call("Kernel32::ExpandEnvironmentStringsW", sStr, lpBuffer, nBufSize / 2))
    sStr = AkelPad.MemRead(lpBuffer, DT_UNICODE);

  return sStr;
}

function EditIniFile()
{
  var sPlugDir = AkelPad.GetAkelDir(4 /*ADTYPE_PLUGS*/) + "\\";
  var aSel     = GetSelArrayLV();
  var aNoFile  = [];
  var sIniFile;
  var nSelStart;
  var sMessage;
  var i;

  for (i = 0; i < aSel.length; ++i)
  {
    sIniFile = sPlugDir + GetItemTextLV(aSel[i], 0) + ".ini";

    if (oFSO.FileExists(sIniFile))
    {
      if (AkelPad.OpenFile(sIniFile) == 0 /*EOD_SUCCESS*/)
      {
        nSelStart = AkelPad.TextFind(AkelPad.GetEditWnd(), GetItemTextLV(aSel[i], 1), 0x00200001 /*FR_DOWN|FR_BEGINNING*/);
        if (nSelStart > -1)
          AkelPad.SetSel(nSelStart, nSelStart + GetItemTextLV(aSel[i], 1).length);
      }
    }
    else
      aNoFile.push(aSel[i]);
  }

  if (aNoFile.length)
  {
    sMessage = sTxtNoFiles + "\n";
    for (i = 0; i < aNoFile.length; ++i)
      sMessage += sPlugDir + GetItemTextLV(aSel[i], 0) + ".ini" + "\n";

    AkelPad.MessageBox(hDlg, sMessage, sTxtScriptName, 0x30 /*MB_ICONWARNING*/);
  }
}

function OpenInRegEdit()
{
  var aSel     = GetSelArrayLV();
  var hKey     = GetRegKeyHandle(0x80000001 /*HKEY_CURRENT_USER*/, "Software\\Microsoft\\Windows\\CurrentVersion\\Applets\\Regedit", 0x0002 /*KEY_SET_VALUE*/);
  var sValue   = "HKEY_CURRENT_USER\\Software\\Akelsoft\\AkelPad\\Plugs\\" + GetItemTextLV(aSel[0], 0);
  var nSize    = (sValue.length + 1) * 2;
  var lpData   = AkelPad.MemAlloc(nSize);
  var sProcess = "regedit.exe";

  TerminateProcess(sProcess);

  AkelPad.MemCopy(lpData, sValue, DT_UNICODE);

  oSys.Call("Advapi32::RegSetValueExW",
    hKey,      //hKey
    "LastKey", //lpValueName
    0,         //Reserved
    1,         //dwType = REG_SZ
    lpData,    //lpData
    nSize);    //cbData
  
  oSys.Call("Advapi32::RegCloseKey", hKey);
  AkelPad.MemFree(lpData);

  AkelPad.Exec("rundll32.exe shell32, ShellExec_RunDLL " + sProcess);
}

function TerminateProcess(sProcess)
{
  var lpPIDs  = AkelPad.MemAlloc(4000);
  var lpBytes = AkelPad.MemAlloc(4);
  var lpName  = AkelPad.MemAlloc(260 * 2);
  var hProcess;
  var i;

  sProcess = sProcess.toUpperCase();

  oSys.Call("Psapi::EnumProcesses", lpPIDs, 4000, lpBytes);

  for (i = 0; i < AkelPad.MemRead(lpBytes, DT_DWORD) / 4; ++i)
  {
    if (hProcess = oSys.Call("Kernel32::OpenProcess",
                     0x0411 /*PROCESS_QUERY_INFORMATION|PROCESS_VM_READ|PROCESS_TERMINATE*/,
                     0,
                     AkelPad.MemRead(_PtrAdd(lpPIDs, i * 4), DT_DWORD)))
    {
      oSys.Call("Psapi::GetModuleBaseNameW", hProcess, 0, lpName, 260);

      if (AkelPad.MemRead(lpName, DT_UNICODE).toUpperCase() == sProcess)
        oSys.Call("Kernel32::TerminateProcess", hProcess, 0);

      oSys.Call("Kernel32::CloseHandle", hProcess);
    }
  }

  AkelPad.MemFree(lpPIDs);
  AkelPad.MemFree(lpBytes);
  AkelPad.MemFree(lpName);
}

function CopyFile(sFromFile, sToFile)
{
  try
  {
    oFSO.CopyFile(sFromFile, sToFile, 1 /*overwrite*/);
    return 1;
  }
  catch (oError)
  {}
}

function DeleteFile(sFile)
{
  try
  {
    oFSO.DeleteFile(sFile, 1 /*force*/);
    return 1;
  }
  catch (oError)
  {}
}

function RenameFile(sOldName, sNewName)
{
  DeleteFile(sNewName);

  try
  {
    oFSO.MoveFile(sOldName, sNewName);
    return 1;
  }
  catch (oError)
  {}
}

function IsScriptRunning()
{
  var hDlg = oSys.Call("User32::FindWindowExW", 0, 0, sClass, 0);

  if (hDlg)
  {
    if (! oSys.Call("User32::IsWindowVisible", hDlg))
      oSys.Call("User32::ShowWindow", hDlg, 8 /*SW_SHOWNA*/);
    if (oSys.Call("User32::IsIconic", hDlg))
      oSys.Call("User32::ShowWindow", hDlg, 9 /*SW_RESTORE*/);

    oSys.Call("User32::SetForegroundWindow", hDlg);
    return true;
  }
}

function IsSDI()
{
  if (! AkelPad.IsMDI())
  {
    AkelPad.MessageBox(hMainWnd, sTxtOnlyMDI, sTxtScriptName, 0x30 /*MB_ICONWARNING*/);
    return true;
  }
}

function ReadIni()
{
  var sLangTxt = AkelPad.ReadFile(WScript.ScriptFullName.replace(/\.js$/i, "_" + AkelPad.GetLangId() + ".lng"), 0x1D /*OD_ADT_BINARY_ERROR|OD_ADT_DETECT_CODEPAGE|OD_ADT_DETECT_BOM|OD_ADT_NOMESSAGES*/);
  if (sLangTxt)
  {
    try
    {
      eval(sLangTxt);
    }
    catch (oError)
    {
      sLangTxt = "";
    }
  }

  try
  {
    eval(AkelPad.ReadFile(WScript.ScriptFullName.replace(/\.js$/i, ".ini"), 0x10 /*OD_ADT_NOMESSAGES*/, 1200 /*UTF-16LE*/, 1 /*bBOM*/));
  }
  catch (oError)
  {}

  if (nWndPosW < nWndMinW) nWndPosW = nWndMinW;
  if (nWndPosH < nWndMinH) nWndPosH = nWndMinH;

  if ((! sTextDirS) || (! oFSO.FolderExists(ExpandDirName(sTextDirS))))
    sTextDirS = "%p\\";
  else if (sTextDirS.slice(-1) != "\\")
    sTextDirS += "\\";
}

function WriteIni()
{
  var lpRect = AkelPad.MemAlloc(16); //sizeof(RECT)
  var sPlug;
  var sText;
  var sIniText;
  var i, n;

  oSys.Call("User32::GetWindowRect", hDlg, lpRect);
  nWndPosX = AkelPad.MemRead(_PtrAdd(lpRect,  0), DT_DWORD);
  nWndPosY = AkelPad.MemRead(_PtrAdd(lpRect,  4), DT_DWORD);
  nWndPosW = AkelPad.MemRead(_PtrAdd(lpRect,  8), DT_DWORD) - nWndPosX;
  nWndPosH = AkelPad.MemRead(_PtrAdd(lpRect, 12), DT_DWORD) - nWndPosY;
  AkelPad.MemFree(lpRect);

  oPlugText = {};
  for (i = 0; i < GetItemCountLV(); ++i)
  {
    sPlug = GetItemTextLV(i, 0);
    sText = GetItemTextLV(i, 1);

    if (! oPlugText[sPlug])
      oPlugText[sPlug] = {};

    if (! oPlugText[sPlug][sText])
      oPlugText[sPlug][sText] = {Sel: AkelPad.SendMessage(aDlg[IDPLUG][HWND], 0x102C /*LVM_GETITEMSTATE*/, i, 0x0002 /*LVIS_SELECTED*/), File: GetItemTextLV(i, 2)};
  }

  sIniText = 'nWndPosX='   + nWndPosX + ';\r\n' +
             'nWndPosY='   + nWndPosY + ';\r\n' +
             'nWndPosW='   + nWndPosW + ';\r\n' +
             'nWndPosH='   + nWndPosH + ';\r\n' +
             'sTextDirS="' + sTextDirS.replace(/[\\"]/g, "\\$&") + '";\r\noPlugText={';

  for (i in oPlugText)
  {
    sIniText += '"' + i + '":{';
    for (n in oPlugText[i])
    {
      sIniText += '"' + n + '":{Sel:' + oPlugText[i][n].Sel + ',File:"' + oPlugText[i][n].File + '"},';
    }
    if (sIniText.slice(-1) == ",")
      sIniText = sIniText.slice(0, -1);
    sIniText += '},';
  }
  if (sIniText.slice(-1) == ",")
    sIniText = sIniText.slice(0, -1);
  sIniText += '};';

  AkelPad.WriteFile(WScript.ScriptFullName.replace(/\.js$/i, ".ini"), sIniText, sIniText.length, 1200 /*UTF-16LE*/, 1 /*bBOM*/);
}


The only changes I made in js-file are:
1) Inserted language-file reading code from one of another your scripts to ReadIni() function:

Code: Select all

  var sLangTxt = AkelPad.ReadFile(WScript.ScriptFullName.replace(/\.js$/i, "_" + AkelPad.GetLangId() + ".lng"), 0x1D /*OD_ADT_BINARY_ERROR|OD_ADT_DETECT_CODEPAGE|OD_ADT_DETECT_BOM|OD_ADT_NOMESSAGES*/);
  if (sLangTxt)
  {
    try
    {
      eval(sLangTxt);
    }
    catch (oError)
    {
      sLangTxt = "";
    }
  }

2) Added spaces before hotkeys in button labels:

Code: Select all

aDlg[IDB1  ]=["BUTTON",        0, 0x50000000, sTxtEditText + " (F1)"];
aDlg[IDB2  ]=["BUTTON",        0, 0x50000000, sTxtLoadText + " (F2)"];
aDlg[IDB3  ]=["BUTTON",        0, 0x50000000, sTxtSaveTextFile + " (F3)"];
aDlg[IDB4  ]=["BUTTON",        0, 0x50000000, sTxtEditTextFile + " (F4)"];
aDlg[IDB5  ]=["BUTTON",        0, 0x50000000, sTxtLoadTextFile + " (F5)"];
aDlg[IDB6  ]=["BUTTON",        0, 0x50000000, sTxtRenameFile + " (F7)"];
aDlg[IDB7  ]=["BUTTON",        0, 0x50000000, sTxtDeleteFile + " (F8)"];
aDlg[IDB8  ]=["BUTTON",        0, 0x50000000, sTxtChangeDir + " (F9)"];
aDlg[IDB9  ]=["BUTTON",        0, 0x50000000, (bSetInReg ? sTxtOpenRegEdit : sTxtEditIniFile) + " (Shift+F4)"];

(beyond compare screenshot)

KDJ
Offline
Posts: 1949
Joined: Sat Mar 06, 2010 7:40 pm
Location: Poland

Post by KDJ »

InsertTextLN.js
Changed: now dialog box is modeless.
Added: "Apply" button.
Locked