Scripts discussion (3)

Discuss and announce AkelPad plugins
Locked
  • Author
  • Message
Offline
Posts: 1162
Joined: Sun Oct 20, 2013 11:44 am

Post by Skif_off »

Andrey_A_A
Перевести могу, я спрашивал - а нужен ли он тут? :) Пара фраз всего.
Ошибочные данные попадают, т.к. я не решил первый вопрос.

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

Post by KDJ »

Skif_off
The script can insert more than one character. This piece of code is unnecessary:

Code: Select all

  if (sHex.length != 4)
  {
    AkelPad.MessageBox(hMainWnd, "Four digits only (0-9, A-F).", "Error", 0x10 /*MB_ICONERROR*/);
  }
As the first parameter in the call to MessageBox function specify the handle of the dialog box instead of AkelPad main window.
Action() should be call with the parameter hWnd (dialog box handle) and should return "false" if an error occurred.
Close the dialog box just in case if Action() function returns "true":

Code: Select all

...
    if (nLowParam == IDOKB)
    {
      if (Action(hWnd))
        oSys.Call("User32::EndDialog", hWnd, 0);
    }
...
  if (/[^a-f\d]+/i.test(sHex))
  {
    AkelPad.MessageBox(hWnd, "Hex digits only (0-9, A-F).", "Error", 0x10 /*MB_ICONERROR*/);
    return false;
  }
  else
  {
...
  }
...
  return true;
}

Offline
Posts: 1162
Joined: Sun Oct 20, 2013 11:44 am

Post by Skif_off »

KDJ
Big thanks, now:

Code: Select all

    if (nLowParam == IDOKB)
    {
      if (Action())
      {
        oSys.Call("User32::EndDialog", hWnd, 0);
      }
    }
May be necessary to replace

Code: Select all

  else
  {
    if (AkelPad.GetEditWnd())
    {
      if(fso.FileExists(pAkelPlugsDir + "\\HexSel.dll"))
      {
        AkelPad.Call("HexSel::Main", 1, 10, "", "", sHex);
      }
      else
      {
        if (sHex = sHex.substr(0, Math.floor(sHex.length / 4) * 4))
        {
          for (i = 0; i < sHex.length; i += 4)
            sChar += String.fromCharCode(parseInt(sHex.substr(i, 4), 16));

          AkelPad.ReplaceSel(sChar);
        }
      }
    }
    return true;
  }
on

Code: Select all

  else
  {
    if (AkelPad.GetEditWnd())
    {
      if (sHex = sHex.substr(0, Math.floor(sHex.length / 4) * 4))
      {
        if(fso.FileExists(pAkelPlugsDir + "\\HexSel.dll"))
        {
          AkelPad.Call("HexSel::Main", 1, 10, "", "", sHex);
        }
        else
        {
          for (i = 0; i < sHex.length; i += 4)
            sChar += String.fromCharCode(parseInt(sHex.substr(i, 4), 16));

          AkelPad.ReplaceSel(sChar);
        }
      }
    }
    return true;
  }
?

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

Post by KDJ »

Skif_off

Code: Select all

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

  if (uMsg == 272 /*WM_INITDIALOG*/)
  {
    //fill ComboBox
    for (i = 0; i < aHex.length; ++i)
      AkelPad.SendMessage(aDlg[IDTEXTCB].HWND, 323 /*CB_ADDSTRING*/, 0, aHex[i]);

    AkelPad.SendMessage(aDlg[IDTEXTCB].HWND, 334 /*CB_SETCURSEL*/, 0, 0);
  }

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

    if (nLowParam == IDOKB)
    {
      if (Action(hWnd))
        oSys.Call("User32::EndDialog", hWnd, 0);
    }

    else if ((nLowParam == IDCANCELB) || (nLowParam == 2 /*IDCANCEL*/))
      oSys.Call("User32::EndDialog", hWnd, 0);
  }
}

