Code: Select all
// InsertUnicodeChar_test.js
// http://akelpad.sourceforge.net/forum/viewtopic.php?p=26918#p26918
// Version: 2014-12-xx (x86/x64)
// Authors:
// - idea & first version: Skif_off;
// - development: KDJ, VladSh, Instructor.
//
// Insert Unicode characters
//
// Required to include: CreateDialog_functions.js
// Для работы необходим: CreateDialog_functions.js
// The script should be saved in Unicode format.
// Скрипт должен быть сохранен в Unicode
//
// 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();
GetLangStrings();
var oSys = AkelPad.SystemFunction();
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))
{
aHex = AkelPad.ReadFile(sIniFile, 0x10 /*OD_ADT_NOMESSAGES*/, 1200 /*UTF-16LE*/, true).split(/[,]/);
}
else
{
aHex = ["002F"];
}
}
else
{
aHex = ["002F"];
}
//find file with templates
var sTemplatesFile = WScript.ScriptFullName.replace(/\.js$/i, "_templates.tsv");
var nW = "";
var nH = "";
if (fso.FileExists(sTemplatesFile))
{
nW = 15;
nH = 15;
}
else
{
nW = 0;
nH = 0;
}
//GUI. Thanks KDJ
var IDLABELS = 1000;
var IDTEXTCB = 1001;
var IDOKB = 1002;
var IDCANCELB = 1004;
var IDTEMPLATE = 1005;
var aDlg = [];
aDlg.Title = sTxtTitle;
aDlg.Style = WS_VISIBLE | WS_POPUP | WS_CAPTION | WS_SYSMENU | DS_CENTER;
aDlg.Parent = AkelPad.GetMainWnd();
aDlg.Callback = DialogCallback;
aDlg.W = 216;
aDlg.H = 62;
aDlg.CtlStyle = WS_VISIBLE;
aDlg.CtlFontN = "MS Shell Dlg";
aDlg.CtlFirst = IDLABELS;
aDlg.Icon = oSys.Call("User32::LoadImageW",
AkelPad.GetInstanceDll(), //hinst
101, //lpszName
1, //uType=IMAGE_ICON
16, //cxDesired
16, //cyDesired
0x40); //fuLoad=LR_DEFAULTSIZE
aDlg[IDLABELS] = {X: 8, Y: 8, W: 200, H: 10, Title: sTxtLabel, Class: "STATIC"};
aDlg[IDTEXTCB] = {X: 8, Y: 20, W: 200, H: 100, Class: "COMBOBOX", Style: WS_TABSTOP | CBS_DROPDOWN};
aDlg[IDOKB] = {X: 100, Y: 40, W: 50, H: 15, Title: sTxtOK, Style: WS_TABSTOP | BS_DEFPUSHBUTTON};
aDlg[IDCANCELB] = {X: 158, Y: 40, W: 50, H: 15, Title: sTxtCancel, Style: WS_TABSTOP};
aDlg[IDTEMPLATE] = {X: 8, Y: 40, W: nW, H: nH, Title: ">", Class: "BUTTON", Style: BS_PUSHBUTTON};
CreateDialogBox(aDlg);
oSys.Call("User32::DestroyIcon", aDlg.Icon);
function DialogCallback(hWnd, uMsg, wParam, lParam)
{
var nLowParam;
var i;
if (uMsg == 272 /*WM_INITDIALOG*/)
{
aDlg[IDTEXTCB].HWNDE = GetComboBoxEditWnd(aDlg[IDTEXTCB].HWND);
//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 == IDTEMPLATE)
{
Templates();
}
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 oPattern;
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, sTxtTextError, sTxtError, 0x10 /*MB_ICONERROR*/);
return false;
}
else
{
if (AkelPad.GetEditWnd())
{
if (fso.FileExists(AkelPad.GetAkelDir(4) + "\\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)
{
if (sHex != aHex[0]) aHex.unshift(sHex);
if (aHex.length > nArg2) aHex.splice(nArg2, aHex.length);
sIniString = aHex.join(",");
oPattern = new RegExp(","+ sHex + ",", "gi");
sIniString = sIniString.replace(oPattern, ",");
oPattern = new RegExp(","+ sHex + "$", "gi");
sIniString = sIniString.replace(oPattern, "");
sIniString = sIniString.toUpperCase()
AkelPad.WriteFile(WScript.ScriptFullName.replace(/\.js$/i, ".ini"), sIniString, sIniString.length, 1200 /*UTF-16LE*/, true);
}
}
return true;
}
function Templates()
{
var lpRect = AkelPad.MemAlloc(16 /*sizeof(RECT)*/);
var hMenu = oSys.Call("User32::CreatePopupMenu");
var nString = 0x0000; //MF_STRING
var nSepar = 0x0800; //MF_SEPARATOR
var nX;
var nY;
var sTemplates;
var aMenu;
var nCmd;
var i;
oSys.Call("User32::GetWindowRect", aDlg[IDTEXTCB].HWND, lpRect);
nX = AkelPad.MemRead(lpRect + 4, 3 /*DT_DWORD*/);
nY = AkelPad.MemRead(lpRect + 4, 3 /*DT_DWORD*/);
AkelPad.MemFree(lpRect);
sTemplates = 'aMenu = [[nString, ' + AkelPad.ReadFile(sTemplatesFile, 0x10 /*OD_ADT_NOMESSAGES*/, 1200 /*UTF-16LE*/, true)
sTemplates = sTemplates.replace(/\r\n/g, '],[nString, ') + '],[nSepar],[nString, sTxtEmpty, ""]];'
eval(sTemplates)
for (i = 0; i < aMenu.length; ++i)
oSys.Call("User32::AppendMenuW", hMenu, aMenu[i][0], i + 1, aMenu[i][1] + " " + aMenu[i][2]);
nCmd = oSys.Call("User32::TrackPopupMenu", hMenu, 0x0188 /*TPM_RETURNCMD|TPM_NONOTIFY|TPM_RIGHTALIGN*/, nX, nY, 0, aDlg.HWND, 0);
oSys.Call("User32::DestroyMenu", hMenu);
if (nCmd--)
{
oSys.Call("User32::SetFocus", aDlg[IDTEXTCB].HWND);
if (aMenu[nCmd][1] == sTxtEmpty)
{
oSys.Call("User32::SendMessageW", aDlg[IDTEXTCB].HWND, 12 /*WM_SETTEXT*/, 0, "");
}
else
{
var nGetTextLength = oSys.Call("User32::SendMessageW", aDlg[IDTEXTCB].HWNDE, 14 /*WM_GETTEXTLENGTH*/, 0, 0);
oSys.Call("User32::SendMessageW", aDlg[IDTEXTCB].HWNDE, 0xB1 /*EM_SETSEL*/, nGetTextLength, nGetTextLength);
oSys.Call("User32::SendMessageW", aDlg[IDTEXTCB].HWNDE, 194 /*EM_REPLACESEL*/, 1, aMenu[nCmd][1]);
}
}
}
function GetComboBoxEditWnd(hWndCB)
{
var lpCOMBOBOXINFO = AkelPad.MemAlloc(_X64 ? 64 : 52 /*sizeof(COMBOBOXINFO)*/);
var hWndCBE = 0;
AkelPad.MemCopy(lpCOMBOBOXINFO, _X64 ? 64 : 52, 3 /*DT_DWORD*/); //cbSize
AkelPad.SendMessage(hWndCB, 0x0164 /*CB_GETCOMBOBOXINFO*/, 0, lpCOMBOBOXINFO);
hWndCBE = AkelPad.MemRead(lpCOMBOBOXINFO + (_X64 ? 48 : 44) /*hwndItem*/, 2 /*DT_QWORD*/);
AkelPad.MemFree(lpCOMBOBOXINFO);
return hWndCBE;
}
function GetLangStrings()
{
if (AkelPad.GetLangId(0 /*LANGID_FULL*/) == 1049 /*Russian*/)
{
sTxtTitle = "Вставить символы Unicode";
sTxtLabel = "Четырехсимвольные шестнадцатеричные коды:";
sTxtOK = "OK";
sTxtCancel = "Отмена";
sTxtTextError = "Только цифры в шестнадцатеричной системе (0-9, A-F).";
sTxtError = "Ошибка";
sTxtEmpty = "Очистить";
}
else
{
sTxtTitle = "Insert Unicode characters";
sTxtLabel = "Four digits hex codes:";
sTxtOK = "OK";
sTxtCancel = "Cancel";
sTxtTextError = "Hex digits only (0-9, A-F).";
sTxtError = "Error";
sTxtEmpty = "Clean";
}
}