Scripts collection

Discuss and announce AkelPad plugins
  • Author
  • Message
Offline
Posts: 330
Joined: Mon Jun 03, 2019 2:33 am

Post by AZJIO »

Сделайте ссылку на этот пост в шапке с пояснением что RU-описание функций.

  • QuoteExtend.js - Расширяет (или создает) выделение, до кавычек или скобок вокруг.
  • History.js - Резидентный скрипт, позволяющий восстановить недавно закрытые документы.
  • XMLValidator.js - Проверяет выделенный или весь текст XML.
  • coder2wl.js - Объединяет список слов, из Coder-файла с белыми списками SpellCheck.
  • SetMargins.js - Устанавливает как левые, так и правые поля.
  • ADODB.js - Microsoft Data Access - Объекты данных ActiveX - набор констант и помощников
  • SetCoderExt.js - установить тему расширения Coder по расширению
  • transparency.js - сделать AkelPad полупрозрачным
  • Win32 Constants Library - набор констант, используемых при написании скриптов с использованием системных вызовов Win32
  • AutoTag.js - автоматическое закрытие тегов для BBCode и XML/HTML/SGML
  • ChooseColor.js - выбрать & вставить/изменить цвет в RGB-формате стандартным диалогом выбора цвета
  • zen-coding - привязки zen-кодирования для AkelPad

  • Script_Andrey_A.zip - scripts archive.
  • getWords.vbs - Извлечение русских\английских слов\цифр из выделенного текста
  • WriteInWhiteSpellCheckList.vbs - Добавляет к белому списку SpellCheck выделенное слово или список
  • getMail.vbs - Извлекает e-mail адреса из выделенного текста в новую вкладку
  • Functions.vbs - Скрипт с различными Функциями, более 1400 строк
  • CreateLink.vbs - Создание ярлыка папки\файла, открытого для редактирования.
  • Descript.vbs - Вставить выделенный текст в файл комментариев - Descript.ion.
  • InsertMsgBox.vbs - Вставить окно сообщения в скрипт-файл.
  • DublicateFile.vbs - копирование файла с добавлением счетчика
  • OpenFileNameFromBuffer.vbs - поиск файла в указанных папках и открытие его
  • SwitchSplittedWindow.vbs - циклическое разделение окна текущего документа с заданным приоритетом

  • randomCTheme.js - Случайная цветовая тема.
  • insertPathToFile.js - вставить относительный/абсолютный путь к выбранный файл
  • WinMerge.js - сравнение текущих и выбранных файлов с помощью WinMerge
  • LanguageHelp.js - показать справку (из chm) для выделенного слова или слова под кареткой
  • CSSTidy.js - обработать текущий файл в CSSTidy
  • phpCB.js - обработать текущий файл в phpCB

  • cpBarSwitch.js - Переключение между указанным меню, панелью инструментов, строкой состояния и состояниями вкладок.
  • cpFontSwitch.js - Переключение между указанными настройками шрифта.
  • UndoMax.js, UndoMax_lite.js - Продвинутое действие Отменить/Повторить.
  • AutohideTab.js - Скрыть панель вкладок, если одна вкладка.

  • ZipCurrentFile.js - В Zip текущий файл.
  • KeySubst.js - Скрипт подменяет нажатые клавиш
  • RunMe.js - Мое видение запуска файла из AkelPad (включая компиляцию)
  • ProcessSelectedText.js - шаблон скрипта для изменения текста, выделенного в AkelPad

  • NeO.Numbers.js - подсчитывает числа в выделенном тексте
  • NeO.Sort.js - сортировать текст по столбцам

  • OpenAsEmail.js - Открыть необработанный файл электронной почты в соответствующем почтовом модуле (расширение "eml" должно быть зарегистрировано в ОС)
  • Log.js - Записать сообщение в текстовый файл для фрагментов
  • base64.js - преобразует выделенное в Base64 и наоборот

  • Macro2SendKeys.vbs - преобразующий макросы в SendKeys
  • MacroDecoder.vbs - Декодер макросов по словарю Surveyor-а
  • VersionInfo.js - Информация о версии AkelPad и плагинов

  • InsertNum.js - Вставить последовательность чисел
  • SearchReplace_cml.js - Командная строка для поиска и замены с аргументом(ами)
  • SearchReplace_multi.js - Множественный поиск и замена с использованием регулярных выражений
  • SearchReplace_multi.js - Множественный поиск и замена с использованием регулярных выражений
  • NumberCount.js - Вставьте текст и/или последовательность чисел/случайных чисел в начало и/или конец каждой строки

  • createSelectedFile.js - Создать файл из выделения.
  • autoInsertQuotes.js - Добавление кавычек для значения атрибута при вводе знака равенства (=) внутри тега HTML.
  • autoInsertTab.js - Автоматическая вставка tab после нажатия Enter.

  • md5sel.js - Заменяет выделенное своим хэшем.
  • PassGen.js - Генератор паролей


  • Kavychker.js - применять основные правила русской типографии


  • createFile.js - создать новый текстовый файл в текущем каталоге редактирования файлов

  • Evaluate.js - простой математический (JavaScript) Калькулятор

  • IndentsToTabs.js - Преобразовать пробелы-отступы в табуляцию.

  • CRC32txt.vbs - Сравнение контрольных сумм выбранных текстов.


  • SessionMenu.js - Показать меню с файлами конкретной сессии
  • DeletePhrasesInText.js - Удаление строк, содержащих/не содержащих выделенную фразу
  • ConvertNumColorValue.js - Преобразование числовых и цветовых значений между собой
  • AlignColumns.js - Выравнивание выделенного текста по столбцам
  • BackUpCurrentFile.js - Создать резервную копию текущего файла
  • SwapText.js - Поменять местами текст, слова, строки
  • RenameFileAs.js - Переименовать / Сохранить как ... файл.
  • HotKeyCode2String.js - Перевод цифрового кода горячих клавиш в строку.
  • HexSelAs.js - GUI для плагина HexSel.
  • MsgBoxBuild.js - Генерация строки кода для MessageBox и InputBox.

  • JsMin.js - Сократите текущий файл JavaScript или выделение, используя классический алгоритм Дугласа Крокфорда
  • AkelEmmet.js - Полный обработчик Emmet (например, Zen Coding)
  • FastFind.js - Полезно для быстрого выбора и поиска слова под курсором или выбранной фразы без открытия каких-либо диалогов
  • MarkIt.js - Помечает/снимает отметку с текущего слова/строки или выделенного текста. Каждый раз, когда цвет маркера меняется через 34 значения.

Offline
Posts: 330
Joined: Mon Jun 03, 2019 2:33 am

Post by AZJIO »

Code: Select all

// AZJIO, 12.09.2019
// Description(1033): Combine the lines of two lists, one of which is on the clipboard
// Description(1049): Объединить строки двух списков, один из которых в буфере обмена
//
// Usage:
//   Call("Scripts::Main", 1, "Combine_Lists.js")
// Примечание:
// Списки не обязательно должны быть равными по количеству строк. Если ничего не выделено, то используется весь текст.

var sText = AkelPad.GetClipboardText();
if(sText == "") {
	WScript.Echo('Буфер обмена пуст');
	WScript.Quit();
};
sText = sText.replace(/\r\n|\n\r|\r/g, '\n'); // замена смешанного \r\n на однотипный \n
/*
sText = sText.replace(/\r\n/g, '\n'); // замена \r\n
sText = sText.replace(/\n\r/g, '\n'); // замена \r\n
sText = sText.replace(/\r/g, '\n'); // замена \r\n
*/
var aStr2 = sText.split('\n'); // получаем массив строк
// sText = '' // очищаем переменную
var sText = AkelPad.GetTextRange(0, -1); // получаем текст из AkelPad
var bAllText = false;

sText = AkelPad.GetSelText() // если ничего не выделенно, то получаем весь текст документа
if(sText == "") {
	sText = AkelPad.GetTextRange(0, -1); // получаем текст из AkelPad
	bAllText = true
};

// тут проверить тип переноса строк у исходного текста

sText = sText.replace(/\r\n|\n\r|\r/g, '\n'); // замена смешанного \r\n на однотипный \n
var aStr1 = sText.split('\n'); // получаем массив строк

if(bAllText) {
	AkelPad.SetSel(0, -1);
}
AkelPad.ReplaceSel(CombineLists(aStr1, aStr2))

function CombineLists(aStr1, aStr2) {
	var Max;
	var Str = '';

	if(aStr1.length >= aStr2.length) {
		Max = aStr1.length
		Min = aStr2.length
		for(var i = 0; i <= Min - 1; i++) {
			aStr1[i] += aStr2[i];
		};
	}
	else {
		Max = aStr2.length
		Min = aStr1.length
		aStr1.length = Max
		for(var i = 0; i <= Min - 1; i++) {
			aStr1[i] += aStr2[i];
		};
		for(var i = Min; i <= Max - 1; i++) {
			aStr1[i] = aStr2[i];
		};
	}
	for(var i = 0; i <= Max - 1; i++) {
		Str += aStr1[i] + '\n';
	};

	Str = Str.slice(0, -1);
	return Str;
}

Combine the lines of two lists, one of which is on the clipboard
Объединить строки двух списков, один из которых в буфере обмена.


Допустим есть два списка англ и русский перевод текста и нужно написать сценарий замены одно другим. Писать вручную построчно копируя - не наш метод. Мы берём первый список, обрамляем его, допустим вставляем тексты-префиксы в начало строк методом вставки вертикального текста. Далее вставляем разделительную часть методом рег.выр. заменив \n на "текст\n". Далее объединяем списки, копируя русский перевод в буфер обмена и вызываем команду (рег.выр. так не сделает). Далее в конец текста опять вставляем заключительный текст командной строки. И вот оно - сценарий замены готов. Ранее эти вещи я делал в табличном редакторе типа Excel, но он во-первых платный, во вторых запускать громоздкую прогу ради такого простого действия. Я уже писал для NPP такой плаг TextA

Offline
Posts: 330
Joined: Mon Jun 03, 2019 2:33 am

Post by AZJIO »

Code: Select all

// попытка отступов построчно проверяя увеличение/уменьшение
// AZJIO, 16.09.2019
// Description(1033): Calculate indent and replace with tab
// Description(1049): Вычислить отступ и заменить табуляцией
//
// Usage:
//   Call("Scripts::Main", 1, "indent2Tab.js")
// Примечание: только что готов, тестируется временем.
var hMainWnd = AkelPad.GetMainWnd();
var pText = AkelPad.GetTextRange(0, -1);

var pattern = /^\t*([ ]+)\b/gm;
if (!pattern.test(pText)) {
	WScript.Echo('Не найдено.\n\nЛибо отступ одинаковый,\nлибо уже заменён табуляций');
	WScript.Quit();
}

// pattern = /^\t*\K([ ]*)\b/gm;
// pattern = /^\t*\([ ]+)\b/gm;
pattern = /^\t*([ ]*)\b/gm;
var ArrSpace;
var last_count = 0;
var count_space;
var diff;
var j = 0;
oNum = new Object()
while ((ArrSpace = pattern.exec(pText)) != null) {
	ArrSpace[0] = ArrSpace[0].replace(/\t+/g, '') // удаляем табуляции
	count_space = ArrSpace[0].length;
	// WScript.Echo('ArrSpace[0] = |' + ArrSpace[0] + '|'); // по числу строк
	if (count_space != last_count) {
		// WScript.Echo('ArrSpace[0] = |' + ArrSpace[0] + '|'); // по числу разниц
		diff = Math.abs(last_count - count_space);
		if (oNum[diff]) { // если ключ с именем разницы существует, то
			oNum[diff]++; // увеличиваем его
		} else {
			oNum[diff] = 1; // создаём впервые со значением 1
			j++ // подсчитываем число созданных ключей
		}
		last_count = count_space;
	}
}

// WScript.Echo('j = ' + j + '\n');

if (j == 0) {
	WScript.Echo('Не найдено.\n\nЛибо отступ одинаковый,\nлибо уже заменён табуляций');
	WScript.Quit();
}

last_count = 0;
var top = 0; // ширина шага отступа в пробелах, по наибольшему значению

// Вычисляем ключ (top на выходе), содержащий наибольшее значение (last_count на выходе)
for (var p in oNum) {
	if (oNum[p] > last_count) {
		top = p
		last_count = oNum[p]
	}
}
var TextSpace = "                                        ".substr(0, top); // берём из строки столько пробелов, сколько указано в top, то есть 1 таб равен полученной ширине пробелов

/*
var infa = ''
if (top == '1') {
	infa = 'Если "1 таб = 1 пробел", то это скорее ошибка, где-то закрался лишний пробел.'
}
*/

// var warn = AkelPad.GetArgValue("warn", "0"); // можно показать отступ и пойти по 2-м вариантам замены
var nChoice = AkelPad.MessageBox(hMainWnd, 'Автоопределение 1 таб = ' + top + ' пробел(а)\n\nЗаменить на табуляцию?\n\n1 способ - корректирует смешанные отступы\n2 способ - замена по количеству пробелов на табуляцию', "Сообщение", 32 /*MB_ICONQUESTION*/ , 0,
	1 /*IDOK*/ , "1 способ", 1 /*там где 1, та кнопка по умолчанию*/ ,
	4 /*IDRETRY*/ , "2 способ", 0,
	2 /*IDCANCEL*/ , "Отмена", 0);

if (nChoice == 2) {
	WScript.Quit();
} else if (nChoice == 4) {
	Direct_Replacement()
	// WScript.Quit();
} else if (nChoice == 1) {
	Fixed_Replacement()
	// WScript.Quit();
}

function Direct_Replacement() {
	pattern = new RegExp('^(\t*)(' + TextSpace + ')', 'm');
	do {
		pText = pText.replace(pattern, "$1\t")
	} while (pattern.test(pText)) // если всё ещё содержит, то повторно заменяем
	AkelPad.SetSel(0, -1); // выделить весь текст
	AkelPad.ReplaceSel(pText); // Заменить весь выделенный текст
}

// здесь как в предыдущем варианте дошли до определения числа пробелов на табуляцию, чтобы заменить в смешанных отступах табуляцию на вычисленный пробел, потом вернуть всё в обратно в табуляцию. Просто переход между табуляционным отступом и пробельным не возможно вычислить разницу.

function Fixed_Replacement() {
	pText2 = ''
	// pText3 = '' // тест
	last_count = 0; // сбрасываем в 0 и используем для подсчёта числа пробелов в отступе
	// pattern = /^(\t*[ ]*)/g; // если использовать [ ]+ или \b то проблема для пустых строк... уже не надо, уже "new RegExp"
	// var pattern2 = /^\t*[ ]+\b/gm; // бывший тест игнора строк с табуляцией
	var sTab = ''; // для текущего отступа из табуляций
	// var ArrString = pText.split(/\r\n|\r|\n/g); // с рег.выр. не захватывались пустые строки
	// var ArrString = pText.split('\n'); // почему то \n здесь не воспринимается как символ LF, использование \r или \r\n тоже давало проблемы
	var ArrString = pText.split(String.fromCharCode(13)); // 13 = CR = \r   10 = LF = \n
	/*
	WScript.Echo('ArrString.length = ' + ArrString.length); // просмотр правильности числа строк
	WScript.Quit();
	*/
	for (var i = 0; i <= ArrString.length - 1; i++) { // перечисление построчно
		if ((ArrString[i].length == 0) || /^[\t ]+$/.test(ArrString[i])) { // если строка пустая или содержит только пробельные символы, то
			last_count = 0;
			pText2 += '\n'; // добавляем пустую строку
			sTab = '';
			// WScript.Echo('строка = |' + ArrString[i] + '|\nНомер строки = ' + i); // просмотр пустых строк
			continue;
		}
		pattern = new RegExp("^(\t*[ ]*)", 'g'); // новый объект, чтобы без lastIndex
		ArrSpace = pattern.exec(ArrString[i]); // ищем пробелы в начале строки
		// WScript.Echo('ArrSpace[0] = |' + ArrSpace[0] + '|'); // вывод ширины
		// if ((!ArrSpace) || (ArrSpace[0].length == 0) || (!pattern2.test(ArrString[i]))) { // изначально было много ошибок
		if (!ArrSpace) { // null не должно, так как массив создан с помощью split, а рег.выр. захватывает даже если не найдено
			WScript.Echo('Ошибка захвата пробела в строке, заврешаем ничего не делая.');
			WScript.Quit(); // а можно ли? Интерпретатор вероятно всё освободит и закроет сам
			// continue;
		}
		if (ArrSpace[0].length == 0) { // если в строке нет отступов, то... добавляем строку как есть, а переменные сбрасываем в 0
			last_count = 0;
			pText2 += ArrString[i] + '\n';
			sTab = '';
			// WScript.Echo('строка = |' + ArrString[i] + '|\n пробелы = |' + ArrSpace[0] + '|\n длина = ' + ArrSpace[0].length + '\n массив = ' + !ArrSpace); // просмотр
			continue;
		}
		ArrSpace[0] = ArrSpace[0].replace(/\t/g, TextSpace); // заменяем табуляции пробелами, по ранее вычиссленной ширине
		count_space = ArrSpace[0].length; // число пробелов в отступе
		// WScript.Echo('ArrSpace[0] = |' + ArrSpace[0] + '|\n' + count_space + ' ' + last_count); // просмотр отступа
		if (count_space > last_count) { // если текущий отступ больше предыдущего, то
			// WScript.Echo('ArrSpace[0] -= |' + ArrSpace[0] + '|\n' + count_space + ' ' + last_count); // просмотр увеличения отступа
			sTab += '	'; // добавляем таб
			last_count = count_space;
		} else if (count_space < last_count) { // если текущий отступ меньше предыдущего, то... повтор условия устраняет вариант "count_space == last_count"
			// WScript.Echo('ArrSpace[0] += |' + ArrSpace[0] + '|\n' + count_space + ' ' + last_count); // просмотр уменьшенияотступа
			sTab = sTab.slice(0, -1); // отрезаем 1 таб
			last_count = count_space;
		}
		// если "count_space == last_count", то используем ширину отступа вычисленную на предыдущем шаге
		ArrString[i] = ArrString[i].replace(/^[\t ]+/g, ''); // удаляем отступы, чтобы импортировать вычисленные отступы (sTab)
		pText2 += sTab + ArrString[i] + '\n'; // добавляем с отступами

	};
	pText2 = pText2.slice(0, -1); // отрезаем последний лишний добавленный скриптом перенос

	AkelPad.SetSel(0, -1); // выделить весь текст
	AkelPad.ReplaceSel(pText2); // Заменить весь выделенный текст
}

Calculate indent and replace with tab
Вычислить отступ и заменить табуляцией

Увеличение/уменьшение табуляции по увеличению/уменьшению отступа, соответственно не зависит от среднего числа пробелов на табуляцию и соответственно лучше работает при смешанных отступах (чётных 2 и 4, нечётных 3, с табуляцией), при смешанных в одном отступе пробела и табуляции.

Обновил 2 раза. Добавил диалог выбора способа замены.

Обнаружил проблему нового способа: если отступ не через шаг, а сразу на 2 отступа, то это всё равно воспринимается как один отступ. Поэтому для правильных файлов с ровными и равными отступами можно использовать 2-й способ прямой замены.
Вот пример 3 отступа за раз.

Code: Select all

var nChoice=AkelPad.MessageBox(hMainWnd, "MyText", "MyCaption", 32 /*MB_ICONQUESTION*/, 0,
            1 /*IDOK*/,     "&OK",     0x1 /*BMB_DEFAULT*/,
            2 /*IDCANCEL*/, "&Cancel", 0);

DV
Offline
Posts: 1250
Joined: Thu Nov 16, 2006 11:53 am
Location: Kyiv, Ukraine

Post by DV »

Поскольку под AkelPad такого ещё не было, выкладываю прототип CommandPalette (список всех доступных команд) для AkelPad. Вдохновлено угадайте каким редактором, в связи с чем предлагается горячая клавиша Ctrl+Shift+P.
В случае одобрения данного функционала сообществом скриптописателей, предлагается общими усилиями добавить следующие возможности:
1. Изменение размеров окна;
2. Подсветка частей слов, совпадающих с фильтром;
3. Прочие улучшения.
Давайте обсуждать скрипт в соседней теме:
http://akelpad.sourceforge.net/forum/vi ... php?t=2151

Code: Select all

// http://akelpad.sourceforge.net/forum/viewtopic.php?p=34456#p34456
// Version: 0.6.1
// Author: Vitaliy Dovgan aka DV
//
// *** Command Palette: AkelPad's and Plugins' commands ***
//
//

/*
FAQ:

Q: The script shows an error "File not found: CommandPalette.lng".
   The script shows an error "File is empty: CommandPalette.lng".
A: The script _requires_ the file "CommandPalette.lng" because this file
   contains the list of the commands shown by the script.

Q: The CommandPalette's command list contains unreadable symbols.
A: The file "CommandPalette_1049.lng" (or other .lng file that contains
   non-Latin characters) must be saved using the UTF-16 LE (1200) encoding.

Q: I want more commands in the CommandPalette!
A: Edit the file "CommandPalette.lng" manually. This is a text file that
   contains lines in a form of
     command = "caption"
   where 'command' is either an internal command (number) under the [AkelPad]
   section or a plugin/script call (string) under the [Plugins] and [Scripts]
   section. The [Exec] section contains command-line commands.
*/

var ShowCmdIds = true; // true -> "[4153] Edit: Cut", false -> "Edit: Cut"
var ApplyColorTheme = true;
var UseListView = false; // true -> ListView, false -> ListBox
var CmdTextMaxLength = 0; // auto-calculated
var CmdShortcutMaxLength = 0; // auto-calculated
var CmdTotalMaxLength = 0; // auto-calculated
var CmdTextMaxLengthListBox = 74;

// Commands...
var CMDTYPE_AKELPAD = 1;
var CMDTYPE_PLUGIN  = 2;
var CMDTYPE_SCRIPT  = 3;
var CMDTYPE_EXEC    = 4;
var Commands = [];

// Windows Messages...
var WM_CREATE          = 0x0001;
var WM_DESTROY         = 0x0002;
var WM_ACTIVATE        = 0x0006;
var WM_SETFOCUS        = 0x0007;
var WM_SETREDRAW       = 0x000B;
var WM_CLOSE           = 0x0010;
var WM_SETFONT         = 0x0030;
var WM_GETFONT         = 0x0031;
var WM_NOTIFY          = 0x004E;
var WM_KEYDOWN         = 0x0100;
var WM_CHAR            = 0x0102;
var WM_SYSKEYDOWN      = 0x0104;
var WM_COMMAND         = 0x0111;
var WM_CTLCOLOREDIT    = 0x0133;
var WM_CTLCOLORLISTBOX = 0x0134;
var NM_DBLCLK          = -3;
var EM_GETSEL          = 0x00B0;
var EM_SETSEL          = 0x00B1;
var EM_REPLACESEL      = 0x00C2;
var LB_ADDSTRING       = 0x0180;
var LB_RESETCONTENT    = 0x0184;
var LB_SETCURSEL       = 0x0186;
var LB_GETCURSEL       = 0x0188;
var LB_GETTEXT         = 0x0189;
var LB_GETITEMDATA     = 0x0199;
var LB_SETITEMDATA     = 0x019A;
var LBN_DBLCLK         = 2;
var LVM_SETBKCOLOR     = 0x1001;
var LVM_DELETEALLITEMS = 0x1009;
var LVM_GETNEXTITEM    = 0x100C;
var LVM_ENSUREVISIBLE  = 0x1013;
var LVM_SETTEXTCOLOR   = 0x1024;
var LVM_SETTEXTBKCOLOR = 0x1026;
var LVM_SETITEMSTATE   = 0x102B;
var LVM_GETITEMW       = 0x104B;
var LVM_INSERTITEMW    = 0x104D;
var LVM_INSERTCOLUMNW  = 0x1061;
var LVM_SETITEMTEXTW   = 0x1074;
var LVM_SETEXTENDEDLISTVIEWSTYLE = 0x1036;
var LVCF_FMT           = 0x1;
var LVCF_WIDTH         = 0x2;
var LVCF_TEXT          = 0x4;
var LVCFMT_LEFT        = 0x0;
var LVCFMT_RIGHT       = 0x1;
var LVCFMT_CENTER      = 0x2;
var LVIF_TEXT          = 0x1;
var LVIF_PARAM         = 0x4;
var LVIF_STATE         = 0x8;
var LVIS_FOCUSED       = 0x1;
var LVIS_SELECTED      = 0x2;
var LVNI_FOCUSED       = 0x1;
var LVNI_SELECTED      = 0x2;

// Windows Constants...
var TRUE  = 1;
var FALSE = 0;
var VK_BACK     = 0x08; // BackSpace
var VK_TAB      = 0x09;
var VK_RETURN   = 0x0D; // Enter
var VK_CONTROL  = 0x11; // Ctrl
var VK_ESCAPE   = 0x1B;
var VK_PRIOR    = 0x21; // Page Up
var VK_NEXT     = 0x22; // Page Down
var VK_END      = 0x23;
var VK_HOME     = 0x24;
var VK_LEFT     = 0x25;
var VK_UP       = 0x26;
var VK_RIGHT    = 0x27;
var VK_DOWN     = 0x28;
var VK_DELETE   = 0x2E;
var SW_SHOWNA  = 8;
var SW_RESTORE = 9;
var DEFAULT_GUI_FONT = 17;
var COLOR_WINDOW = 5;
var HWND_DESKTOP = 0;
var MB_OK          = 0x0000;
var MB_ICONERROR   = 0x0010;
var MB_ICONWARNING = 0x0030;

var MF_BYCOMMAND  = 0x00000000;
var MF_BYPOSITION = 0x00000400;
var MF_UNCHECKED  = 0x00000000;
var MF_CHECKED    = 0x00000008;

var WS_TABSTOP  = 0x00010000;
var WS_SYSMENU  = 0x00080000;
var WS_HSCROLL  = 0x00100000;
var WS_VSCROLL  = 0x00200000;
var WS_BORDER   = 0x00800000;
var WS_CAPTION  = 0x00C00000;
var WS_VISIBLE  = 0x10000000;
var WS_CHILD    = 0x40000000;
var WS_POPUP    = 0x80000000;
var ES_AUTOHSCROLL  = 0x0080;
var LBS_NOTIFY      = 0x0001;
var LBS_SORT        = 0x0002;
var LBS_USETABSTOPS = 0x0080;
var LVS_REPORT          = 0x0001;
var LVS_SINGLESEL       = 0x0004;
var LVS_SHOWSELALWAYS   = 0x0008;
var LVS_NOCOLUMNHEADER  = 0x4000;
var LVS_NOSORTHEADER    = 0x8000;
var LVS_EX_FULLROWSELECT = 0x0020;

var CP_ACP   = 0;
var CP_OEMCP = 1;
var CP_UTF8  = 65001;

var LANGID_FULL    = 0;
var LANGID_PRIMARY = 1;
var LANGID_SUB     = 2;

// AkelPad Constants...
var DT_ANSI    = 0;
var DT_UNICODE = 1;
var DT_QWORD   = 2;
var DT_DWORD   = 3;
var DT_WORD    = 4;
var DT_BYTE    = 5;

var IDM_FILE_CREATENEWWINDOW       = 4102;
var IDM_OPTIONS_SINGLEOPEN_PROGRAM = 4256;

var AKD_GETMAININFO = 1222;
var MI_SINGLEOPENPROGRAM = 153;


// The Program...
var oSys       = AkelPad.SystemFunction();
var hInstDLL   = AkelPad.GetInstanceDll();
var sClassName = "AkelPad::Scripts::" + WScript.ScriptName + "::" + hInstDLL;
var hWndDlg;
var hWndFilterEdit;
var hWndCommandsList; // either ListView or ListBox
var hSubclassFilterEdit;
var hSubclassCommandsList;
var sCmdFilter = "";
var sCmdFilter0 = "";
var nCmdIndex = -1;
var nCmdIndex0 = -1;

if (!UseListView)
{
  CmdTextMaxLength = CmdTextMaxLengthListBox;
  CmdTotalMaxLength = CmdTextMaxLength;
}

ReadLngFile();
//WScript.Echo("CmdTotalMaxLength = " + CmdTotalMaxLength);