function Action(hWnd)
{
  var nTextLen   = AkelPad.SendMessage(aDlg[IDTEXTCB].HWND, 14 /*WM_GETTEXTLENGTH*/, 0, 0) + 1;
  var lpText     = AkelPad.MemAlloc(nTextLen * 2);
  var sIniString = "";
  var sChar      = "";
  var sHex       = "";
  var i;

  AkelPad.SendMessage(aDlg[IDTEXTCB].HWND, 13 /*WM_GETTEXT*/, nTextLen, lpText);
  sHex = AkelPad.MemRead(lpText, 1 /*DT_UNICODE*/);
  AkelPad.MemFree(lpText);

  if (/[^a-f\d]+/i.test(sHex))
  {
    AkelPad.MessageBox(hWnd, "Hex digits only (0-9, A-F).", "Error", 0x10 /*MB_ICONERROR*/);
    return false;
  }
  else
  {
    if (AkelPad.GetEditWnd())
    {
      if(fso.FileExists(pAkelPlugsDir + "\\HexSel.dll"))
      {
        AkelPad.Call("HexSel::Main", 1, 10, "", "", sHex);
      }
      else
      {
        if (sHex = sHex.substr(0, Math.floor(sHex.length / 4) * 4))
        {
          for (i = 0; i < sHex.length; i += 4)
            sChar += String.fromCharCode(parseInt(sHex.substr(i, 4), 16));

          AkelPad.ReplaceSel(sChar);
        }
      }
    }
  }

  //add sHex to aHex & write parameters (aHex and other) to ini file
  if (nArg1 = 1)
  {
    var oFile   = fso.OpenTextFile(WScript.ScriptFullName.substring(0, WScript.ScriptFullName.lastIndexOf(".")) + ".ini", 2, true, -1);

    if (sHex != aHex[0])
    {
      sIniString = aHex.unshift(sHex);
    }
    if (aHex.length > nArg2)
    {
      aHex.splice(nArg2, aHex.length)
    }
    sIniString = aHex.join(",");
 
    oFile.Write(sIniString);
    oFile.Close();
  }

  return true;
}

Offline
Posts: 1162
Joined: Sun Oct 20, 2013 11:44 am

Post by Skif_off »

KDJ
Thank you, I got a little differently (history without duplicates):

Code: Select all

// Argumens:
//   -RW=0         - (default) don't store inserted strings
//      =1         - store inserted strings
//   -history=20   - (default) set history length (with -RW=1 only)
// Ru:
//   -RW=0         - по умолчанию не сохранять введенные строки
//      =1         - сохранять введенные строки
//   -history=20   - размер истории, по умолчанию 20, только вместе с -RW=1
//
// Usage:
// Call("Scripts::Main", 1, "InsertUnicodeChar.js")
// Call("Scripts::Main", 1, "InsertUnicodeChar.js", '-RW=1')
// Call("Scripts::Main", 1, "InsertUnicodeChar.js", '-RW=1 -history=10')

if (! AkelPad.Include("CreateDialog_functions.js")) WScript.Quit();

var oSys            = AkelPad.SystemFunction();
var pAkelPlugsDir   = AkelPad.GetAkelDir(4);
var pAkelScriptsDir = AkelPad.GetAkelDir(5);
var nArg1           = AkelPad.GetArgValue("RW", 0);
var nArg2           = AkelPad.GetArgValue("history", 20);
var fso             = new ActiveXObject("Scripting.FileSystemObject");
var aHex;

//read parameters from ini file
if (nArg1 == 1)
{
  var sIniFile = WScript.ScriptFullName.replace(/\.js$/i, ".ini");
  
  if (fso.FileExists(sIniFile))
  {
    var aHex = AkelPad.ReadFile(sIniFile, 0x10 /*OD_ADT_NOMESSAGES*/, 1200 /*UTF-16LE*/, true).split(/[,]/);
  }
  else
  {
    var aHex = ["002F"];
  }
}
else
{
  var aHex = ["002F"];
}

//GUI. Thanks KDJ
var IDLABELS  = 1000;
var IDTEXTCB  = 1001;
var IDOKB     = 1002;
var IDCANCELB = 1004;
var aDlg      = [];

aDlg.Title    = "Insert characters from hex codes";
aDlg.Style    = WS_VISIBLE | WS_POPUP | WS_CAPTION | WS_SYSMENU | DS_CENTER;
aDlg.Parent   = AkelPad.GetMainWnd();
aDlg.Callback = DialogCallback;
aDlg.W        = 216;
aDlg.H        = 63;
aDlg.CtlStyle = WS_VISIBLE;
aDlg.CtlFontN = "MS Shell Dlg";
aDlg.CtlFirst = IDLABELS;

aDlg[IDLABELS]  = {X:   8, Y:   8, W: 200, H:  10, Title: "Four digits hex codes:", Class: "STATIC"};
aDlg[IDTEXTCB]  = {X:   8, Y:  20, W: 200, H: 100,                          Class: "COMBOBOX", Style: WS_TABSTOP | CBS_DROPDOWN};
aDlg[IDOKB]     = {X:   8, Y:  40, W:  50, H:  15, Title: "OK",                                Style: WS_TABSTOP | BS_DEFPUSHBUTTON};
aDlg[IDCANCELB] = {X:  66, Y:  40, W:  50, H:  15, Title: "Cancel",                            Style: WS_TABSTOP};

