Временное меню с иконками, как?

Russian main discussion
Post Reply
  • Author
  • Message
Offline
Posts: 348
Joined: Mon Jun 03, 2019 2:33 am

Временное меню с иконками, как?

Post by AZJIO »

Изучая js у меня получилось сделать временное меню, но хотелось бы с иконками.
Не так давно добавил скрипт TabSwitch.js и время спустя вспомнил, почему бы сделать своё меню аналогично?

Начал смотреть код, там массив lpFrameList отвечает за пукнты меню, формируются они в функции GetFrameList.

иконку берёт с вкладки

Code: Select all

    //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*/);
То есть иконку надо взять используя ExtractIconEx из WinAPI.

Может кто сделает готовые функции, чтобы только указывать пункты меню, иконки, события в некотором массиве строк в начале скрипта, потому что для меня это пока выглядит нереально.

YuS
Offline
Posts: 513
Joined: Sun Sep 15, 2013 8:25 am
Location: 013 в Тентуре, семь по Спирали, налево от Большой Медведицы

Re: Временное меню с иконками, как?

Post by YuS »

AZJIO wrote:Изучая js у меня получилось сделать временное меню, но хотелось бы с иконками.
А этого не достаточно:
ContextMenu-Rus.txt wrote: Создание пункта меню:
[-]"[текст пункта меню]" [Command() | Call() | +Call() | Exec() | OpenFile() | SaveFile() | Font() | Recode() | Insert() | Link() | Favourites() | Menu()] [Icon()]
...
Icon(["файл"][, индекс])
Icon("Shell32.dll", 47)
иконка находится в файле Shell32.dll под индексом 47.
Icon("%a\AkelFiles\Plugs\Explorer.dll")
иконка находится в файле Explorer.dll под индексом 0.
Icon("%a\AkelFiles\Plugs\Toolbar\MyIcon.ico")
иконка находится в файле MyIcon.ico.
Icon(12)
иконка находится в файле ContextMenu.dll под индексом 12.
?

ЗЫ
Что такое "временное меню", увидеть не могу, ибо pastebin.com для меня недоступен...

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

Re: Временное меню с иконками, как?

Post by AZJIO »

YuS wrote:А этого не достаточно:
Плаг ContextMenu настраивает/регулирует 6 меню, а тот что в скрипте (использует ShowMenu.js) создаёт меню на момент выбора из меню, а после клика всё уничтожается, память особождается. Посмотри в моей сборке Menu_by_type.js по клавише F8.
YuS wrote:ЗЫ
Что такое "временное меню", увидеть не могу, ибо pastebin.com для меня недоступен...
на момент вызова появляется.

Как вариант можно создать подменю в "Меню ContextMenu::Show", а потом вызвать его по имени или по номеру пункта:

Code: Select all

"Под-меню 23 BBCode" Call("ContextMenu::Show", 1, "-1", "-1", 23)
"Под-меню BBCode" Call("ContextMenu::Show", 1, "-6", "-6", -1, "BBCODE")

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

Re: Временное меню с иконками, как?

Post by VladSh »

YuS wrote:Что такое "временное меню", увидеть не могу, ибо pastebin.com для меня недоступен...
Все скрипты, что используют ShowMenu.js или ShowMenuEx.js (в этом случае списки настраиваются в ini- или json-файлах).
Можно, например, склеить ProcessFolderFiles.js и ShowMenu.js - получаем список файлов в папке, налету генерим меню с помощью ShowMenu.js и после выбора имени файла, к примеру, удаляем его.

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

Post by AZJIO »

Попробовал сделать функцию ExtractIconEx

Code: Select all

var oSys=AkelPad.SystemFunction();

//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*/);

// var hInstDLL = AkelPad.GetInstanceDll();
// var hIcon    = oSys.Call("User32::LoadImageW", hInstDLL, 101 /*lpszName*/, 1 /*uType=IMAGE_ICON*/, 16 /*cxDesired*/, 16 /*cyDesired*/, 0 /*fuLoad*/);


var phIcon=AkelPad.MemAlloc(_X64?8:4 /*sizeof(HWND)*/) // указатель на декскриптор иконки
// var sFile = "C:\\icon.ico"; // путь к иконке
var sFile = "C:\\Windows\\System32\\Shell32.dll"; // путь к иконке
var lpFile = AkelPad.MemAlloc(260 * 2); // Выделяем память и получаем указатель
AkelPad.MemCopy(lpFile, sFile, 0 /*DT_ANSI*/); // Копируем путь в указатель
oSys.Call("Shell32::ExtractIconEx", lpFile, 0 /* IndexIcon */, 0, phIcon, 1); // Получает иконку из файла 16x16
var count = oSys.Call("Shell32::ExtractIconEx", lpFile, -1 /* IndexIcon */, null, null, 1); // число значков в DLL (проверка успеха функции)
// oSys.Call("Shell32::ExtractIconEx", lpFile, 0 /* IndexIcon */, phIcon, 0, 1); // Получает иконку из файла 32x32
hIcon=AkelPad.MemRead(phIcon, 2 /*DT_QWORD*/);
WScript.Echo(" " + count); // число значков в DLL

/* ExtractIconEx (
LPCTSTR lpszFile,
int     nIconIndex,
HICON   *phiconLarge,
HICON   *phiconSmall,
UINT    nIcons
)
*/

WScript.Echo(" " + hIcon); // дескриптор иконки, почему то 0
WScript.Echo(" " + phIcon); // указатель на дескриптор иконки
oSys.Call("User32::DestroyIcon", hIcon);
AkelPad.MemFree(lpFile);
AkelPad.MemFree(phIcon);
- заработала, DT_UNICODE сменил на DT_ANSI и иконка применилась к окну и показала дескриптор.

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

Post by AZJIO »

Code: Select all

// Используя скрипт TabSwitch (Instructor) удалось переделать его в собственное меню.
// Смотреть строки 36 (пункты меню) и 60 (команды)
//
// Ниже старые параметры ком строки, из которых я часть удалил и выпилил из скрипта за неактуальностью
//  `-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, "MyMenu.js", `-WindowLeft=%bl -WindowTop=%bb`)
// ContextMenu item example:
//   -"Моё меню" Call("Scripts::Main", 1, "MyMenu.js", `-WindowLeft=-2 -WindowTop=-2`)