if (hWndDlg = oSys.Call("user32::FindWindowEx" + _TCHAR, 0, 0, sClassName, 0))
{
  if (! oSys.Call("user32::IsWindowVisible", hWndDlg))
    oSys.Call("user32::ShowWindow", hWndDlg, SW_SHOWNA);
  if (oSys.Call("user32::IsIconic", hWndDlg))
    oSys.Call("user32::ShowWindow", hWndDlg, SW_RESTORE);

  oSys.Call("user32::SetForegroundWindow", hWndDlg);
}
else
{
  var sScripName = "Command Palette";
  var ActionItem = undefined;

  var IDX_ID      = 0;
  var IDX_CLASS   = 1;
  var IDX_HWND    = 2;
  var IDX_EXSTYLE = 3;
  var IDX_STYLE   = 4;
  var IDX_X       = 5;
  var IDX_Y       = 6;
  var IDX_W       = 7;
  var IDX_H       = 8;

  var aWnd          = [];
  var IDC_ED_FILTER = 1011;
  var IDC_LB_ITEMS  = 1021;
  var IDC_LV_ITEMS  = 1021;

  var nDlgWidth  = 600;
  var nDlgHeight = 530;
  var nEditHeight = 20;

  var hMainWnd = AkelPad.GetMainWnd();
  var rectMainWnd = GetWindowRect(hMainWnd);

  var nTextColorRGB = -1;
  var nBkColorRGB = -1;
  var hBkColorBrush = 0;
  var hGuiFont;
  var hWndEdit = AkelPad.GetEditWnd();
  var hFontEdit = AkelPad.SendMessage(hWndEdit, WM_GETFONT, 0, 0);
  if (hFontEdit)
  {
    hGuiFont = hFontEdit;
    var r = getRequiredWidthAndHeight(hWndEdit, hFontEdit);
    // WScript.Echo("r.Width = " + r.Width + "\nr.Height = " + r.Height);
    if (r.Width > 0)
    {
      nDlgWidth = r.Width;
    }
    if (r.Height > 0)
    {
      nEditHeight = r.Height;
    }
    if (ApplyColorTheme && AkelPad.IsPluginRunning("Coder::HighLight"))
    {
      var sTextColor = getColorThemeVariable(hWndEdit, "HighLight_BasicTextColor");
      var sBkColor = getColorThemeVariable(hWndEdit, "HighLight_BasicBkColor");
      nTextColorRGB = getRgbIntFromHex(sTextColor);
      nBkColorRGB = getRgbIntFromHex(sBkColor);
      //WScript.Echo("TextColor = " + sTextColor + "\nBkColor = " + sBkColor);
      if (nTextColorRGB != -1 && nBkColorRGB != -1)
      {
        hBkColorBrush = oSys.Call("gdi32::CreateSolidBrush", nBkColorRGB);
      }
    }
  }
  else
  {
    hGuiFont = oSys.Call("gdi32::GetStockObject", DEFAULT_GUI_FONT);
    // var r = getRequiredWidthAndHeight(hMainWnd, hGuiFont);
    // if (r.Width > 0)
    // {
    //   nDlgWidth = r.Width;
    // }
  }

  var nEdStyle = WS_VISIBLE|WS_CHILD|WS_TABSTOP|ES_AUTOHSCROLL;
  //Windows         ID,      CLASS,        HWND,EXSTYLE,   STYLE,   X,    Y,          W,   H
  aWnd.push([IDC_ED_FILTER,  "EDIT",          0,      0, nEdStyle,  2,     4,         -1, nEditHeight]);
  if (UseListView)
  {
      var nLvStyle = WS_VISIBLE|WS_CHILD|LVS_NOCOLUMNHEADER|LVS_NOSORTHEADER|LVS_SHOWSELALWAYS|LVS_SINGLESEL|LVS_REPORT;
    aWnd.push([IDC_LV_ITEMS, "SysListView32", 0,      0, nLvStyle,  2, nEditHeight+6, -1, -1]);
  }
  else
  {
      var nLbStyle = WS_VISIBLE|WS_CHILD|WS_VSCROLL|WS_BORDER|WS_TABSTOP|LBS_USETABSTOPS|LBS_NOTIFY;
      aWnd.push([IDC_LB_ITEMS, "LISTBOX",       0,      0, nLbStyle,  2, nEditHeight+6, -1, -1]);
  }

  ReadWriteIni(false);
  AkelPad.ScriptNoMutex(0x11 /*ULT_LOCKSENDMESSAGE|ULT_UNLOCKSCRIPTSQUEUE*/);
  AkelPad.WindowRegisterClass(sClassName);

  hWndDlg = oSys.Call("user32::CreateWindowEx" + _TCHAR,
                      0,                // dwExStyle
                      sClassName,       // lpClassName
                      sScripName,       // lpWindowName
                      WS_VISIBLE|WS_POPUP|WS_CAPTION|WS_SYSMENU,  // style
                      rectMainWnd.X + Math.floor((rectMainWnd.W - nDlgWidth)/2),  // x
                      rectMainWnd.Y + 40,   // y
                      nDlgWidth,        // nWidth
                      nDlgHeight,       // nHeight
                      hMainWnd,         // hWndParent
                      0,                // hMenu
                      hInstDLL,         // hInstance
                      DialogCallback);  // Script function callback. To use it class must be registered by WindowRegisterClass.

  AkelPad.WindowGetMessage();
  AkelPad.WindowUnregisterClass(sClassName);

  if (hBkColorBrush)
  {
    oSys.Call("gdi32::DeleteObject", hBkColorBrush);
  }

  if (ActionItem != undefined)
  {
    oSys.Call("user32::SetFocus", hMainWnd);
    if (ActionItem.type == CMDTYPE_AKELPAD)
    {
      if (ActionItem.cmd == IDM_FILE_CREATENEWWINDOW)
      {
        // Allowing "New Window" when "Single open program" is on
        if (AkelPad.SendMessage(hMainWnd, AKD_GETMAININFO, MI_SINGLEOPENPROGRAM, 0))
        {
          AkelPad.Command(IDM_OPTIONS_SINGLEOPEN_PROGRAM);
          var hNewMainWnd = AkelPad.Command(ActionItem.cmd);
          AkelPad.Command(IDM_OPTIONS_SINGLEOPEN_PROGRAM);
          AkelPad.SendMessage(hNewMainWnd, WM_COMMAND, IDM_OPTIONS_SINGLEOPEN_PROGRAM, 0);
        }
        else
          AkelPad.Command(ActionItem.cmd);
      }
      else
        AkelPad.Command(ActionItem.cmd);
    }
    else if (ActionItem.type == CMDTYPE_PLUGIN)
    {
      if (ActionItem.cmd.indexOf(",") == -1)
      {
        // Example: AkelPad.Call("Coder::Settings");
        AkelPad.Call(ActionItem.cmd);
      }
      else
      {
        // Example: AkelPad.Call("Coder::HighLight", 2, "#000000", "#9BFF9B");
        try
        {
          eval("AkelPad.Call(" + ActionItem.cmd + ");");
        }
        catch (oError)
        {
        }
      }
    }
    else if (ActionItem.type == CMDTYPE_SCRIPT)
    {
      if (ActionItem.cmd.indexOf(",") == -1)
      {
        AkelPad.Call("Scripts::Main", 1, ActionItem.cmd);
      }
      else
      {
        // Example: AkelPad.Call("Scripts::Main", 1, "SCRIPT", "ARGUMENTS");
        try
        {
          eval('AkelPad.Call("Scripts::Main", 1, ' + ActionItem.cmd + ');');
        }
        catch (oError)
        {
        }
      }
    }
    else if (ActionItem.type == CMDTYPE_EXEC)
    {
      var cmd = substituteVars(ActionItem.cmd, AkelPad.GetEditFile(0));
      AkelPad.Exec(cmd);
    }
  }
}

function getColorThemeVariable(hWndEdit, varName)
{
  var sVarValue = "";
  var lpVarValue = AkelPad.MemAlloc(32 * 2 /*sizeof(wchar_t)*/);
  if (lpVarValue)
  {
    AkelPad.CallW("Coder::Settings", 22, hWndEdit, 0, varName, lpVarValue);
    sVarValue = AkelPad.MemRead(lpVarValue, DT_UNICODE);
    AkelPad.MemFree(lpVarValue);
  }
  return sVarValue;
}

function getRgbIntFromHex(sRgb)
{
  if (sRgb.length != 0)
  {
    var i = 0;
    if (sRgb.substr(0, 1) == "#")
      i = 1;
    if (sRgb.length - i == 6)
    {
      var rgbInt = 0;
      var n = parseInt(sRgb.substr(i + 0, 2), 16);
      if (!isNaN(n))
      {
        rgbInt += n;
        n = parseInt(sRgb.substr(i + 2, 2), 16);
        if (!isNaN(n))
        {
          rgbInt += n * 0x100;
          n = parseInt(sRgb.substr(i + 4, 2), 16);
          if (!isNaN(n))
          {
            rgbInt += n * 0x10000;
            return rgbInt;
          }
        }
      }
    }
  }
  return -1;
}

function isApplyingColorTheme()
{
  return (ApplyColorTheme && nBkColorRGB != -1 && nTextColorRGB != -1);
}

function getRequiredWidthAndHeight(hWndEdit, hFontEdit)
{
  var nWidth = 0;
  var nHeight = 0;
  var lpSize = AkelPad.MemAlloc(8 /*sizeof(SIZE)*/);
  if (lpSize)
  {
    var hDC = oSys.Call("user32::GetDC", hWndEdit);
    if (hDC)
    {
      var S = "";
      var i = CmdTotalMaxLength;
      while (i != 0)
      {
        S = S + "a";
        i--;
      }
      oSys.Call("gdi32::SelectObject", hDC, hFontEdit);
      if (oSys.Call("gdi32::GetTextExtentPoint32" + _TCHAR, hDC, S, S.length, lpSize))
      {
        nWidth = AkelPad.MemRead(_PtrAdd(lpSize, 0) /*offsetof(SIZE, cx)*/, DT_DWORD);
        nHeight = AkelPad.MemRead(_PtrAdd(lpSize, 4) /*offsetof(SIZE, cy)*/, DT_DWORD);
      }
      oSys.Call("user32::ReleaseDC", hWndEdit, hDC);
    }
    AkelPad.MemFree(lpSize);
  }
  if (nWidth > 0)
  {
    nWidth += 32;
  }
  var r  = new Object();
  r.Width = nWidth;
  r.Height = nHeight;
  return r;
}

function substituteVars(cmd, filePathName)
{
  if (cmd.indexOf("%a") >= 0)
  {
    cmd = cmd.replace(/%a/g, getAkelPadDir(0));
  }
  if (cmd.indexOf("%d") >= 0)
  {
    cmd = cmd.replace(/%d/g, getFileDir(filePathName));
  }
  if (cmd.indexOf("%e") >= 0)
  {
    cmd = cmd.replace(/%e/g, getFileExt(filePathName));
  }
  if (cmd.indexOf("%f") >= 0)
  {
    cmd = cmd.replace(/%f/g, filePathName);
  }
  if (cmd.indexOf("%n") >= 0)
  {
    cmd = cmd.replace(/%n/g, getFileName(filePathName));
  }
  return cmd;
}

function IsCtrlPressed()
{
  return oSys.Call("user32::GetKeyState", VK_CONTROL) & 0x8000;
}

function DialogCallback(hWnd, uMsg, wParam, lParam)
{
  if (uMsg == WM_CREATE)
  {
    var i;
    var W, H;
    var rectClient, rectWnd, rectLB, rectLV;

    rectClient = GetClientRect(hWnd);
    rectWnd = GetWindowRect(hWnd);

    for (i = 0; i < aWnd.length; ++i)
    {
      W = (aWnd[i][IDX_W] < 0) ? (rectClient.W - 2*aWnd[i][IDX_X]) : aWnd[i][IDX_W];
      H = (aWnd[i][IDX_H] < 0) ? (rectClient.H - aWnd[i][IDX_Y]) : aWnd[i][IDX_H];
      aWnd[i][IDX_HWND] =
        oSys.Call("user32::CreateWindowEx" + _TCHAR,
                  aWnd[i][IDX_EXSTYLE], //dwExStyle
                  aWnd[i][IDX_CLASS],   //lpClassName
                  0,                    //lpWindowName
                  aWnd[i][IDX_STYLE],   //dwStyle
                  aWnd[i][IDX_X],       //x
                  aWnd[i][IDX_Y],       //y
                  W,                    //nWidth
                  H,                    //nHeight
                  hWnd,                 //hWndParent
                  aWnd[i][IDX_ID],      //ID
                  hInstDLL,             //hInstance
                  0);                   //lpParam

      if (aWnd[i][IDX_HWND] == 0)
      {
        WScript.Echo("CreateWindowEx() failed for ID = " + aWnd[i][IDX_ID] + ", GetLastError = " + oSys.GetLastError());
        oSys.Call("user32::PostMessage" + _TCHAR, hWnd, WM_CLOSE, 0, 0);
        return 0;
      }

      SetWndFont(aWnd[i][IDX_HWND], hGuiFont);
    }

    hWndFilterEdit = oSys.Call("user32::GetDlgItem", hWnd, IDC_ED_FILTER);
    if (UseListView)
    {
      hWndCommandsList = oSys.Call("user32::GetDlgItem", hWnd, IDC_LV_ITEMS);

      rectLV = GetChildWindowRect(hWndCommandsList);
      H = rectWnd.H - rectClient.H + rectLV.Y + rectLV.H + 3;
    }
    else
    {
      hWndCommandsList = oSys.Call("user32::GetDlgItem", hWnd, IDC_LB_ITEMS);

      rectLB = GetChildWindowRect(hWndCommandsList);
      H = rectWnd.H - rectClient.H + rectLB.Y + rectLB.H + 3;
    }
    ResizeWindow(hWnd, rectWnd.W, H);

    if (UseListView)
    {
      InitCommandsListView(hWndCommandsList, rectWnd.W);
      if (isApplyingColorTheme())
      {
        AkelPad.SendMessage(hWndCommandsList, LVM_SETBKCOLOR, 0, nBkColorRGB);
        AkelPad.SendMessage(hWndCommandsList, LVM_SETTEXTBKCOLOR, 0, nBkColorRGB);
        AkelPad.SendMessage(hWndCommandsList, LVM_SETTEXTCOLOR, 0, nTextColorRGB);
      }
    }

    if (sCmdFilter == "")
    {
      CommandsList_Fill(hWndCommandsList, undefined);
    }
    else
    {
      oSys.Call("user32::SetWindowTextW", hWndFilterEdit, sCmdFilter);
      i = sCmdFilter.length;
      AkelPad.SendMessage(hWndFilterEdit, EM_SETSEL, 0, -1);
      CommandsList_Fill(hWndCommandsList, sCmdFilter);
    }
    if (nCmdIndex != -1)
    {
      CommandsList_SetCurSel(hWndCommandsList, nCmdIndex);
    }
    oSys.Call("user32::SetFocus", hWndFilterEdit);

    hSubclassFilterEdit = AkelPad.WindowSubClass(hWndFilterEdit, FilterEditCallback);
    hSubclassCommandsList = AkelPad.WindowSubClass(hWndCommandsList, CommandsListCallback);
  }

  else if (uMsg == WM_KEYDOWN)
  {
    if (wParam == VK_ESCAPE)
    {
      sCmdFilter = "";
      nCmdIndex = -1;
      oSys.Call("user32::PostMessage" + _TCHAR, hWnd, WM_CLOSE, 0, 0);
    }
    else if (wParam == VK_RETURN)
    {
      ActionItem = CommandsList_GetCurSelItem(hWndCommandsList);
      oSys.Call("user32::PostMessage" + _TCHAR, hWnd, WM_CLOSE, 0, 0);
    }
  }

  else if (uMsg == WM_COMMAND)
  {
    if (HIWORD(wParam) == LBN_DBLCLK)
    {
      if (LOWORD(wParam) == IDC_LB_ITEMS)
      {
        ActionItem = CommandsList_GetCurSelItem(hWndCommandsList);
        oSys.Call("user32::PostMessage" + _TCHAR, hWnd, WM_CLOSE, 0, 0);
      }
    }
  }

  else if (uMsg == WM_NOTIFY)
  {
    if (wParam == IDC_LV_ITEMS)
    {
      var code = AkelPad.MemRead(_PtrAdd(lParam, _X64 ? 16 : 8), DT_DWORD);
      if (code == NM_DBLCLK)
      {
        ActionItem = CommandsList_GetCurSelItem(hWndCommandsList);
        oSys.Call("user32::PostMessage" + _TCHAR, hWnd, WM_CLOSE, 0, 0);
      }
    }
  }

  else if (uMsg == WM_CTLCOLOREDIT && isApplyingColorTheme())
  {
    if (lParam == hWndFilterEdit)
    {
      oSys.Call("gdi32::SetTextColor", wParam, nTextColorRGB);
      oSys.Call("gdi32::SetBkColor", wParam, nBkColorRGB);
      return hBkColorBrush;
    }
    else
    {
      oSys.Call("gdi32::SetBkColor", wParam, oSys.Call("user32::GetSysColor", COLOR_WINDOW));
      return oSys.Call("user32::GetSysColorBrush", COLOR_WINDOW);
    }
  }

  else if (uMsg == WM_CTLCOLORLISTBOX && isApplyingColorTheme())
  {
    if (lParam == hWndCommandsList)
    {
      oSys.Call("gdi32::SetTextColor", wParam, nTextColorRGB);
      oSys.Call("gdi32::SetBkColor", wParam, nBkColorRGB);
      return hBkColorBrush;
    }
    else
    {
      oSys.Call("gdi32::SetBkColor", wParam, oSys.Call("user32::GetSysColor", COLOR_WINDOW));
      return oSys.Call("user32::GetSysColorBrush", COLOR_WINDOW);
    }
  }

  else if (uMsg == WM_CLOSE)
  {
    ReadWriteIni(true);
    oSys.Call("user32::DestroyWindow", hWnd); // Destroy dialog
  }

  // else if (uMsg == WM_ACTIVATE)
  // {
  //   oSys.Call("user32::SetFocus", hWndFilterEdit);
  // }

  else if (uMsg == WM_DESTROY)
  {
    oSys.Call("user32::PostQuitMessage", 0); // Exit message loop
  }

  return 0;
}

function FilterEditCallback(hWnd, uMsg, wParam, lParam)
{
  if (uMsg == WM_KEYDOWN)
  {
    if ((wParam == VK_BACK) || (wParam == VK_DELETE))
    {
      if ((wParam == VK_BACK) && IsCtrlPressed())
      {
        var n1, n2;
        n2 = HIWORD(AkelPad.SendMessage(hWnd, EM_GETSEL, 0, 0));
        AkelPad.WindowNextProc(hSubclassFilterEdit, hWnd, uMsg, VK_LEFT, 0);
        n1 = LOWORD(AkelPad.SendMessage(hWnd, EM_GETSEL, 0, 0));
        AkelPad.SendMessage(hWndFilterEdit, EM_SETSEL, n1, n2);
        AkelPad.SendMessage(hWndFilterEdit, EM_REPLACESEL, 1, "");
      }
      else
        AkelPad.WindowNextProc(hSubclassFilterEdit, hWnd, uMsg, wParam, lParam);

      sCmdFilter = GetWindowText(hWnd);
      CommandsList_Fill(hWndCommandsList, sCmdFilter);

      AkelPad.WindowNoNextProc(hSubclassFilterEdit);
      return 0;
    }
    if ((wParam == VK_DOWN) || (wParam == VK_UP) ||
        (wParam == VK_PRIOR) || (wParam == VK_NEXT))
    {
      AkelPad.SendMessage(hWndCommandsList, uMsg, wParam, lParam);

      AkelPad.WindowNoNextProc(hSubclassFilterEdit);
      return 0;
    }
  }
  else if (uMsg == WM_CHAR)
  {
    if ((wParam == 0x7F) && IsCtrlPressed()) // 0x7F is Ctrl+Backspace. Why? Ask M$
    {
      // do nothing
    }
    else
    {
      AkelPad.WindowNextProc(hSubclassFilterEdit, hWnd, uMsg, wParam, lParam);

      sCmdFilter = GetWindowText(hWnd);
      CommandsList_Fill(hWndCommandsList, sCmdFilter);
    }

    AkelPad.WindowNoNextProc(hSubclassFilterEdit);
    return 0;
  }
}

function CommandsListCallback(hWnd, uMsg, wParam, lParam)
{
  if (uMsg == WM_KEYDOWN)
  {
    if ((wParam == VK_DOWN) || (wParam == VK_UP) ||
        (wParam == VK_PRIOR) || (wParam == VK_NEXT) ||
        (wParam == VK_HOME) || (wParam == VK_END))
    {
      // default processing
    }
    else
    {
      AkelPad.SendMessage(hWndFilterEdit, uMsg, wParam, lParam);
      oSys.Call("user32::SetFocus", hWndFilterEdit);
      AkelPad.WindowNoNextProc(hSubclassCommandsList);
      return 0;
    }
  }
  else if (uMsg == WM_CHAR)
  {
    AkelPad.SendMessage(hWndFilterEdit, uMsg, wParam, lParam);
    oSys.Call("user32::SetFocus", hWndFilterEdit);
    AkelPad.WindowNoNextProc(hSubclassCommandsList);
    return 0;
  }
}

function GetWindowRect(hWnd)
{
  var oRect  = new Object();
  var lpRect = AkelPad.MemAlloc(16); //sizeof(RECT)

  oSys.Call("user32::GetWindowRect", hWnd, lpRect);

  oRect.X = AkelPad.MemRead(_PtrAdd(lpRect,  0), DT_DWORD);
  oRect.Y = AkelPad.MemRead(_PtrAdd(lpRect,  4), DT_DWORD);
  oRect.W = AkelPad.MemRead(_PtrAdd(lpRect,  8), DT_DWORD) - oRect.X;
  oRect.H = AkelPad.MemRead(_PtrAdd(lpRect, 12), DT_DWORD) - oRect.Y;

  AkelPad.MemFree(lpRect);
  return oRect;
}

function GetClientRect(hWnd)
{
  var oRect  = new Object();
  var lpRect = AkelPad.MemAlloc(16); //sizeof(RECT)

  oSys.Call("user32::GetClientRect", hWnd, lpRect);

  oRect.X = AkelPad.MemRead(_PtrAdd(lpRect,  0), DT_DWORD);
  oRect.Y = AkelPad.MemRead(_PtrAdd(lpRect,  4), DT_DWORD);
  oRect.W = AkelPad.MemRead(_PtrAdd(lpRect,  8), DT_DWORD) - oRect.X;
  oRect.H = AkelPad.MemRead(_PtrAdd(lpRect, 12), DT_DWORD) - oRect.Y;

  AkelPad.MemFree(lpRect);
  return oRect;
}

function GetChildWindowRect(hWnd)
{
  var oRect  = new Object();
  var lpRect = AkelPad.MemAlloc(16); //sizeof(RECT)
  var hParentWnd = oSys.Call("user32::GetParent", hWnd);

  oSys.Call("user32::GetWindowRect", hWnd, lpRect);
  oSys.Call("user32::MapWindowPoints", HWND_DESKTOP, hParentWnd, lpRect, 2);

  oRect.X = AkelPad.MemRead(_PtrAdd(lpRect,  0), DT_DWORD);
  oRect.Y = AkelPad.MemRead(_PtrAdd(lpRect,  4), DT_DWORD);
  oRect.W = AkelPad.MemRead(_PtrAdd(lpRect,  8), DT_DWORD) - oRect.X;
  oRect.H = AkelPad.MemRead(_PtrAdd(lpRect, 12), DT_DWORD) - oRect.Y;

  AkelPad.MemFree(lpRect);
  return oRect;
}

function ResizeWindow(hWnd, w, h)
{
  oSys.Call("user32::SetWindowPos", hWnd, 0, 0, 0, w, h, 0x16 /*SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOMOVE*/);
}

function SetWndFont(hWnd, hFont)
{
  AkelPad.SendMessage(hWnd, WM_SETFONT, hFont, TRUE);
}

function GetWindowText(hWnd)
{
  var nMaxTextLen = 1024;
  var lpText = AkelPad.MemAlloc(nMaxTextLen * 2);
  oSys.Call("user32::GetWindowTextW", hWnd, lpText, nMaxTextLen);
  var S = AkelPad.MemRead(lpText, DT_UNICODE);
  AkelPad.MemFree(lpText);
  return S;
}

function MatchFilter(sFilter, sLine)
{
  var i;
  var j;
  var m;

  i = sLine.indexOf(sFilter);
  if (i != -1)
  {
    m = "" + i;
    while (m.length < 3)  m = "0" + m;
    return "e" + m; // exact match
  }

  j = 0;
  m = "";
  for (i = 0; i < sFilter.length; i++)
  {
    j = sLine.indexOf(sFilter.substr(i, 1), j);
    if (j == -1)
      return ""; // no match

    while (m.length < j)  m = m + "x";
    m = m + "v";
    ++j;
  }
  return "p" + m; // partial match
}

function compareByCommand(a, b)
{
  if ((a[2] < b[2]) || (a[2] == b[2] && a[1] < b[1]))
    return -1;
  if ((a[2] > b[2]) || (a[2] == b[2] && a[1] > b[1]))
    return 1;
  return 0;
}

function getFullCmdText(cmdText, cmdIdx)
{
  if (ShowCmdIds)
  {
    var oCmd = Commands[cmdIdx];
    if (oCmd.type == CMDTYPE_AKELPAD)
    {
      var num = oCmd.cmd.toString();
      while (num.length < 4)  num = "0" + num;
      cmdText = "[" + num + "] " + cmdText;
    }
    else if (oCmd.type == CMDTYPE_PLUGIN)
    {
      cmdText = "[plug] " + cmdText;
    }
    else if (oCmd.type == CMDTYPE_SCRIPT)
    {
      cmdText = "[scrp] " + cmdText;
    }
    else if (oCmd.type == CMDTYPE_EXEC)
    {
      cmdText = "[exec] " + cmdText;
    }
  }
  return cmdText;
}

function getCmdName(cmdText)
{
  var n = cmdText.lastIndexOf("\\t");
  if (n != -1)
    return cmdText.substr(0, n);
  else
    return cmdText;
}

function getCmdShortcutKey(cmdText)
{
  var n = cmdText.lastIndexOf("\\t");
  if (n != -1)
    return cmdText.substr(n+2);
  else
    return "";
}

function InitCommandsListView(hLvWnd, width)
{
  var width0 = Math.floor(width*(CmdTextMaxLength - 1)/CmdTotalMaxLength);
  var width1 = Math.floor(width*(CmdShortcutMaxLength + 1)/CmdTotalMaxLength);
  var lpLvColumn = AkelPad.MemAlloc(_X64 ? 56 : 44); // sizeof(LVCOLUMN)

  AkelPad.SendMessage(hLvWnd, LVM_SETEXTENDEDLISTVIEWSTYLE, LVS_EX_FULLROWSELECT, LVS_EX_FULLROWSELECT);

  // LVCOLUMN.mask:
  AkelPad.MemCopy(_PtrAdd(lpLvColumn, 0), LVCF_FMT|LVCF_WIDTH, DT_DWORD);
  // LVCOLUMN.fmt:
  AkelPad.MemCopy(_PtrAdd(lpLvColumn, 4), LVCFMT_LEFT, DT_DWORD);
  // LVCOLUMN.cx:
  AkelPad.MemCopy(_PtrAdd(lpLvColumn, 8), width0, DT_DWORD);
  // Inserting a column:
  AkelPad.SendMessage(hLvWnd, LVM_INSERTCOLUMNW, 0, lpLvColumn);

  // LVCOLUMN.mask:
  AkelPad.MemCopy(_PtrAdd(lpLvColumn, 0), LVCF_FMT|LVCF_WIDTH, DT_DWORD);
  // LVCOLUMN.fmt:
  AkelPad.MemCopy(_PtrAdd(lpLvColumn, 4), LVCFMT_LEFT, DT_DWORD);
  // LVCOLUMN.cx:
  AkelPad.MemCopy(_PtrAdd(lpLvColumn, 8), width1, DT_DWORD);
  // Inserting a column:
  AkelPad.SendMessage(hLvWnd, LVM_INSERTCOLUMNW, 1, lpLvColumn);

  AkelPad.MemFree(lpLvColumn);
}

function GetLvFocusedIndex(hLvWnd)
{
  return AkelPad.SendMessage(hLvWnd, LVM_GETNEXTITEM, -1, LVNI_FOCUSED);
}

function GetLvSelectedIndex(hLvWnd)
{
  return AkelPad.SendMessage(hLvWnd, LVM_GETNEXTITEM, -1, LVNI_SELECTED);
}

function CommandsList_GetCurSelItem(hListWnd)
{
  var n;
  var cmdIdx;

  if (UseListView)
  {
    n = GetLvFocusedIndex(hListWnd);
    if (n < 0)
      n = 0;

    nCmdIndex = n;

    var lpLvItem = AkelPad.MemAlloc(_X64 ? 72 : 60); // sizeof(LVITEM)

    // LVITEM.mask:
    AkelPad.MemCopy(_PtrAdd(lpLvItem, 0), LVIF_PARAM, DT_DWORD);
    // LVITEM.iItem:
    AkelPad.MemCopy(_PtrAdd(lpLvItem, 4), n, DT_DWORD);
    // LVITEM.iSubItem:
    AkelPad.MemCopy(_PtrAdd(lpLvItem, 8), 0, DT_DWORD);
    // Get the item:
    AkelPad.SendMessage(hListWnd, LVM_GETITEMW, 0, lpLvItem);

    // Get LVITEM.lParam:
    cmdIdx = AkelPad.MemRead(_PtrAdd(lpLvItem, _X64 ? 40 : 32), DT_DWORD);

    AkelPad.MemFree(lpLvItem);
  }
  else
  {
    n = AkelPad.SendMessage(hListWnd, LB_GETCURSEL, 0, 0);
    if (n < 0)
      n = 0;

    nCmdIndex = n;

    cmdIdx = AkelPad.SendMessage(hListWnd, LB_GETITEMDATA, n, 0);
  }

  return Commands[cmdIdx];
}


function CommandsList_SetCurSel(hListWnd, nItem)
{
  if (UseListView)
  {
    var lpLvItem = AkelPad.MemAlloc(_X64 ? 72 : 60); // sizeof(LVITEM)

    // LVITEM.mask:
    AkelPad.MemCopy(_PtrAdd(lpLvItem, 0), LVIF_STATE, DT_DWORD);
    // LVITEM.state:
    AkelPad.MemCopy(_PtrAdd(lpLvItem, 12), LVIS_SELECTED|LVIS_FOCUSED, DT_DWORD);
    // LVITEM.stateMask:
    AkelPad.MemCopy(_PtrAdd(lpLvItem, 16), LVIS_SELECTED|LVIS_FOCUSED, DT_DWORD);
    // Set the item state:
    AkelPad.SendMessage(hListWnd, LVM_SETITEMSTATE, nItem, lpLvItem);
    AkelPad.SendMessage(hListWnd, LVM_ENSUREVISIBLE, nItem, FALSE);

    AkelPad.MemFree(lpLvItem);
  }
  else
  {
      AkelPad.SendMessage(hListWnd, LB_SETCURSEL, nCmdIndex, 0);
  }
}

function CommandsList_Clear(hListWnd)
{
  if (UseListView)
    AkelPad.SendMessage(hListWnd, LVM_DELETEALLITEMS, 0, 0);
  else
    AkelPad.SendMessage(hListWnd, LB_RESETCONTENT, 0, 0);
}

function CommandsList_AddItem(hListWnd, cmdName, cmdIdx, i)
{
  var cmdText;
  var cmdShortcut;
  var n;

  if (UseListView)
  {
    var lpLvItem = AkelPad.MemAlloc(_X64 ? 72 : 60); // sizeof(LVITEM)

    cmdText = getCmdName(getFullCmdText(cmdName, cmdIdx));
    cmdShortcut = getCmdShortcutKey(cmdName);

    // LVITEM.mask:
    AkelPad.MemCopy(_PtrAdd(lpLvItem, 0), LVIF_TEXT|LVIF_PARAM, DT_DWORD);
    // LVITEM.iItem:
    AkelPad.MemCopy(_PtrAdd(lpLvItem, 4), i, DT_DWORD);
    // LVITEM.iSubItem:
    AkelPad.MemCopy(_PtrAdd(lpLvItem, 8), 0, DT_DWORD);
    // LVITEM.pszText:
    AkelPad.MemCopy(_PtrAdd(lpLvItem, _X64 ? 24 : 20), cmdText, DT_QWORD);
    // LVITEM.lParam:
    AkelPad.MemCopy(_PtrAdd(lpLvItem, _X64 ? 40 : 32), cmdIdx, DT_DWORD);
    // Inserting an item:
    AkelPad.SendMessage(hListWnd, LVM_INSERTITEMW, 0, lpLvItem);

    // LVITEM.mask:
    AkelPad.MemCopy(_PtrAdd(lpLvItem, 0), LVIF_TEXT, DT_DWORD);
    // LVITEM.iItem:
    AkelPad.MemCopy(_PtrAdd(lpLvItem, 4), i, DT_DWORD);
    // LVITEM.iSubItem:
    AkelPad.MemCopy(_PtrAdd(lpLvItem, 8), 1, DT_DWORD);
    // LVITEM.pszText:
    AkelPad.MemCopy(_PtrAdd(lpLvItem, _X64 ? 24 : 20), cmdShortcut, DT_QWORD);
    // Inserting an item:
    AkelPad.SendMessage(hListWnd, LVM_SETITEMTEXTW, i, lpLvItem);

    AkelPad.MemFree(lpLvItem);
  }
  else
  {
    cmdText = getFullCmdText(cmdName, cmdIdx);
    n = AkelPad.SendMessage(hListWnd, LB_ADDSTRING, 0, cmdText);
    AkelPad.SendMessage(hListWnd, LB_SETITEMDATA, n, cmdIdx);
  }
}