CreateDialogBox(aDlg);

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

  if (uMsg == 272 /*WM_INITDIALOG*/)
  {
    //fill ComboBox
    for (i = 0; i < aHex.length; ++i)
      AkelPad.SendMessage(aDlg[IDTEXTCB].HWND, 323 /*CB_ADDSTRING*/, 0, aHex[i]);

    AkelPad.SendMessage(aDlg[IDTEXTCB].HWND, 334 /*CB_SETCURSEL*/, 0, 0);
  }

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

    if (nLowParam == IDOKB)
    {
      if (Action(hWnd))
      {
        oSys.Call("User32::EndDialog", hWnd, 0);
      }
    }

    else if ((nLowParam == IDCANCELB) || (nLowParam == 2 /*IDCANCEL*/))
      oSys.Call("User32::EndDialog", hWnd, 0);
  }
}

function Action(hWnd)
{
  var nTextLen   = AkelPad.SendMessage(aDlg[IDTEXTCB].HWND, 14 /*WM_GETTEXTLENGTH*/, 0, 0) + 1;
  var lpText     = AkelPad.MemAlloc(nTextLen * 2);
  var sIniString = "";
  var sChar      = "";
  var sHex       = "";
  var i2         = -1;
  var i;

  AkelPad.SendMessage(aDlg[IDTEXTCB].HWND, 13 /*WM_GETTEXT*/, nTextLen, lpText);
  sHex = AkelPad.MemRead(lpText, 1 /*DT_UNICODE*/);
  AkelPad.MemFree(lpText);

  if (/[^a-f\d]+/i.test(sHex))
  {
    AkelPad.MessageBox(hWnd, "Hex digits only (0-9, A-F).", "Error", 0x10 /*MB_ICONERROR*/);
    return false;
  }
  else
  {
    if (AkelPad.GetEditWnd())
    {
      if(fso.FileExists(pAkelPlugsDir + "\\HexSel.dll"))
      {
        AkelPad.Call("HexSel::Main", 1, 10, "", "", sHex);
      }
      else
      {
        if (sHex = sHex.substr(0, Math.floor(sHex.length / 4) * 4))
        {
          for (i = 0; i < sHex.length; i += 4)
            sChar += String.fromCharCode(parseInt(sHex.substr(i, 4), 16));

          AkelPad.ReplaceSel(sChar);
        }
      }
    }
    //add sHex to aHex & write parameters (aHex and other) to ini file
    if (nArg1 == 1)
    {
      var oFile   = fso.OpenTextFile(WScript.ScriptFullName.substring(0, WScript.ScriptFullName.lastIndexOf(".")) + ".ini", 2, true, -1);

      if (sHex != aHex[0]) aHex.unshift(sHex);
      if (aHex.length > nArg2) aHex.splice(nArg2, aHex.length);

      sIniString = aHex.join(",");
      oFile.Write(sIniString);
      oFile.Close();
    }
  }
  return true;
}


Code: Select all

if (! AkelPad.Include("CreateDialog_functions.js"))
{
  InsertWithoutCreateDialog()
  WScript.Quit();
}

...

function InsertWithoutCreateDialog()
{
  var hMainWnd      = AkelPad.GetMainWnd();
  var pAkelPlugsDir = AkelPad.GetAkelDir(4);
  var fso           = new ActiveXObject("Scripting.FileSystemObject");
  var sHex          = "002F";
  var sChar         = "";
  var i;

  if (AkelPad.GetEditWnd())
  {
    for (;;)
    {
      sHex = AkelPad.InputBox(hMainWnd, "Insert characters from hex codes", "Four digits hex codes:", sHex);
  
      if (! sHex)
        break;
      else if (/[^a-f\d]+/i.test(sHex))
        AkelPad.MessageBox(hMainWnd, "Hex digits only (0-9, A-F).", "Error", 0x10 /*MB_ICONERROR*/);
      else
      {
        if(fso.FileExists(pAkelPlugsDir + "\\HexSel.dll"))
        {
          AkelPad.Call("HexSel::Main", 1, 10, "", "", sHex);
        }
        else
        {
          if (sHex = sHex.substr(0, Math.floor(sHex.length / 4) * 4))
          {
            for (i = 0; i < sHex.length; i += 4)
              sChar += String.fromCharCode(parseInt(sHex.substr(i, 4), 16));
  
            AkelPad.ReplaceSel(sChar);
          }
        }
        break;
      }
    }
  }
}
, but I see error Cannot open file "%a\AkelFiles\Plugs\Scripts\Include\CreateDialog_functions.js". Сan it be corrected or it doesn't make sense?