function GetFrameList(lpFrameList) {
	var i=0;

// Здесь создаём пункты меню, копируя блок
	lpFrameList[i] = [0, 0];
	lpFrameList[i][0] = "Пункт " + i;
	// lpFrameList[i][1] = 1; // временно не используется, будет удалён или задействован
	lpFrameList[i][1] = GetIcon("C:\\Windows\\System32\\Shell32.dll", 32);
	++i;

	lpFrameList[i] = [0, 0];
	lpFrameList[i][0] = "Пункт " + i;
	lpFrameList[i][1] = GetIcon("C:\\icon.ico", 0);
	++i;

	lpFrameList[i] = [0, 0];
	lpFrameList[i][0] = "Пункт " + i;
	lpFrameList[i][1] = 0; // без иконки
	++i;

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

// Здесь создаём команды пунктов меню.
function Execute(idx_item) {
	switch(idx_item) { //сравнение ==
		case 0:
			AkelPad.MessageBox(hMainWnd, 'Выбран пункт "' + lpFrameList[idx_item][0] + '"', WScript.ScriptName, 48);
			break;
		case 1:
			AkelPad.MessageBox(hMainWnd, 'Выбран пункт "' + lpFrameList[idx_item][0] + '"', WScript.ScriptName, 48);
			break;
		case 2:
			AkelPad.MessageBox(hMainWnd, 'Выбран пункт "' + lpFrameList[idx_item][0] + '"', WScript.ScriptName, 48);
			break;
	}
}

//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 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 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 sFile = "C:\\Windows\\System32\\Shell32.dll"; // путь к иконке
	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]);
	}
}
- собственно адаптированный скрипт на онове TabSwitch.js. Понятие "вкладки" полностью выпилено. Нужно всего лишь добавлять пункты меню и команды в строке от 36 по 73.
Обновил 4 раза.

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

Post by AZJIO »

Code: Select all