function CommandsList_Fill(hListWnd, sFilter)
{
  var i;
  var n;
  var C;
  var cmdText;
  var Matches = [];

  if (sFilter != undefined)
    sFilter = sFilter.toLowerCase();

  for (i = 0; i < Commands.length; i++)
  {
    C = [];
    C.push(i); // [0] = idx
    C.push(Commands[i].name); // [1] = name
    if (sFilter == undefined || sFilter == "")
    {
      C.push(0); // [2] = match result
      Matches.push(C);
    }
    else
    {
      cmdText = C[1].toLowerCase();
      n = cmdText.indexOf("::");
      if (n != -1)
      {
        // allows to type ' ' instead of '::'
        cmdText = cmdText.replace("::", ":: ");
      }
      cmdText = getFullCmdText(cmdText, C[0]);
      n = MatchFilter(sFilter, cmdText);
      if (n != "")
      {
        C.push(n); // [2] = match result
        Matches.push(C);
      }
    }
  }

  Matches.sort(compareByCommand);

  AkelPad.SendMessage(hListWnd, WM_SETREDRAW, FALSE, 0);
  CommandsList_Clear(hListWnd);

  for (i = 0; i < Matches.length; i++)
  {
    CommandsList_AddItem(hListWnd, Matches[i][1], Matches[i][0], i);
  }

  AkelPad.SendMessage(hListWnd, WM_SETREDRAW, TRUE, 0);
  CommandsList_SetCurSel(hListWnd, 0);
}

function LOWORD(nParam)
{
  return (nParam & 0xFFFF);
}

function HIWORD(nParam)
{
  return ((nParam >> 16) & 0xFFFF);
}

function ReadWriteIni(bWrite)
{
  var oFSO     = new ActiveXObject("Scripting.FileSystemObject");
  var sIniFile = WScript.ScriptFullName.substring(0, WScript.ScriptFullName.lastIndexOf(".")) + ".ini";

  if (bWrite)
  {
    if ((sCmdFilter0 != sCmdFilter) ||
        (nCmdIndex0 != nCmdIndex))
    {
      var sIniTxt = "sCmdFilter=\"" + sCmdFilter + "\";\r\n" +
                    "nCmdIndex=" + nCmdIndex + ";";

      var oFile = oFSO.OpenTextFile(sIniFile, 2, true, -1);
      oFile.Write(sIniTxt);
      oFile.Close();
    }
  }
  else if (oFSO.FileExists(sIniFile))
  {
    var oFile = oFSO.OpenTextFile(sIniFile, 1, false, -1);

    try
    {
      eval(oFile.ReadAll());

      sCmdFilter0 = sCmdFilter;
      nCmdIndex0 = nCmdIndex;
    }
    catch (oError)
    {
    }

    oFile.Close();
  }
}

function alignCmdShortcut(cmdText)
{
  var nMaxLen = CmdTextMaxLength - (ShowCmdIds ? 7 : 0);
  var n = cmdText.lastIndexOf("\\t");
  if (n != -1)
  {
    if (cmdText.length < nMaxLen)
    {
      var t = "";
      var i = cmdText.length;
      while (i < nMaxLen)
      {
        t = t + " ";
        i++;
      }
      cmdText = cmdText.substr(0, n) + t + cmdText.substr(n + 2);
    }
    else
    {
      cmdText = cmdText.substr(0, n) + "  " + cmdText.substr(n + 2);
    }
  }
  return cmdText;
}

function CreateCmdObj(type, cmd, name)
{
  var cmdObj = new Object();
  cmdObj.type = type; // one of CMD_TYPE_*
  cmdObj.cmd  = cmd;  // AkelPad's Command Id or Plugin Call
  cmdObj.name = name; // full Command Name = Command Text + Shortcut key
  return cmdObj;
}

function createCmdObjName(s)
{
  if (UseListView)
  {
    adjustCmdMaxLength(s);
  }
  else
  {
    s = alignCmdShortcut(s);
  }
  return s;
}

function adjustCmdMaxLength(s)
{
  var lenText = getCmdName(s).length;
  var lenShortcut = getCmdShortcutKey(s).length;
  if (ShowCmdIds)
    lenText += 7;
  if (lenText > CmdTextMaxLength)
    CmdTextMaxLength = lenText;
  if (lenShortcut > CmdShortcutMaxLength)
    CmdShortcutMaxLength = lenShortcut;
  CmdTotalMaxLength = CmdTextMaxLength + CmdShortcutMaxLength + 4;
}

function getByteFromWideChar(c)
{
  var n = c.charCodeAt(0);
  if (n > 0xFF)
  {
    var pBufA = AkelPad.MemAlloc(4);
    var pStrW = AkelPad.MemStrPtr(c);
    oSys.Call("kernel32::WideCharToMultiByte", CP_ACP, 0, pStrW, 1, pBufA, 2, 0, 0);
    n = AkelPad.MemRead(pBufA, DT_BYTE);
    AkelPad.MemFree(pBufA);
  }
  return n;
}

function isUnicodeTextFile(oFSO, filePathName)
{
  var oTextStream = oFSO.OpenTextFile(filePathName, 1, false, 0); // read as ASCII
  var n1 = 0;
  var n2 = 0;

  if (!oTextStream.AtEndOfStream)
  {
    n1 = getByteFromWideChar(oTextStream.Read(1));
    if (!oTextStream.AtEndOfStream)
      n2 = getByteFromWideChar(oTextStream.Read(1));
  }
  oTextStream.Close();

  // WScript.Echo(n1 + ", " + n2);
  return (n1 == 0xFF && n2 == 0xFE);
}