Добавлено:
Skif_off wrote:history without duplicates
Does not work, deleted.

Offline
Posts: 670
Joined: Thu Jun 03, 2010 8:47 am
Location: Сочи, Хоста
Contact:

Post by Andrey_A_A »

я спрашивал - а нужен ли он тут?
Skif_off
Решай сам, если скрипт попадёт ко мне в сборку, то он будет там в переведённом виде.

Offline
Posts: 1162
Joined: Sun Oct 20, 2013 11:44 am

Post by Skif_off »

Чуть поправил GUI (CreateDialog_functions.js - это круто), добавил перевод и удаление повторов в истории (это было нечто, заодно научился вешать скрипт циклом for :))).

Есть мысль проверять наличие CreateDialog_functions.js и при отсутствии запускать в старой версии, с AkelPad.InputBox и без истории. Добавить или ни к чему? Чего-то он так раздулся :)

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

Post by VladSh »

Skif_off wrote:Есть мысль проверять наличие CreateDialog_functions.js и при отсутствии запускать в старой версии, с AkelPad.InputBox и без истории. Добавить или ни к чему? Чего-то он так раздулся :)
По моему, добавить. Несколько строк погоды уже не сделают))

Offline
Posts: 276
Joined: Mon Jun 20, 2011 8:33 am
Location: Электросталь

Post by yozhic »

Skif_off wrote:Чуть поправил GUI ...
А где код? Может вам пора его в Scripts Collection запостить? Только версию в комментсах припишите. Удобный скрипт получился, на ноутбуке без NumPad' а с ним красота :)

Offline
Posts: 1162
Joined: Sun Oct 20, 2013 11:44 am

Post by Skif_off »

Skif_off wrote:Есть мысль проверять наличие CreateDialog_functions.js и при отсутствии запускать в старой версии, с AkelPad.InputBox и без истории. Добавить или ни к чему?
Не получилось, переменные должны быть объявлены, надо ещё подумать.

InsertUnicodeChar.js (С историей могут быть нюансы: может отличаться от ожидаемого +/- 1-2 шт., пока не разобрался).
yozhic wrote:на ноутбуке без NumPad' а с ним красота :)
Не уловил связь :)

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

Post by VladSh »

Skif_off wrote:Не получилось, переменные должны быть объявлены, надо ещё подумать.
Я бы все эти переменные, специфичные диалогу, перенёс бы в отдельную функцию, и вызывал бы или InputBox или эту функцию. Возвращал бы оттуда введеный символ, а обработку (вставку и дополнительную проверку "писать или не писать в ini") сделал бы в конце скрипта.

Offline
Posts: 1162
Joined: Sun Oct 20, 2013 11:44 am

Post by Skif_off »

VladSh
Спасибо, подумаю.

InsertUnicodeChar.js
Немного поправлено удаление повторов в истории, добавлен пропущенный флаг регистронезависимого поиска i.

Offline
Posts: 276
Joined: Mon Jun 20, 2011 8:33 am
Location: Электросталь

Post by yozhic »

Skif_off wrote:Не уловил связь
При работе на десктопе активно пользуюсь Alt-кодами, когда нужно быстро ввести символ, отсутствующий на клавиатуре. А на ноуте клавиатура маленькая, без NumPad' а. И вот рука по привычке вправо потянется – раз, облом. Системный CharMap – неудобный и медленный. А со скриптом теперь совсем другое дело – повесил его на Alt+Ctrl+I и нужные символы доступны также быстро, как по Alt-коду.

Мне в нём ещё не хватает шпоры-подсказки по часто употребляемым символам. Наподобие, как в FindReplaceEx по F1, только настраиваемую, чтобы самому можно было редактировать (ну, можно и в скрипте подправить, если что). В формате: Код [табулятор] Символ. Например:

Code: Select all

00AB     «  (left quote)
00BB     »  (right quote)
2013     –  (En Dash)
2014     —  (Em Dash)
00B7     ·  (middle dot)
2022     •  (bullet) 

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

Post by VladSh »

yozhic
Если бы сделал так - зашёл бы прямо в ini и через "пробел (или табуляцию) тире пробел" добавил бы описание. В итоге в диалоге отображался бы код с описанием, а код для вставки брался бы до первого пробела.
Это, собсна, предложение по скрипту для Skif_off :D

Offline
Posts: 276
Joined: Mon Jun 20, 2011 8:33 am
Location: Электросталь

Post by yozhic »

VladSh
Дык, этж история. Будет потихоньку двигаться к низу, пока совсем не пропадёт. А шпора – она навсегда!
Locked