// Используя скрипт TabSwitch (Instructor) удалось переделать его в собственное меню.
// Смотреть строки 38 (пункты меню) и 282 (команды)
//
// Ниже старые параметры ком строки, из которых я часть удалил и выпилил из скрипта за неактуальностью
//  `-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, "MyMenu.js", `-WindowLeft=%bl -WindowTop=%bb`)
// ContextMenu item example:
//   -"Моё меню" Call("Scripts::Main", 1, "MyMenu.js", `-WindowLeft=-2 -WindowTop=-2`)
function GetFrameList(lpFrameList) {
	var i = 0;
	// Здесь создаём пункты меню, копируя блок
	switch (sFileExt) {

		case "js":
			lpFrameList[i] = [0, 0];
			lpFrameList[i][0] = "sBeautifier (Tidy)";
			lpFrameList[i][1] = GetIcon(pPath + "\\AkelFiles\\Plugs\\Scripts.dll", 0);
			++i;

			lpFrameList[i] = [0, 0];
			lpFrameList[i][0] = "RegExpTestJS";
			lpFrameList[i][1] = GetIcon(pPath + "\\AkelFiles\\Plugs\\Scripts.dll", 0);
			++i;

			lpFrameList[i] = [0, 0];
			lpFrameList[i][0] = "Прыжок к функции";
			lpFrameList[i][1] = GetIcon(pPath + "\\AkelFiles\\icons\\ToolbarEx.dll", 46);
			++i;

			var sAutoitPath = "C:\\AutoIt3\\";
			lpFrameList[i] = [0, 0];
			lpFrameList[i][0] = "Отладчик в буфер";
			lpFrameList[i][1] = GetIcon(sAutoitPath + "Tools\\debugger.ico", 0);
			++i;

			lpFrameList[i] = [0, 0];
			lpFrameList[i][0] = "JS.chm";
			lpFrameList[i][1] = GetIcon("C:\\Windows\\System32\\HH.exe", 0);
			++i;

			lpFrameList[i] = [0, 0];
			lpFrameList[i][0] = "JS.chm (поиск)";
			lpFrameList[i][1] = GetIcon("C:\\Windows\\System32\\HH.exe", 0);
			++i;

			lpFrameList[i] = [0, 0];
			lpFrameList[i][0] = "wsh.chm (поиск)";
			lpFrameList[i][1] = GetIcon("C:\\Windows\\System32\\HH.exe", 0);
			++i;
			break;

		case "reg":
			lpFrameList[i] = [0, 0];
			lpFrameList[i][0] = "Открыть выделенный раздел реестра";
			lpFrameList[i][1] = GetIcon("C:\\Windows\\regedit.exe", 0);
			++i;

			var wsh = new ActiveXObject("WScript.Shell");
			var APPDATA = wsh.ExpandEnvironmentStrings("%APPDATA%")
			lpFrameList[i] = [0, 0];
			lpFrameList[i][0] = "Запуск JumpReg";
			lpFrameList[i][1] = GetIcon(APPDATA + '\\AZJIO_Soft\\JumpReg\\JumpReg.exe', 0);
			++i;

			lpFrameList[i] = [0, 0];
			lpFrameList[i][0] = "Поиск в реестре";
			lpFrameList[i][1] = GetIcon(APPDATA + '\\AZJIO_Soft\\JumpReg\\RegScanner\\RegScanner.exe', 0);
			++i;
			break;

		case "htm":
		case "html":
			lpFrameList[i] = [0, 0];
			lpFrameList[i][0] = "Генерировать ссылку на этот файл";
			lpFrameList[i][1] = GetIcon(pPath + "\\AkelFiles\\Plugs\\Scripts.dll", 0);
			++i;

			lpFrameList[i] = [0, 0];
			lpFrameList[i][0] = "Tidy";
			lpFrameList[i][1] = 0;
			++i;

			lpFrameList[i] = [0, 0];
			lpFrameList[i][0] = "Вставить html-таблицу";
			lpFrameList[i][1] = GetIcon(pPath + "\\AkelFiles\\icons\\ico\\table.ico", 0);
			++i;
			break;

		case "pb":
		case "pbi":
			lpFrameList[i] = [0, 0];
			lpFrameList[i][0] = "Запуск";
			// lpFrameList[i][1] = GetIcon(pPath + "\\AkelFiles\\icons\\ToolbarEx.dll", 17);
			// lpFrameList[i][1] = GetIcon("C:\\WINDOWS\\System32\\wmploc.dll", 91);
			lpFrameList[i][1] = GetIcon("C:\\WINDOWS\\System32\\shell32.dll", 137);
			++i;

			lpFrameList[i] = [0, 0];
			lpFrameList[i][0] = "Компилировать в EXE";
			lpFrameList[i][1] = GetIcon(pPath + "\\AkelFiles\\icons\\ToolbarEx.dll", 50);
			++i;

			lpFrameList[i] = [0, 0];
			lpFrameList[i][0] = "Check";
			lpFrameList[i][1] = GetIcon("C:\\Windows\\System32\\Shell32.dll", 23);
			++i;

			lpFrameList[i] = [0, 0];
			lpFrameList[i][0] = "Debugger";
			lpFrameList[i][1] = GetIcon(pPath + "\\AkelFiles\\icons\\ToolbarEx.dll", 53);
			++i;

			lpFrameList[i] = [0, 0];
			lpFrameList[i][0] = "Справка (RU)";
			lpFrameList[i][1] = GetIcon("C:\\Windows\\System32\\HH.exe", 0);
			++i;

			lpFrameList[i] = [0, 0];
			lpFrameList[i][0] = "Прыжок к процедуре";
			lpFrameList[i][1] = GetIcon(pPath + "\\AkelFiles\\icons\\ToolbarEx.dll", 46);
			++i;

			lpFrameList[i] = [0, 0];
			lpFrameList[i][0] = "Получить asm-код";
			lpFrameList[i][1] = GetIcon("C:\\WINDOWS\\System32\\shell32.dll", 137);
			++i;

			lpFrameList[i] = [0, 0];
			lpFrameList[i][0] = "Препроцессинг";
			lpFrameList[i][1] = GetIcon("C:\\WINDOWS\\System32\\shell32.dll", 137);
			++i;

			lpFrameList[i] = [0, 0];
			lpFrameList[i][0] = "Компилировать в DLL";
			lpFrameList[i][1] = GetIcon(pPath + "\\AkelFiles\\icons\\ToolbarEx.dll", 50);
			++i;
			break;

		case "au3":
			var sAutoitPath = "C:\\AutoIt3\\";
			lpFrameList[i] = [0, 0];
			lpFrameList[i][0] = "Запуск";
			// lpFrameList[i][1] = GetIcon(pPath + "\\AkelFiles\\icons\\ToolbarEx.dll", 17);
			// lpFrameList[i][1] = GetIcon("C:\\WINDOWS\\System32\\wmploc.dll", 91);
			lpFrameList[i][1] = GetIcon("C:\\WINDOWS\\System32\\shell32.dll", 137);
			++i;

			lpFrameList[i] = [0, 0];
			lpFrameList[i][0] = "Запуск + Консоль";
			// lpFrameList[i][1] = GetIcon(pPath + "\\AkelFiles\\icons\\ToolbarEx.dll", 17);
			// lpFrameList[i][1] = GetIcon("C:\\WINDOWS\\System32\\wmploc.dll", 91);
			lpFrameList[i][1] = GetIcon("C:\\WINDOWS\\System32\\shell32.dll", 137);
			++i;

			lpFrameList[i] = [0, 0];
			lpFrameList[i][0] = "Tidy";
			lpFrameList[i][1] = GetIcon(sAutoitPath + "SciTE\\Tidy\\Tidy.exe", 0);
			++i;

			lpFrameList[i] = [0, 0];
			lpFrameList[i][0] = "Au3Info";
			lpFrameList[i][1] = GetIcon("C:\\AutoIt3\\Au3Info.exe", 0);
			++i;

			lpFrameList[i] = [0, 0];
			lpFrameList[i][0] = "Компилировать";
			lpFrameList[i][1] = GetIcon(sAutoitPath + "SciTE\\AutoIt3Wrapper\\AutoIt3Wrapper.exe", 0);
			++i;

			lpFrameList[i] = [0, 0];
			lpFrameList[i][0] = "Include Helper";
			lpFrameList[i][1] = GetIcon(sAutoitPath + "Tools\\Include_Helper.ico", 0);
			++i;

			lpFrameList[i] = [0, 0];
			lpFrameList[i][0] = "Прыжок к функции";
			lpFrameList[i][1] = GetIcon(pPath + "\\AkelFiles\\icons\\ToolbarEx.dll", 46);
			++i;

			lpFrameList[i] = [0, 0];
			lpFrameList[i][0] = "Справка (RU)";
			lpFrameList[i][1] = GetIcon("C:\\Windows\\System32\\HH.exe", 0);
			++i;

			lpFrameList[i] = [0, 0];
			lpFrameList[i][0] = "Выделенный текст в AU3";
			lpFrameList[i][1] = GetIcon(pPath + "\\AkelFiles\\icons\\ToolbarEx.dll", 54);
			++i;

			lpFrameList[i] = [0, 0];
			lpFrameList[i][0] = "Список переменных и функций";
			lpFrameList[i][1] = GetIcon(pPath + "\\AkelFiles\\icons\\ToolbarEx.dll", 37);
			++i;

			lpFrameList[i] = [0, 0];
			lpFrameList[i][0] = "Переименование переменных";
			lpFrameList[i][1] = GetIcon(pPath + "\\AkelFiles\\icons\\ToolbarEx.dll", 42);
			++i;

			lpFrameList[i] = [0, 0];
			lpFrameList[i][0] = "Выделенные переменные в отладчик";
			lpFrameList[i][1] = GetIcon(sAutoitPath + "Tools\\debugger.ico", 0);
			++i;

			lpFrameList[i] = [0, 0];
			lpFrameList[i][0] = "Запуск с v3.3.14.3";
			// lpFrameList[i][1] = GetIcon(pPath + "\\AkelFiles\\icons\\ToolbarEx.dll", 17);
			// lpFrameList[i][1] = GetIcon("C:\\WINDOWS\\System32\\wmploc.dll", 91);
			lpFrameList[i][1] = GetIcon("C:\\WINDOWS\\System32\\shell32.dll", 137);
			++i;
			break;

		case "bas":
		case "bi":
			lpFrameList[i] = [0, 0];
			lpFrameList[i][0] = "Компилировать GUI";
			lpFrameList[i][1] = GetIcon(pPath + "\\AkelFiles\\icons\\ToolbarEx.dll", 50);
			++i;

			lpFrameList[i] = [0, 0];
			lpFrameList[i][0] = "Компилировать";
			lpFrameList[i][1] = GetIcon(pPath + "\\AkelFiles\\icons\\ToolbarEx.dll", 50);
			++i;

			lpFrameList[i] = [0, 0];
			lpFrameList[i][0] = "Компилировать DLL";
			lpFrameList[i][1] = GetIcon(pPath + "\\AkelFiles\\icons\\ToolbarEx.dll", 50);
			++i;

			lpFrameList[i] = [0, 0];
			lpFrameList[i][0] = "Проверка кода";
			lpFrameList[i][1] = GetIcon("C:\\Windows\\System32\\Shell32.dll", 23);
			++i;

			lpFrameList[i] = [0, 0];
			lpFrameList[i][0] = "Выдать asm-код";
			lpFrameList[i][1] = GetIcon(pPath + "\\AkelFiles\\icons\\ToolbarEx.dll", 42);
			++i;

			lpFrameList[i] = [0, 0];
			lpFrameList[i][0] = "Выдать c-код";
			lpFrameList[i][1] = GetIcon(pPath + "\\AkelFiles\\icons\\ToolbarEx.dll", 42);
			++i;

			lpFrameList[i] = [0, 0];
			lpFrameList[i][0] = "Прыжок к функции";
			lpFrameList[i][1] = GetIcon(pPath + "\\AkelFiles\\icons\\ToolbarEx.dll", 46);
			++i;

			lpFrameList[i] = [0, 0];
			lpFrameList[i][0] = "Справка";
			lpFrameList[i][1] = GetIcon("C:\\Windows\\System32\\HH.exe", 0);
			++i;

			lpFrameList[i] = [0, 0];
			lpFrameList[i][0] = "Версия компилятора";
			lpFrameList[i][1] = GetIcon("C:\\Windows\\System32\\Shell32.dll", 23);
			++i;
			break;

	}

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

// Здесь создаём команды пунктов меню.
function Execute(idx_item) {
	switch (sFileExt) {

		case "bas":
		case "bi":
			var sFreeBASICPath = "C:\\Program Files (x86)\\FreeBASIC\\";
			switch (idx_item) { //сравнение ==
				case 0:
					AkelPad.Call("Log::Output", 1, '"' + sFreeBASICPath + 'fbc.exe" "' + sEditFile + '" -exx -s gui', "", '^Error: Line (\d+)', '/GOTOLINE=\1:1', 866, 1251);
					break;
				case 1:
					AkelPad.Call("Log::Output", 1, '"' + sFreeBASICPath + 'fbc.exe" "' + sEditFile + '" -exx -s console', "", '^Error: Line (\d+)', '/GOTOLINE=\1:1', 866, 1251);
					break;
				case 2:
					AkelPad.Call("Log::Output", 1, '"' + sFreeBASICPath + 'fbc.exe" "' + sEditFile + '" -exx -dll', "", '^Error: Line (\d+)', '/GOTOLINE=\1:1', 866, 1251);
					break;
				case 3:
					AkelPad.Call("Log::Output", 1, '"' + sFreeBASICPath + 'fbc.exe" "' + sEditFile + '" -exx', "", '^Error: Line (\d+)', '/GOTOLINE=\1:1', 866, 1251);
					break;
				case 4:
					AkelPad.Call("Log::Output", 1, '"' + sFreeBASICPath + 'fbc.exe" "' + sEditFile + '" -r', "", '^Error: Line (\d+)', '/GOTOLINE=\1:1', 866, 1251);
					break;
				case 5:
					AkelPad.Call("Log::Output", 1, '"' + sFreeBASICPath + 'fbc.exe" "' + sEditFile + '" -gen gcc', "", '^Error: Line (\d+)', '/GOTOLINE=\1:1', 866, 1251);
					break;
				case 6:
					// AkelPad.TextFind(hWndEdit, 'function ' + sSelText, 0x00000001 | 0x00200000 /*FRF_DOWN|FRF_BEGINNING*/ );
					AkelPad.TextFind(hWndEdit, 'function[ \\t]+\\K' + sSelText + '(?=[ \\t]*\\()', 0x00000001 | 0x00200000 | 0x00080000 /*FRF_DOWN | FRF_BEGINNING | FRF_REGEXP*/ );
					break;
				case 7:
					// AkelPad.Exec('"' + sFreeBASICPath + 'FB-manual-0.23.0.chm" "' + sSelText + ' bas');
					AkelPad.Exec('"%a\\AkelFiles\\Tools\\Help\\Help.exe" ' + sSelText + ' bas');
					break;
				case 8:
					AkelPad.Call("Log::Output", 1, '"' + sFreeBASICPath + 'fbc.exe" -version', "", '^Error: Line (\d+)', '/GOTOLINE=\1:1', 866, 1251);
					break;
			}
			break;

		case "js":
			switch (idx_item) { //сравнение ==
				case 0:
					AkelPad.Call("Scripts::Main", 1, "jsBeautifier.js", "")
					break;
				case 1:
					AkelPad.Call("Scripts::Main", 1, "RegExpTestJS.js", "")
					break;
				case 2:
					// AkelPad.TextFind(hWndEdit, 'function ' + sSelText, 0x00000001 | 0x00200000 /*FRF_DOWN|FRF_BEGINNING*/ );
					AkelPad.TextFind(hWndEdit, 'function[ \\t]+\\K' + sSelText + '(?=[ \\t]*\\()', 0x00000001 | 0x00200000 | 0x00080000 /*FRF_DOWN | FRF_BEGINNING | FRF_REGEXP*/ );
					break;
				case 3:
					AkelPad.SetClipboardText('\nWScript.Echo(' + sSelText + ');');
					break;
				case 4:
					AkelPad.Exec("HH.exe %a\\AkelFiles\\Help\\JS.chm::/html/RegExp.html");
					break;
				case 5:
					var sAutoitPath = "C:\\AutoIt3\\";
					// AkelPad.Exec('"' + sAutoitPath + 'AutoIt3.exe" "%a\\AkelFiles\\Tools\\Help\\Help.au3" ' + sSelText + ' js');
					AkelPad.Exec('"%a\\AkelFiles\\Tools\\Help\\Help.exe" ' + sSelText + ' js');
					break;
				case 6:
					AkelPad.Exec('"%a\\AkelFiles\\Tools\\Help\\Help.exe" ' + sSelText + ' wsh');
					break;
			}
			break;

		case "reg":
			switch (idx_item) { //сравнение ==
				case 0:
					var sAutoitPath = "C:\\AutoIt3\\";
					// добавьте #RequireAdmin в начало скрипта JumpRegCMD.au3
					AkelPad.Exec('"' + sAutoitPath + 'AutoIt3.exe" "' + sAutoitPath + 'Tools\\JumpRegCMD.au3" "' + sSelText + '"');
					break;
				case 1:
					var wsh = new ActiveXObject("WScript.Shell");
					var APPDATA = wsh.ExpandEnvironmentStrings("%APPDATA%")
					// AkelPad.Exec('"' + APPDATA + '\\AZJIO_Soft\\JumpReg\\JumpReg.exe" "' + sSelText + '"'); // прыжок в реестр
					AkelPad.Exec('"' + APPDATA + '\\AZJIO_Soft\\JumpReg\\JumpReg.exe"');
					break;
				case 2:
					var wsh = new ActiveXObject("WScript.Shell");
					var APPDATA = wsh.ExpandEnvironmentStrings("%APPDATA%")
					AkelPad.Exec('"' + APPDATA + '\\AZJIO_Soft\\JumpReg\\RegScanner\\RegScanner.exe"');
					break;
			}
			break;

		case "htm":
		case "html":
			switch (idx_item) { //сравнение ==
				case 0:
					var sText = AkelPad.ReadFile(sEditFile);
					if (/<title>(.+?)<\/title>/.test(sText)) {
						sText = RegExp.$1;
						var sFileName = AkelPad.GetFilePath(sEditFile, 3);
						AkelPad.SetClipboardText('<a href="' + sFileName + '.htm">' + sText + '</a>');
					}
					break;
				case 1:
					AkelPad.Call("Scripts::Main", 1, "tidy.js", "")
					break;
				case 2:
					AkelPad.Call("Scripts::Main", 1, "ins_html_table.js", "")
					break;
			}
			break;

		case "pb":
		case "pbi":
			var sPBPath = "C:\\D\\PureBasic\\Purebasic 5.70 x86\\";
			switch (idx_item) { //сравнение ==
				case 0:
					AkelPad.Call("Log::Output", 1, '"' + sPBPath + 'Compilers\\pbcompiler.exe" /XP /DPIAWARE -q "' + sEditFile + '"', "%temp%", '^Error: Line (\d+)', '/GOTOLINE=\1:1', 866, 1251);
					break;
				case 1:
					//  IconFindSource() - поиск иконки в исходнике для компиляции с иконкой
					//  ExeFindSource() - поиск  Exe-файла в исходнике для компиляции с заданным именем
					AkelPad.Call("Log::Output", 1, '"' + sPBPath + 'Compilers\\pbcompiler.exe" "' + sEditFile + '" /XP /DPIAWARE -q /EXE "' + ExeFindSource(sEditFile, 'exe') + '"' + IconFindSource(sEditFile), "", '^Error: Line (\d+)', '/GOTOLINE=\1:1', 866, 1251);
					break;
				case 2:
					AkelPad.Call("Log::Output", 1, '"' + sPBPath + 'Compilers\\pbcompiler.exe" "' + sEditFile + '" /XP /DPIAWARE -k', "", '^Error: Line (\d+)', '/GOTOLINE=\1:1', 866, 1251);
					break;
				case 3:
					AkelPad.Call("Log::Output", 1, '"' + sPBPath + 'Compilers\\pbcompiler.exe" "' + sEditFile + '" /XP /DPIAWARE --debugger', "%temp%", '^Error: Line (\d+)', '/GOTOLINE=\1:1', 866, 1251);
					break;
				case 4:
					// AkelPad.Exec('"' + sAutoitPath + 'AutoIt3.exe" "' + sPBPath + 'Instrument_azjio\\Help\\Help.au3" ' + sSelText + ' 1');
					AkelPad.Exec('"%a\\AkelFiles\\Tools\\Help\\Help.exe" ' + sSelText + ' pb');
					break;
				case 5:
					// AkelPad.TextFind(hWndEdit, 'Procedure ' + sSelText, 0x00000001 | 0x00200000 /*FRF_DOWN|FRF_BEGINNING*/ );
					AkelPad.TextFind(hWndEdit, 'Procedure[CDL]*[ \\t]+\\K' + sSelText + '(?=[ \\t]*\\()', 0x00000001 | 0x00200000 | 0x00080000 /*FRF_DOWN | FRF_BEGINNING | FRF_REGEXP*/ );
					break;
				case 6:
// 					var fso = new ActiveXObject("Scripting.FileSystemObject");
// 					var pTmp = sFileDir + '\\PureBasic.exe'
// 					fNotExists = 0
// 					if (!fso.FileExists(pTmp))
// 					{
// 						fNotExists = 1
// 					}
					AkelPad.Call("Log::Output", 1, '"' + sPBPath + 'Compilers\\pbcompiler.exe" /XP /DPIAWARE -q /COMMENTED "' + sEditFile + '"', sFileDir, '^Error: Line (\d+)', '/GOTOLINE=\1:1', 866, 1251);
// 					if (fNotExists = 1)
// 					{
// 						WScript.Sleep(2000);
// 						if (fso.FileExists(pTmp))
// 						{
// 							fso.DeleteFile(pTmp, 1);
// 						}
// 					}
					break;
				case 7:
					AkelPad.Call("Log::Output", 1, '"' + sPBPath + 'Compilers\\pbcompiler.exe" /XP /DPIAWARE -q "' + sEditFile + '" -pp "' + sEditFile.slice(0,-(sFileExt.length + 1)) + '_pp.pb"', sFileDir, '^Error: Line (\d+)', '/GOTOLINE=\1:1', 866, 1251);
					break;
				case 8:
					AkelPad.Call("Log::Output", 1, '"' + sPBPath + 'Compilers\\pbcompiler.exe" "' + sEditFile + '" /XP /DPIAWARE -q /EXE "' + ExeFindSource(sEditFile, 'dll') + '" /DLL', "", '^Error: Line (\d+)', '/GOTOLINE=\1:1', 866, 1251);
					break;
			}
			break;

		case "au3":
			var sAutoitPath = "C:\\AutoIt3\\";
			switch (idx_item) { //сравнение ==
				case 0:
					AkelPad.Exec('"' + sAutoitPath + 'AutoIt3.exe" "' + sEditFile + '"');
					break;
				case 1:
					AkelPad.Call("Log::Output", 1, '"' + sAutoitPath + 'AutoIt3.exe" "' + sEditFile + '"', '', '', '', 866, 1251)
					break;
				case 2:
					AkelPad.Exec('"' + sAutoitPath + 'SciTE\\Tidy\\Tidy.exe" "' + sEditFile + '" /reel /bdir=' + sAutoitPath + 'BackUp');
					break;
				case 3:
					AkelPad.Exec('"' + sAutoitPath + 'Au3Info.exe"');
					break;
				case 4:
					AkelPad.Exec('"' + sAutoitPath + 'SciTE\\AutoIt3Wrapper\\AutoIt3Wrapper.exe" /in "' + sEditFile + '"');

					// WScript.Echo('"' + sAutoitPath + 'SciTE\\AutoIt3Wrapper\\AutoIt3Wrapper.exe /in " "' + sEditFile + '"');
					break;
				case 5:
					AkelPad.Exec('"' + sAutoitPath + 'AutoIt3.exe" "' + sAutoitPath + 'Tools\\Include_Helper.au3" "' + sEditFile + '"');
					break;
				case 6:
					// AkelPad.TextFind(hWndEdit, 'Func ' + sSelText, 0x00000001 | 0x00200000 /*FRF_DOWN|FRF_BEGINNING*/ );
					// AkelPad.TextFind(hWndEdit, '(?<=Func[ \\t])[ \\t]*' + sSelText + '(?=[ \\t]*\\()', 0x00000001 | 0x00200000 | 0x00080000 /*FRF_DOWN | FRF_BEGINNING | FRF_REGEXP*/ );
					AkelPad.TextFind(hWndEdit, 'Func[ \\t]+\\K' + sSelText + '(?=[ \\t]*\\()', 0x00000001 | 0x00200000 | 0x00080000 /*FRF_DOWN | FRF_BEGINNING | FRF_REGEXP*/ );
					break;
				case 7:
					AkelPad.Exec('"' + sAutoitPath + 'AutoIt3.exe" "' + sAutoitPath + 'HELP_AutoIt3.au3" ' + sSelText + ' 1');
					break;
				case 8:
					AkelPad.Exec('"' + sAutoitPath + 'AutoIt3.exe" "' + sAutoitPath + 'Tools\\txt2au3.au3" "' + sSelText + '"');
					break;
				case 9:
					AkelPad.Exec('"' + sAutoitPath + 'AutoIt3.exe" "' + sAutoitPath + 'Tools\\list_var_funk.au3" "' + sEditFile + '"');
					break;
				case 10:
					AkelPad.Exec('"' + sAutoitPath + 'AutoIt3.exe" "' + sAutoitPath + 'Tools\\Renaming_variables.au3" "' + sEditFile + '"');
					break;
				case 11:
					AkelPad.Exec('"' + sAutoitPath + 'AutoIt3.exe" "' + sAutoitPath + 'Tools\\debugger.au3" "' + sSelText + '"');
					break;
				case 12:
					var sAutoitPath = "C:\\AutoIt_v3.3.14.3\\";
					AkelPad.Exec('"' + sAutoitPath + 'AutoIt3.exe" "' + sEditFile + '"');
					break;
			}
			break;

	}
}
// AkelPad.MessageBox(hMainWnd, sFileDir, 'Скрипт "Меню по типу"', 64 /*MB_ICONINFORMATION*/ );


//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 sFileDir = AkelPad.GetFilePath(sEditFile, 1 /*CPF_DIR*/ );
// var sFileWiExt = AkelPad.GetFilePath(sEditFile, 3 /*CPF_FILEBASENAME*/ );
var sFileWiExt = sEditFile.slice(0,-sFileExt.length); // полный путь без расширения
var sSelText = AkelPad.GetSelText();
var pPath = AkelPad.GetAkelDir();
sFileExt = sFileExt.toLowerCase()

var hMainWnd = AkelPad.GetMainWnd();

// чтобы не создавать меню на других файлах
switch (sFileExt) {
	case "js":
	case "reg":
	case "htm":
	case "html":
	case "pb":
	case "pbi":
	case "au3":
	case "bas":
	case "bi":
		break;
	default:
		AkelPad.MessageBox(hMainWnd, "Этот тип файлов не поддерживается. \n Поддерживаемые: js, reg, htm, html, au3, pb, pbi, bas.", 'Скрипт "Меню по типу"', 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]);
	}
}