function ReadLngFile()
{
  var oFSO     = new ActiveXObject("Scripting.FileSystemObject");
  var sLngFile = WScript.ScriptFullName.replace(/\.js$/i, "_" + AkelPad.GetLangId(LANGID_FULL).toString() + ".lng");
  if (!oFSO.FileExists(sLngFile))
  {
    sLngFile = WScript.ScriptFullName.replace(/\.js$/i, ".lng");
  }
  if (oFSO.FileExists(sLngFile))
  {
    var c;
    var s;
    var m;
    var section = "";
    var oTextStream;

    if (isUnicodeTextFile(oFSO, sLngFile))
      oTextStream = oFSO.OpenTextFile(sLngFile, 1, false, -1); // Unicode
    else
      oTextStream = oFSO.OpenTextFile(sLngFile, 1, false, 0); // ASCII

    if (oTextStream.AtEndOfStream)
    {
      oTextStream.Close();
      FatalErr("File is empty:\n\"" + sLngFile + "\"");
    }

    while (!oTextStream.AtEndOfStream)
    {
      s = oTextStream.ReadLine();
      m = s.match(/^\s*\/\/.*/);
      if (m)
      {
        // Comment
        continue;
      }
      m = s.match(/^\s*\[([^\]]+)\]\s*$/);
      if (m)
      {
        // [Section]
        section = m[1].toLowerCase();
        continue;
      }
      if (section == "akelpad")
      {
        m = s.match(/^\s*(\w+)\s*=\s*"(.+)"\s*$/);
        if (m)
        {
          // AkelPad's Command: id = Text
          c = parseInt(m[1]);
          if (isNaN(c))
          {
            c = oTextStream.Line - 1;
            oTextStream.Close();
            FatalErr("Command Id is not a number: \"" + m[1] + "\"!\nFile: \"" + sLngFile + "\"\nLine: " + c);
          }
          s = createCmdObjName(m[2]);
          Commands.push( CreateCmdObj(CMDTYPE_AKELPAD, c, s) );
          continue;
        }
      }
      else if (section == "plugins")
      {
        m = s.match(/^\s*"(.+)"\s*=\s*"(.+)"\s*$/);
        if (!m)
          m = s.match(/^\s*'(.+)'\s*=\s*"(.+)"\s*$/);
        if (m)
        {
          // Plugin's Command: Plugin::Method = Text
          c = m[1];
          s = createCmdObjName(m[2]);
          Commands.push( CreateCmdObj(CMDTYPE_PLUGIN, c, s) );
          continue;
        }
      }
      else if (section == "scripts")
      {
        m = s.match(/^\s*"(.*)"\s*=\s*"(.+)"\s*$/);
        if (!m)
          m = s.match(/^\s*'(.*)'\s*=\s*"(.+)"\s*$/);
        if (m)
        {
          // Scripts's Command: Script = Text
          c = m[1].replace(/\`/g, "\"");
          s = createCmdObjName(m[2]);
          Commands.push( CreateCmdObj(CMDTYPE_SCRIPT, c, s) );
          continue;
        }
      }
      else if (section == "exec")
      {
        m = s.match(/^\s*"(.+)"\s*=\s*"(.+)"\s*$/);
        if (!m)
          m = s.match(/^\s*'(.+)'\s*=\s*"(.+)"\s*$/);
        if (m)
        {
          // Command Line: Command = Text
          c = m[1];
          s = createCmdObjName(m[2]);
          Commands.push( CreateCmdObj(CMDTYPE_EXEC, c, s) );
          continue;
        }
      }
    }
    oTextStream.Close();
  }
  else
  {
    FatalErr("File not found:\n\"" + sLngFile + "\"");
  }
}

function FatalErr(errMsg)
{
  AkelPad.MessageBox(AkelPad.GetMainWnd(), errMsg, WScript.ScriptName, MB_OK|MB_ICONERROR);
  WScript.Quit();
}


Внимание! Скрипт не будет работать без файла "CommandPalette.lng"!
Этот файл содержит перечисление команд, отображаемых скриптом. Сохраняйте файл "CommandPalette.lng" в кодировке UTF-16 LE (1200).

Содержимое файлов CommandPalette.lng (английская версия) и CommandPalette_1049.lng (русская версия) см. двумя сообщениями ниже из-за ограничения на кол-во символов в одном сообщении.
Last edited by DV on Mon Apr 26, 2021 7:11 am, edited 17 times in total.

Offline
Posts: 5
Joined: Sat Nov 09, 2019 2:53 pm

Post by hexep »

Code: Select all

// Version: 1.2
// Author: HEXEP
// Description(1033): On / Off column selection mode.
// Description(1049): Включение / Выключение режима выделения столбца.
//
// Использование:
//  SET(128, If("SendEdit(3127 /*AEM_GETCOLUMNSEL*/, 0, 0)", 0x1, 0x0))
//    "Режим выделения столбца" Call("Scripts::Main", 1, "SelectionModeSwitch.js")
//  UNSET(128)


/* Используемые константы */
WSC_MAINPROC			= 1;
WSC_FRAMEPROC			= 3;
WM_NOTIFY					= 78;
AENM_SELCHANGE		= 128;
AEM_GETEVENTMASK	= 3225;
AEM_SETEVENTMASK	= 3226;
AEN_SELCHANGING		= 2078;
SH_FINDSCRIPT			= 3;
SH_CLOSESCRIPT		= 33;
SH_GETMESSAGELOOP	= 13;
AEM_UPDATESEL			= 3128;
AESELT_COLUMNOFF	= 0;
AESELT_COLUMNON		= 1;
AESELT_LOCKNOTIFY	= 4;
AESELT_LOCKSCROLL	= 8;


/* Объявление переменных */
var hEditWnd	= AkelPad.GetEditWnd();
var hMainWnd	= AkelPad.GetMainWnd();
var oSys			= AkelPad.SystemFunction();
var hScript		= AkelPad.ScriptHandle(WScript.ScriptName, SH_FINDSCRIPT);
var curEventMask;


if (hScript && AkelPad.ScriptHandle(hScript, SH_GETMESSAGELOOP))
{
	/* Скрипт в текущее время запущен */
	// Указываем AkelPad'у отправлять сообщения AEN_SELCHANGING
	AkelPad.SendMessage(hMainWnd, AEM_SETEVENTMASK, 0, curEventMask);
	// Выключаем работу скрипта
	AkelPad.ScriptHandle(hScript, SH_CLOSESCRIPT);
	// Переводим тип выделения в обычный
	SetSelectionType(false);
}
else
{
	/* Скрипт в текущее время не запущен */
	// В зависимости от текущего оконного режима, определяем для чего нужно установить перехватчик сообщений
	var hHandle;
	if (AkelPad.IsMDI() == 1)
		hHandle = WSC_FRAMEPROC;
	else
		hHandle = WSC_MAINPROC;
	// Получаем текущие обрабатываемые AkelPad'ом сообщения
	var curEventMask = AkelPad.SendMessage(hMainWnd, AEM_GETEVENTMASK, 0, 0);
	// Указываем AkelPad'у отправлять сообщения AEN_SELCHANGING
	AkelPad.SendMessage(hMainWnd, AEM_SETEVENTMASK, 0, curEventMask|AENM_SELCHANGE);
	// Устанавливаем режим выделения столбца
	SetSelectionType(true);
	// Начинаем обрабатывать сообщения WM_NOTIFY, которые передают AEN_SELCHANGING
	var sSubClass = AkelPad.WindowSubClass(hHandle, sCallback, WM_NOTIFY);
	AkelPad.ScriptNoMutex();
	AkelPad.WindowGetMessage();
	AkelPad.WindowUnsubClass(WSC_MAINPROC);
}


function sCallback(hWnd, uMsg, wParam, lParam)
{
	if ((uMsg == WM_NOTIFY))
	{
		if (AkelPad.MemRead(_PtrAdd(lParam, _X64 ? 16 : 8), 3) == AEN_SELCHANGING)
		{
			AkelPad.SendMessage(hEditWnd, AEM_UPDATESEL, AESELT_COLUMNON|AESELT_LOCKNOTIFY|AESELT_LOCKSCROLL, 0);
		}
	}
	return 0;
}


/* Переключение режима выделения для всех вкладок */
function SetSelectionType(bColumn)
{
	var cofFrameInitial = AkelPad.SendMessage(hMainWnd, 1288 /*AKD_FRAMEFIND*/, 1 /*FWF_CURRENT*/, 0);
	var cofCurFrame;

	// Определение настройки порядка вкладок AkelPad
	var tabOpts = AkelPad.SendMessage(hMainWnd, 1222 /*AKD_GETMAININFO*/, 157 /*MI_TABOPTIONSMDI*/, 0);
	var tabRightLeft = (tabOpts & 0x20000 /*TAB_SWITCH_RIGHTLEFT*/);
	// Установка, если необходимо, опции "Вкладки -> Правая-Левая"
	if (!tabRightLeft) AkelPad.Command(4311 /*IDM_WINDOW_TABSWITCH_RIGHTLEFT*/);

	// Выключаем прорисовку окна редактора на время перебора вкладок
	SetRedraw(false);

	// Цикл переключения открытых вкладок
	for(;;)
	{
		// Переключение режима выделения
		AkelPad.SendMessage(hEditWnd, AEM_UPDATESEL, bColumn|AESELT_LOCKSCROLL, 0);

		// Переключение на следующую вкладку
		cofCurFrame = AkelPad.Command(4316 /*IDM_WINDOW_FRAMENEXT*/);

		// Если текущая вкладка идентична начальной, выходим из цикла
    if (cofCurFrame == cofFrameInitial)
			break;
	}

	// Включаем прорисовку окна редактора после перебора вкладок
	SetRedraw(true);

	// Возврат предыдущих настроек, если изначально не выбрана опция "Вкладки -> Правая-Левая"
	if (!tabRightLeft)
		AkelPad.SendMessage(hMainWnd, 1219 /*AKD_SETMAININFO*/, 157 /*MIS_TABOPTIONSMDI*/, tabOpts);
}


function SetRedraw(bEnable)
{
	oSys.Call("User32::EnableWindow", hMainWnd, bEnable);
	AkelPad.SendMessage(hMainWnd, 11 /*WM_SETREDRAW*/, bEnable, 0);
	AkelPad.SendMessage(hMainWnd, 3185 /*AEM_LOCKSCROLL*/, 3 /*SB_BOTH*/, ! bEnable);

	if (bEnable)
		oSys.Call("User32::InvalidateRect", hEditWnd, 0, 1);
}


On / Off column selection mode.
Включение / Выключение режима выделения столбца.
Last edited by hexep on Tue Dec 31, 2019 10:18 am, edited 2 times in total.

Offline
Posts: 330
Joined: Mon Jun 03, 2019 2:33 am

Post by AZJIO »

Code: Select all

// AZJIO 20.11.19
// Description(1033): Search on the Internet, with the ability to specify the domain
// Description(1049): Поиск выделенного в интернете, с возможностью указать домен

// Используя скрипт TabSwitch (Instructor) удалось переделать его в собственное меню.
// Смотреть строки 51 (пункты меню) и 115 (команды). 4 общих и остальные взависимости от расширения файла
//
// Ниже старые параметры ком строки, из которых я часть удалил и выпилил из скрипта за неактуальностью
//  `-WindowLeft=%bl -WindowTop=%bb`
// Description(1049): собственное меню
//
// Arguments:
// -FontName="Arial"    -Font name. Unchanged, if "".
// -FontStyle=3         -Font style (one of the following):
//                         0  ignored (default).
//                         1  normal.
//                         2  bold.
//                         3  italic.
//                         4  bold italic.
// -FontSize=10         -Font size. Unchanged, if 0 (default).
// -LineGap=10          -Space between items (default is 1).
// -SingleClick=false   -Single mouse click chooses item (default is true).
// -WindowLeft=100      -Left window position. Special values:
//                        -1 centered (default).
//                        -2 cursor position.
// -WindowTop=100       -Top window position. Special values:
//                        -1 centered (default).
//                        -2 cursor position.
// -WindowMaxHeight=500 -Maximum window height. Special values:
//                        -1 unlimited (default).
// -WindowMaxWidth=500  -Maximum window width. Special values:
//                        -1 unlimited (default).
//
// Usage:
// Toolbar button example:
//   -"Моё меню" Call("Scripts::Main", 1, "Search_internet.js", `-WindowLeft=%bl -WindowTop=%bb`)
// ContextMenu item example:
//   -"Моё меню" Call("Scripts::Main", 1, "Search_internet.js", `-WindowLeft=-2 -WindowTop=-2`)


var sSelText=AkelPad.GetSelText();
if (sSelText=="") {
	sSelText = getWordCaret()
	if (sSelText=="") {
		sSelText = getWordCaret()
		WScript.Echo("Выделите текст, который нужно искать.");
		WScript.Quit();
	}
}

function GetFrameList(lpFrameList) {
	var i = 0;
	// Здесь создаём пункты меню, копируя блок

			lpFrameList[i] = [0, 0];
			lpFrameList[i][0] = "Найти в Google";
			lpFrameList[i][1] = GetIcon(pPath + "\\AkelFiles\\icons\\ico\\google.ico", 0);
			++i;

			lpFrameList[i] = [0, 0];
			lpFrameList[i][0] = "Найти в Яндекс";
			lpFrameList[i][1] = GetIcon(pPath + "\\AkelFiles\\icons\\ico\\yandex.ico", 0);
			++i;

			lpFrameList[i] = [0, 0];
			lpFrameList[i][0] = "Найти на форуме AkelPad";
			lpFrameList[i][1] = GetIcon(pPath + "\\AkelFiles\\icons\\ico\\google.ico", 0);
			++i;

			lpFrameList[i] = [0, 0];
			lpFrameList[i][0] = "Найти в домене...";
			lpFrameList[i][1] = GetIcon(pPath + "\\AkelFiles\\icons\\ico\\google.ico", 0);
			++i;

	switch (sFileExt) {

		case "css":
		case "htm":
		case "html":
			lpFrameList[i] = [0, 0];
			lpFrameList[i][0] = "Найти на сайте htmlbook.ru";
			lpFrameList[i][1] = GetIcon(pPath + "\\AkelFiles\\icons\\ico\\google.ico", 0);
			++i;
			break;

		case "pb":
			lpFrameList[i] = [0, 0];
			lpFrameList[i][0] = "Найти на форуме purebasic.info";
			lpFrameList[i][1] = GetIcon(pPath + "\\AkelFiles\\icons\\ico\\google.ico", 0);
			++i;

			lpFrameList[i] = [0, 0];
			lpFrameList[i][0] = "Найти на форуме purebasic.fr";
			lpFrameList[i][1] = GetIcon(pPath + "\\AkelFiles\\icons\\ico\\google.ico", 0);
			++i;
			break;

		case "au3":
			lpFrameList[i] = [0, 0];
			lpFrameList[i][0] = "Найти на форуме autoitscript.com/forum";
			lpFrameList[i][1] = GetIcon(pPath + "\\AkelFiles\\icons\\ico\\google.ico", 0);
			++i;

			lpFrameList[i] = [0, 0];
			lpFrameList[i][0] = "Найти на форуме autoit-script.ru";
			lpFrameList[i][1] = GetIcon(pPath + "\\AkelFiles\\icons\\ico\\google.ico", 0);
			++i;
			break;

	}

	// Возвращаем индекс выделенного пункта меню
	return 0;
}


// Здесь создаём команды пунктов меню.
function Execute(idx_item) {
	var sLink
	switch (idx_item) { //сравнение ==
		case 0:
			sLink = 'https://www.google.com/search?source=hp&q=' + sSelText + '&oq=' + sSelText
			oSys.Call("Shell32::ShellExecuteW", 0, "open", sLink, 0, 0, 1);
			break;
		case 1:
			sLink = 'https://yandex.ru/search/?&text=' + sSelText
			oSys.Call("Shell32::ShellExecuteW", 0, "open", sLink, 0, 0, 1);
			break;
		case 2:
			sSelText += ' site:akelpad.sourceforge.net/forum/'
			sLink = 'https://www.google.com/search?source=hp&q=' + sSelText + '&oq=' + sSelText
			// sLink = 'https://yandex.ru/search/?&text=' + sSelText
			oSys.Call("Shell32::ShellExecuteW", 0, "open", sLink, 0, 0, 1);
			break;
		case 3:
			var sValue;
			if (sValue=AkelPad.InputBox(hMainWnd, WScript.ScriptName, "Задайте домен","")) { // если жмём "ОК"
				sSelText += ' site:' + sValue
				sLink = 'https://www.google.com/search?source=hp&q=' + sSelText + '&oq=' + sSelText
				// sLink = 'https://yandex.ru/search/?&text=' + sSelText
				oSys.Call("Shell32::ShellExecuteW", 0, "open", sLink, 0, 0, 1);
			}
			break;
	}

	switch (sFileExt) {

		case "css":
		case "htm":
		case "html":
			switch (idx_item) { //сравнение ==
				case 4:
					sSelText += ' site:htmlbook.ru'
					sLink = 'https://www.google.com/search?source=hp&q=' + sSelText + '&oq=' + sSelText
					oSys.Call("Shell32::ShellExecuteW", 0, "open", sLink, 0, 0, 1);
					break;
			}
			break;

		case "pb":
			switch (idx_item) { //сравнение ==
				case 4:
					sSelText += ' site:purebasic.info'
					sLink = 'https://www.google.com/search?source=hp&q=' + sSelText + '&oq=' + sSelText
					oSys.Call("Shell32::ShellExecuteW", 0, "open", sLink, 0, 0, 1);
					break;
				case 5:
					sSelText += ' site:purebasic.fr'
					sLink = 'https://www.google.com/search?source=hp&q=' + sSelText + '&oq=' + sSelText
					oSys.Call("Shell32::ShellExecuteW", 0, "open", sLink, 0, 0, 1);
					break;
			}
			break;

		case "au3":
			switch (idx_item) { //сравнение ==
				case 4:
					sSelText += ' site:autoitscript.com/forum'
					sLink = 'https://www.google.com/search?source=hp&q=' + sSelText + '&oq=' + sSelText
					oSys.Call("Shell32::ShellExecuteW", 0, "open", sLink, 0, 0, 1);
					break;
				case 5:
					sSelText += ' site:autoit-script.ru'
					sLink = 'https://www.google.com/search?source=hp&q=' + sSelText + '&oq=' + sSelText
					oSys.Call("Shell32::ShellExecuteW", 0, "open", sLink, 0, 0, 1);
					break;
			}
			break;

	}
}

// CaretSelect.js
function getWordCaretInfo(hWndEdit) {
	if (hWndEdit) {
		var nCaretPos = AkelPad.GetSelStart();
		var crInfo = [];
		crInfo.min = AkelPad.SendMessage(hWndEdit, 1100 /*EM_FINDWORDBREAK */, 0/*WB_LEFT*/, nCaretPos);
		crInfo.max = AkelPad.SendMessage(hWndEdit, 1100 /*EM_FINDWORDBREAK */, 7/*WB_RIGHTBREAK*/, crInfo.min);
		//! For case when caret located on word start position i.e. "prev-word |word-to-copy"
		if (crInfo.max < nCaretPos) {
			crInfo.min = AkelPad.SendMessage(hWndEdit, 1100/*EM_FINDWORDBREAK*/, 0/*WB_LEFT*/, nCaretPos + 1);
			crInfo.max = AkelPad.SendMessage(hWndEdit, 1100/*EM_FINDWORDBREAK*/, 7/*WB_RIGHTBREAK*/, crInfo.min);
		}
		if (crInfo.max >= nCaretPos)
			return crInfo;
	}
}

// Возвращает текст слова, на котором установлена каретка
function getWordCaret() {
	var sResult = "";
	var hWndEdit = AkelPad.GetEditWnd();
	var crInfo = getWordCaretInfo(hWndEdit);
	if (crInfo) sResult = AkelPad.GetTextRange(crInfo.min, crInfo.max);
	return sResult;
}

//Arguments
var pFontName = AkelPad.GetArgValue("FontName", "");
var nFontStyle = AkelPad.GetArgValue("FontStyle", 0);
var nFontSize = AkelPad.GetArgValue("FontSize", 0);
var nLineGap = AkelPad.GetArgValue("LineGap", 1);
var bSingleClick = AkelPad.GetArgValue("SingleClick", true);
var nWindowLeft = AkelPad.GetArgValue("WindowLeft", -1);
var nWindowTop = AkelPad.GetArgValue("WindowTop", -1);
var nWindowMaxHeight = AkelPad.GetArgValue("WindowMaxHeight", -1);
var nWindowMaxWidth = AkelPad.GetArgValue("WindowMaxWidth", -1);

//Variables
var sEditFile = AkelPad.GetEditFile(0);
var sFileExt = AkelPad.GetFilePath(sEditFile, 4 /*CPF_FILEEXT*/ );
// var sSelText = AkelPad.GetSelText();
var pPath = AkelPad.GetAkelDir();
sFileExt = sFileExt.toLowerCase()

var hMainWnd = AkelPad.GetMainWnd();

// чтобы не создавать меню на других файлах
// switch (sFileExt) {
// 	case "css":
// 	case "htm":
// 	case "html":
// 	case "pb":
// 	case "au3":
// 		break;
// 	default:
// 		AkelPad.MessageBox(hMainWnd, "Этот тип файлов не поддерживается. \n Поддерживаемые: js, reg, html, au3, pb.", 'Скрипт "Поиск в интернете"', 64 /*MB_ICONINFORMATION*/ );
// 		WScript.Quit();
// 		break;
// };
var hWndEdit = AkelPad.GetEditWnd();
var oSys = AkelPad.SystemFunction();
var hInstanceDLL = AkelPad.GetInstanceDll();
var pClassName = "AkelPad::Scripts::" + WScript.ScriptName + "::" + oSys.Call("kernel32::GetCurrentProcessId");
var hWndContainer = 0;
var hWndListBox = 0;
var hHookPost;
var hHookSend;
var dwMainThreadID = oSys.Call("user32::GetWindowThreadProcessId", hMainWnd, 0);
var hSubClass;
var hDC;
var hBrushHollow;
var hFontEdit;
var lpFrameList = [];
var rcMain = [];
var ptPoint = [];
var nItemHeight;
var nScreenWidth;
var nControlWidth;
var nControlHeight;
var nMaxControlHeight;
var nCharWidth;
var nCharHeight;
var nMaxCharWidth = 0;
var nMaxCharHeight = 0;
var nIconSize = 16;
var nIconGap = 2;
var bNoSwitch = false;
var i;

// Получить список документов
nCurSel = GetFrameList(lpFrameList);

// Получить шрифт
if (pFontName || nFontStyle || nFontSize)
	hFontEdit = CreateFont(pFontName, nFontStyle, nFontSize);
else
	hFontEdit = AkelPad.SendMessage(hWndEdit, 0x31 /*WM_GETFONT*/ , 0, 0);
if (!hFontEdit) WScript.Quit();

// Получить максимальный размер символа
if (lpSize = AkelPad.MemAlloc(8 /*sizeof(SIZE)*/ )) {
	if (hDC = oSys.Call("user32::GetDC", hWndEdit)) {
		oSys.Call("gdi32::SelectObject", hDC, hFontEdit);

		for (i = 0; i < lpFrameList.length; ++i) {
			if (oSys.Call("gdi32::GetTextExtentPoint32" + _TCHAR, hDC, lpFrameList[i][0], lpFrameList[i][0].length, lpSize)) {
				nCharWidth = AkelPad.MemRead(_PtrAdd(lpSize, 0) /*offsetof(SIZE, cx)*/ , 3 /*DT_DWORD*/ );
				nCharHeight = AkelPad.MemRead(_PtrAdd(lpSize, 4) /*offsetof(SIZE, cy)*/ , 3 /*DT_DWORD*/ );
				if (nCharWidth > nMaxCharWidth) nMaxCharWidth = nCharWidth;
				if (nCharHeight > nMaxCharHeight) nMaxCharHeight = nCharHeight;
			}
		}
		oSys.Call("user32::ReleaseDC", hWndEdit, hDC);
	}
	nMaxCharWidth += nIconSize + nIconGap + 16;

	AkelPad.MemFree(lpSize);
}

// Создаёт диалог
if (AkelPad.WindowRegisterClass(pClassName, 0x21 /*WM_MOUSEACTIVATE*/ ,
		0x2B /*WM_DRAWITEM*/ )) {
	if (hWndContainer = oSys.Call("user32::CreateWindowEx" + _TCHAR, 0, pClassName, 0, 0x80000000 /*WS_POPUP*/ , 0, 0, 0, 0, hMainWnd, 0, hInstanceDLL, DialogCallback)) {
		if (hWndListBox = oSys.Call("user32::CreateWindowEx" + _TCHAR, 0, "LISTBOX", 0, 0x50700010 /*WS_VISIBLE|WS_CHILD|WS_HSCROLL|WS_VSCROLL|WS_DLGFRAME|LBS_OWNERDRAWFIXED*/ , 0, 0, 0, 0, hWndContainer, 0, hInstanceDLL, 0)) {
			//Make hWndContainer invisible
			hBrushHollow = oSys.Call("gdi32::GetStockObject", 5 /*HOLLOW_BRUSH*/ );
			oSys.Call("user32::SetClassLong" + _TCHAR, hWndContainer, -10 /*GCL_HBRBACKGROUND*/ , hBrushHollow);

			AkelPad.SendMessage(hWndListBox, 48 /*WM_SETFONT*/ , hFontEdit, 1);
			nItemHeight = nMaxCharHeight + nLineGap;
			i = AkelPad.SendMessage(hWndListBox, 0x1A1 /*LB_GETITEMHEIGHT*/ , 0, 0);
			if (nItemHeight < i)
				nItemHeight = i;
			else
				AkelPad.SendMessage(hWndListBox, 0x1A0 /*LB_SETITEMHEIGHT*/ , 0, nItemHeight);
			nMaxControlHeight = lpFrameList.length * nItemHeight + oSys.Call("user32::GetSystemMetrics", 8 /*SM_CYDLGFRAME*/ ) * 2;
			if (nWindowMaxHeight > 0)
				nControlHeight = Math.min(nWindowMaxHeight, nMaxControlHeight);
			else
				nControlHeight = nMaxControlHeight;
			nControlHeight = Math.min(oSys.Call("user32::GetSystemMetrics", 62 /*SM_CYMAXIMIZED*/ ) - 8, nControlHeight);
			if (nWindowMaxWidth > 0)
				nControlWidth = Math.min(nWindowMaxWidth, nMaxCharWidth);
			else
				nControlWidth = nMaxCharWidth;
			nControlWidth = Math.min(oSys.Call("user32::GetSystemMetrics", 61 /*SM_CXMAXIMIZED*/ ) - 8, nControlWidth);

			if (nMaxCharWidth > nControlWidth) {
				AkelPad.SendMessage(hWndListBox, 0x194 /*LB_SETHORIZONTALEXTENT*/ , nMaxCharWidth, 0);
				if (nMaxControlHeight == nControlHeight)
					nControlHeight += oSys.Call("user32::GetSystemMetrics", 21 /*SM_CXHSCROLL*/ );
			}

			//Fill listbox
			for (i = 0; i < lpFrameList.length; ++i)
				oSys.Call("user32::SendMessage" + _TCHAR, hWndListBox, 0x180 /*LB_ADDSTRING*/ , 0, lpFrameList[i][0]);

			GetWindowSize(hMainWnd, 0, rcMain);
			if (nWindowLeft >= 0)
				rcMain.left = nWindowLeft;
			else if (nWindowLeft == -2) {
				GetCursorPos(ptPoint);
				rcMain.left = ptPoint.x;
			} else
				rcMain.left += rcMain.right / 2 - nControlWidth / 2;
			if (!(nScreenWidth = oSys.Call("user32::GetSystemMetrics", 78 /*SM_CXVIRTUALSCREEN*/ )))
				nScreenWidth = oSys.Call("user32::GetSystemMetrics", 61 /*SM_CXMAXIMIZED*/ );
			rcMain.left = Math.min(rcMain.left, Math.max((nScreenWidth - 8) - nControlWidth, 0));
			if (rcMain.left < 0) rcMain.left = 0;

			if (nWindowTop >= 0)
				rcMain.top = nWindowTop;
			else if (nWindowTop == -2) {
				GetCursorPos(ptPoint);
				rcMain.top = ptPoint.y;
			} else
				rcMain.top += rcMain.bottom / 2 - nControlHeight / 2;
			rcMain.top = Math.min(rcMain.top, Math.max((oSys.Call("user32::GetSystemMetrics", 62 /*SM_CYMAXIMIZED*/ ) - 8) - nControlHeight, 0));
			if (rcMain.top < 0) rcMain.top = 0;

			oSys.Call("user32::SetWindowPos", hWndContainer, 0, rcMain.left, rcMain.top, nControlWidth, nControlHeight, 0x14 /*SWP_NOZORDER|SWP_NOACTIVATE*/ );
			oSys.Call("user32::SetWindowPos", hWndListBox, 0, 0, 0, nControlWidth, nControlHeight, 0x16 /*SWP_NOMOVE|SWP_NOZORDER|SWP_NOACTIVATE*/ );
			AkelPad.SendMessage(hWndListBox, 0x186 /*LB_SETCURSEL*/ , nCurSel, 0);
			oSys.Call("user32::ShowWindow", hWndContainer, 4 /*SW_SHOWNOACTIVATE*/ );
			//oSys.Call("user32::SetFocus", hWndListBox);
			//oSys.Call("user32::ShowWindow", hWndContainer, 5 /*SW_SHOW*/);
			//oSys.Call("user32::UpdateWindow", hMainWnd);

			//Cause listbox is non-active, hook and send to listbox keyboard and mouse actions.
			// потому что ListBox является неактивным, хук и отправка действия клавиатуры и мыши в ListBox.
			if (hHookPost = AkelPad.ThreadHook(3 /*WH_GETMESSAGE*/ , HookPostCallback, dwMainThreadID, 0x201 /*WM_LBUTTONDOWN*/ ,
					0x0A1 /*WM_NCLBUTTONDOWN*/ ,
					0x204 /*WM_RBUTTONDOWN*/ ,
					0x0A4 /*WM_NCRBUTTONDOWN*/ ,
					0x207 /*WM_MBUTTONDOWN*/ ,
					0x0A7 /*WM_NCMBUTTONDOWN*/ ,
					0x100 /*WM_KEYDOWN*/ ,
					0x101 /*WM_KEYUP*/ ,
					0x104 /*WM_SYSKEYDOWN*/ ,
					0x105 /*WM_SYSKEYUP*/ ,
					0x20A /*WM_MOUSEWHEEL*/ )) {
				if (hHookSend = AkelPad.ThreadHook(4 /*WH_CALLWNDPROC*/ , HookSendCallback, dwMainThreadID, 0x6 /*WM_SETFOCUS*/ )) {
					if (hSubClass = AkelPad.WindowSubClass(hWndListBox, ListBoxCallback, 0x021 /*WM_MOUSEACTIVATE*/ ,
							0x087 /*WM_GETDLGCODE*/ ,
							0x100 /*WM_KEYDOWN*/ ,
							0x101 /*WM_KEYUP*/ ,
							0x201 /*WM_LBUTTONDOWN*/ ,
							0x202 /*WM_LBUTTONUP*/ ,
							0x203 /*WM_LBUTTONDBLCLK*/ )) {
						// Разрешить запуск других сценариев
						AkelPad.ScriptNoMutex();

						// Цикл сообщений
						AkelPad.WindowGetMessage();

						AkelPad.WindowUnsubClass(hWndListBox);
					}
					AkelPad.ThreadUnhook(hHookSend);
				}
				AkelPad.ThreadUnhook(hHookPost);
			}

			if (!bNoSwitch) {
				Execute(AkelPad.SendMessage(hWndListBox, 0x188 /*LB_GETCURSEL*/ , 0, 0))
				// oSys.Call("user32::PostMessage" + _TCHAR, hMainWnd, 1285 /*AKD_FRAMEACTIVATE*/ , 0, lpFrameList[i][1]);
			}
			//oSys.Call("user32::DestroyWindow", hWndListBox);
		}
		oSys.Call("user32::DestroyWindow", hWndContainer);
		Del(lpFrameList); // удаляем иконки
	}
	AkelPad.WindowUnregisterClass(pClassName);
}

// высвободить ресурсы шрифта
if (pFontName || nFontStyle || nFontSize) {
	if (hFontEdit)
		oSys.Call("gdi32::DeleteObject", hFontEdit);
}

function DialogCallback(hWnd, uMsg, wParam, lParam) {
	if (uMsg == 0x021 /*WM_MOUSEACTIVATE*/ ) {
		return 3 /*MA_NOACTIVATE*/ ;
	} else if (uMsg == 0x2B /*WM_DRAWITEM*/ ) {
		var hDC;
		var hIcon;
		var nItemID;
		var nItemState;
		var lpItem;
		var rcItem = [];
		var crText;
		var crBk;
		var hBrushBk;
		var nModeBkOld;

		hDC = AkelPad.MemRead(_PtrAdd(lParam, _X64 ? 32 : 24) /*offsetof(DRAWITEMSTRUCT, hDC)*/ , 2 /*DT_QWORD*/ );
		nItemID = AkelPad.MemRead(_PtrAdd(lParam, _X64 ? 8 : 8) /*offsetof(DRAWITEMSTRUCT, itemID)*/ , 3 /*DT_DWORD*/ );
		nItemState = AkelPad.MemRead(_PtrAdd(lParam, _X64 ? 16 : 16) /*offsetof(DRAWITEMSTRUCT, itemState)*/ , 3 /*DT_DWORD*/ );
		lpItem = _PtrAdd(lParam, _X64 ? 40 : 28) /*offsetof(DRAWITEMSTRUCT, rcItem)*/ ;
		RectToArray(lpItem, rcItem);

		// Установить фон
		if (nItemState & 0x1 /*ODS_SELECTED*/ ) {
			crText = oSys.Call("user32::GetSysColor", 14 /*COLOR_HIGHLIGHTTEXT*/ );
			crBk = oSys.Call("user32::GetSysColor", 13 /*COLOR_HIGHLIGHT*/ );
			hBrushBk = oSys.Call("user32::GetSysColorBrush", 13 /*COLOR_HIGHLIGHT*/ );
		} else {
			crText = oSys.Call("user32::GetSysColor", 8 /*COLOR_WINDOWTEXT*/ );
			crBk = oSys.Call("user32::GetSysColor", 5 /*COLOR_WINDOW*/ );
			hBrushBk = oSys.Call("user32::GetSysColorBrush", 5 /*COLOR_WINDOW*/ );
		}
		oSys.Call("user32::FillRect", hDC, lpItem, hBrushBk);
		nModeBkOld = oSys.Call("gdi32::SetBkMode", hDC, 1 /*TRANSPARENT*/ );

		// Нарисовать иконку
		if (lpFrameList[nItemID][1]) // если есть иконка, то рисуем её
			oSys.Call("user32::DrawIconEx", hDC, rcItem.left, rcItem.top + (rcItem.bottom - rcItem.top) / 2 - nIconSize / 2, lpFrameList[nItemID][1], nIconSize, nIconSize, 0, 0, 0x3 /*DI_NORMAL*/ );

		// Нарисовать текст
		oSys.Call("gdi32::SetTextColor", hDC, crText);
		oSys.Call("gdi32::SetBkColor", hDC, crBk);
		oSys.Call("gdi32::TextOut" + _TCHAR, hDC, rcItem.left + nIconSize + nIconGap, rcItem.top + (rcItem.bottom - rcItem.top) / 2 - nMaxCharHeight / 2, lpFrameList[nItemID][0], lpFrameList[nItemID][0].length);

		oSys.Call("gdi32::SetBkMode", hDC, nModeBkOld);
	}
	return 0;
}

function HookPostCallback(nCode, wParam, lParam) {
	var uMsg = AkelPad.MemRead(_PtrAdd(lParam, _X64 ? 8 : 4) /*offsetof(MSG, message)*/ , 3 /*DT_DWORD*/ );
	var nParamW;
	var nParamL;

	if (uMsg == 0x201 /*WM_LBUTTONDOWN*/ ||
		uMsg == 0x0A1 /*WM_NCLBUTTONDOWN*/ ||
		uMsg == 0x204 /*WM_RBUTTONDOWN*/ ||
		uMsg == 0x0A4 /*WM_NCRBUTTONDOWN*/ ||
		uMsg == 0x207 /*WM_MBUTTONDOWN*/ ||
		uMsg == 0x0A7 /*WM_NCMBUTTONDOWN*/ ) {
		var hWnd = AkelPad.MemRead(_PtrAdd(lParam, 0) /*offsetof(MSG, hwnd)*/ , 2 /*DT_QWORD*/ );

		if (hWnd != hWndListBox) {
			// Не в прямоугольнике
			bNoSwitch = true;

			// Выход из цикла сообщений
			oSys.Call("user32::PostQuitMessage", 0);
		}
	} else if (uMsg == 0x100 /*WM_KEYDOWN*/ ||
		uMsg == 0x101 /*WM_KEYUP*/ ||
		uMsg == 0x104 /*WM_SYSKEYDOWN*/ ||
		uMsg == 0x105 /*WM_SYSKEYUP*/ ||
		uMsg == 0x20A /*WM_MOUSEWHEEL*/ ) {
		nParamW = AkelPad.MemRead(_PtrAdd(lParam, _X64 ? 16 : 8) /*offsetof(MSG, nParamW)*/ , 2 /*DT_QWORD*/ );
		nParamL = AkelPad.MemRead(_PtrAdd(lParam, _X64 ? 24 : 12) /*offsetof(MSG, lParam)*/ , 2 /*DT_QWORD*/ );
		AkelPad.SendMessage(hWndListBox, uMsg, nParamW, nParamL);
		AkelPad.MemCopy(_PtrAdd(lParam, _X64 ? 8 : 4) /*offsetof(MSG, message)*/ , 0 /*WM_NULL*/ , 3 /*DT_DWORD*/ );
	}
}

function HookSendCallback(nCode, wParam, lParam) {
	var uMsg = AkelPad.MemRead(_PtrAdd(lParam, _X64 ? 16 : 8) /*offsetof(CWPSTRUCT, message)*/ , 3 /*DT_DWORD*/ );
	var nParamW;
	var nParamL;

	if (uMsg == 0x6 /*WM_SETFOCUS*/ ) {
		bNoSwitch = true;

		// Выход из цикла сообщений
		oSys.Call("user32::PostQuitMessage", 0);
	}
}

function ListBoxCallback(hWnd, uMsg, wParam, lParam) {
	if (uMsg == 0x021 /*WM_MOUSEACTIVATE*/ ) {
		return 3 /*MA_NOACTIVATE*/ ;
	} else if (uMsg == 0x087 /*WM_GETDLGCODE*/ ) {
		AkelPad.WindowNoNextProc(hSubClass);
		return 0x4 /*DLGC_WANTALLKEYS*/ ;
	} else if (uMsg == 0x100 /*WM_KEYDOWN*/ ) {
		if (wParam == 0x43 /*c*/ ) { // если Ctrl+C на списке то копируем пункт
			if (oSys.Call("user32::GetKeyState", 0x11 /*VK_CONTROL*/ ) & 0x8000) { // если нажат Ctrl при нажатии С
				i = AkelPad.SendMessage(hWndListBox, 0x188 /*LB_GETCURSEL*/ , 0, 0);
				AkelPad.SetClipboardText(lpFrameList[i][0]);
			}
		} else if (wParam == 0x9 /*VK_TAB*/ ) { // если нажат TAB то двигаем курсор по списку, если ещё и SHIFT, то в обратном порядке
			var nCount;

			nCount = AkelPad.SendMessage(hWndListBox, 0x18B /*LB_GETCOUNT*/ , 0, 0);
			i = AkelPad.SendMessage(hWndListBox, 0x188 /*LB_GETCURSEL*/ , 0, 0);

			if (!(oSys.Call("user32::GetKeyState", 0x10 /*VK_SHIFT*/ ) & 0x8000)) {
				if (++i >= nCount)
					i = 0;
			} else {
				if (--i < 0)
					i = nCount - 1;
			}
			AkelPad.SendMessage(hWndListBox, 0x186 /*LB_SETCURSEL*/ , i, 0);
		} else if (wParam == 0xD /*VK_RETURN*/ ) { // клавиша ENTER
			// Выход из цикла сообщений
			oSys.Call("user32::PostQuitMessage", 0);
		} else if (wParam == 0x1B /*VK_ESCAPE*/ ) {
			bNoSwitch = true;

			// Выход из цикла сообщений
			oSys.Call("user32::PostQuitMessage", 0);
		}
	} else if (uMsg == 0x101 /*WM_KEYUP*/ ) {} else if (uMsg == 0x201 /*WM_LBUTTONDOWN*/ ) {
		var lResult = AkelPad.SendMessage(hWndListBox, 0x01A9 /*LB_ITEMFROMPOINT*/ , 0, lParam);

		if (HIWORD(lResult) == 0)
			AkelPad.SendMessage(hWndListBox, 0x186 /*LB_SETCURSEL*/ , LOWORD(lResult), 0);
		AkelPad.WindowNoNextProc(hSubClass);
	} else if (uMsg == 0x202 /*WM_LBUTTONUP*/ ||
		uMsg == 0x203 /*WM_LBUTTONDBLCLK*/ ) {
		if (uMsg == 0x203 /*WM_LBUTTONDBLCLK*/ || bSingleClick) {
			// Выход из цикла сообщений
			oSys.Call("user32::PostQuitMessage", 0);
		}
	}
}

function CreateFont(pFaceName, nFontStyle, nPointSize) {
	// Высвобождение командой: oSys.Call("gdi32::DeleteObject", hFont);
	var lpLogFontSrc;
	var lpLogFontDst;
	var hDC;
	var hFont = 0;
	var nHeight;
	var nWeight;
	var nItalic;

	if (lpLogFontDst = AkelPad.MemAlloc(92 /*sizeof(LOGFONTW)*/ )) {
		lpLogFontSrc = AkelPad.SendMessage(hMainWnd, 1223 /*AKD_GETFRAMEINFO*/ , 48 /*FI_EDITFONTW*/ , 0);
		oSys.Call("kernel32::RtlMoveMemory", lpLogFontDst, lpLogFontSrc, 92 /*sizeof(LOGFONTW)*/ );

		if (nPointSize) {
			if (hDC = oSys.Call("user32::GetDC", hMainWnd)) {
				nHeight = -oSys.Call("kernel32::MulDiv", nPointSize, oSys.Call("gdi32::GetDeviceCaps", hDC, 90 /*LOGPIXELSY*/ ), 72);
				AkelPad.MemCopy(_PtrAdd(lpLogFontDst, 0) /*offsetof(LOGFONTW, lfHeight)*/ , nHeight, 3 /*DT_DWORD*/ );
				oSys.Call("user32::ReleaseDC", hMainWnd, hDC);
			}
		}
		if (nFontStyle != 0 /*FS_NONE*/ ) {
			nWeight = (nFontStyle == 2 /*FS_FONTBOLD*/ || nFontStyle == 4 /*FS_FONTBOLDITALIC*/ ) ? 700 /*FW_BOLD*/ : 400 /*FW_NORMAL*/ ;
			AkelPad.MemCopy(_PtrAdd(lpLogFontDst, 16) /*offsetof(LOGFONTW, lfWeight)*/ , nWeight, 3 /*DT_DWORD*/ );
			nItalic = (nFontStyle == 3 /*FS_FONTITALIC*/ || nFontStyle == 4 /*FS_FONTBOLDITALIC*/ ) ? 1 : 0;
			AkelPad.MemCopy(_PtrAdd(lpLogFontDst, 20) /*offsetof(LOGFONTW, lfItalic)*/ , nItalic, 5 /*DT_BYTE*/ );
		}
		if (_TSTR == 0 /*DT_ANSI*/ && !pFaceName)
			pFaceName = AkelPad.MemRead(_PtrAdd(lpLogFontDst, 28) /*offsetof(LOGFONTW, lfFaceName)*/ , 1 /*DT_UNICODE*/ );
		if (pFaceName)
			AkelPad.MemCopy(_PtrAdd(lpLogFontDst, 28) /*offsetof(LOGFONTW, lfFaceName)*/ , pFaceName.substr(0, 32 /*LF_FACESIZE*/ ), _TSTR);

		hFont = oSys.Call("gdi32::CreateFontIndirect" + _TCHAR, lpLogFontDst);
		AkelPad.MemFree(lpLogFontDst);
	}
	return hFont;
}

function GetCursorPos(ptPoint) {
	var lpPoint;

	ptPoint.x = 0;
	ptPoint.y = 0;

	if (lpPoint = AkelPad.MemAlloc(8 /*sizeof(POINT)*/ )) {
		if (oSys.Call("user32::GetCursorPos", lpPoint)) {
			ptPoint.x = AkelPad.MemRead(_PtrAdd(lpPoint, 0) /*offsetof(POINT, x)*/ , 3 /*DT_DWORD*/ );
			ptPoint.y = AkelPad.MemRead(_PtrAdd(lpPoint, 4) /*offsetof(POINT, y)*/ , 3 /*DT_DWORD*/ );
		}
		AkelPad.MemFree(lpPoint);
	}
}

function RectToArray(lpRect, rcRect) {
	rcRect.left = AkelPad.MemRead(_PtrAdd(lpRect, 0) /*offsetof(RECT, left)*/ , 3 /*DT_DWORD*/ );
	rcRect.top = AkelPad.MemRead(_PtrAdd(lpRect, 4) /*offsetof(RECT, top)*/ , 3 /*DT_DWORD*/ );
	rcRect.right = AkelPad.MemRead(_PtrAdd(lpRect, 8) /*offsetof(RECT, right)*/ , 3 /*DT_DWORD*/ );
	rcRect.bottom = AkelPad.MemRead(_PtrAdd(lpRect, 12) /*offsetof(RECT, bottom)*/ , 3 /*DT_DWORD*/ );
	return rcRect;
}

function GetWindowSize(hWnd, hWndOwner, rcRect) {
	var lpRect;
	var bResult = false;

	if (lpRect = AkelPad.MemAlloc(16 /*sizeof(RECT)*/ )) {
		if (oSys.Call("user32::GetWindowRect", hWnd, lpRect)) {
			RectToArray(lpRect, rcRect);
			rcRect.right -= rcRect.left;
			rcRect.bottom -= rcRect.top;

			if (hWndOwner)
				bResult = oSys.Call("user32::ScreenToClient", hWndOwner, lpRect);
			else
				bResult = true;
			rcRect.left = AkelPad.MemRead(_PtrAdd(lpRect, 0) /*offsetof(RECT, left)*/ , 3 /*DT_DWORD*/ );
			rcRect.top = AkelPad.MemRead(_PtrAdd(lpRect, 4) /*offsetof(RECT, top)*/ , 3 /*DT_DWORD*/ );
		}
		AkelPad.MemFree(lpRect);
	}
	return bResult;
}

function LOWORD(dwNumber) {
	return (dwNumber & 0xffff);
}

function HIWORD(dwNumber) {
	return (dwNumber >> 16);
}

function MAKELONG(a, b) {
	return (a & 0xffff) | ((b & 0xffff) << 16);
}

function GetIcon(sFile, IndexIcon) {
	if (sFile == '')
		return 0
	var fso = new ActiveXObject("Scripting.FileSystemObject");
	if (!fso.FileExists(sFile))
		return 0
	var phIcon = AkelPad.MemAlloc(_X64 ? 8 : 4 /*sizeof(HWND)*/ ) // указатель на декскриптор иконки
	var lpFile = AkelPad.MemAlloc(260 * 2); // Выделяем память и получаем указатель
	AkelPad.MemCopy(lpFile, sFile, 0 /*DT_ANSI*/ ); // Копируем путь в указатель
	oSys.Call("Shell32::ExtractIconEx", lpFile, IndexIcon /* IndexIcon */ , 0, phIcon, 1); // Получает иконку из файла 16x16
	hIcon = AkelPad.MemRead(phIcon, 2 /*DT_QWORD*/ );
	AkelPad.MemFree(lpFile);
	AkelPad.MemFree(phIcon);
	return hIcon
}

function Del(lpFrameList) {
	var i;
	for (i = 0; i < lpFrameList.length; ++i) {
		if (lpFrameList[i][1])
			oSys.Call("User32::DestroyIcon", lpFrameList[i][1]);
	}
}

Search on the Internet, with the ability to specify the domain
Поиск выделенного в интернете, с возможностью указать домен
Image
Last edited by AZJIO on Tue Oct 06, 2020 11:43 am, edited 1 time in total.

DV
Offline
Posts: 1250
Joined: Thu Nov 16, 2006 11:53 am
Location: Kyiv, Ukraine

Post by DV »

Code: Select all

// CommandPalette.js
// Version: 0.5
// Language: English (1033)

[AkelPad]
4101 = "File: New\tCtrl+N"
4102 = "File: New Window\tCtrl+Shift+N"
4103 = "File: Open...\tCtrl+O"
4104 = "File: Reopen\tF5"
4105 = "File: Save\tCtrl+S | F2"
4106 = "File: Save As...\tCtrl+Shift+S"
4107 = "File: Print Setup..."
4108 = "File: Print...\tCtrl+P"
4109 = "File: Exit\tAlt+F4"
4110 = "File: Save All\tCtrl+Alt+F2"
4111 = "File: Save All As..."
4113 = "File: Print"
4114 = "File: Print Preview..."
4121 = "File: Redetect Code Page\tAlt+F5"
4122 = "File: Reopen As ANSI\tAlt+W"
4123 = "File: Reopen As OEM\tAlt+D"
4124 = "File: Reopen As KOI-R\tAlt+K"
4125 = "File: Reopen As UTF-16 LE\tAlt+L"
4126 = "File: Reopen As UTF-16 BE\tAlt+B"
4127 = "File: Reopen As UTF-8\tAlt+U"
4131 = "File: Save As ANSI\tShift+Alt+W"
4132 = "File: Save As OEM\tShift+Alt+D"
4133 = "File: Save As KOI-R\tShift+Alt+K"
4134 = "File: Save As UTF-16 LE\tShift+Alt+L"
4135 = "File: Save As UTF-16 BE\tShift+Alt+B"
4136 = "File: Save As UTF-8\tShift+Alt+U"
4137 = "File: Save As UTF-8 without BOM"
4140 = "Edit: Show codepages context menu...\tF12"
4151 = "Edit: Undo\tCtrl+Z"
4152 = "Edit: Redo\tCtrl+Shift+Z"
4153 = "Edit: Cut\tCtrl+X"
4154 = "Edit: Copy\tCtrl+C"
4155 = "Edit: Paste\tCtrl+V"
4156 = "Edit: Delete\tDel"
4157 = "Edit: Select all\tCtrl+A"
4158 = "Edit: Find...\tCtrl+F"
4159 = "Edit: Find Next (down)\tF3"
4160 = "Edit: Find Previous (up)\tShift+F3"
4161 = "Edit: Replace...\tCtrl+H | Ctrl+R"
4162 = "Edit: Go to...\tCtrl+G"
4163 = "Edit: Insert Character...\tCtrl+I"
4164 = "Edit: Tab Indent"
4165 = "Edit: Tab Indent if several lines selected"
4166 = "Edit: Tab Unindent if several lines selected else Tab Indent"
4167 = "Edit: Tab Unindent if several lines selected"
4168 = "Edit: Space Indent"
4169 = "Edit: Space Indent if several lines selected"
4170 = "Edit: Space Unindent if several lines selected else Space Indent"
4171 = "Edit: Space Unindent only if several lines selected"
4172 = "Edit: Delete first char"
4173 = "Edit: Delete first char only if selection not empty"
4174 = "Edit: Delete trailing whitespaces\tAlt+Backspace"
4175 = "Edit: Convert text to `UPPERCASE`\tCtrl+6"
4176 = "Edit: Convert text to `lowercase`\tCtrl+7"
4177 = "Edit: Convert text to `Sentence case`\tCtrl+8"
4178 = "Edit: Convert text to `Title Case`\tCtrl+9"
4179 = "Edit: Convert text to `iNVERT cASE`\tCtrl+0"
4180 = "Edit: Cycle case conversions\tCtrl+5"
4182 = "Edit: Recode...\tAlt+R"
4183 = "Edit: Insert Date\tCtrl+D"
4184 = "Edit: Windows newline format"
4185 = "Edit: Unix newline format"
4186 = "Edit: Mac newline format"
4190 = "Edit: Insert/Overtype mode"
4191 = "Edit: Paste as ANSI text\tCtrl+Shift+V"
4192 = "Edit: Paste to column selection\tAlt+V"
4193 = "Edit: Paste text after caret"
4194 = "Edit: Paste text according to the selection case"
4195 = "Edit: Delete all whitespaces in selection"
4196 = "Edit: Insert new line with indent (`Keep left spaces` is off)"
4197 = "Edit: Delete current line\tCtrl+Y"
4198 = "Edit: Move caret to opposite end of selection\tAlt+\"
4199 = "Edit: Move caret to prev. location (navigate backward)\tAlt+,"
4200 = "Edit: Move caret to next location (navigate forward)\tAlt+."
4201 = "View: Font..."
4202 = "View: Colors..."
4204 = "View: Increase Font 1pt\tCtrl+Num+"
4205 = "View: Decrease Font 1pt\tCtrl+Num-"
4206 = "View: Restore font to size at startup\tCtrl+Num*"
4209 = "View: Word Wrap (on/off)\tCtrl+U"
4210 = "View: Always on top (on/off)\tCtrl+T"
4211 = "View: Show Status Bar (on/off)"
4212 = "View: Split window into four panes"
4213 = "View: Split window into two vertical panes"
4214 = "View: Split window into two horizontal panes"
4215 = "View: Split window (on/off)"
4216 = "View: Read only (on/off)"
4251 = "Options: Execute a command...\tCtrl+F5"
4252 = "Options: Preserve file time (on/off)"
4253 = "Options: Watch file change (on/off)"
4254 = "Options: Keep left spaces (on/off)\tCtrl+L"
4255 = "Options: Single open file (on/off)"
4256 = "Options: Single open program (on/off)"
4259 = "Options: Plugins...\tAlt+P"
4260 = "Options: Settings..."
4261 = "Options: SDI window mode"
4262 = "Options: MDI window mode"
4263 = "Options: Pseudo MDI window mode"
4301 = "Options: Tab List is above the main window"
4302 = "Options: Tab List is below the main window"
4303 = "Options: Hide Tab List"
4304 = "Options: Standard Tab List style"
4305 = "Options: Buttons Tab List style"
4306 = "Options: Flat buttons Tab List style"
4307 = "Window: MDI windows - horizontal tile"
4308 = "Window: MDI windows - vertical tile"
4309 = "Window: MDI windows - cascade"
4310 = "Options: Switch tabs: next-previous"
4311 = "Options: Switch tabs: right-left"
4316 = "Window: Activate next tab\tCtrl+Tab"
4317 = "Window: Activate previous tab\tCtrl+Shift+Tab"
4318 = "Window: Close current tab\tCtrl+F4 | Ctrl+W"
4319 = "Window: Close all tabs"
4320 = "Window: Close all tabs but active"
4321 = "Window: Close all unmodified tabs"
4322 = "Window: Clone current tab"
4323 = "Window: Copy current tab file path"
4324 = "File: Close file"
4325 = "File: Close file and exit (SDI) or close current tab (MDI/PMDI)"
4327 = "Window: Select window...\tF10"
4331 = "Window: Restore/Maximize main window\tAlt+Enter"
4332 = "Window: Activate next dialog window\tF6"
4333 = "Window: Activate previous dialog window\tShift+F6"
4341 = "View: Activate next pane (split window)\tF9"
4342 = "View: Activate previous pane (split window)\tShift+F9"
4351 = "Help: About..."
4352 = "Help: Manual..."
4353 = "Help: Check Updates (AkelUpdater)..."
5001 = "File: Delete dead files from the `Recent files` list"

[Plugins]
"Clipboard::Capture" = "Clipboard: Capture..."
"Clipboard::Paste" = "Clipboard: Paste text"
"Clipboard::PasteSerial" = "Clipboard: Paste serial number"
"Clipboard::SelAutoCopy" = "Clipboard: Selection auto-copy on/off"
"Clipboard::Settings" = "Clipboard: Settings..."
"Coder::AutoComplete" = "Coder: Autocompletion on/off"
"Coder::CodeFold" = "Coder: Code folding on/off"
'"Coder::CodeFold", 1' = "Coder: List of folds on/off"
"Coder::HighLight" = "Coder: Syntax highlighting on/off"
"Coder::Settings" = "Coder: Settings..."
"ContextMenu::Main" = "ContextMenu: Configure..."
"ContextMenu::Show" = "ContextMenu: Show..."
"Exit::Main" = "Exit: Enable/Disable (exit by Esc)"
"Exit::Settings" = "Exit: Settings..."
"Explorer::Main" = "Explorer: Explorer panel on/off"
'"Explorer::Main", 1, ""' = "Explorer: Go to Current file"
"Fonts::Main" = "Fonts: Enable/Disable"
"Format::Decrypt" = "Format: Decrypt selection..."
"Format::Encrypt" = "Format: Encrypt selection..."
"Format::LineFixWrap" = "Format: Insert end-of-line character in wrap places"
"Format::LineGetDuplicates" = "Format: Extract duplicate lines"
"Format::LineGetUnique" = "Format: Extract unique lines"
"Format::LineRemoveDuplicates" = "Format: Remove duplicate lines"
"Format::LineReverse" = "Format: Reverse line order"
"Format::LineSortIntAsc" = "Format: Sort lines by integer ascending"
"Format::LineSortIntDesc" = "Format: Sort lines by integer descending"
"Format::LineSortStrAsc" = "Format: Sort lines by string ascending"
"Format::LineSortStrDesc" = "Format: Sort lines by string descending"
"Format::LinkExtract" = "Format: Extract links from HTML text"
"FullScreen::Main" = "FullScreen: Enable/Disable"
"HexSel::Main" = "HexSel: HexSel panel on/off"
"Hotkeys::Main" = "Hotkeys: Hotkeys..."
"LineBoard::Main" = "LineBoard: Enable/Disable"
"LineBoard::Settings" = "LineBoard: Settings..."
"Log::Output" = "Log: Output panel on/off"
"Log::Settings" = "Log: Settings..."
"Log::Watch" = "Log: Watch in real time on/off"
"Macros::Main" = "Macros: Macros..."
"MinimizeToTray::Always" = "MinimizeToTray: Always minimize to tray on/off"
"MinimizeToTray::Now" = "MinimizeToTray: Now"
"QSearch::DialogSwitcher" = "QSearch: Dialog switcher on/off"
"QSearch::QSearch" = "QSearch: QSearch panel\tF7"
"QSearch::SelFindNext" = "QSearch: Find (selected text) next"
"QSearch::SelFindPrev" = "QSearch: Find (selected text) previous"
"RecentFiles::DeleteNonExistent" = "RecentFiles: Delete non-existent"
"RecentFiles::Manage" = "RecentFiles: Manage..."
"RecentFiles::Show" = "RecentFiles: Show menu..."
"SaveFile::AutoSave" = "SaveFile: Autosaving on/off"
"SaveFile::SaveNoBOM" = "SaveFile: Save without BOM on/off"
"SaveFile::Settings" = "SaveFile: Settings..."
"Scripts::Main" = "Scripts: Scripts..."
"Scroll::AlignCaret" = "Scroll: Align caret on/off"
"Scroll::AutoFocus" = "Scroll: Autofocus on/off"
"Scroll::AutoScroll" = "Scroll: Autoscrolling on/off"
"Scroll::NoScroll" = "Scroll: No scroll operations on/off"
"Scroll::Settings" = "Scroll: Settings..."
"Scroll::SyncHorz" = "Scroll: Horizontal synchronization on/off"
"Scroll::SyncVert" = "Scroll: Vertical synchronization on/off"
"Sessions::Main" = "Sessions: Sessions..."
'"Sessions::Main", 10' = "Sessions: Enable/Disable"
"SmartSel::NoSelEOL" = "SmartSel: Exclude EOL from selection on/off"
"SmartSel::Settings" = "SmartSel: Settings..."
"SmartSel::SmartBackspace" = "SmartSel: Smart Backspace on/off"
"SmartSel::SmartEnd" = "SmartSel: Smart End on/off"
"SmartSel::SmartHome" = "SmartSel: Smart Home on/off"
"SmartSel::SmartUpDown" = "SmartSel: Smart Up/Down on/off"
"Sounds::Main" = "Sounds: Enable/Disable"
"Sounds::Settings" = "Sounds: Settings..."
"SpecialChar::Main" = "SpecialChar: Enable/Disable"
"SpecialChar::Settings" = "SpecialChar: Settings..."
"Speech::Main" = "Speech: Speech panel"
"SpellCheck::Background" = "SpellCheck: Background check"
"SpellCheck::CheckDocument" = "SpellCheck: Check document"
"SpellCheck::CheckSelection" = "SpellCheck: Check selection"
"SpellCheck::Settings" = "SpellCheck: Settings..."
"SpellCheck::Suggest" = "SpellCheck: Suggest word"
"Stats::Main" = "Stats: Stats..."
"Templates::Main" = "Templates: Enable/Disable"
"Templates::Open" = "Templates: Open..."
"ToolBar::Main" = "ToolBar: Enable/Disable"
"XBrackets::GoToMatchingBracket" = "XBrackets: Go to matching bracket"
"XBrackets::GoToNearestBracket" = "XBrackets: Go to nearest bracket"
"XBrackets::Main" = "XBrackets: Enable/Disable"
"XBrackets::SelToMatchingBracket" = "XBrackets: Select to matching bracket"
"XBrackets::SelToNearestBrackets" = "XBrackets: Select to nearest brackets"
"XBrackets::Settings" = "XBrackets: Settings..."
// CodeFold operations...
"Coder::CodeFold::CurrentCollapse" = "Code Folding: Collapse/Expand the current level\tCtrl+="
"Coder::CodeFold::CurrentGoBegin" = "Code Folding: Go to the beginning of the current level\tCtrl+["
"Coder::CodeFold::CurrentGoEnd" = "Code Folding: Go to the end of the current level\tCtrl+]"
"Coder::CodeFold::CurrentSelect" = "Code Folding: Select the current level\tCtrl+\"
"Coder::CodeFold::AllCollapse" = "Code Folding: Collapse/Expand all levels\tCtrl+Alt+="
"Coder::CodeFold::AllNextLevel" = "Code Folding: Go to the next block\tCtrl+Alt+]"
"Coder::CodeFold::AllPrevLevel" = "Code Folding: Go to the previous block\tCtrl+Alt+["
"Coder::CodeFold::FindRootLevel" = "Code Folding: Find the root level"
// Syntax Themes...
'"Coder::Settings", 1, "1s"'   = "Syntax Theme: 1с"
'"Coder::Settings", 1, "asm"'  = "Syntax Theme: Assembler"
'"Coder::Settings", 1, "au3"'  = "Syntax Theme: AutoIt"
'"Coder::Settings", 1, "awk"'  = "Syntax Theme: Awk"
'"Coder::Settings", 1, "bat"'  = "Syntax Theme: Bat"
'"Coder::Settings", 1, "cpp"'  = "Syntax Theme: C++ (cpp)"
'"Coder::Settings", 1, "cs"'   = "Syntax Theme: C# (cs)"
'"Coder::Settings", 1, "css"'  = "Syntax Theme: CSS"
'"Coder::Settings", 1, "html"' = "Syntax Theme: HTML"
'"Coder::Settings", 1, "ini"'  = "Syntax Theme: Ini"
'"Coder::Settings", 1, "iss"'  = "Syntax Theme: Inno (iss)"
'"Coder::Settings", 1, "js"'   = "Syntax Theme: JScript"
'"Coder::Settings", 1, "lua"'  = "Syntax Theme: Lua"
'"Coder::Settings", 1, "nsi"'  = "Syntax Theme: NSIS"
'"Coder::Settings", 1, "dpr"'  = "Syntax Theme: Pascal"
'"Coder::Settings", 1, "pl"'   = "Syntax Theme: Perl"
'"Coder::Settings", 1, "php"'  = "Syntax Theme: PHP"
'"Coder::Settings", 1, "ps1"'  = "Syntax Theme: PowerShell (ps1)"
'"Coder::Settings", 1, "py"'   = "Syntax Theme: Python"
'"Coder::Settings", 1, "rc"'   = "Syntax Theme: Resource (rc)"
'"Coder::Settings", 1, "sh"'   = "Syntax Theme: Shell (sh)"
'"Coder::Settings", 1, "sql"'  = "Syntax Theme: SQL"
'"Coder::Settings", 1, "vbs"'  = "Syntax Theme: VBScript"
'"Coder::Settings", 1, "xml"'  = "Syntax Theme: XML"
'"Coder::Settings", 1, "?"'    = "Syntax Theme: none"
// Color Themes...
'"Coder::Settings", 5, "Default"'         = "Color Theme: Default"
'"Coder::Settings", 5, "Active4D"'        = "Color Theme: Active4D"
'"Coder::Settings", 5, "Bespin"'          = "Color Theme: Bespin"
'"Coder::Settings", 5, "Cobalt"'          = "Color Theme: Cobalt"
'"Coder::Settings", 5, "Dawn"'            = "Color Theme: Dawn"
'"Coder::Settings", 5, "Earth"'           = "Color Theme: Earth"
'"Coder::Settings", 5, "iPlastic"'        = "Color Theme: iPlastic"
'"Coder::Settings", 5, "Lazy"'            = "Color Theme: Lazy"
'"Coder::Settings", 5, "Mac Classic"'     = "Color Theme: Mac Classic"
'"Coder::Settings", 5, "Monokai"'         = "Color Theme: Monokai"
'"Coder::Settings", 5, "Obsidian"'        = "Color Theme: Obsidian"
'"Coder::Settings", 5, "Solarized Light"' = "Color Theme: Solarized Light"
'"Coder::Settings", 5, "Solarized Dark"'  = "Color Theme: Solarized Dark"
'"Coder::Settings", 5, "SpaceCadet"'      = "Color Theme: SpaceCadet"
'"Coder::Settings", 5, "Sunburst"'        = "Color Theme: Sunburst"
'"Coder::Settings", 5, "Twilight"'        = "Color Theme: Twilight"
'"Coder::Settings", 5, "Zenburn"'         = "Color Theme: Zenburn"
// Mark...
'"Coder::HighLight", 2, 0, "#9BFFFF", 1, 0, 11' = "Mark: Cyan"
'"Coder::HighLight", 2, 0, "#FFCD9B", 1, 0, 12' = "Mark: Orange"
'"Coder::HighLight", 2, 0, "#FFFF9B", 1, 0, 13' = "Mark: Yellow"
'"Coder::HighLight", 2, 0, "#BE7DFF", 1, 0, 14' = "Mark: Violet"
'"Coder::HighLight", 2, 0, "#88E188", 1, 0, 15' = "Mark: Green"
'"Coder::HighLight", 3, 0'                      = "Mark: Remove all marks"
// Special Characters...
'"SpecialChar::Settings", 1, "8", "0", "0", -1, -1'               = "SpecialChar: Show Indent line (vertical)"
'"SpecialChar::Settings", 1, "1,2,3,9,7,4,5,6", "0", "0", -3, -3' = "SpecialChar: Show All symbols"
'"SpecialChar::Settings", 1, "1,2", "0", "0", -3, -3'             = "SpecialChar: Show Space and Tabulation"
'"SpecialChar::Settings", 1, "3,9", "0", "0", -3, -3'             = "SpecialChar: Show New line and End of file"
'"SpecialChar::Settings", 1, "7", "0", "0", -1, -1'               = "SpecialChar: Show Wrap line"
'"SpecialChar::Settings", 1, "4,5,6", "0", "0", -3, -3'           = "SpecialChar: Show VertTab, Form-feed, Null"
// Lineboard...
'"LineBoard::Main", 3, -1' = "LineBoard: Ruler on/off"
'"LineBoard::Main", 17'    = "Bookmarks: Show all bookmarks...\tAlt+Home"
'"LineBoard::Main", 18'    = "Bookmarks: Go to next bookmark\tAlt+PgDn"
'"LineBoard::Main", 19'    = "Bookmarks: Go to previous bookmark\tAlt+PgUp"
'"LineBoard::Main", 15'    = "Bookmarks: Set bookmark\tAlt+Insert"
'"LineBoard::Main", 16'    = "Bookmarks: Delete bookmark\tAlt+Delete"
'"LineBoard::Main", 14'    = "Bookmarks: Delete all bookmarks\tShift+Alt+Delete"

[Scripts]
"" = "Scripts: Run the last called script"
"Calculator.js" = "Scripts: Text calculator"
"ColumnCounter.js" = "Scripts: Column selection counter"
"InsertDate.js" = "Scripts: Insert date"
"InsertFile.js" = "Scripts: Insert file..."
'"Keyboard.js", `-Type=Layout -Direction=En->Ru`'   = "Scripts: Convert keyboard layout En->Ru"
'"Keyboard.js", `-Type=Layout -Direction=Ru->En`'   = "Scripts: Convert keyboard layout Ru->En"
'"Keyboard.js", `-Type=Translit -Direction=En->Ru`' = "Scripts: Transliteration Latin->Cyrillic"
'"Keyboard.js", `-Type=Translit -Direction=Ru->En`' = "Scripts: Transliteration Cyrillic->Latin"
"LinesFilter.js" = "Scripts: Filter lines with regular expressions..."
"RenameFile.js" = "Scripts: Rename current file..."
"SearchReplace.js" = "Scripts: Search/Replace with regular expressions...\tCtrl+Shift+F"
"SpellCheck.js" = "Scripts: Spell check"
"TabSwitch.js" = "Scripts: Tab Switch\tCtrl+Tab"

[Exec]
'explorer /e,/select, "%f"' = "Open in Explorer"



Code: Select all

// CommandPalette.js
// Version: 0.5
// Language: Russian (1049)

[AkelPad]
4101 = "Файл: Новый\tCtrl+N"
4102 = "Файл: Новое окно\tCtrl+Shift+N"
4103 = "Файл: Открыть...\tCtrl+O"
4104 = "Файл: Переоткрыть\tF5"
4105 = "Файл: Сохранить\tCtrl+S | F2"
4106 = "Файл: Сохранить как...\tCtrl+Shift+S"
4107 = "Файл: Параметры страницы..."
4108 = "Файл: Печать...\tCtrl+P"
4109 = "Файл: Выход\tAlt+F4"
4110 = "Файл: Сохранить все\tCtrl+Alt+F2"
4111 = "Файл: Сохранить все как..."
4113 = "Файл: Печать"
4114 = "Файл: Предпросмотр..."
4121 = "Файл: Определить кодировку заново\tAlt+F5"
4122 = "Файл: Открыть как ANSI\tAlt+W"
4123 = "Файл: Открыть как OEM\tAlt+D"
4124 = "Файл: Открыть как KOI-R\tAlt+K"
4125 = "Файл: Открыть как UTF-16 LE\tAlt+L"
4126 = "Файл: Открыть как UTF-16 BE\tAlt+B"
4127 = "Файл: Открыть как UTF-8\tAlt+U"
4131 = "Файл: Сохранить как ANSI\tShift+Alt+W"
4132 = "Файл: Сохранить как OEM\tShift+Alt+D"
4133 = "Файл: Сохранить как KOI-R\tShift+Alt+K"
4134 = "Файл: Сохранить как UTF-16 LE\tShift+Alt+L"
4135 = "Файл: Сохранить как UTF-16 BE\tShift+Alt+B"
4136 = "Файл: Сохранить как UTF-8\tShift+Alt+U"
4137 = "Файл: Сохранить как UTF-8 без BOM"
4140 = "Правка: Конт. меню преобр. кодировок\tF12"
4151 = "Правка: Отменить\tCtrl+Z"
4152 = "Правка: Вернуть отменённое\tCtrl+Shift+Z"
4153 = "Правка: Вырезать\tCtrl+X"
4154 = "Правка: Копировать\tCtrl+C"
4155 = "Правка: Вставить\tCtrl+V"
4156 = "Правка: Удалить\tDel"
4157 = "Правка: Выделить всё\tCtrl+A"
4158 = "Правка: Найти...\tCtrl+F"
4159 = "Правка: Найти следующее\tF3"
4160 = "Правка: Найти предыдущее\tShift+F3"
4161 = "Правка: Заменить...\tCtrl+H | Ctrl+R"
4162 = "Правка: Перейти к...\tCtrl+G"
4163 = "Правка: Запуск 'Таблица символов'\tCtrl+I"
4164 = "Правка: Отступ табуляцией"
4165 = "Правка: Отступ табуляцией, если несколько строк"
4166 = "Правка: Удал. табуляцию, если неск. строк, либо Отступ табуляцией"
4167 = "Правка: Удалить табуляцию, если несколько строк"
4168 = "Правка: Отступ пробелом"
4169 = "Правка: Отступ пробелом, если несколько строк"
4170 = "Правка: Удал. пробел, если неск. строк, либо Отступ пробелом"
4171 = "Правка: Удалить пробел, только если несколько строк"
4172 = "Правка: Удалить первый символ"
4173 = "Правка: Удалить первый символ, если есть выделенный текст"
4174 = "Правка: Удалить пробелы и табы в конце строк\tAlt+Backspace"
4175 = "Правка: В ВЕРХНИЙ РЕГИСТР\tCtrl+6"
4176 = "Правка: в нижний регистр\tCtrl+7"
4177 = "Правка: С заглавной буквы (регистр)\tCtrl+8"
4178 = "Правка: Каждое Слово С Заглавной (регистр)\tCtrl+9"
4179 = "Правка: иНВЕРТИРОВАТЬ рЕГИСТР\tCtrl+0"
4180 = "Правка: Преобразовать регистр по кругу (5 видов)\tCtrl+5"
4182 = "Правка: Перекодировать...\tAlt+R"
4183 = "Правка: Вставить дату\tCtrl+D"
4184 = "Правка: Формат новой строки DOS/Windows (0Dh, 0Ah)"
4185 = "Правка: Формат новой строки Unix (0Ah)"
4186 = "Правка: Формат новой строки Mac (0Dh)"
4190 = "Правка: Режим вставки/замены символов"
4191 = "Правка: Вставить как ANSI текст\tCtrl+Shift+V"
4192 = "Правка: Вставить в вертикал. выделение\tAlt+V"
4193 = "Правка: Вставить текст после каретки"
4194 = "Правка: Вставить текст с учётом регистра выделения"
4195 = "Правка: Удалить все пробелы в выделении"
4196 = "Правка: Встав. нов. строку с отступом (`Сохр. отступы слева` выкл)"
4197 = "Правка: Удалить текущую строку\tCtrl+Y"
4198 = "Правка: Переместить курсор в противополож. конец выделения\tAlt+\"
4199 = "Правка: Переместить курсор на предыдущую позицию\tAlt+,"
4200 = "Правка: Переместить курсор на следующую позицию\tAlt+."
4201 = "Вид: Шрифт..."
4202 = "Вид: Цвет..."
4204 = "Вид: Увеличить шрифт 1pt\tCtrl+Num+"
4205 = "Вид: Уменьшить шрифт 1pt\tCtrl+Num-"
4206 = "Вид: Восстановить размер шрифта при запуске\tCtrl+Num*"
4209 = "Вид: Перенос по словам\tCtrl+U"
4210 = "Вид: Поверх всех окон\tCtrl+T"
4211 = "Вид: Строка состояния"
4212 = "Вид: Разделить окно на 4 части"
4213 = "Вид: Разделить окно вертикально"
4214 = "Вид: Разделить окно горизонтально"
4215 = "Вид: Разделить окно (вкл/выкл)"
4216 = "Вид: Только чтение (блокир. в редакторе)"
4251 = "Настройки: Выполнить...\tCtrl+F5"
4252 = "Настройки: Сохранять время файла"
4253 = "Настройки: Следить за изменением файла"
4254 = "Настройки: Сохранять отступы слева\tCtrl+L"
4255 = "Настройки: Не открывать файл дважды"
4256 = "Настройки: Не открывать программу дважды"
4259 = "Настройки: Плагины...\tAlt+P"
4260 = "Настройки: Параметры..."
4261 = "Настройки: Однооконный режим (SDI)"
4262 = "Настройки: Многооконный режим (MDI)"
4263 = "Настройки: Псевдо-многооконный режим (PMDI)"
4301 = "Настройки: Вкладки сверху"
4302 = "Настройки: Вкладки снизу"
4303 = "Настройки: Скрыть вкладки"
4304 = "Настройки: Стандартные вкладки"
4305 = "Настройки: Вкладки как кнопки"
4306 = "Настройки: Вкладки как плоские кнопки"
4307 = "Окно: Выстроить окна горизонтально"
4308 = "Окно: Выстроить окна вертикально"
4309 = "Окно: Выстроить окна каскадом"
4310 = "Настройки: Переключать вкладки следующая-предыдущая"
4311 = "Настройки: Переключать вкладки правая-левая"
4316 = "Окно: Активировать следующую вкладку\tCtrl+Tab"
4317 = "Окно: Активировать предыдущую вкладку\tCtrl+Shift+Tab"
4318 = "Окно: Закрыть вкладку\tCtrl+F4 | Ctrl+W"
4319 = "Окно: Закрыть все вкладки"
4320 = "Окно: Закрыть все вкладки, кроме текущей"
4321 = "Окно: Закрыть все неизмененные вкладки"
4322 = "Окно: Клонировать вкладку"
4323 = "Окно: Копировать путь файла"
4324 = "Файл: Закрыть файл"
4325 = "Файл: Закрыть файл и выйти (SDI) или закрыть вкладку (MDI/PMDI)"
4327 = "Окно: Выбрать окно...\tF10"
4331 = "Окно: Восстановить/развернуть главное окно\tAlt+Enter"
4332 = "Окно: Перейти к следующему диалоговому окну\tF6"
4333 = "Окно: Перейти к предыдущему диалоговому окну\tShift+F6"
4341 = "Вид: Перейти к следующей части разделенного окна\tF9"
4342 = "Вид: Перейти к предыдущей части разделенного окна\tShift+F9"
4351 = "Справка: О программе..."
4352 = "Справка: Руководство ..."
4353 = "Справка: Обновление..."
5001 = "Файл: Удалить несуществующие из списка последних файлов"

[Plugins]
"Clipboard::Capture" = "Буфер обмена: Захват..."
"Clipboard::Paste" = "Буфер обмена: Вставить текст"
"Clipboard::PasteSerial" = "Буфер обмена: Вставка серийного номера"
"Clipboard::SelAutoCopy" = "Буфер обмена: Автоматически копировать выделенный текст вкл/выкл"
"Clipboard::Settings" = "Буфер обмена: Настройки..."
"Coder::AutoComplete" = "Программирование: Автодополнение вкл/выкл"
"Coder::CodeFold" = "Программирование: Сворачивание блоков вкл/выкл"
'"Coder::CodeFold", 1' = "Программирование: Список сворачиваемых блоков вкл/выкл"
"Coder::HighLight" = "Программирование: Подсветка синтаксиса вкл/выкл"
"Coder::Settings" = "Программирование: Настройки..."
"ContextMenu::Main" = "Контекстное меню: Настроить..."
"ContextMenu::Show" = "Контекстное меню: Показать..."
"Exit::Main" = "Клавиша Escape: Вкл/Выкл (выход по Esc)"
"Exit::Settings" = "Клавиша Escape: Настройки..."
"Explorer::Main" = "Панель проводника: Вкл/Выкл"
'"Explorer::Main", 1, ""' = "Панель проводника: Перейти к текущему файлу"
"Fonts::Main" = "Шрифты: Вкл/Выкл"
"Format::Decrypt" = "Преобразовать: Расшифровать выделение..."
"Format::Encrypt" = "Преобразовать: Зашифровать выделение..."
"Format::LineFixWrap" = "Преобразовать: Вставить разрыв строки в местах переноса"
"Format::LineGetDuplicates" = "Преобразовать: Получить дублирующиеся строки"
"Format::LineGetUnique" = "Преобразовать: Получить уникальные строки"
"Format::LineRemoveDuplicates" = "Преобразовать: Удалить дублирующиеся строки"
"Format::LineReverse" = "Преобразовать: Инвертировать порядок строк"
"Format::LineSortIntAsc" = "Преобразовать: Сортировать строки по числовому возрастанию"
"Format::LineSortIntDesc" = "Преобразовать: Сортировать строки по числовому убыванию"
"Format::LineSortStrAsc" = "Преобразовать: Сортировать строки по возрастанию"
"Format::LineSortStrDesc" = "Преобразовать: Сортировать строки по убыванию"
"Format::LinkExtract" = "Преобразовать: Извлечь ссылки из HTML текста"
"FullScreen::Main" = "Полноэкранный режим: Вкл/Выкл"
"HexSel::Main" = "Hex-код: Панель Hex-кода вкл/выкл"
"Hotkeys::Main" = "Горячие клавиши: Горячие клавиши..."
"LineBoard::Main" = "Номера строк и закладки: Вкл/Выкл"
"LineBoard::Settings" = "Номера строк и закладки: Настройки..."
"Log::Output" = "Просмотр лога: Панель вывода вкл/выкл"
"Log::Settings" = "Просмотр лога: Настройки..."
"Log::Watch" = "Просмотр лога: В реальном времени вкл/выкл"
"Macros::Main" = "Макросы: Макросы..."
"MinimizeToTray::Always" = "Свернуть в трей: Сворачивать в трей всегда вкл/выкл"
"MinimizeToTray::Now" = "Свернуть в трей: Свернуть в трей"
"QSearch::DialogSwitcher" = "Панель поиска: Быстрое переключение диалогов вкл/выкл"
"QSearch::QSearch" = "Панель поиска: Вкл/Выкл\tF7"
"QSearch::SelFindNext" = "Панель поиска: Найти (выделенный текст) вперёд"
"QSearch::SelFindPrev" = "Панель поиска: Найти (выделенный текст) назад"
"RecentFiles::DeleteNonExistent" = "Последние файлы: Удалить несуществующие"
"RecentFiles::Manage" = "Последние файлы: Управлять..."
"RecentFiles::Show" = "Последние файлы: Показать меню..."
"SaveFile::AutoSave" = "Сохранение файла: Автосохранение вкл/выкл"
"SaveFile::SaveNoBOM" = "Сохранение файла: Сохранять без BOM вкл/выкл"
"SaveFile::Settings" = "Сохранение файла: Настройки..."
"Scripts::Main" = "Скрипты: Скрипты..."
"Scroll::AlignCaret" = "Прокрутка: Выравнивание каретки вкл/выкл"
"Scroll::AutoFocus" = "Прокрутка: Автоматическая передача фокуса вкл/выкл"
"Scroll::AutoScroll" = "Прокрутка: Автоматическая прокрутка текста вкл/выкл"
"Scroll::NoScroll" = "Прокрутка: Обработка непрокручиваемых операций вкл/выкл"
"Scroll::Settings" = "Прокрутка: Настройки..."
"Scroll::SyncHorz" = "Прокрутка: Горизонтальная синхронизация вкл/выкл"
"Scroll::SyncVert" = "Прокрутка: Вертикальная синхронизация вкл/выкл"
"Sessions::Main" = "Сессии: Сессии..."
'"Sessions::Main", 10' = "Сессии: Вкл/Выкл"
"SmartSel::NoSelEOL" = "Умная навигация: Исключить EOL из выделения вкл/выкл"
"SmartSel::Settings" = "Умная навигация: Настройки..."
"SmartSel::SmartBackspace" = "Умная навигация: Умная клавиша Backspace вкл/выкл"
"SmartSel::SmartEnd" = "Умная навигация: Умная клавиша End вкл/выкл"
"SmartSel::SmartHome" = "Умная навигация: Умная клавиша Home вкл/выкл"
"SmartSel::SmartUpDown" = "Умная навигация: Умные клавиши Up/Down вкл/выкл"
"Sounds::Main" = "Звуковой набор текста: Вкл/Выкл"
"Sounds::Settings" = "Звуковой набор текста: Настройки..."
"SpecialChar::Main" = "Специальные символы: Вкл/Выкл"
"SpecialChar::Settings" = "Специальные символы: Настройки..."
"Speech::Main" = "Машинное чтение текста: Панель чтения"
"SpellCheck::Background" = "Проверка орфографии: Фоновая проверка"
"SpellCheck::CheckDocument" = "Проверка орфографии: Проверить документ"
"SpellCheck::CheckSelection" = "Проверка орфографии: Проверить выделение"
"SpellCheck::Settings" = "Проверка орфографии: Настройки..."
"SpellCheck::Suggest" = "Проверка орфографии: Проверить слово"
"Stats::Main" = "Статистика: Статистика..."
"Templates::Main" = "Шаблоны: Вкл/Выкл"
"Templates::Open" = "Шаблоны: Открыть..."
"ToolBar::Main" = "Панель инструментов: Вкл/Выкл"
"XBrackets::GoToMatchingBracket" = "Парные скобки: Перейти к парной скобке"
"XBrackets::GoToNearestBracket" = "Парные скобки: Перейти к ближайшей скобке"
"XBrackets::Main" = "Парные скобки: Вкл/Выкл"
"XBrackets::SelToMatchingBracket" = "Парные скобки: Выделить до парной скобки"
"XBrackets::SelToNearestBrackets" = "Парные скобки: Выделить до ближайших скобок"
"XBrackets::Settings" = "Парные скобки: Настройки..."
// CodeFold operations...
"Coder::CodeFold::CurrentCollapse" = "Сворачивание кода: Свернуть/Развернуть текущий уровень\tCtrl+="
"Coder::CodeFold::CurrentGoBegin" = "Сворачивание кода: Перейти к началу текущего уровня\tCtrl+["
"Coder::CodeFold::CurrentGoEnd" = "Сворачивание кода: Перейти к концу текущего уровня\tCtrl+]"
"Coder::CodeFold::CurrentSelect" = "Сворачивание кода: Выделить текущий уровень\tCtrl+\"
"Coder::CodeFold::AllCollapse" = "Сворачивание кода: Свернуть/Развернуть все уровни\tCtrl+Alt+="
"Coder::CodeFold::AllNextLevel" = "Сворачивание кода: Перейти к следующему блоку\tCtrl+Alt+]"
"Coder::CodeFold::AllPrevLevel" = "Сворачивание кода: Перейти к предыдущему блоку\tCtrl+Alt+["
"Coder::CodeFold::FindRootLevel" = "Сворачивание кода: Найти корень"
// Syntax Themes...
'"Coder::Settings", 1, "1s"'   = "Синтаксическая тема: 1с"
'"Coder::Settings", 1, "asm"'  = "Синтаксическая тема: Assembler"
'"Coder::Settings", 1, "au3"'  = "Синтаксическая тема: AutoIt"
'"Coder::Settings", 1, "awk"'  = "Синтаксическая тема: Awk"
'"Coder::Settings", 1, "bat"'  = "Синтаксическая тема: Bat"
'"Coder::Settings", 1, "cpp"'  = "Синтаксическая тема: C++ (cpp)"
'"Coder::Settings", 1, "cs"'   = "Синтаксическая тема: C# (cs)"
'"Coder::Settings", 1, "css"'  = "Синтаксическая тема: CSS"
'"Coder::Settings", 1, "html"' = "Синтаксическая тема: HTML"
'"Coder::Settings", 1, "ini"'  = "Синтаксическая тема: Ini"
'"Coder::Settings", 1, "iss"'  = "Синтаксическая тема: Inno (iss)"
'"Coder::Settings", 1, "js"'   = "Синтаксическая тема: JScript"
'"Coder::Settings", 1, "lua"'  = "Синтаксическая тема: Lua"
'"Coder::Settings", 1, "nsi"'  = "Синтаксическая тема: NSIS"
'"Coder::Settings", 1, "dpr"'  = "Синтаксическая тема: Pascal"
'"Coder::Settings", 1, "pl"'   = "Синтаксическая тема: Perl"
'"Coder::Settings", 1, "php"'  = "Синтаксическая тема: PHP"
'"Coder::Settings", 1, "py"'   = "Синтаксическая тема: Python"
'"Coder::Settings", 1, "rc"'   = "Синтаксическая тема: Resource (rc)"
'"Coder::Settings", 1, "sql"'  = "Синтаксическая тема: SQL"
'"Coder::Settings", 1, "vbs"'  = "Синтаксическая тема: VBScript"
'"Coder::Settings", 1, "xml"'  = "Синтаксическая тема: XML"
'"Coder::Settings", 1, "?"'    = "Синтаксическая тема: Без темы"
// Color Themes...
'"Coder::Settings", 5, "Default"'         = "Цветовая тема: Default"
'"Coder::Settings", 5, "Active4D"'        = "Цветовая тема: Active4D"
'"Coder::Settings", 5, "Bespin"'          = "Цветовая тема: Bespin"
'"Coder::Settings", 5, "Cobalt"'          = "Цветовая тема: Cobalt"
'"Coder::Settings", 5, "Dawn"'            = "Цветовая тема: Dawn"
'"Coder::Settings", 5, "Earth"'           = "Цветовая тема: Earth"
'"Coder::Settings", 5, "iPlastic"'        = "Цветовая тема: iPlastic"
'"Coder::Settings", 5, "Lazy"'            = "Цветовая тема: Lazy"
'"Coder::Settings", 5, "Mac Classic"'     = "Цветовая тема: Mac Classic"
'"Coder::Settings", 5, "Monokai"'         = "Цветовая тема: Monokai"
'"Coder::Settings", 5, "Obsidian"'        = "Цветовая тема: Obsidian"
'"Coder::Settings", 5, "Solarized Light"' = "Цветовая тема: Solarized Light"
'"Coder::Settings", 5, "Solarized Dark"'  = "Цветовая тема: Solarized Dark"
'"Coder::Settings", 5, "SpaceCadet"'      = "Цветовая тема: SpaceCadet"
'"Coder::Settings", 5, "Sunburst"'        = "Цветовая тема: Sunburst"
'"Coder::Settings", 5, "Twilight"'        = "Цветовая тема: Twilight"
'"Coder::Settings", 5, "Zenburn"'         = "Цветовая тема: Zenburn"
// Mark...
'"Coder::HighLight", 2, 0, "#9BFFFF", 1, 0, 11' = "Отметить: Бирюзовым"
'"Coder::HighLight", 2, 0, "#FFCD9B", 1, 0, 12' = "Отметить: Оранжевым"
'"Coder::HighLight", 2, 0, "#FFFF9B", 1, 0, 13' = "Отметить: Желтым"
'"Coder::HighLight", 2, 0, "#BE7DFF", 1, 0, 14' = "Отметить: Фиолетовым"
'"Coder::HighLight", 2, 0, "#88E188", 1, 0, 15' = "Отметить: Зеленым"
'"Coder::HighLight", 3, 0'                      = "Отметить: Убрать все отметки"
// Special Characters...
'"SpecialChar::Settings", 1, "8", "0", "0", -1, -1'               = "Специальные символы: Отображать Линию отступа (вертикально)"
'"SpecialChar::Settings", 1, "1,2,3,9,7,4,5,6", "0", "0", -3, -3' = "Специальные символы: Отображать Все символы"
'"SpecialChar::Settings", 1, "1,2", "0", "0", -3, -3'             = "Специальные символы: Отображать Пробел и Табуляцию"
'"SpecialChar::Settings", 1, "3,9", "0", "0", -3, -3'             = "Специальные символы: Отображать Новую строку и Конец файла"
'"SpecialChar::Settings", 1, "7", "0", "0", -1, -1'               = "Специальные символы: Отображать Перенос строки"
'"SpecialChar::Settings", 1, "4,5,6", "0", "0", -3, -3'           = "Специальные символы: Отображать ВертТаб, Прогон листа, Null"
// Lineboard...
'"LineBoard::Main", 3, -1' = "Номера строк и закладки: Линейка вкл/выкл"
'"LineBoard::Main", 17'    = "Закладки: Меню закладок...\tAlt+Home"
'"LineBoard::Main", 18'    = "Закладки: Перейти к следующей закладке\tAlt+PgDn"
'"LineBoard::Main", 19'    = "Закладки: Перейти к предыдущей закладке\tAlt+PgUp"
'"LineBoard::Main", 15'    = "Закладки: Установить закладку\tAlt+Insert"
'"LineBoard::Main", 16'    = "Закладки: Удалить закладку\tAlt+Delete"
'"LineBoard::Main", 14'    = "Закладки: Удалить все закладки\tShift+Alt+Delete"

[Scripts]
"" = "Скрипты: Запустить последний вызванный"
"Calculator.js" = "Скрипты: Текстовый калькулятор"
"ColumnCounter.js" = "Скрипты: Счетчик вертикального выделения"
"InsertDate.js" = "Скрипты: Вставить дату"
"InsertFile.js" = "Скрипты: Вставить файл..."
'"Keyboard.js", `-Type=Layout -Direction=En->Ru`'   = "Скрипты: Исправить клавиатурный набор En->Ru"
'"Keyboard.js", `-Type=Layout -Direction=Ru->En`'   = "Скрипты: Исправить клавиатурный набор Ru->En"
'"Keyboard.js", `-Type=Translit -Direction=En->Ru`' = "Скрипты: Транслитерация Latin->Cyrillic"
'"Keyboard.js", `-Type=Translit -Direction=Ru->En`' = "Скрипты: Транслитерация Cyrillic->Latin"
"LinesFilter.js" = "Скрипты: Фильтр строк с регулярными выражениями..."
"RenameFile.js" = "Скрипты: Переименовать текущий файл..."
"SearchReplace.js" = "Скрипты: Поиск/Замена с регулярными выражениями...\tCtrl+Shift+F"
"SpellCheck.js" = "Скрипты: Проверить орфографию"
"TabSwitch.js" = "Скрипты: Переключить вкладку\tCtrl+Tab"

[Exec]
'explorer /e,/select, "%f"' = "Открыть в Проводнике (Explorer)"
Last edited by DV on Thu Jul 02, 2020 9:07 pm, edited 1 time in total.

Offline
Posts: 6
Joined: Sat Jan 11, 2020 11:32 am

Sum up numbers in the selected text

Post by nut99 »

Sum up numbers in the selected text. Also works for numbers with thousand separators.

Code: Select all

// Description(1033): Sum up numbers in the selected text. 
// Version: 1.0 (2020.01.10) 
// Author: 
// 
// Usage: 
//    -"SumNumbersA" Call("Scripts::Main", 1, "SumNumbers.js") 

var str = AkelPad.GetSelText(); 
if (str) { 
   AkelPad.Call("Log::Output", 4, "", -1, 1); 
   var a = str.split("\n"); 
   var sum = 0; 
   for( var i = 0; i < a.length; i++ ) { 
      var b = a[i].replace(/[^0-9,.-]/g, " ").split(" "); 
      for( var j = 0; j < b.length; j++ ) { 
         var c = b[j].split("."); 
         if( c.length > 2 ) { 
            AkelPad.Call("Log::Output", 4, "Number format error!\n", -1, 1); 
            WScript.Quit(); 
         } 
         var d = c[0].split(","); 
         if( d.length > 1) { 
            if( d[0].length > 3) { 
               AkelPad.Call("Log::Output", 4, "Number format error!\n", -1, 1); 
               WScript.Quit(); 
            } 
            for( var k = 1; k < d.length; k++ ) { 
               if( d[k].length != 3) { 
                  AkelPad.Call("Log::Output", 4, "Number format error!\n", -1, 1); 
                  WScript.Quit(); 
               } 
            } 
         } 
         sum += Number(b[j].replace(/,/g, "")); 
      } 
   } 
   AkelPad.Call("Log::Output", 4, sum + "\n", -1, 1); 
}
Last edited by nut99 on Tue Jan 14, 2020 1:26 pm, edited 2 times in total.

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

Post by VladSh »


Offline
Posts: 6
Joined: Sat Jan 11, 2020 11:32 am

Post by nut99 »

VladSh wrote:nut99
SumNumbers.js.
Hi, VladSh. I made some modification based on your code. Thank you. :) Sorry for forgetting to use a new name for the script. I am a newbie in writing JS scripts.

Offline
Posts: 44
Joined: Wed May 01, 2019 10:10 am

Post by Олег »

Code: Select all

' InsertSymbols.vbs
' Вставка символов в каждую выделенную строку с выбором позиции вставки.
' Без параметров-пропускать строки, короче заданной длины.
' Параметры: "s"-дополнять пробелами короткую строку.
' -"Диалог вставки символов в каждую выделенную строку" Call("Scripts::Main", 1, "InsertSymbols.vbs", `"s"`)
' ==============================================
tTxt = AkelPad.GetSelText
If tTxt = "" Then MsgBox "Сначала выделите текст." : WScript.Quit
n = InputBox ("Введите номер символа, с которого начинается вставка:", "Вставка символов")
If IsNumeric(n) = False Then MsgBox "Допускается введение только целых чисел." : WScript.Quit
n = CInt(n)
T = InputBox("Введите вставляемые символы:", "Вставка символов")
Txt = Split(tTxt, chr(13))
TS = Ubound(Txt) - 1
For k = 0 To TS
  If Len(Txt(k)) + 2 > n Then
    Text = Text & Mid(Txt(k), 1, n - 1) & T & Mid(Txt(k), n)
    If k < (TS) Then Text = Text & vbNewLine
  Else
    If WScript.Arguments.Count > 0 Then
      If WScript.Arguments(0) = "s" Then
        S = Space(n - Len(Txt(k)) - 1)
        Text = Text & Txt(k) & S & T
        If k < (TS) Then Text = Text & vbNewLine
      End If
    Else
      Text = Text & Txt(k)
      If k < (TS) Then Text = Text & vbNewLine
    End If
  End If
Next
AkelPad.ReplaceSel(Text)


Написал простой скрипт вставки символов в заданную позицию от начала каждой выделенной строки

Offline
Posts: 330
Joined: Mon Jun 03, 2019 2:33 am

Post by AZJIO »

Create a new file or copy next to the current document.
Создать новый файл или копию рядом с текущим документом.

Code: Select all

// AZJIO 02.04.2020, обновлено 09.10.2020
//
// Description(1033): Create a new file or copy next to the current document.
// Description(1049): Создать новый файл или копию рядом с текущим документом.
//
// Arguments:
//   -Ask=false                          - Ask for file name | Спросить имя новому файлу. При создании нового предлагается заданное, а для копии имя оригинала. Во всех случаях добавляется номер несуществующей копии 
//   -Copy=false                          - Copy or New | Копировать или Новый
//          =false                          - Create a new file | Создать новый файл
//          =true                          - Copy current file | Копировать текущий файл
//
// Usage:
//   Call("Scripts::Main", 1, "CreateNewFileNext.js")
//   "Новый рядом" Call("Scripts::Main", 1, "CreateNewFileNext.js") Icon("%a\AkelFiles\icons\ToolbarEx.dll", 0)
//   "New near" ...
//   "Копия рядом" Call("Scripts::Main", 1, "CreateNewFileNext.js", `-Ask=true -Copy=true`) Icon("%a\AkelFiles\icons\ToolbarEx.dll", 0)
//   "Copy near" ...

var bAsk = AkelPad.GetArgValue("Ask", false);
var bCopy = AkelPad.GetArgValue("Copy", false);
var pName = AkelPad.GetArgValue("Name", "я_");
// bAsk = true
// bCopy = true;


var sNewName;
var FilePath;
var sEditFile = AkelPad.GetEditFile(0);
if (bCopy)
	sNewName = AkelPad.GetFilePath(sEditFile, 3) + '_'; // можно продублировать имя
else
	sNewName = pName; // sPrefix. "я" чтобы файл был в конце списка в проводнике
	// sNewName = 'я_'; // sPrefix. "я" чтобы файл был в конце списка в проводнике

var sFileFolder  = AkelPad.GetFilePath(sEditFile, 1);

if (sFileFolder == '') {
	// WScript.Echo('только для существующих файлов');
	// WScript.Echo('existing files only');
	WScript.Quit();
}

// Сообщение с полем ввода, чтобы задать новое имя вручную
if (bAsk)
{
	var hMainWnd = AkelPad.GetMainWnd(); 
	var pInput = AkelPad.InputBox(hMainWnd, "Имя файла", "Новое", sNewName);

	if (pInput == undefined)
		WScript.Quit();
	else
		sNewName = pInput;
}

var sFileExt = AkelPad.GetFilePath(sEditFile, 4 /*CPF_FILEEXT*/ );
var fso = new ActiveXObject("Scripting.FileSystemObject");

if (!fso.FolderExists(sFileFolder)) { // если каталог удалён, например файл из архива в %temp%
// if (!fso.FileExists(sEditFile)) { // если файл удалён, но в принципе создать файл в той же папке можно
	// WScript.Echo('папка не найдена');
	WScript.Echo('folder not found');
	WScript.Quit();
// 	if (AkelPad.SaveFile(hWndEdit, "C:\\MyFile.txt");) { // если документа нет то можно вызвать сохранение
// 		WScript.Echo('Сохранено успешно');
// 	}
}

// Проверка, что имя файла не существует
i = 0;
do {
    i += 1;
    FilePath = sFileFolder + '\\' + sNewName + i + '.' + sFileExt;
} while (fso.FileExists(FilePath))
if (bCopy)
	fso.CopyFile(sEditFile, FilePath, false); // можно копировать со старым содержимым
else
	fso.CreateTextFile(FilePath, false, true); // флаги UTF8, без перезаписи

if (fso.FileExists(FilePath)) {
	AkelPad.OpenFile(FilePath);
}

Полезно если вы пишете какой-то код au3, pb, js и нужно потестировать некоторые функции, или сохранить несколько заготовок для проекта, какие то участки кода, то есть нужно быстро в папке проекта создать файл.
Есть вариант клавишей "Insert" в плаге Explirer, но это медленней, прогрузка пути и файлов с построением дерева, активация окна, клавиша "Insert", и ввод имя файла с расширением. В моём же варианте если повесить на хоткей, то только вызов хоткея и файл уже открыт, единственное хотелось бы, чтобы вкладка появлялась рядом справа от исходного файла, а не в конце справа.
Обновил, при отсутствии папки скрипт не падает, а сообщает.
Обновил, есть аргументы запроса имени и копии вместо нового, это работает как бэкап файла.

Мне посоветовали добавить подобный скрипт BackUpCurrentFile.js в пост, как более продвинутый для бэкапа файла с индексом, много параметров, чтобы был выбор.
Last edited by AZJIO on Tue Oct 13, 2020 5:03 pm, edited 4 times in total.

Offline
Posts: 330
Joined: Mon Jun 03, 2019 2:33 am

Post by AZJIO »

Подсветить выделенный текст плавно регулируя цвет метки ползунками HSB. Ранее выкладывал тут. Обновил, ID генерируется новый, чтобы не затирать предыдущие метки.

Code: Select all

// AZJIO 07.10.19 - 28.03.20
// Description(1033): Highlight the selected text by adjusting the color of the mark
// Description(1049): Подсветить выделенный текст регулируя цвет метки
//
// GUI построен используя скрипт-пример CreateDialog.js от KDJ
// Требуется в папке include: CreateDialog_functions.js
/*
var sSelText = AkelPad.GetSelText()
if(sSelText == "") {
	WScript.Echo("Выделите текст");
	WScript.Quit();
}
*/


if (AkelPad.GetLangId(0 /*LANGID_FULL*/) == 0x0419) //Russian
{

  var sLng1 = "Нужно выделить текст!\nИспользовать регулярное выражения из буфера обмена?";
  var sLng2 = "Изменять фон (иначе текст)"
  var sLng3 = "Применить"
  var sLng4 = "Сброс"
  var sLng5 = "Тон"
  var sLng6 = "Насыщенность"
  var sLng7 = "Яркость"
  var sLng8 = "Регулировка цвета"
}
// else if (AkelPad.GetLangId(0 /*LANGID_FULL*/) == 0x0415) //Polish
// {
//   var sLng1       = "";
//   var sLng2  = "";
// }
else
{
  var sLng1 = "Need to select text!\nUse regular expressions from clipboard?";
  var sLng2 = "Change the background, otherwise the text"
  var sLng3 = "Apply"
  var sLng4 = "Reset"
  var sLng5 = "Tone"
  var sLng6 = "Saturation"
  var sLng7 = "Brightness"
  var sLng8 = "Color adjustment"
}




var sSelText = AkelPad.GetSelText()
if(sSelText == "") {
	var hMainWnd = AkelPad.GetMainWnd();
	// var nChoice = AkelPad.MessageBox(hMainWnd, "Нужно выделить текст!\nИспользовать регулярное выражения из буфера обмена?", "Сообщение", 32 /*MB_ICONQUESTION*/ , 0,
		// 1 /*IDOK*/ , "&Да", 0,
		// 2 /*IDCANCEL*/ , "&Отмена", 0x1 /*BMB_DEFAULT*/ );
	// if(nChoice == 1) {
	if(AkelPad.MessageBox(hMainWnd, sLng1, WScript.ScriptName, 4+256+32) == 6) {
		sSelText = AkelPad.GetClipboardText();
	}
	else {
		WScript.Quit();
	}
}

var oSys = AkelPad.SystemFunction();
var sClass = "AkelPad::Scripts::" + WScript.ScriptName + "::" + AkelPad.GetInstanceDll(); // придумываем имя класса окна
var hDlg = oSys.Call("User32::FindWindowW", sClass, 0); // Ищем это окно, FindWindowW возвращает дескриптор
var sAkelDir = AkelPad.GetAkelDir();

var arr_hsb = [0, 100, 100]; // создаёт и задаёт начальную позицию
var arr_rgb = [0, 0, 0];
var bChecSt = 1;
var sBgColor = "ff0000";
var sFgColor = "ddff00";
// var ID_Color = 1;
var ID_Color = GetNewMarkID(100);
// var kk1 = 0;
// var kk2 = 0;

// AkelPad.Call("Coder::HighLight", 3, -2);

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); // делаем окно активным
}
else if(AkelPad.Include("CreateDialog_functions.js")) // иначе (если окно не найдено) если существует необходимый скрипт, то
{
	var hIcon = oSys.Call("User32::LoadImageW", AkelPad.GetInstanceDll(), 101, 1 /*uType=IMAGE_ICON*/ , 0, 0, 0x40 /*LR_DEFAULTSIZE*/ ); // загружает иконку, возвращая дескриптор
	// var hImage = 0;
	// var hWndOutput = GetOutputWindow(); // получить дескриптор окна консоли
	var hDC;
	var MemDC;
	var MemBM;
	var hOldBMP;
	var fMemDC = 1;
	// Константы ID элементов управления окна
	// var ID_GROUPE = 2001; // линия группирования элементов
	var ID_CHECKB = 2002; // идентификатор чекбокса
	var ID_INP = 2003; // поле ввода
	var ID_BTN_OK = 2004; // кнопка ОК
	var ID_CANCEL = 2005; // кнопка отмена
	var ID_LBID = 2006; // Надпись над полем ввода
	var ID_TB1 = 2007;
	var ID_TB2 = 2008;
	var ID_TB3 = 2009;
	var ID_LBTB1 = 2010;
	var ID_LBTB2 = 2011;
	var ID_LBTB3 = 2012;
	var ID_LBTB4 = 2013;
	var ID_LBTB5 = 2014;
	var ID_LBTB6 = 2015;
	var ID_INPID = 2016;
	// var ID_LBColor = 2017;
	// var ID_SPEKTR = 2018;

	if(AkelPad.WindowRegisterClass(sClass)) // если класс зарегистрирован
	{
		// Разрешить запуск других скриптов
		AkelPad.ScriptNoMutex();

		CreateDialog(false, false, AkelPad.GetMainWnd()); // Функция создания окна
		AkelPad.WindowUnregisterClass(sClass); // разрегистрировать класс после закрытия окна, то есть по завершении предыдущей функции
	}

	oSys.Call("user32::DestroyIcon", hIcon); // Удалить дескриптор значка, освободив ресурсы
	// oSys.Call("User32::DestroyIcon", hImage);
	// oSys.Call("user32::ReleaseDC", aDlg.HWND, hDC);
}

function CreateDialog(bBox, bModeless, hParent) {
	var aDlg = [];
	var nResult;
	var hFocus;

	aDlg.Modeless = bModeless;
	aDlg.Title = sLng8 /* Color adjustment */ ; // Заголовок окна
	aDlg.Style = WS_VISIBLE | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX; // Стиль окна
	aDlg.Parent = hParent; // Родитель окна (блокировать доступ к родителю или закрывать при закрытии родителя)
	aDlg.Callback = DialogCallback; // Имя функции обратного вызова принимающая события окна
	aDlg.Icon = hIcon; // дескриптор иконки окна ранее полученный
	aDlg.X = 20; // X-координата окна
	aDlg.W = 420; // ширина окна
	aDlg.H = 240; // высота окна
	aDlg.PosPar = 3;
	aDlg.CtlFirst = ID_CHECKB; // первый элемент управления
	aDlg.CtlStyle = WS_VISIBLE;

	// если флаг бокс-окно
	aDlg.PosPix = true;
	aDlg.CtlFontN = "MS Shell Dlg";

	// Масив элементов управления окна
	// Задаёт характеристики каждого (положение и размеры, текст, стиль), чтобы потом создать функцией InitDialog()
	/*
	aDlg[ID_GROUPE] = {
		X: 10,
		Y: 10,
		W: 150,
		H: 95,
		Title: "",
		Style: BS_GROUPBOX | BS_CENTER
	};
	*/
	aDlg[ID_LBID] = {
		X: 20,
		Y: 30,
		W: 20,
		H: 13,
		Title: "ID:",
		Class: "STATIC"
	};
	aDlg[ID_INPID] = {
		X: 40,
		Y: 27,
		W: 40,
		H: 20,
		Title: ""+ID_Color,
		Class: "EDIT",
		Style: WS_TABSTOP | WS_BORDER
	};
	aDlg[ID_INP] = {
		X: 333,
		Y: 63,
		W: 80,
		H: 20,
		Title: "",
		Class: "EDIT",
		Style: WS_TABSTOP | WS_BORDER
	};
	aDlg[ID_CHECKB] = {
		X: 20,
		Y: 80,
		W: 190,
		H: 16,
		Title: sLng2 /* Change the background */ ,
		Style: WS_TABSTOP | BS_AUTOCHECKBOX
	};
	aDlg[ID_BTN_OK] = {
		X: 333,
		Y: 90,
		W: 80,
		H: 23,
		Title: sLng3 /* Apply */ ,
		Style: WS_TABSTOP | BS_PUSHBUTTON
	};
	aDlg[ID_CANCEL] = {
		X: 270,
		Y: 90,
		W: 60,
		H: 23,
		Title: sLng4 /* Reset */ ,
		Style: WS_TABSTOP | BS_PUSHBUTTON
	};

	aDlg[ID_TB1] = {
		X: 5,
		Y: 140,
		W: 282,
		H: 30,
		Class: "msctls_trackbar32",
		Style: WS_TABSTOP | TBS_AUTOTICKS
	};

	aDlg[ID_TB2] = {
		X: 5,
		Y: 170,
		W: 282,
		H: 30,
		Class: "msctls_trackbar32",
		Style: WS_TABSTOP | TBS_AUTOTICKS
	};

	aDlg[ID_TB3] = {
		X: 5,
		Y: 200,
		W: 282,
		H: 30,
		Class: "msctls_trackbar32",
		Style: WS_TABSTOP | TBS_AUTOTICKS
	};
	aDlg[ID_LBTB1] = {
		X: 293,
		Y: 140,
		W: 20,
		H: 13,
		Title: "0",
		Class: "STATIC"
	};
	aDlg[ID_LBTB2] = {
		X: 293,
		Y: 170,
		W: 20,
		H: 13,
		Title: "0",
		Class: "STATIC"
	};
	aDlg[ID_LBTB3] = {
		X: 293,
		Y: 200,
		W: 20,
		H: 13,
		Title: "0",
		Class: "STATIC"
	};
	aDlg[ID_LBTB4] = {
		X: 330,
		Y: 140,
		W: 80,
		H: 13,
		Title: sLng5 /* Tone */ ,
		Class: "STATIC"
	};
	aDlg[ID_LBTB5] = {
		X: 330,
		Y: 170,
		W: 80,
		H: 13,
		Title: sLng6 /* Saturation */ ,
		Class: "STATIC"
	};
	aDlg[ID_LBTB6] = {
		X: 330,
		Y: 200,
		W: 80,
		H: 13,
		Title: sLng7 /* Brightness */ ,
		Class: "STATIC"
	};
	/*
	aDlg[ID_LBColor] = {
		X: 393,
		Y: 40,
		W: 80,
		H: 40,
		Title: "",
		Class: "STATIC",
		Style: BS_OWNERDRAW
	};
	aDlg[ID_SPEKTR] = {
		X: 16,
		Y: 134,
		W: 1,
		H: 1,
		Title: "|     |",
		Style: SS_BITMAP,
		Class: "STATIC"
	};
	*/

	// если флаг бокс-окно
	nResult = CreateDialogBox(aDlg);

	// Функция обратного вызова принимающая события
	function DialogCallback(hWnd, uMsg, wParam, lParam) {
		if(uMsg == 1 /*WM_CREATE*/ ) // если пришло сообщение о создании окна
		{
			aDlg.HWND = hWnd; // Дописываем дексриптор
			CreateDialogWindow(aDlg, 2, hWnd);
			InitDialog(); // Задаёт начальное состояние элементов в окне
			hFocus = aDlg[ID_CHECKB].HWND; // Указываем дескриптор в фокусе

			// не получается покрасить лейбл
			// hDC=AkelPad.MemRead(_PtrAdd(lParam, _X64?32:24) /*offsetof(DRAWITEMSTRUCT, hDC)*/, 2 /*DT_QWORD*/);
			// oSys.Call("gdi32::SetBkColor", hDC, 0xFFFFFF);
		}

		switch(uMsg) { // сравнение ==
			// case 0x0138 : //WM_CTLCOLORSTATIC
    // if (lParam == aDlg[ID_LBColor].HWND)
    // {
				// WScript.Echo("HWND =" + wParam + "  " + lParam); //  проходит
      /*
      oSys.Call("Gdi32::DeleteObject", hBrushColor);
      oSys.Call("Gdi32::SetTextColor", wParam, 0x006000);
      */
      // oSys.Call("Gdi32::SetBkColor", wParam, 0xFFFFFF);
      /*
      hBrushColor = oSys.Call("Gdi32::CreateSolidBrush", 0xFFFFFF);
      return hBrushColor;
      */
    // }
				// break;
			// case 78 /*WM_NOTIFY*/ :
				// var nLowParam = LoWord(wParam); // младшее слово содержит ID элемента управления
				// var nHiwParam = HiWord(wParam); // младшее слово содержит ID элемента управления
				// switch(lParam) { // если дексриптор равен
				// switch(AkelPad.MemRead(lParam + (_X64 ? 16 : 8), 3 /*DT_DWORD*/)) { // если дексриптор равен
				// }
				// break;
			case 272 /*WM_INITDIALOG*/ :
				InitDialog(); // Задаёт начальное состояние элементов в окне
				break;
			// case 561 /*WM_ENTERSIZEMOVE*/ :
				// хотел сделать копирование Bitmap от DrawLBColor в начале перемещения,
				// но не понятно как поведёт себя если начало перемещения будет частично за экраном
				// break;
			case 15: //WM_PAINT - перерисовать объекты требующие перерисовки (при запуске и за экран)
				DrawLBColor(aDlg, "" + hex(arr_rgb[0]) + hex(arr_rgb[1]) + hex(arr_rgb[2]));
				
				if (fMemDC) { // если первый вызов, то рисуем спектр и копируем в память
					Draw_SPEKTR();
					MemBM = oSys.Call("Gdi32::CreateCompatibleBitmap", hDC, 280, 140); // создаём совместимый Bitmap
					hOldBMP = oSys.Call("Gdi32::SelectObject", MemDC, MemBM); // выбираем Bitmap
					oSys.Call("Gdi32::BitBlt", MemDC, 17, 134, 260, 4, hDC, 17, 134, 0x00CC0020 /* SRCCOPY */ ); // копировать данные Bitmap из hDC в MemDC
					oSys.Call("Gdi32::DeleteObject", MemBM); // больше шаблон Bitmap не нужен
					fMemDC = 0;
				} else { // иначе возвращаем из памяти
					oSys.Call("Gdi32::BitBlt", hDC, 17, 134, 260, 4, MemDC, 17, 134, 0x00CC0020 /* SRCCOPY */ ); // копировать Bitmap из MemDC в hDC
				}
		
				
				// oSys.Call("User32::SetWindowTextW", hWnd, "Заменяем текст в заголовке окна"); // Заменяем текст в заголовке окна
				// kk1++
				// oSys.Call("User32::SetDlgItemTextW", hWnd, ID_LBTB5, "PAINT=" + kk1); // подситываем колич. срабатываний
				// oSys.Call("User32::SetDlgItemTextW", hWnd, ID_LBTB5, "=" + wParam); // подситываем колич. срабатываний
				// WScript.Echo("HWND =" + wParam + "  " + lParam); //  проходит
				break;
			case 276 /*WM_HSCROLL */ : // уведомление прокрутки
				var nLowParam = LoWord(wParam); // младшее слово содержит ID элемента управления
				var nHiwParam = HiWord(wParam); // младшее слово содержит ID элемента управления
				// WScript.Echo("HWND =" + aDlg[ID_TB1].HWND + "  " + lParam); //  проходит
				switch(lParam) { // если дексриптор равен
					case aDlg[ID_TB1].HWND: // декскриптору слайдера

						switch(nLowParam) { // уведомление
							case 0: // SB_LINELEFT - клавишами, влево, аналогично для ниже следующих
							case 1: // SB_LINERIGHT
							case 2: // SB_PAGELEFT
							case 3: // SB_PAGERIGHT
								arr_hsb[0] = AkelPad.SendMessage(aDlg[ID_TB1].HWND, 1024 /*TBM_GETPOS*/ , 0, 0); // чтение позиции со слайдера
								SetColor(hWnd, aDlg)
								oSys.Call("User32::SetDlgItemTextW", hWnd, ID_LBTB1, "" + arr_hsb[0]);
								break;
							case 4: // SB_THUMBPOSITION - колесом мыши
							case 5: // SB_THUMBTRACK - стрелкой мыши
								// WScript.Echo("nHiwParam = " + nHiwParam); // проходит
								arr_hsb[0] = nHiwParam;
								// WScript.Echo("arr_rgb[0] = " + arr_rgb[0]); // проходит
								SetColor(hWnd, aDlg)
								oSys.Call("User32::SetDlgItemTextW", hWnd, ID_LBTB1, "" + arr_hsb[0]);
								break;
						}
						break;
					case aDlg[ID_TB2].HWND: // декскриптору слайдера

						switch(nLowParam) { // уведомление
							case 0: // SB_LINELEFT - клавишами, влево, аналогично для ниже следующих
							case 1: // SB_LINERIGHT
							case 2: // SB_PAGELEFT
							case 3: // SB_PAGERIGHT
								arr_hsb[1] = AkelPad.SendMessage(aDlg[ID_TB2].HWND, 1024 /*TBM_GETPOS*/ , 0, 0); // чтение позиции со слайдера
								SetColor(hWnd, aDlg)
								oSys.Call("User32::SetDlgItemTextW", hWnd, ID_LBTB2, "" + arr_hsb[1]);
								break;
							case 4: // SB_THUMBPOSITION - колесом мыши
							case 5: // SB_THUMBTRACK - стрелкой мыши
								// WScript.Echo("nHiwParam = " + nHiwParam); // проходит
								arr_hsb[1] = nHiwParam;
								SetColor(hWnd, aDlg)
								oSys.Call("User32::SetDlgItemTextW", hWnd, ID_LBTB2, "" + arr_hsb[1]);
								break;
						}
						break;
					case aDlg[ID_TB3].HWND: // декскриптору слайдера

						switch(nLowParam) { // уведомление
							case 0: // SB_LINELEFT - клавишами, влево, аналогично для ниже следующих
							case 1: // SB_LINERIGHT
							case 2: // SB_PAGELEFT
							case 3: // SB_PAGERIGHT
								arr_hsb[2] = AkelPad.SendMessage(aDlg[ID_TB3].HWND, 1024 /*TBM_GETPOS*/ , 0, 0); // чтение позиции со слайдера
								SetColor(hWnd, aDlg)
								oSys.Call("User32::SetDlgItemTextW", hWnd, ID_LBTB3, "" + arr_hsb[2]);
								break;
							case 4: // SB_THUMBPOSITION - колесом мыши
							case 5: // SB_THUMBTRACK - стрелкой мыши
								// WScript.Echo("nHiwParam = " + nHiwParam); // проходит
								arr_hsb[2] = nHiwParam;
								SetColor(hWnd, aDlg)
								oSys.Call("User32::SetDlgItemTextW", hWnd, ID_LBTB3, "" + arr_hsb[2]);
								break;
						}
						break;
				}
				break;
			case 273 /*WM_COMMAND*/ :
				var nLowParam = LoWord(wParam); // младшее слово содержит ID элемента управления
				var nHiwParam = HiWord(wParam); // старшее слово = код действия с кнопкой (NotifyCode)
				switch(nLowParam) { // в switch сравнение ==
					case ID_INPID: // декскриптору поля ввода ID
						switch(nHiwParam) { // уведомление
							case 0x300: // EN_CHANGE - изменение в поле ввода

								// Блок для чтения из поля ввода
								var nEditLen = 32767; // число символов с запасом для поля ввода
								var lpEdit = AkelPad.MemAlloc((nEditLen + 1) * 2); // Выделяем память и получаем указатель
								oSys.Call("User32::GetDlgItemTextW", hWnd, ID_INPID, lpEdit, nEditLen); // Высылает текст поля ввода в указатель
								var sText_input = AkelPad.MemRead(lpEdit, 1 /*DT_UNICODE*/ ); // Читаем с указателя
								AkelPad.MemFree(lpEdit); // Освобождаем память
								
								if (/\D/.test(sText_input)) // если введены не цифры, то
								{
								  sText_input = sText_input.replace(/\D+/g, ''); // удаляем всё кроме цифр
								  oSys.Call("User32::SetDlgItemTextW", hWnd, ID_INPID, sText_input); // заменяем
								}
								ID_Color = parseInt(sText_input)
								// ID_Color = Math.abs(parseInt(sText_input))

								break;
						}
						break;
					case ID_CHECKB: // кнопка отмены вызылает окну команду закрытия
						bChecSt = AkelPad.SendMessage(aDlg[ID_CHECKB].HWND, 240 /*BM_GETCHECK*/ , 0, 0) // получаем состояние чекбокса
						if(bChecSt) {
							oSys.Call("User32::SetDlgItemTextW", hWnd, ID_INP, sBgColor);
						}
						else {
							oSys.Call("User32::SetDlgItemTextW", hWnd, ID_INP, sFgColor);
						}
						// break;
					case ID_BTN_OK: // событие нажатия "ОК", стандартно считываем параметры, чтобы использовать в дальнейшем
						// if (nHiwParam == 0)

						// Блок для чтения из поля ввода
						var nEditLen = 32767; // число символов с запасом для поля ввода
						var lpEdit = AkelPad.MemAlloc((nEditLen + 1) * 2); // Выделяем память и получаем указатель
						oSys.Call("User32::GetDlgItemTextW", hWnd, ID_INP, lpEdit, nEditLen); // Высылает текст поля ввода в указатель
						var sText_input = AkelPad.MemRead(lpEdit, 1 /*DT_UNICODE*/ ); // Читаем с указателя
						AkelPad.MemFree(lpEdit); // Освобождаем память

						// var CheckboxState = AkelPad.SendMessage(aDlg[ID_CHECKB].HWND, 240 /*BM_GETCHECK*/ , 0, 0) // получаем состояние чекбокса
						// AkelPad.MessageBox(hWnd, 'Чекбокс = ' + CheckboxState + '\n\n Поле ввода: ' + sText_input, 'Результат', 0x40 /*MB_ICONINFORMATION*/ );
						HexToRGB(sText_input);
						rgb_to_hsb();
						SetColor2(aDlg, sText_input);
						break;
					case ID_CANCEL: // кнопка отмены вызылает окну команду закрытия
						// oSys.Call("User32::PostMessageW", hWnd, 16 /*WM_CLOSE*/ , nLowParam, 0);
						AkelPad.Call("Coder::HighLight", 3, 0)
						break;
						// case ID_CHECKB: // если событие клик на чекбоксе, то есть активно изменить что-либо сразу в окне
						// break;
				}
				break;
			case 16 /*WM_CLOSE*/ : // если событие закрытия окна, то
				oSys.Call("user32::ReleaseDC", aDlg.HWND, hDC); // особождает DC
				oSys.Call("Gdi32::SelectObject", MemDC, hOldBMP); // Выбирает предыдущий объект
				oSys.Call("Gdi32::DeleteDC", MemDC); // особождает копию DC в памяти
				oSys.Call("User32::EndDialog", hWnd, wParam);
				// WScript.Echo("Ушёл"); //  проходит
				break;
			case 2 /*WM_DESTROY*/ : // если событие уничтожения окна, то
				oSys.Call("User32::PostQuitMessage", 0);
				break;
		}

		return 0;
	}

	function InitDialog() {
		var i;
		
		hDC = oSys.Call("User32::GetDC", aDlg.HWND); // получаем контекст устройства
		MemDC = oSys.Call("Gdi32::CreateCompatibleDC", hDC); // получаем совместимый контекст устройства
		
		// Ставит галочку в CheckBox
		AkelPad.SendMessage(aDlg[ID_CHECKB].HWND, 241 /*BM_SETCHECK*/ , 1 /*BST_CHECKED*/ , 0);

		//TrackBar
		AkelPad.SendMessage(aDlg[ID_TB1].HWND, 1044 /*TBM_SETTICFREQE*/ , 10, 0); // TBM_SETTICFREQ =  шкала с шагом 10
		AkelPad.SendMessage(aDlg[ID_TB2].HWND, 1044 /*TBM_SETTICFREQE*/ , 10, 0); // TBM_SETTICFREQ =  шкала с шагом 10
		AkelPad.SendMessage(aDlg[ID_TB3].HWND, 1044 /*TBM_SETTICFREQE*/ , 10, 0); // TBM_SETTICFREQ =  шкала с шагом 10
		// AkelPad.SendMessage(aDlg[ID_TB1].HWND, 1030 /*TBM_SETRANGE*/ , 50, 50); // TBM_SETRANGE =  шкала с шагом 10
		AkelPad.SendMessage(aDlg[ID_TB1].HWND, 1032 /*TBM_SETRANGEMAX*/ , 0, 360); // TBM_SETRANGEMAX =  максимальное значение 360
		AkelPad.SendMessage(aDlg[ID_TB2].HWND, 1032 /*TBM_SETRANGEMAX*/ , 0, 100); // TBM_SETRANGEMAX =  максимальное значение 100
		AkelPad.SendMessage(aDlg[ID_TB3].HWND, 1032 /*TBM_SETRANGEMAX*/ , 0, 100); // TBM_SETRANGEMAX =  максимальное значение 100
		// AkelPad.SendMessage(aDlg[ID_TB1].HWND, 1029 /*TBM_SETPOS*/ , 1, 33); // задать позицию.
		AkelPad.SendMessage(aDlg[ID_TB2].HWND, 1029 /*TBM_SETPOS*/ , 1, arr_hsb[1]); // задать позицию.
		oSys.Call("User32::SetDlgItemTextW", aDlg.HWND, ID_LBTB2, "" + arr_hsb[1]);
		AkelPad.SendMessage(aDlg[ID_TB3].HWND, 1029 /*TBM_SETPOS*/ , 1, arr_hsb[2]); // задать позицию.
		oSys.Call("User32::SetDlgItemTextW", aDlg.HWND, ID_LBTB3, "" + arr_hsb[2]);
		// oSys.Call("User32::SetDlgItemTextW", hWnd, ID_LBTB2, arr_hsb[1] + ' ' + arr_rgb[1] + ' ' + hex(arr_rgb[1]));
		// hsb_to_rgb() // и пересчитываем rgb
		// hImage = LoadImage2(sAkelDir + "\\AkelFiles\\Plugs\\Scripts\\Image\\Spektr.bmp");
		// AkelPad.SendMessage(aDlg[ID_SPEKTR].HWND, 0x0172 /*STM_SETIMAGE*/, 0, hImage);
		SetColor(aDlg.HWND, aDlg);
		

	}

}


/*
function GetOutputWindow() {
	var lpWnd;
	var hWnd = 0;

	if(lpWnd = AkelPad.MemAlloc(_X64 ? 8 : 4)) { // sizeof(HWND)
		AkelPad.Call("Log::Output", 2, lpWnd);
		hWnd = AkelPad.MemRead(lpWnd, 2); // DT_QWORD
		AkelPad.MemFree(lpWnd);
	}
	return hWnd;
}
*/

function SetColor(hWnd, aDlg) {
	hsb_to_rgb()
	var sText = "" + hex(arr_rgb[0]) + hex(arr_rgb[1]) + hex(arr_rgb[2]);
	DrawLBColor(aDlg, sText);
	oSys.Call("User32::SetDlgItemTextW", hWnd, ID_INP, sText);
	if(bChecSt) {
		sBgColor = sText;
		AkelPad.Call("Coder::HighLight", 2, '#' + sFgColor, '#' + sBgColor, 2, 0, ID_Color, sSelText); // пример изменения выделенного цвета (фона)
	}
	else {
		sFgColor = sText;
		AkelPad.Call("Coder::HighLight", 2, '#' + sFgColor, '#' + sBgColor, 2, 0, ID_Color, sSelText); // пример изменения выделенного цвета
	}
	// var nPos = SendMessage(lParam, 1024 /*TBM_GETPOS*/, 0, 0);
	// WScript.Echo("nHiwParam = " + AkelPad.SendMessage(aDlg[ID_TB1].HWND, 1024 /*TBM_GETPOS*/ , 0, 0)); // проходит
	// WScript.Echo("arr_hsb[0] = " + arr_hsb[0] + '\n' + "arr_hsb[1] = " + arr_hsb[1] + '\n' + "arr_hsb[2] = " + arr_hsb[2] + '\n'); // проходит
}

// Применить цвет
function SetColor2(aDlg, sText) {
	AkelPad.SendMessage(aDlg[ID_TB1].HWND, 1029 /*TBM_SETPOS*/ , 1, arr_hsb[0]); // задать позицию.
	AkelPad.SendMessage(aDlg[ID_TB2].HWND, 1029 /*TBM_SETPOS*/ , 1, arr_hsb[1]); // задать позицию.
	AkelPad.SendMessage(aDlg[ID_TB3].HWND, 1029 /*TBM_SETPOS*/ , 1, arr_hsb[2]); // задать позицию.
	oSys.Call("User32::SetDlgItemTextW", aDlg.HWND, ID_LBTB1, "" + arr_hsb[0]);
	oSys.Call("User32::SetDlgItemTextW", aDlg.HWND, ID_LBTB2, "" + arr_hsb[1]);
	oSys.Call("User32::SetDlgItemTextW", aDlg.HWND, ID_LBTB3, "" + arr_hsb[2]);
	if(bChecSt) {
		sBgColor = sText;
		AkelPad.Call("Coder::HighLight", 2, '#' + sFgColor, '#' + sBgColor, 2, 0, ID_Color, sSelText); // пример изменения выделенного цвета (фона)
	}
	else {
		sFgColor = sText;
		AkelPad.Call("Coder::HighLight", 2, '#' + sFgColor, '#' + sBgColor, 2, 0, ID_Color, sSelText); // пример изменения выделенного цвета
	}
	DrawLBColor(aDlg, "" + hex(arr_rgb[0]) + hex(arr_rgb[1]) + hex(arr_rgb[2]));
}

function DrawLBColor(aDlg, Color) {
	hBrush = oSys.Call("Gdi32::CreateSolidBrush", HexToRGB1("#" + Color));

	var rcWnd = getWindowRect(aDlg.HWND);
	if(!rcWnd)
		return;

	var lpRect = AkelPad.MemAlloc(16); //sizeof(RECT)
	if(!lpRect)
		return;

	AkelPad.MemCopy(lpRect, 333, 3 /*DT_DWORD*/);
	AkelPad.MemCopy(lpRect + 4, 20, 3 /*DT_DWORD*/);
	AkelPad.MemCopy(lpRect + 8, 333+80, 3 /*DT_DWORD*/);
	AkelPad.MemCopy(lpRect + 12, 20+40, 3 /*DT_DWORD*/);
	oSys.Call("User32::FillRect", hDC, lpRect, hBrush);
	oSys.Call("Gdi32::DeleteObject", hBrush);
}

// Создаёт градиент с помощью GDI
function Draw_SPEKTR() {
	var arr_hsb_tmp = [arr_rgb[0], arr_rgb[1], arr_rgb[2]]; // кэшируем массив
	w = 260;
	var Color;
	for(var i = 0; i <= w; i++) {
		arr_hsb[0] = i*360/w;
		hsb_to_rgb();
		Color = ((arr_rgb[2] << 8) + arr_rgb[1] << 8) + arr_rgb[0]; // rgb to int
		// Color = parseInt("0x" + hex(arr_rgb[2]) + hex(arr_rgb[1]) + hex(arr_rgb[0]))
		hPen = oSys.Call("gdi32::CreatePen", 0 /* PS_SOLID */ , 1 /* Width */ , Color);
		oSys.Call("Gdi32::SelectObject", hDC, hPen);
		oSys.Call("gdi32::MoveToEx", hDC, i+17, 134, 0); // перемещаем позицию
		oSys.Call("gdi32::LineTo", hDC, i+17, 138);
		oSys.Call("Gdi32::DeleteObject", hPen);
	}
	arr_rgb = [arr_hsb_tmp[0], arr_hsb_tmp[1], arr_hsb_tmp[2]];
}

function getWindowRect(hWnd, hWndParent) {
	var lpRect = AkelPad.MemAlloc(16); //sizeof(RECT)
	if(!lpRect)
		return null;
	oSys.Call("user32::GetWindowRect", hWnd, lpRect);
	hWndParent && oSys.Call("user32::ScreenToClient", hWndParent, lpRect);
	var rcWnd = parseRect(lpRect);
	AkelPad.MemFree(lpRect);
	return rcWnd;
}

function parseRect(lpRect) {
	return {
		left:   AkelPad.MemRead(lpRect,      3 /*DT_DWORD*/),
		top:    AkelPad.MemRead(lpRect +  4, 3 /*DT_DWORD*/),
		right:  AkelPad.MemRead(lpRect +  8, 3 /*DT_DWORD*/),
		bottom: AkelPad.MemRead(lpRect + 12, 3 /*DT_DWORD*/)
	};
}

function HexToRGB1(sHex)
{
  if (/^#[\da-f]{6}$/i.test(sHex))
    return parseInt(sHex.substr(5, 2) + sHex.substr(3, 2) + sHex.substr(1, 2), 16);

  return oSys.Call("User32::GetSysColor", 15);
}

// вытаскивает младшее слово из двойного слова
function LoWord(nDwNum) {
	return nDwNum & 0xFFFF;
}

// вытаскивает старшее слово из двойного слова
function HiWord(nDwNum) {
	return (nDwNum >> 16);
}

// AZJIO
function hsb_to_rgb() {
	var sector;
	var ff, pp, qq, tt;
	var af_rgb = []; // создаём массивы в которых числа будут в диапазоне 0-1
	var af_hsb = [];
	// var arr_rgb = [];

	af_hsb[2] = arr_hsb[2] / 100;

	if(arr_hsb[1] == 0) { // если серый, то одно значение всем
		arr_rgb[0] = Math.round(af_hsb[2] * 255);
		arr_rgb[1] = arr_rgb[0];
		arr_rgb[2] = arr_rgb[0];
		// return arr_rgb;
		return
	}
	else {
		while(arr_hsb[0] >= 360) { // если тон задан большим запредельным числом, то
			arr_hsb[0] -= 360;
		}

		af_hsb[1] = arr_hsb[1] / 100;
		af_hsb[0] = arr_hsb[0] / 60;
		sector = parseInt(af_hsb[0]); // округление до целого
		// sector = Math.ceil(af_hsb[0]); // округление в меньшую сторону

		ff = af_hsb[0] - sector;
		pp = af_hsb[2] * (1 - af_hsb[1]);
		qq = af_hsb[2] * (1 - af_hsb[1] * ff);
		tt = af_hsb[2] * (1 - af_hsb[1] * (1 - ff));

		switch(sector) {
			case 0:
				af_rgb[0] = af_hsb[2];
				af_rgb[1] = tt;
				af_rgb[2] = pp;
				break;
			case 1:
				af_rgb[0] = qq;
				af_rgb[1] = af_hsb[2];
				af_rgb[2] = pp;
				break;
			case 2:
				af_rgb[0] = pp;
				af_rgb[1] = af_hsb[2];
				af_rgb[2] = tt;
				break;
			case 3:
				af_rgb[0] = pp;
				af_rgb[1] = qq;
				af_rgb[2] = af_hsb[2];
				break;
			case 4:
				af_rgb[0] = tt;
				af_rgb[1] = pp;
				af_rgb[2] = af_hsb[2];
				break;
			default:
				af_rgb[0] = af_hsb[2];
				af_rgb[1] = pp;
				af_rgb[2] = qq;
		}
	}
	// RGB
	arr_rgb[0] = Math.round(af_rgb[0] * 255);
	arr_rgb[1] = Math.round(af_rgb[1] * 255);
	arr_rgb[2] = Math.round(af_rgb[2] * 255);

	// BGR
	/*
	arr_rgb[2] = Math.round(af_rgb[0] * 255);
	arr_rgb[1] = Math.round(af_rgb[1] * 255);
	arr_rgb[0] = Math.round(af_rgb[2] * 255);
	*/

	// return arr_rgb
}

// AZJIO
function rgb_to_hsb() {
	var min, max;

	if(arr_rgb[0] <= arr_rgb[1]) {
		min = arr_rgb[0];
		max = arr_rgb[1];
	}
	else {
		min = arr_rgb[1];
		max = arr_rgb[0];
	}

	if(min > arr_rgb[2]) {
		min = arr_rgb[2];
	}

	if(max < arr_rgb[2]) {
		max = arr_rgb[2];
	}

	if(max == min) {
		arr_hsb[0] = 0;
	}
	else if(max == arr_rgb[0]) {
		arr_hsb[0] = 60 * (arr_rgb[1] - arr_rgb[2]) / (max - min);
		if(arr_rgb[1] < arr_rgb[2])
			arr_hsb[0] += 360;
	}
	else if(max == arr_rgb[1]) {
		arr_hsb[0] = (60 * (arr_rgb[2] - arr_rgb[0]) / (max - min)) + 120;
	}
	else if(max == arr_rgb[2]) {
		arr_hsb[0] = 60 * (arr_rgb[0] - arr_rgb[1]) / (max - min) + 240;
	}

	if(max == 0) {
		arr_hsb[1] = 0;
	}
	else {
		arr_hsb[1] = (1 - min / max) * 100;
	}

	arr_hsb[2] = max / 255 * 100;

	arr_hsb[0] = Math.round(arr_hsb[0]);
	arr_hsb[1] = Math.round(arr_hsb[1]);
	arr_hsb[2] = Math.round(arr_hsb[2]);

	// return arr_hsb
}

function hex(n) { // взял из "colorsConverter.js"
	var h = (typeof n == "number" ? n : parseInt(n, 10)).toString(16);
	if(h.length > 2)
		return null;
	return "00".substr(h.length) + h;
}

function HexToRGB(sHex) {
	if(/^[\da-f]{6}$/i.test(sHex)) { // валидация
		arr_rgb[0] = parseInt(sHex.substr(0, 2), 16);
		arr_rgb[1] = parseInt(sHex.substr(2, 2), 16);
		arr_rgb[2] = parseInt(sHex.substr(4, 2), 16);
	}
}

// Загрузка рисунка спектра из файла, теперь вместо этого Draw_SPEKTR
function LoadImage2(sFile) {
	var fso = new ActiveXObject("Scripting.FileSystemObject");
	if (!fso.FileExists(sFile))
		return 0;
	var lpFile = AkelPad.MemAlloc(260 * 2); // Выделяем память и получаем указатель
	AkelPad.MemCopy(lpFile, sFile, 1 /*DT_UNICODE*/); // Копируем путь в указатель
	var hImage = oSys.Call("User32::LoadImageW", 0, lpFile, 0, 0, 0, 8304); // 16+64+8192+32
	AkelPad.MemFree(lpFile);
	return hImage;
}


function GetNewMarkID(id)
{
	//based on Instructor's code GetMarks.js: http://akelpad.sourceforge.net/forum/viewtopic.php?p=25591&hilit=#p25591
	var aCur = [];
	var lpMarkStack = AkelPad.MemAlloc(_X64 ? 16 : 8 /*sizeof(STACKMARKTEXT)*/);
	var lpMarkText;
	var nMarkID;
	var i;
	// var id = 100;
	var flaf = 0;
	
	aCur.length = 0;
	
	AkelPad.Call("Coder::HighLight", 12 /*DLLA_HIGHLIGHT_GETMARKSTACK*/, AkelPad.GetEditWnd(), AkelPad.GetEditDoc(), lpMarkStack);

	lpMarkText = AkelPad.MemRead(lpMarkStack /*offsetof(STACKMARKTEXT,first)*/, 2 /*DT_QWORD*/);
	
	while (lpMarkText) {
	    nMarkID    = AkelPad.MemRead(_PtrAdd(lpMarkText, _X64 ? 24 : 12) /*offsetof(MARKTEXT,dwMarkID)*/, 3 /*DT_DWORD*/);
		aCur.push([nMarkID]);
		lpMarkText = AkelPad.MemRead(lpMarkText /*offsetof(MARKTEXT,next)*/, 2 /*DT_QWORD*/);
	}
	
	AkelPad.MemFree(lpMarkStack);

// поиск свободного ID
	do {
		flaf = 0;
		id +=1
		for (i = 0; i < aCur.length; i++) {
			if (aCur[i] == id) {
				flaf = 1;
				break
			}
		}
	} while (flaf)
	return id
}
Last edited by AZJIO on Tue May 18, 2021 2:00 pm, edited 1 time in total.

Offline
Posts: 1862
Joined: Mon Aug 06, 2007 1:07 pm
Contact:

Post by Infocatcher »

Code: Select all

// http://akelpad.sourceforge.net/forum/viewtopic.php?p=35014#p35014
// http://infocatcher.ucoz.net/js/akelpad_scripts/closeUnsavedTabs.js
// https://github.com/Infocatcher/AkelPad_scripts/blob/master/closeUnsavedTabs.js

// (c) Infocatcher 2019-2020
// Version: 0.1.1 - 2020-05-30
// Author: Infocatcher

//// Close unsaved tabs (all or only empty)
// Required MDI or PMDI window mode!

// Arguments:
//   -onlyEmpty=false     - close only empty tabs
//   -askToSave=true      - ask to save (or mark file as not modified to silently close)
//   -closeCurrent=true   - also close current tab
//   -stopOnCancel=true   - stop tabs iteration, if pressed Cancel button

// Usage:
//   Call("Scripts::Main", 1, "closeUnsavedTabs.js")
//   Call("Scripts::Main", 1, "closeUnsavedTabs.js", "-onlyEmpty=false -askToSave=false -closeCurrent=true -stopOnCancel=true")

var hMainWnd = AkelPad.GetMainWnd();
var onlyEmpty = AkelPad.GetArgValue("onlyEmpty", false);
var askToSave = AkelPad.GetArgValue("askToSave", true);
var closeCurrent = AkelPad.GetArgValue("closeCurrent", true);
var stopOnCancel = AkelPad.GetArgValue("stopOnCancel", true);

if(AkelPad.IsMDI())
	closeEmptyTabs();
else
	AkelPad.MessageBox(hMainWnd, "MDI or PMDI window mode required!", WScript.ScriptName, 48 /*MB_ICONEXCLAMATION*/);

function closeEmptyTabs() {
	var lpFrameInitial = AkelPad.SendMessage(hMainWnd, 1288 /*AKD_FRAMEFIND*/, 1 /*FWF_CURRENT*/, 0);
	for(; !stop; ) {
		AkelPad.SendMessage(hMainWnd, 273 /*WM_COMMAND*/, 4316 /*IDM_WINDOW_FRAMENEXT*/, 0);
		var lpFrame = AkelPad.SendMessage(hMainWnd, 1288 /*AKD_FRAMEFIND*/, 1 /*FWF_CURRENT*/, 0);
		var stop = lpFrame == lpFrameInitial;
		if((!stop || closeCurrent) && !closeEmptyTab() && stopOnCancel) // Canceled
			return;
	}
	AkelPad.SendMessage(hMainWnd, 1285 /*AKD_FRAMEACTIVATE*/, 0, lpFrameInitial);
}
function closeEmptyTab() {
	if(
		AkelPad.GetEditFile(0) // Saved
		|| onlyEmpty && AkelPad.GetTextRange(0, 1) // Not empty
	)
		return true;
	if(!askToSave) { // Force mark as not modified
		var hWndEdit = AkelPad.GetEditWnd();
		if(AkelPad.SendMessage(hWndEdit, 3086 /*AEM_GETMODIFY*/, 0, 0))
			AkelPad.SendMessage(hWndEdit, 3087 /*AEM_SETMODIFY*/, false, 0);
	}
	return AkelPad.SendMessage(hMainWnd, 273 /*WM_COMMAND*/, 4318 /*IDM_WINDOW_FRAMECLOSE*/, 0);
}
<download | development version>
Close unsaved tabs (all or only empty)
Required MDI or PMDI window mode!

Offline
Posts: 330
Joined: Mon Jun 03, 2019 2:33 am

Post by AZJIO »

Code: Select all

// http://akelpad.sourceforge.net/forum/viewtopic.php?p=35176#p35176
// Author: Скрипт переделал AZJIO из скрипта TabSwitch.js от Instructor
//
//
// Description(1033): Closes tabs of the specified type, for example, all htm files
// Description(1049): Закрывает вкладки определённого типа, например все htm-файлы
//
// Arguments:
// -CtrlTab=false       -No Ctrl+Tab hotkey is assigned to TabSwitch.js (default is true).
// -MinTabs=2           -Minimum number of tabs before switch window appeared (default is 2).
// -FontName="Arial"    -Font name. Unchanged, if "".
// -FontStyle=3         -Font style (one of the following):
//                         0  ignored (default).
//                         1  normal.
//                         2  bold.
//                         3  italic.
//                         4  bold italic.
// -FontSize=10         -Font size. Unchanged, if 0 (default).
// -LineGap=10          -Space between items (default is 1).
// -SingleClick=false   -Single mouse click chooses item (default is true).
// -ShowModify=2        -Show modification sign (one of the following):
//                         0  hidden.
//                         1  display asterisk * at the end (default).
//                         2  display asterisk * at the beginning.
// -WindowLeft=100      -Left window position. Special values:
//                        -1 centered (default).
//                        -2 cursor position.
// -WindowTop=100       -Top window position. Special values:
//                        -1 centered (default).
//                        -2 cursor position.
// -WindowMaxHeight=500 -Maximum window height. Special values:
//                        -1 unlimited (default).
// -WindowMaxWidth=500  -Maximum window width. Special values:
//                        -1 unlimited (default).
//
// Usage:
// Toolbar button example:
//   -"Close tabs by extension" Call("Scripts::Main", 1, "CloseTabByExt.js", `-CtrlTab=false -MinTabs=1 -WindowLeft=%bl -WindowTop=%bb`)
// ContextMenu item example:
//   -"Close tabs by extension" Call("Scripts::Main", 1, "CloseTabByExt.js", `-CtrlTab=false -MinTabs=1 -WindowLeft=-2 -WindowTop=-2`)

//Arguments
var bCtrlTab = AkelPad.GetArgValue("CtrlTab", true);
var nMinTabs = AkelPad.GetArgValue("MinTabs", 2);
var pFontName = AkelPad.GetArgValue("FontName", "");
var nFontStyle = AkelPad.GetArgValue("FontStyle", 0);
var nFontSize = AkelPad.GetArgValue("FontSize", 0);
var nLineGap = AkelPad.GetArgValue("LineGap", 1);
var bSingleClick = AkelPad.GetArgValue("SingleClick", true);
var nWindowLeft = AkelPad.GetArgValue("WindowLeft", -1);
var nWindowTop = AkelPad.GetArgValue("WindowTop", -1);
var nWindowMaxHeight = AkelPad.GetArgValue("WindowMaxHeight", -1);
var nWindowMaxWidth = AkelPad.GetArgValue("WindowMaxWidth", -1);
var bAsk = AkelPad.GetArgValue("Ask", false);

//Variables
var hMainWnd = AkelPad.GetMainWnd();
var hWndEdit = AkelPad.GetEditWnd();
var oSys = AkelPad.SystemFunction();
var hInstanceDLL = AkelPad.GetInstanceDll();
var pClassName = "AkelPad::Scripts::" + WScript.ScriptName + "::" + oSys.Call("kernel32::GetCurrentProcessId");
var hWndContainer = 0;
var hWndListBox = 0;
var hHookPost;
var hHookSend;
var dwMainThreadID = oSys.Call("user32::GetWindowThreadProcessId", hMainWnd, 0);
var hSubClass;
var hDC;
var hBrushHollow;
var hFontEdit;
var lpFrameList = [];
var lpAllList = [];
var rcMain = [];
var ptPoint = [];
var nItemHeight;
var nScreenWidth;
var nControlWidth;
var nControlHeight;
var nMaxControlHeight;
var nCharWidth;
var nCharHeight;
var nMaxCharWidth = 0;
var nMaxCharHeight = 0;
var nIconSize = 16;
var nIconGap = 2;
var bNoSwitch = false;
var i;



//Get list of documents
nCurSel = GetFrameList(lpFrameList, lpAllList);
// WScript.Echo(lpFrameList.length);
if (lpFrameList.length > 0)
// if (lpFrameList.length >= nMinTabs && lpFrameList.length > 0)
{

	//Get font
	if (pFontName || nFontStyle || nFontSize)
		hFontEdit = CreateFont(pFontName, nFontStyle, nFontSize);
	else
		hFontEdit = AkelPad.SendMessage(hWndEdit, 0x31 /*WM_GETFONT*/ , 0, 0);
	if (!hFontEdit) WScript.Quit();

	//Get maximum character size
	if (lpSize = AkelPad.MemAlloc(8 /*sizeof(SIZE)*/ )) {
		if (hDC = oSys.Call("user32::GetDC", hWndEdit)) {
			oSys.Call("gdi32::SelectObject", hDC, hFontEdit);

			for (i = 0; i < lpFrameList.length; ++i) {
				if (oSys.Call("gdi32::GetTextExtentPoint32" + _TCHAR, hDC, lpFrameList[i][0], lpFrameList[i][0].length, lpSize)) {
					nCharWidth = AkelPad.MemRead(_PtrAdd(lpSize, 0) /*offsetof(SIZE, cx)*/ , 3 /*DT_DWORD*/ );
					nCharHeight = AkelPad.MemRead(_PtrAdd(lpSize, 4) /*offsetof(SIZE, cy)*/ , 3 /*DT_DWORD*/ );
					if (nCharWidth > nMaxCharWidth) nMaxCharWidth = nCharWidth;
					if (nCharHeight > nMaxCharHeight) nMaxCharHeight = nCharHeight;
				}
			}
			oSys.Call("user32::ReleaseDC", hWndEdit, hDC);
		}
		nMaxCharWidth += nIconSize + nIconGap + 16;

		AkelPad.MemFree(lpSize);
	}

	//Create dialog
	if (AkelPad.WindowRegisterClass(pClassName, 0x21 /*WM_MOUSEACTIVATE*/ ,
			0x2B /*WM_DRAWITEM*/ )) {
		if (hWndContainer = oSys.Call("user32::CreateWindowEx" + _TCHAR, 0, pClassName, 0, 0x80000000 /*WS_POPUP*/ , 0, 0, 0, 0, hMainWnd, 0, hInstanceDLL, DialogCallback)) {
			if (hWndListBox = oSys.Call("user32::CreateWindowEx" + _TCHAR, 0, "LISTBOX", 0, 0x50700010 /*WS_VISIBLE|WS_CHILD|WS_HSCROLL|WS_VSCROLL|WS_DLGFRAME|LBS_OWNERDRAWFIXED*/ , 0, 0, 0, 0, hWndContainer, 0, hInstanceDLL, 0)) {
				//Make hWndContainer invisible
				hBrushHollow = oSys.Call("gdi32::GetStockObject", 5 /*HOLLOW_BRUSH*/ );
				oSys.Call("user32::SetClassLong" + _TCHAR, hWndContainer, -10 /*GCL_HBRBACKGROUND*/ , hBrushHollow);

				AkelPad.SendMessage(hWndListBox, 48 /*WM_SETFONT*/ , hFontEdit, 1);
				nItemHeight = nMaxCharHeight + nLineGap;
				i = AkelPad.SendMessage(hWndListBox, 0x1A1 /*LB_GETITEMHEIGHT*/ , 0, 0);
				if (nItemHeight < i)
					nItemHeight = i;
				else
					AkelPad.SendMessage(hWndListBox, 0x1A0 /*LB_SETITEMHEIGHT*/ , 0, nItemHeight);
				nMaxControlHeight = lpFrameList.length * nItemHeight + oSys.Call("user32::GetSystemMetrics", 8 /*SM_CYDLGFRAME*/ ) * 2;
				if (nWindowMaxHeight > 0)
					nControlHeight = Math.min(nWindowMaxHeight, nMaxControlHeight);
				else
					nControlHeight = nMaxControlHeight;
				nControlHeight = Math.min(oSys.Call("user32::GetSystemMetrics", 62 /*SM_CYMAXIMIZED*/ ) - 8, nControlHeight);
				if (nWindowMaxWidth > 0)
					nControlWidth = Math.min(nWindowMaxWidth, nMaxCharWidth);
				else
					nControlWidth = nMaxCharWidth;
				nControlWidth = Math.min(oSys.Call("user32::GetSystemMetrics", 61 /*SM_CXMAXIMIZED*/ ) - 8, nControlWidth);

				if (nMaxCharWidth > nControlWidth) {
					AkelPad.SendMessage(hWndListBox, 0x194 /*LB_SETHORIZONTALEXTENT*/ , nMaxCharWidth, 0);
					if (nMaxControlHeight == nControlHeight)
						nControlHeight += oSys.Call("user32::GetSystemMetrics", 21 /*SM_CXHSCROLL*/ );
				}

				//Fill listbox
				for (i = 0; i < lpFrameList.length; ++i)
					oSys.Call("user32::SendMessage" + _TCHAR, hWndListBox, 0x180 /*LB_ADDSTRING*/ , 0, lpFrameList[i][0]);

				GetWindowSize(hMainWnd, 0, rcMain);
				if (nWindowLeft >= 0)
					rcMain.left = nWindowLeft;
				else if (nWindowLeft == -2) {
					GetCursorPos(ptPoint);
					rcMain.left = ptPoint.x;
				} else
					rcMain.left += rcMain.right / 2 - nControlWidth / 2;
				if (!(nScreenWidth = oSys.Call("user32::GetSystemMetrics", 78 /*SM_CXVIRTUALSCREEN*/ )))
					nScreenWidth = oSys.Call("user32::GetSystemMetrics", 61 /*SM_CXMAXIMIZED*/ );
				rcMain.left = Math.min(rcMain.left, Math.max((nScreenWidth - 8) - nControlWidth, 0));
				if (rcMain.left < 0) rcMain.left = 0;

				if (nWindowTop >= 0)
					rcMain.top = nWindowTop;
				else if (nWindowTop == -2) {
					GetCursorPos(ptPoint);
					rcMain.top = ptPoint.y;
				} else
					rcMain.top += rcMain.bottom / 2 - nControlHeight / 2;
				rcMain.top = Math.min(rcMain.top, Math.max((oSys.Call("user32::GetSystemMetrics", 62 /*SM_CYMAXIMIZED*/ ) - 8) - nControlHeight, 0));
				if (rcMain.top < 0) rcMain.top = 0;

				oSys.Call("user32::SetWindowPos", hWndContainer, 0, rcMain.left, rcMain.top, nControlWidth, nControlHeight, 0x14 /*SWP_NOZORDER|SWP_NOACTIVATE*/ );
				oSys.Call("user32::SetWindowPos", hWndListBox, 0, 0, 0, nControlWidth, nControlHeight, 0x16 /*SWP_NOMOVE|SWP_NOZORDER|SWP_NOACTIVATE*/ );
				AkelPad.SendMessage(hWndListBox, 0x186 /*LB_SETCURSEL*/ , nCurSel, 0);
				oSys.Call("user32::ShowWindow", hWndContainer, 4 /*SW_SHOWNOACTIVATE*/ );
				//oSys.Call("user32::SetFocus", hWndListBox);
				//oSys.Call("user32::ShowWindow", hWndContainer, 5 /*SW_SHOW*/);
				//oSys.Call("user32::UpdateWindow", hMainWnd);

				//Cause listbox is non-active, hook and send to listbox keyboard and mouse actions.
				if (hHookPost = AkelPad.ThreadHook(3 /*WH_GETMESSAGE*/ , HookPostCallback, dwMainThreadID, 0x201 /*WM_LBUTTONDOWN*/ ,
						0x0A1 /*WM_NCLBUTTONDOWN*/ ,
						0x204 /*WM_RBUTTONDOWN*/ ,
						0x0A4 /*WM_NCRBUTTONDOWN*/ ,
						0x207 /*WM_MBUTTONDOWN*/ ,
						0x0A7 /*WM_NCMBUTTONDOWN*/ ,
						0x100 /*WM_KEYDOWN*/ ,
						0x101 /*WM_KEYUP*/ ,
						0x104 /*WM_SYSKEYDOWN*/ ,
						0x105 /*WM_SYSKEYUP*/ ,
						0x20A /*WM_MOUSEWHEEL*/ )) {
					if (hHookSend = AkelPad.ThreadHook(4 /*WH_CALLWNDPROC*/ , HookSendCallback, dwMainThreadID, 0x6 /*WM_SETFOCUS*/ )) {
						if (hSubClass = AkelPad.WindowSubClass(hWndListBox, ListBoxCallback, 0x021 /*WM_MOUSEACTIVATE*/ ,
								0x087 /*WM_GETDLGCODE*/ ,
								0x100 /*WM_KEYDOWN*/ ,
								0x101 /*WM_KEYUP*/ ,
								0x201 /*WM_LBUTTONDOWN*/ ,
								0x202 /*WM_LBUTTONUP*/ ,
								0x203 /*WM_LBUTTONDBLCLK*/ )) {
							//Allow other scripts running
							AkelPad.ScriptNoMutex();

							//Message loop
							AkelPad.WindowGetMessage();

							AkelPad.WindowUnsubClass(hWndListBox);
						}
						AkelPad.ThreadUnhook(hHookSend);
					}
					AkelPad.ThreadUnhook(hHookPost);
				}

				if (!bNoSwitch) {
					i = AkelPad.SendMessage(hWndListBox, 0x188 /*LB_GETCURSEL*/ , 0, 0);
					// oSys.Call("user32::PostMessage" + _TCHAR, hMainWnd, 1285 /*AKD_FRAMEACTIVATE*/ , 0, lpFrameList[i][1]);
					// Редактируемый участок 1
					var Pos;
					var Ext;
					Pos = lpFrameList[i][0].indexOf(" - ")
					Ext = lpFrameList[i][0].substr(Pos + 3)
					if (bAsk)
					{
						var mess = "";
						for (i = 0; i < lpAllList.length; ++i) {
							if (Ext === lpAllList[i][0])
							{
								mess += AkelPad.GetFilePath(lpAllList[i][2], 2) + "\n";
							}
						}
						if (AkelPad.MessageBox(hMainWnd, mess, "Закрыть эти вкладки?", 32, 0, 1 , "&OK", 0x1 , 2 , "&Cancel", 0) == 1)
						{
							for (i = 0; i < lpAllList.length; ++i) {
								if (Ext === lpAllList[i][0])
								{
									oSys.Call("user32::PostMessage" + _TCHAR, hMainWnd, 1287 /*AKD_FRAMEDESTROY*/ , 0, lpAllList[i][1]);
								}
							}
						}
					} else {
						for (i = 0; i < lpAllList.length; ++i) {
							if (Ext === lpAllList[i][0])
							{
								oSys.Call("user32::PostMessage" + _TCHAR, hMainWnd, 1287 /*AKD_FRAMEDESTROY*/ , 0, lpAllList[i][1]);
							}
						}
					}
					// Конец Редактируемый участок 1
				}
				//oSys.Call("user32::DestroyWindow", hWndListBox);
			}
			oSys.Call("user32::DestroyWindow", hWndContainer);
		}
		AkelPad.WindowUnregisterClass(pClassName);
	}

	//Release font
	if (pFontName || nFontStyle || nFontSize) {
		if (hFontEdit)
			oSys.Call("gdi32::DeleteObject", hFontEdit);
	}
} else {
	if (lpFrameList.length >= 2)
		oSys.Call("user32::PostMessage" + _TCHAR, hMainWnd, 1285 /*AKD_FRAMEACTIVATE*/ , 0, lpFrameList[nCurSel][1]);
}

function DialogCallback(hWnd, uMsg, wParam, lParam) {
	if (uMsg == 0x021 /*WM_MOUSEACTIVATE*/ ) {
		return 3 /*MA_NOACTIVATE*/ ;
	} else if (uMsg == 0x2B /*WM_DRAWITEM*/ ) {
		var hDC;
		var hIcon;
		var nItemID;
		var nItemState;
		var lpItem;
		var rcItem = [];
		var crText;
		var crBk;
		var hBrushBk;
		var nModeBkOld;

		hDC = AkelPad.MemRead(_PtrAdd(lParam, _X64 ? 32 : 24) /*offsetof(DRAWITEMSTRUCT, hDC)*/ , 2 /*DT_QWORD*/ );
		nItemID = AkelPad.MemRead(_PtrAdd(lParam, _X64 ? 8 : 8) /*offsetof(DRAWITEMSTRUCT, itemID)*/ , 3 /*DT_DWORD*/ );
		nItemState = AkelPad.MemRead(_PtrAdd(lParam, _X64 ? 16 : 16) /*offsetof(DRAWITEMSTRUCT, itemState)*/ , 3 /*DT_DWORD*/ );
		lpItem = _PtrAdd(lParam, _X64 ? 40 : 28) /*offsetof(DRAWITEMSTRUCT, rcItem)*/ ;
		RectToArray(lpItem, rcItem);

		//Set background
		if (nItemState & 0x1 /*ODS_SELECTED*/ ) {
			crText = oSys.Call("user32::GetSysColor", 14 /*COLOR_HIGHLIGHTTEXT*/ );
			crBk = oSys.Call("user32::GetSysColor", 13 /*COLOR_HIGHLIGHT*/ );
			hBrushBk = oSys.Call("user32::GetSysColorBrush", 13 /*COLOR_HIGHLIGHT*/ );
		} else {
			crText = oSys.Call("user32::GetSysColor", 8 /*COLOR_WINDOWTEXT*/ );
			crBk = oSys.Call("user32::GetSysColor", 5 /*COLOR_WINDOW*/ );
			hBrushBk = oSys.Call("user32::GetSysColorBrush", 5 /*COLOR_WINDOW*/ );
		}
		oSys.Call("user32::FillRect", hDC, lpItem, hBrushBk);
		nModeBkOld = oSys.Call("gdi32::SetBkMode", hDC, 1 /*TRANSPARENT*/ );

		//Draw icon
		hIcon = AkelPad.SendMessage(hMainWnd, 1223 /*AKD_GETFRAMEINFO*/ , 38 /*FI_ICONHANDLE*/ , lpFrameList[nItemID][1]);
		oSys.Call("user32::DrawIconEx", hDC, rcItem.left, rcItem.top + (rcItem.bottom - rcItem.top) / 2 - nIconSize / 2, hIcon, nIconSize, nIconSize, 0, 0, 0x3 /*DI_NORMAL*/ );

		//Draw text
		oSys.Call("gdi32::SetTextColor", hDC, crText);
		oSys.Call("gdi32::SetBkColor", hDC, crBk);
		oSys.Call("gdi32::TextOut" + _TCHAR, hDC, rcItem.left + nIconSize + nIconGap, rcItem.top + (rcItem.bottom - rcItem.top) / 2 - nMaxCharHeight / 2, lpFrameList[nItemID][0], lpFrameList[nItemID][0].length);

		oSys.Call("gdi32::SetBkMode", hDC, nModeBkOld);
	}
	return 0;
}

function HookPostCallback(nCode, wParam, lParam) {
	var uMsg = AkelPad.MemRead(_PtrAdd(lParam, _X64 ? 8 : 4) /*offsetof(MSG, message)*/ , 3 /*DT_DWORD*/ );
	var nParamW;
	var nParamL;

	if (uMsg == 0x201 /*WM_LBUTTONDOWN*/ ||
		uMsg == 0x0A1 /*WM_NCLBUTTONDOWN*/ ||
		uMsg == 0x204 /*WM_RBUTTONDOWN*/ ||
		uMsg == 0x0A4 /*WM_NCRBUTTONDOWN*/ ||
		uMsg == 0x207 /*WM_MBUTTONDOWN*/ ||
		uMsg == 0x0A7 /*WM_NCMBUTTONDOWN*/ ) {
		var hWnd = AkelPad.MemRead(_PtrAdd(lParam, 0) /*offsetof(MSG, hwnd)*/ , 2 /*DT_QWORD*/ );

		if (hWnd != hWndListBox) {
			//Not in rect
			bNoSwitch = true;

			//Exit message loop
			oSys.Call("user32::PostQuitMessage", 0);
		}
	} else if (uMsg == 0x100 /*WM_KEYDOWN*/ ||
		uMsg == 0x101 /*WM_KEYUP*/ ||
		uMsg == 0x104 /*WM_SYSKEYDOWN*/ ||
		uMsg == 0x105 /*WM_SYSKEYUP*/ ||
		uMsg == 0x20A /*WM_MOUSEWHEEL*/ ) {
		nParamW = AkelPad.MemRead(_PtrAdd(lParam, _X64 ? 16 : 8) /*offsetof(MSG, nParamW)*/ , 2 /*DT_QWORD*/ );
		nParamL = AkelPad.MemRead(_PtrAdd(lParam, _X64 ? 24 : 12) /*offsetof(MSG, lParam)*/ , 2 /*DT_QWORD*/ );
		AkelPad.SendMessage(hWndListBox, uMsg, nParamW, nParamL);
		AkelPad.MemCopy(_PtrAdd(lParam, _X64 ? 8 : 4) /*offsetof(MSG, message)*/ , 0 /*WM_NULL*/ , 3 /*DT_DWORD*/ );
	}
}

function HookSendCallback(nCode, wParam, lParam) {
	var uMsg = AkelPad.MemRead(_PtrAdd(lParam, _X64 ? 16 : 8) /*offsetof(CWPSTRUCT, message)*/ , 3 /*DT_DWORD*/ );
	var nParamW;
	var nParamL;

	if (uMsg == 0x6 /*WM_SETFOCUS*/ ) {
		bNoSwitch = true;

		//Exit message loop
		oSys.Call("user32::PostQuitMessage", 0);
	}
}

function ListBoxCallback(hWnd, uMsg, wParam, lParam) {
	if (uMsg == 0x021 /*WM_MOUSEACTIVATE*/ ) {
		return 3 /*MA_NOACTIVATE*/ ;
	} else if (uMsg == 0x087 /*WM_GETDLGCODE*/ ) {
		AkelPad.WindowNoNextProc(hSubClass);
		return 0x4 /*DLGC_WANTALLKEYS*/ ;
	} else if (uMsg == 0x100 /*WM_KEYDOWN*/ ) {
		if (wParam == 0x43 /*c*/ ) {
			if (bCtrlTab || (oSys.Call("user32::GetKeyState", 0x11 /*VK_CONTROL*/ ) & 0x8000)) {
				i = AkelPad.SendMessage(hWndListBox, 0x188 /*LB_GETCURSEL*/ , 0, 0);
				AkelPad.SetClipboardText(lpFrameList[i][0]);
			}
		} else if (wParam == 0x9 /*VK_TAB*/ ) {
			var nCount;

			nCount = AkelPad.SendMessage(hWndListBox, 0x18B /*LB_GETCOUNT*/ , 0, 0);
			i = AkelPad.SendMessage(hWndListBox, 0x188 /*LB_GETCURSEL*/ , 0, 0);

			if (!(oSys.Call("user32::GetKeyState", 0x10 /*VK_SHIFT*/ ) & 0x8000)) {
				if (++i >= nCount)
					i = 0;
			} else {
				if (--i < 0)
					i = nCount - 1;
			}
			AkelPad.SendMessage(hWndListBox, 0x186 /*LB_SETCURSEL*/ , i, 0);
		} else if (wParam == 0xD /*VK_RETURN*/ ) {
			//Exit message loop
			oSys.Call("user32::PostQuitMessage", 0);
		} else if (wParam == 0x1B /*VK_ESCAPE*/ ) {
			bNoSwitch = true;

			//Exit message loop
			oSys.Call("user32::PostQuitMessage", 0);
		}
	} else if (uMsg == 0x101 /*WM_KEYUP*/ ) {
		if (wParam == 0x11 /*VK_CONTROL*/ ) {
			if (bCtrlTab) {
				//Exit message loop
				oSys.Call("user32::PostQuitMessage", 0);
			}
		}
	} else if (uMsg == 0x201 /*WM_LBUTTONDOWN*/ ) {
		var lResult = AkelPad.SendMessage(hWndListBox, 0x01A9 /*LB_ITEMFROMPOINT*/ , 0, lParam);

		if (HIWORD(lResult) == 0)
			AkelPad.SendMessage(hWndListBox, 0x186 /*LB_SETCURSEL*/ , LOWORD(lResult), 0);
		AkelPad.WindowNoNextProc(hSubClass);
	} else if (uMsg == 0x202 /*WM_LBUTTONUP*/ ||
		uMsg == 0x203 /*WM_LBUTTONDBLCLK*/ ) {
		if (uMsg == 0x203 /*WM_LBUTTONDBLCLK*/ || bSingleClick) {
			//Exit message loop
			oSys.Call("user32::PostQuitMessage", 0);
		}
	}
}

function GetFrameList(lpFrameList, lpAllList) {
	// var lpCurFrame=AkelPad.SendMessage(hMainWnd, 1288 /*AKD_FRAMEFIND*/, 1 /*FWF_CURRENT*/, 0);
	var lpInitFrame;
	var lpFrame;
	var pNumFind;
	var pStrFind = ":";
	var i;
	var j;
	var n;

	// Редактируемый участок 2
	lpInitFrame = AkelPad.SendMessage(hMainWnd, 1288 /*AKD_FRAMEFIND*/ , 8 /*FWF_BYTABINDEX*/ , 0);
	lpFrame = lpInitFrame;

	j = -1
	for (i = 0; lpFrame; ++i) {

		lpAllList[i] = [0, 0];
		lpAllList[i][0] = AkelPad.GetFilePath(AkelPad.MemRead(AkelPad.SendMessage(hMainWnd, 1223 /*AKD_GETFRAMEINFO*/ , 32 /*FI_FILEW*/ , lpFrame), 1 /*DT_UNICODE*/ ), 4 /*расширение*/ );
		lpAllList[i][1] = lpFrame;
		lpAllList[i][2] = AkelPad.MemRead(AkelPad.SendMessage(hMainWnd, 1223 /*AKD_GETFRAMEINFO*/ , 32 /*FI_FILEW*/ , lpFrame), 1 /*DT_UNICODE*/ );

// Если не найден то добавляем, иначе добавляем +1 к количеству, делая подсчёт однотипных
		if (pStrFind.indexOf(":" + lpAllList[i][0] + ":") === -1) {
			pStrFind += lpAllList[i][0] + ":"
			j += 1
			lpFrameList[j] = [0, 0];
			lpFrameList[j][0] = lpAllList[i][0];
			lpFrameList[j][1] = lpFrame;
// 			if (typeof(lpFrameList[j][2]) == "undefined") {
// 				lpFrameList[j][2] = 0
// 			}
			lpFrameList[j][2] = 1;
		} else {
			for (n = 0; n < lpFrameList.length; ++n) {
				if (lpAllList[i][0] === lpFrameList[n][0])
					lpFrameList[n][2] += 1;
			}
		}
		lpFrame = AkelPad.SendMessage(hMainWnd, 1288 /*AKD_FRAMEFIND*/ , 8 /*FWF_BYTABINDEX*/ , i + 1);
		if (lpFrame == lpInitFrame) break;
	}
	lpFrameList.sort(SortNum) // но сортируется по первой колонке, не то что требуется
	
	if (lpAllList.length < nMinTabs)
	{
		WScript.Quit();
	}

// делаем ширину пунктов одинаковой, для пунктов от 1 до 9 добавляем пробел слева
	for (i = 0; i < lpFrameList.length; ++i) {
		if (10 > lpFrameList[i][2])
		{
			lpFrameList[i][0] = "  " + lpFrameList[i][2] +" - " + lpFrameList[i][0];
		} else {
			lpFrameList[i][0] = lpFrameList[i][2] +" - " + lpFrameList[i][0];
		}
	}
	// Конец Редактируемый участок 2
	return 0;
}

function SortNum(a, b){
	return b[2] - a[2];
//     if(a < b)
//         return -1
//     if(a > b)
//         return 1
//     return 0
}

function CreateFont(pFaceName, nFontStyle, nPointSize) {
	//Release it with: oSys.Call("gdi32::DeleteObject", hFont);
	var lpLogFontSrc;
	var lpLogFontDst;
	var hDC;
	var hFont = 0;
	var nHeight;
	var nWeight;
	var nItalic;

	if (lpLogFontDst = AkelPad.MemAlloc(92 /*sizeof(LOGFONTW)*/ )) {
		lpLogFontSrc = AkelPad.SendMessage(hMainWnd, 1223 /*AKD_GETFRAMEINFO*/ , 48 /*FI_EDITFONTW*/ , 0);
		oSys.Call("kernel32::RtlMoveMemory", lpLogFontDst, lpLogFontSrc, 92 /*sizeof(LOGFONTW)*/ );

		if (nPointSize) {
			if (hDC = oSys.Call("user32::GetDC", hMainWnd)) {
				nHeight = -oSys.Call("kernel32::MulDiv", nPointSize, oSys.Call("gdi32::GetDeviceCaps", hDC, 90 /*LOGPIXELSY*/ ), 72);
				AkelPad.MemCopy(_PtrAdd(lpLogFontDst, 0) /*offsetof(LOGFONTW, lfHeight)*/ , nHeight, 3 /*DT_DWORD*/ );
				oSys.Call("user32::ReleaseDC", hMainWnd, hDC);
			}
		}
		if (nFontStyle != 0 /*FS_NONE*/ ) {
			nWeight = (nFontStyle == 2 /*FS_FONTBOLD*/ || nFontStyle == 4 /*FS_FONTBOLDITALIC*/ ) ? 700 /*FW_BOLD*/ : 400 /*FW_NORMAL*/ ;
			AkelPad.MemCopy(_PtrAdd(lpLogFontDst, 16) /*offsetof(LOGFONTW, lfWeight)*/ , nWeight, 3 /*DT_DWORD*/ );
			nItalic = (nFontStyle == 3 /*FS_FONTITALIC*/ || nFontStyle == 4 /*FS_FONTBOLDITALIC*/ ) ? 1 : 0;
			AkelPad.MemCopy(_PtrAdd(lpLogFontDst, 20) /*offsetof(LOGFONTW, lfItalic)*/ , nItalic, 5 /*DT_BYTE*/ );
		}
		if (_TSTR == 0 /*DT_ANSI*/ && !pFaceName)
			pFaceName = AkelPad.MemRead(_PtrAdd(lpLogFontDst, 28) /*offsetof(LOGFONTW, lfFaceName)*/ , 1 /*DT_UNICODE*/ );
		if (pFaceName)
			AkelPad.MemCopy(_PtrAdd(lpLogFontDst, 28) /*offsetof(LOGFONTW, lfFaceName)*/ , pFaceName.substr(0, 32 /*LF_FACESIZE*/ ), _TSTR);

		hFont = oSys.Call("gdi32::CreateFontIndirect" + _TCHAR, lpLogFontDst);
		AkelPad.MemFree(lpLogFontDst);
	}
	return hFont;
}

function GetCursorPos(ptPoint) {
	var lpPoint;

	ptPoint.x = 0;
	ptPoint.y = 0;

	if (lpPoint = AkelPad.MemAlloc(8 /*sizeof(POINT)*/ )) {
		if (oSys.Call("user32::GetCursorPos", lpPoint)) {
			ptPoint.x = AkelPad.MemRead(_PtrAdd(lpPoint, 0) /*offsetof(POINT, x)*/ , 3 /*DT_DWORD*/ );
			ptPoint.y = AkelPad.MemRead(_PtrAdd(lpPoint, 4) /*offsetof(POINT, y)*/ , 3 /*DT_DWORD*/ );
		}
		AkelPad.MemFree(lpPoint);
	}
}

function RectToArray(lpRect, rcRect) {
	rcRect.left = AkelPad.MemRead(_PtrAdd(lpRect, 0) /*offsetof(RECT, left)*/ , 3 /*DT_DWORD*/ );
	rcRect.top = AkelPad.MemRead(_PtrAdd(lpRect, 4) /*offsetof(RECT, top)*/ , 3 /*DT_DWORD*/ );
	rcRect.right = AkelPad.MemRead(_PtrAdd(lpRect, 8) /*offsetof(RECT, right)*/ , 3 /*DT_DWORD*/ );
	rcRect.bottom = AkelPad.MemRead(_PtrAdd(lpRect, 12) /*offsetof(RECT, bottom)*/ , 3 /*DT_DWORD*/ );
	return rcRect;
}

function GetWindowSize(hWnd, hWndOwner, rcRect) {
	var lpRect;
	var bResult = false;

	if (lpRect = AkelPad.MemAlloc(16 /*sizeof(RECT)*/ )) {
		if (oSys.Call("user32::GetWindowRect", hWnd, lpRect)) {
			RectToArray(lpRect, rcRect);
			rcRect.right -= rcRect.left;
			rcRect.bottom -= rcRect.top;

			if (hWndOwner)
				bResult = oSys.Call("user32::ScreenToClient", hWndOwner, lpRect);
			else
				bResult = true;
			rcRect.left = AkelPad.MemRead(_PtrAdd(lpRect, 0) /*offsetof(RECT, left)*/ , 3 /*DT_DWORD*/ );
			rcRect.top = AkelPad.MemRead(_PtrAdd(lpRect, 4) /*offsetof(RECT, top)*/ , 3 /*DT_DWORD*/ );
		}
		AkelPad.MemFree(lpRect);
	}
	return bResult;
}

function LOWORD(dwNumber) {
	return (dwNumber & 0xffff);
}

function HIWORD(dwNumber) {
	return (dwNumber >> 16);
}

function MAKELONG(a, b) {
	return (a & 0xffff) | ((b & 0xffff) << 16);
}

Description(1033): Closes tabs of the specified type, for example, all htm files
Description(1049): Закрывает вкладки определённого типа, например все htm-файлы

Показывает список расширений и число вкладок для каждого типа, которые будут закрыты при клике на пункте.
Image

Обновлено: добавлена сортировка по числу
Обновлено: добавлен ключ -Ask=true, чтобы выдавать имена закрываемых файлов, и возможность отмены закрытия.
Post Reply