function ExeFindSource(pFile, pExt) {
	var pTmp = AkelPad.ReadFile(pFile);
	var Pos1 = pTmp.indexOf('; Executable = ')
	if (Pos1 != -1)
	{
		Pos1 += 15 //  pStart.length
		var Pos2 = pTmp.indexOf('.' + pExt, Pos1)
		if (Pos2 != -1)
		{
			pTmp = pTmp.substring(Pos1, Pos2 + 4)
			pTmp = sFileDir + '\\' + pTmp
			return pTmp
		}
	}
	return sFileWiExt + pExt
}

function IconFindSource(pFile) {
	var pTmp = AkelPad.ReadFile(pFile);
	var Pos1 = pTmp.indexOf('; UseIcon = ')
	if (Pos1 != -1)
	{
		Pos1 += 12 //  pStart.length
		var Pos2 = pTmp.indexOf('.ico', Pos1)
		if (Pos2 != -1)
		{
			pTmp = pTmp.substring(Pos1, Pos2 + 4)
			var fso = new ActiveXObject("Scripting.FileSystemObject");
			pTmp = sFileDir + '\\' + pTmp
			if (fso.FileExists(pTmp))
			{
				pTmp = ' /ICON "' + pTmp + '"'
			} else {
				pTmp = ''
			}
		}
	}
	return pTmp
}
- повторил меню, но уже с иконками. И, конечно, это меню на самом деле ListBox.

Добавил "Прыжок к функции" для JS.
Добавил расширение bas + FreeBASIC

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

Post by AZJIO »

Всвязи с запросом c-sanchez на добавление команд запуска через ini-файл, я задумался переписать постом выше скипт.

Посмотрел примеры чтения ini-фалов и понял, что во всех случаях используется типа eval(AkelPad.ReadFile(sIniName)); Это просто копирует текст ini-фала в код и определяет строки как назначение переменных. Это удобно если это обычные настройки.

Но в моём случае нужно определить расширения как секции ini-файла [txt], а в них строки команды, например

Code: Select all

a1=имя
a2=иконка
a3=команда
b1=имя
b2=иконка
b3=команда
или так

Code: Select all

a=имя|иконка|команда
b=имя|иконка|команда
то есть неизвестны ни секции, ни имена параметров, ни значения параметров. Фактически формировать массив данных из которых искать совпадение с секцией, брать её контент читая всю секцию или построчно.

Ну и вопрос, существует ли анализатор ini-файла, чтобы запросить значение параметра readIni(файл, секция, параметр)? Существует ли вритуальный ini, то есть чтение в память и разбор данных в массив массивов? Или регулярные выражения, чтобы получить данные разовым запросом с текста. Я такое делал на AutoIt3 - IniVirtual + IniVirtualSPE, может есть аналогичное готовое?

Code: Select all

var sIniName = WScript.ScriptFullName.substring(0, WScript.ScriptFullName.lastIndexOf(".")) + ".ini";

var valie = IniRead(sIniName, 'au3', 'TitleCHM', '')
WScript.Echo(valie);

function IniRead(file, Section, key, def) {
	sINI = AkelPad.ReadFile(file); // Получить содержимое ini-файла
	if (sINI != '') {
		var expr = new RegExp('\\r\\n[\t ]*?\\[[\t ]*?' + Section + '[\t ]*?\\][\t ]*?(\\r\\n[^\\0]+?\\r\\n)[\t ]*?\\[', 'g');
		var tmp;
		if ((tmp = expr.exec("\r\n" + sINI + "\r\n[")) != null) { // добавлен перенос, чтобы без проблем парсить последнюю строку
			// WScript.Echo("|" + tmp[1] + "|");
			var expr = new RegExp('\\r\\n[\t ]*?' + key + '[\t ]*?=[\t ]*?([^\\0]+?)[\t ]*?[\\r\\n]', 'g');
			if ((tmp = expr.exec(tmp[1])) != null) {
				tmp = tmp[1]
				// Если есть обрамляющие кавычки, то убираем их
				// if ((tmp.slice(0, 1) === '"') && ((tmp + " ").slice(-2, -1) === '"'))
				// if ((tmp.slice(0, 1) === '"') && (tmp.substring(tmp.length - 1, tmp.length) === '"'))
				if (/^(["']).+?\1$/.test(tmp)) // тут проверка кавычек или апострофов
				{
					tmp = tmp.slice(1, -1)
				}
				return tmp;
			}
		}
	}
	return def;
}
- получилось (улучшил несколько раз, из последнего улучшения - обрезка кавычек и апострофов рег.выр`ом)

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

Post by AZJIO »

Готовый вариант

Code: Select all

// Используя скрипт TabSwitch (Instructor) удалось переделать его в собственное меню.
// добавлена мной (AZJIO) функция CfgRead для чтения cfg-файла и формирования массива lpFrameList
// Использую горячую клавишу F8 для этого скрипта, и Ctrl+F8 для тестовой версии.
//
// Ниже старые параметры ком строки, из которых я часть удалил и выпилил из скрипта за неактуальностью
//  `-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, "Menu_by_type_Cfg.js", `-WindowLeft=%bl -WindowTop=%bb`)
// ContextMenu item example:
//   -"Моё меню" Call("Scripts::Main", 1, "Menu_by_type_Cfg.js", `-WindowLeft=-2 -WindowTop=-2`)



function CfgRead(Section) {
	var sCfgName = WScript.ScriptFullName.substring(0, WScript.ScriptFullName.lastIndexOf(".")) + ".cfg";
	sCfg = AkelPad.ReadFile(sCfgName); // Получить содержимое ini-файла
	if (sCfg != '') {
		var expr = new RegExp('\\r\\n[\t ]*?\\[[\t ]*?' + Section + '[\t ]*?\\][\t ]*?\\r\\n([^\\0]+?)\\r\\n[\t ]*?\\[', 'g');
		var tmp;
		if ((tmp = expr.exec("\r\n" + sCfg + "\r\n[")) != null) { // добавлен перенос, чтобы без проблем парсить последнюю строку
			// WScript.Echo("|" + tmp[1] + "|");
			if (/^\s*$/.test(tmp[1])) // если секция пуста
			// if (tmp[1] = "") // если секция пуста
			{
				WScript.Quit();
			}
			tmp= tmp[1].replace(/%a/g, pPath)
			tmp = tmp.replace(/%n/g, sFileWiExt)
			tmp = tmp.replace(/%f/g, sEditFile)
			tmp = tmp.replace(/%s/g, sSelText)
			tmp = tmp.replace(/%d/g, sFileDir)
			var arr = tmp.split("\r\n");
			var res = "";
// WScript.Echo(tmp);
			for (var i=0; i < arr.length; i++)
			{
				if (arr[i] != "")
				{
					var aProgSet = arr[i].split("|");
					lpFrameList[i] = [0, 0];
					lpFrameList[i][0] = aProgSet[1];
					lpFrameList[i][2] = aProgSet[2];
					lpFrameList[i][3] = aProgSet[0];
					
// 0|Справка|"%a\AkelFiles\Tools\Help\Help.exe" %s cmd|C:\Windows\System32\HH.exe
						// WScript.Echo("|" + lpFrameList[i][2] + "|");
					if (aProgSet.length == 4)
					{
						var aIcon = aProgSet[3].split(",");
						// aIcon[0] = aIcon[0].replace(/\\/g, "\\\\")
						// WScript.Echo("|" + aIcon[0] + "|");
						if (aIcon.length == 2)
						{
							lpFrameList[i][1] = GetIcon(aIcon[0],parseInt(aIcon[1]));
							// WScript.Echo("|" + aIcon[0] + "|" + aIcon[1] + "|");
						} else {
							lpFrameList[i][1] = GetIcon(aIcon[0], 0);
							// WScript.Echo("|" + aIcon[0] + "|");
						}
					}
				}
			}
		}
	}
	return;
}


function GetFrameList(lpFrameList) {
	var i = 0;
	CfgRead(sFileExt)

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

function Execute(idx_item) {
	if (lpFrameList[idx_item][3] == "1")
	{
		AkelPad.Call("Log::Output", 1, lpFrameList[idx_item][2], "", '^Error: Line (\d+)', '/GOTOLINE=\1:1', 866, 1251);
	} else {
		AkelPad.Exec(lpFrameList[idx_item][2]);
	}
}
// AkelPad.MessageBox(hMainWnd, sFileDir, 'Скрипт "Меню по типу"', 64 /*MB_ICONINFORMATION*/ );


//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 sFileDir = AkelPad.GetFilePath(sEditFile, 1 /*CPF_DIR*/ );
// var sFileWiExt = AkelPad.GetFilePath(sEditFile, 3 /*CPF_FILEBASENAME*/ );
var sFileWiExt = sEditFile.slice(0,-sFileExt.length); // полный путь без расширения
var sSelText = AkelPad.GetSelText();
var pPath = AkelPad.GetAkelDir();
sFileExt = sFileExt.toLowerCase()

var hMainWnd = AkelPad.GetMainWnd();

// чтобы не создавать меню на других файлах
switch (sFileExt) {
	case "js":
	case "reg":
	case "htm":
	case "html":
	case "pb":
	case "pbi":
	case "au3":
	case "bas":
	case "bi":
		break;
	default:
		AkelPad.MessageBox(hMainWnd, "Этот тип файлов не поддерживается. \n Поддерживаемые: js, reg, htm, html, au3, pb, pbi, bas.", 'Скрипт "Меню по типу"', 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]);
	}
}

function ExeFindSource(pFile, pExt) {
	var pTmp = AkelPad.ReadFile(pFile);
	var Pos1 = pTmp.indexOf('; Executable = ')
	if (Pos1 != -1)
	{
		Pos1 += 15 //  pStart.length
		var Pos2 = pTmp.indexOf('.' + pExt, Pos1)
		if (Pos2 != -1)
		{
			pTmp = pTmp.substring(Pos1, Pos2 + 4)
			pTmp = sFileDir + '\\' + pTmp
			return pTmp
		}
	}
	return sFileWiExt + pExt
}

function IconFindSource(pFile) {
	var pTmp = AkelPad.ReadFile(pFile);
	var Pos1 = pTmp.indexOf('; UseIcon = ')
	if (Pos1 != -1)
	{
		Pos1 += 12 //  pStart.length
		var Pos2 = pTmp.indexOf('.ico', Pos1)
		if (Pos2 != -1)
		{
			pTmp = pTmp.substring(Pos1, Pos2 + 4)
			var fso = new ActiveXObject("Scripting.FileSystemObject");
			pTmp = sFileDir + '\\' + pTmp
			if (fso.FileExists(pTmp))
			{
				pTmp = ' /ICON "' + pTmp + '"'
			} else {
				pTmp = ''
			}
		}
	}
	return pTmp
}




Code: Select all

[js]
0|Справка JS|"%a\AkelFiles\Tools\Help\Help.exe" %s js|C:\Windows\System32\HH.exe
0|Справка WSH|"%a\AkelFiles\Tools\Help\Help.exe" %s wsh|C:\Windows\System32\HH.exe

[cmd]
0|Справка|"%a\AkelFiles\Tools\Help\Help.exe" %s cmd|C:\Windows\System32\HH.exe

[wsh]
0|Справка|"%a\AkelFiles\Tools\Help\Help.exe" %s wsh|C:\Windows\System32\HH.exe

[au3]
0|Запуск|"C:\AutoIt3\AutoIt3.exe" "%f"|C:\Windows\System32\Shell32.dll,137
1|Запуск + консоль|"C:\AutoIt3\AutoIt3.exe" "%f"|C:\Windows\System32\Shell32.dll,137
0|Компилировать|"C:\AutoIt3\SciTE\AutoIt3Wrapper\AutoIt3Wrapper.exe" /in "%f"|C:\AutoIt3\SciTE\AutoIt3Wrapper\AutoIt3Wrapper.exe
0|Tidy|"C:\AutoIt3\SciTE\Tidy\Tidy.exe" "%f" /reel /bdir=%d\BackUp|C:\AutoIt3\SciTE\Tidy\Tidy.exe
0|Au3Info|"C:\AutoIt3\Au3Info.exe" /in "%f"|C:\AutoIt3\Au3Info.exe
0|Справка|"%a\AkelFiles\Tools\Help\Help.exe" %s au3|C:\Windows\System32\HH.exe

[pb]
1|Запуск|"C:\D\PureBasic\Purebasic 5.70 x86\Compilers\pbcompiler.exe" /XP /DPIAWARE -q "%f"|C:\Windows\System32\Shell32.dll,137
1|Компилировать|"C:\D\PureBasic\Purebasic 5.70 x86\Compilers\pbcompiler.exe" "%f" /XP /DPIAWARE -q /EXE "%n.exe"|%a\AkelFiles\icons\ToolbarEx.dll,50
1|Компилировать в DLL|"C:\D\PureBasic\Purebasic 5.70 x86\Compilers\pbcompiler.exe" "%f" /XP /DPIAWARE -q /DLL /EXE "%n.dll"|%a\AkelFiles\icons\ToolbarEx.dll,50
1|Проверка кода|"C:\D\PureBasic\Purebasic 5.70 x86\Compilers\pbcompiler.exe" /XP /DPIAWARE -k "%f"|C:\Windows\System32\Shell32.dll,23
1|Отладчик|"C:\D\PureBasic\Purebasic 5.70 x86\Compilers\pbcompiler.exe" /XP /DPIAWARE --debugger "%f"|%a\AkelFiles\icons\ToolbarEx.dll,53
1|Получить asm-код|"C:\D\PureBasic\Purebasic 5.70 x86\Compilers\pbcompiler.exe" /XP /DPIAWARE -q /COMMENTED "%f"|C:\Windows\System32\Shell32.dll,137

[htm]
0|Справка|"%a\AkelFiles\Tools\Help\Help.exe" %s htm|C:\Windows\System32\HH.exe

[html]
0|Справка|"%a\AkelFiles\Tools\Help\Help.exe" %s html|C:\Windows\System32\HH.exe

[css]
0|Справка|"%a\AkelFiles\Tools\Help\Help.exe" %s css|C:\Windows\System32\HH.exe

[wcs]
0|Справка|"%a\AkelFiles\Tools\Help\Help.exe" %s wcs|C:\Windows\System32\HH.exe

[wsc]
0|Справка|"%a\AkelFiles\Tools\Help\Help.exe" %s wsc|C:\Windows\System32\HH.exe

[bas]
1|Компилировать GUI|C:\Program Files (x86)\FreeBASIC\fbc.exe "%f" -exx -s gui|%a\AkelFiles\icons\ToolbarEx.dll,50
1|Компилировать Console|C:\Program Files (x86)\FreeBASIC\fbc.exe "%f" -exx -s console|%a\AkelFiles\icons\ToolbarEx.dll,50
1|Компилировать DLL|C:\Program Files (x86)\FreeBASIC\fbc.exe "%f" -exx -dll|%a\AkelFiles\icons\ToolbarEx.dll,50
1|Проверка кода|C:\Program Files (x86)\FreeBASIC\fbc.exe "%f" -exx|C:\Windows\System32\Shell32.dll,23
1|Выдать asm-код|C:\Program Files (x86)\FreeBASIC\fbc.exe "%f" -r|%a\AkelFiles\icons\ToolbarEx.dll,42
0|Справка|"%a\AkelFiles\Tools\Help\Help.exe" %s bas|C:\Windows\System32\HH.exe
1|Версия компилятора|C:\Program Files (x86)\FreeBASIC\fbc.exe -version|C:\Windows\System32\Shell32.dll,23


Обновил, добавил взаимодействие с Log. В начале каждой сроки cfg есть цифра 0 или 1, если 1 то запуск через Log
Обновил конфиг cfg и добавил переменную %n (путь без расширения файла).

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

Post by AZJIO »

Интересно, можно ли массив карт (или массив словарей) подстроить под свою задачу? То есть в cfg-файл вставить следующую конструкцию, которая будет вставлена в код прямым копированием как это делают все кодеры...

Code: Select all

var au3 = [];
au3[0] = {
	Name: 'Запуск',
	Path: '"C:\D\PureBasic\Purebasic 5.70 x86\Compilers\pbcompiler.exe"',
	Arguments: '"%f" /XP /DPIAWARE -q /EXE "%nexe"',
	PathIcon: "C:\Windows\System32\Shell32.dll",
	nIcon: 137
};
au3[1] = {
	Name: 'Запуск',
	Path: '"C:\D\PureBasic\Purebasic 5.70 x86\Compilers\pbcompiler.exe"',
	Arguments: '"%f" /XP /DPIAWARE -q /EXE "%nexe"',
	PathIcon: "C:\Windows\System32\Shell32.dll",
	nIcon: 137
};
au3[2] = {
	Name: 'Запуск',
	Path: '"C:\D\PureBasic\Purebasic 5.70 x86\Compilers\pbcompiler.exe"',
	Arguments: '"%f" /XP /DPIAWARE -q /EXE "%nexe"',
	PathIcon: "C:\Windows\System32\Shell32.dll",
	nIcon: 137
};

Эту часть кода я взял из HighLight_HSB.js, но ранее это было взято из примеров GUI от KDJ. Пока проблема, что массив не понятно как обрабатывать, расшриение файла берётся текстом, а имя массива это переменная, наверно надо использовать eval. Типа eval(sFileExt + "[" + i + "].Path") и eval(sFileExt + ".length")

пробую, не получается

Code: Select all

ReadCfg() // выполнили код в cfg-файла
// var au3 = [];
sFileExt = "au3"
WScript.Echo(eval(sFileExt + ".length"));
var i = 1 // будущая переменная цикла
WScript.Echo(eval(sFileExt + "[" + i + "].Path"));

function ReadCfg() {
	var oFSO = new ActiveXObject("Scripting.FileSystemObject");
	// var sCfgFile = WScript.ScriptFullName.substring(0, WScript.ScriptFullName.lastIndexOf(".")) + ".ini";
	var sCfgFile = WScript.ScriptFullName.substring(0, WScript.ScriptFullName.lastIndexOf(".")) + ".cfg";

	if (oFSO.FileExists(sCfgFile)) {
		var oFile = oFSO.OpenTextFile(sCfgFile, 1, false, -1);

		try {
			// WScript.Echo(oFile.ReadAll()); // проверка, что код прочитан, разве что eval не сработал
			eval(oFile.ReadAll());
		} catch (oError) {}
		oFile.Close();
	}
}


и так не работает

Code: Select all

ReadCfg() // выполнили код в cfg-файла
// var au3 = [];
sFileExt = "au3"
var lengthArr = 0;
eval("lengthArr = " + sFileExt + ".length")
WScript.Echo(lengthArr);
var i = 1 // будущая переменная цикла
var PathCur = "";
eval("PathCur = " + sFileExt + "[" + i + "].Path")
WScript.Echo(PathCur);



а так работает

Code: Select all

var au3 = [];
au3[0] = {
	Name: 'Запуск',
	Path: '"C:\D\PureBasic\Purebasic 5.70 x86\Compilers\pbcompiler.exe"',
	Arguments: '"%f" /XP /DPIAWARE -q /EXE "%nexe"',
	PathIcon: "C:\Windows\System32\Shell32.dll",
	nIcon: 137
};
au3[1] = {
	Name: 'Запуск',
	Path: '"C:\D\PureBasic\Purebasic 5.70 x86\Compilers\pbcompiler.exe"',
	Arguments: '"%f" /XP /DPIAWARE -q /EXE "%nexe"',
	PathIcon: "C:\Windows\System32\Shell32.dll",
	nIcon: 137
};
au3[2] = {
	Name: 'Запуск',
	Path: '"C:\D\PureBasic\Purebasic 5.70 x86\Compilers\pbcompiler.exe"',
	Arguments: '"%f" /XP /DPIAWARE -q /EXE "%nexe"',
	PathIcon: "C:\Windows\System32\Shell32.dll",
	nIcon: 137
};

sFileExt = "au3"
var lengthArr = 0;
eval("lengthArr = " + sFileExt + ".length")
WScript.Echo(lengthArr);
var i = 1 // будущая переменная цикла
var PathCur = "";
eval("PathCur = " + sFileExt + "[" + i + "].Path")
WScript.Echo(PathCur);


Если использовать как инклуд, то работает. И помещать в папку Include.

Code: Select all

if(!AkelPad.Include("ReadCode.cfg")) WScript.Quit();
Или сделать в начале скрипта редактируемую область данных в понятном формате, то есть тот же массив словарей.

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

Post by VladSh »

Зачем этот "массив словарей"? Здесь лучше использовать json.
Уже писал - пример чтения и разбора ini и json у меня в сборке - pack7zip.js + ShowMenuEx.js и соотв. файлы параметров; всё читается и разбирается с помощью eval. Один раз написал движок разбора, потом просто готовишь json-файл параметров для нового скрипта и всё.
Post Reply