Scripts discussion (2)

Discuss and announce AkelPad plugins
Locked
  • Author
  • Message
Offline
Posts: 2248
Joined: Tue Aug 07, 2007 2:03 pm
Location: Vinnitsa, Ukraine

Post by FeyFre »

VladSh
Ну можно сделать так как я сделал в SpellCheck - искать в реестре место установки тотал-а. HKCU\Software\Ghisler\Total Commander\InstallDir
Некоторые люди выставляют глобальную переменную окружения %COMMANDER_PATH%

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

Post by VladSh »

FeyFre
> Некоторые люди выставляют глобальную переменную окружения %COMMANDER_PATH%
А некоторые не выставляют. Переносимость не гарантирована.

> HKCU\Software\Ghisler\Total Commander\InstallDir
Этот путь я видел, потому и просил добавить функционал поиска в реестре. И всё это выделить в общий скрипт-"библиотеку"...
Только с именем файла нескладуха. Но тут наверное перебором надо будет, - сначала с "64", потом БЕЗ, но это некрасиво, т.к. дурная специфика - сильно выбивается из планируемого "общего функционала".

Offline
Posts: 2248
Joined: Tue Aug 07, 2007 2:03 pm
Location: Vinnitsa, Ukraine

Post by FeyFre »

Updated scripts:
Win32 Constants library Problems in comctl32.js again. Please update it urgently.

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

Post by Infocatcher »

Берем скрипт measuresConverter.js, запускаем.
Переключаемся на валюту и жмем справа «обновить» (для игнорирования кэша можно жать правой кнопкой мыши или Ctrl+F5).
Не дожидаясь завершения, закрываем AkelPad крестиком в заголовке окна.
Видим предложение отменить обновление и намертво зависаем. :)

Code: Select all

	function dialogCallback(hWnd, uMsg, wParam, lParam) {
		...
		switch(uMsg) {
			...
			case 16: //WM_CLOSE
				if(cancelUpdate())
					return 1;
			...
		}
		return 0;
	}

	function cancelUpdate() {
		if(!asyncUpdater.activeRequests)
			return false;
		if(
			AkelPad.MessageBox(
				hWndDialog,
				_localize("Cancel update?"),
				dialogTitle,
				33 /*MB_OKCANCEL|MB_ICONQUESTION*/
			) == 1 /*IDOK*/
		)
			asyncUpdater.abort();
		return true;
	}

Надо отменять закрытие окна как-то иначе?

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

Post by Instructor »

Infocatcher
Можно попробовать так:

Code: Select all

AkelPad.MessageBox(0, ...

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

Post by Infocatcher »

Instructor
Тоже виснет, но теперь доходит до

Code: Select all

		updateCurrencyDataAsync(
			force,
			function onProgress(state, code) {
				...
			},
			function onComplete(state, code) {
				...
				AkelPad.MessageBox(hWndDialog, msg, title, icon);
			},
			maskInclude
		);
(отменить обновление при этом все равно не получается).
Ноль вместо hWndDialog в этом случае ничего относительно зависания не дает.

Надо бы сделать пример без запросов к серверу, а то забанить могут за частые передергивания. :)

Offline
Posts: 2248
Joined: Tue Aug 07, 2007 2:03 pm
Location: Vinnitsa, Ukraine

Post by FeyFre »

Infocatcher, что-то у меня не глючит. Или Вы уже исправили?

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

Post by Infocatcher »

FeyFre
Нет, ничего не исправлял.
Глючит на Windows 7 x86.

Хотя вот странно, сейчас с изначальным вариантом (без нуля в AkelPad.MessageBox()) тоже выдало сообщение об успешности.
Но виснет все так же.
Можно «исправить» (отвиснуть), прибив поток Scripts.dll, но после этого будет не закрыть AkelPad кроме как завершением процесса.

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

Post by Infocatcher »

Упрощенный пример:

Code: Select all

// Testcase for cancel window closing

var hMainWnd = AkelPad.GetMainWnd();
var oSys = AkelPad.SystemFunction();

if(hMainWnd)
	dialog();

function dialog() {
	var hInstanceDLL = AkelPad.GetInstanceDll();
	var dialogClass = "AkelPad::Scripts::" + WScript.ScriptName + "::" + oSys.Call("kernel32::GetCurrentProcessId");

	var hWndDialog = oSys.Call("user32::FindWindowEx" + _TCHAR, 0, 0, dialogClass, 0);
	if(hWndDialog) {
		if(oSys.Call("user32::IsIconic", hWndDialog))
			oSys.Call("user32::ShowWindow", hWndDialog, 9 /*SW_RESTORE*/);
		AkelPad.SendMessage(hWndDialog, 7 /*WM_SETFOCUS*/, 0, 0);
		return;
	}

	if(
		!AkelPad.WindowRegisterClass(dialogClass)
		&& ( // Previous script instance crashed
			!AkelPad.WindowUnregisterClass(dialogClass)
			|| !AkelPad.WindowRegisterClass(dialogClass)
		)
	)
		return;

	var IDC_OK = 1000;
	var hWndOK;

	// Create dialog
	hWndDialog = oSys.Call(
		"user32::CreateWindowEx" + _TCHAR,
		0,             //dwExStyle
		dialogClass,   //lpClassName
		0,             //lpWindowName
		0x90CA0000,    //WS_VISIBLE|WS_POPUP|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX
		0,             //x
		0,             //y
		220,           //nWidth
		70,            //nHeight
		hMainWnd,      //hWndParent
		0,             //ID
		hInstanceDLL,  //hInstance
		dialogCallback //Script function callback. To use it class must be registered by WindowRegisterClass.
	);
	if(!hWndDialog)
		return;

	function dialogCallback(hWnd, uMsg, wParam, lParam) {
		switch(uMsg) {
			case 1: //WM_CREATE
				// Dialog caption
				windowText(hWnd, WScript.ScriptName);

				// Button OK
				hWndOK = oSys.Call(
					"user32::CreateWindowEx" + _TCHAR,
					0,            //dwExStyle
					"BUTTON",     //lpClassName
					0,            //lpWindowName
					0x50010001,   //WS_VISIBLE|WS_CHILD|WS_TABSTOP|BS_DEFPUSHBUTTON
					10,           //x
					10,           //y
					100,          //nWidth
					20,           //nHeight
					hWnd,         //hWndParent
					IDC_OK,       //ID
					hInstanceDLL, //hInstance
					0             //lpParam
				);
				var hGuiFont = oSys.Call("gdi32::GetStockObject", 17 /*DEFAULT_GUI_FONT*/);
				setWindowFontAndText(hWndOK, hGuiFont, "OK");
			break;
			case 7: //WM_SETFOCUS
				oSys.Call("user32::SetFocus", hWndOK);
			break;
			case 273: //WM_COMMAND
				var idc = wParam & 0xffff;
				switch(idc) {
					case IDC_OK:
						oSys.Call("user32::PostMessage" + _TCHAR, hWnd, 16 /*WM_CLOSE*/, 0, 0);
				}
			break;
			case 16: //WM_CLOSE
				if(!confirmClose())
					return 1;
				oSys.Call("user32::DestroyWindow", hWnd); // Destroy dialog
			break;
			case 2: //WM_DESTROY
				oSys.Call("user32::PostQuitMessage", 0); // Exit message loop
		}
		return 0;
	}

	function confirmClose() {
		return AkelPad.MessageBox(
			hWndDialog,
			"Close?",
			WScript.ScriptName,
			33 /*MB_OKCANCEL|MB_ICONQUESTION*/
		) == 1 /*IDOK*/;
	}

	function windowText(hWnd, pText) {
		if(arguments.length > 1)
			return oSys.Call("user32::SetWindowText" + _TCHAR, hWnd, pText);
		var len = oSys.Call("user32::GetWindowTextLength" + _TCHAR, hWnd);
		var lpText = AkelPad.MemAlloc((len + 1)*_TSIZE);
		if(!lpText)
			return "";
		oSys.Call("user32::GetWindowText" + _TCHAR, hWnd, lpText, len + 1);
		pText = AkelPad.MemRead(lpText, _TSTR);
		AkelPad.MemFree(lpText);
		return pText;
	}
	function setWindowFont(hWnd, hFont) {
		AkelPad.SendMessage(hWnd, 48 /*WM_SETFONT*/, hFont, true);
	}
	function setWindowFontAndText(hWnd, hFont, pText) {
		setWindowFont(hWnd, hFont);
		windowText(hWnd, pText);
	}

	AkelPad.ScriptNoMutex(); // Allow other scripts running
	AkelPad.WindowGetMessage(); // Message loop

	AkelPad.WindowUnregisterClass(dialogClass);
}

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

Post by Instructor »

Infocatcher
Это такое свойство MessageBox - останавливать обработку сообщений. В 4.7.3 попробую добавить в API сообщение для создания своего диалога MessageBox, который используется, например, при попытке сохранить файл с потерей символов.

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

Post by KDJ »

I have a question:
How to check in callback function, whether F6 key was pressed?
WM_KEYDOWN message is not sent.

Offline
Posts: 2248
Joined: Tue Aug 07, 2007 2:03 pm
Location: Vinnitsa, Ukraine

Post by FeyFre »

KDJ
oSys.Call("user32::GetAsyncKeyState",...)
oSys.Call("user32::GetKeyState",...)
Note: keyboard and mouse event message are sent only into active thread/window (thread with input focus or into windows with mouse capture)

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

Post by KDJ »

FeyFre
But if you press F6 key, Callback function is not called.

Offline
Posts: 2248
Joined: Tue Aug 07, 2007 2:03 pm
Location: Vinnitsa, Ukraine

Post by FeyFre »

KDJ, script sample?
NB: See viewtopic.php?p=16239#p16239 and viewtopic.php?p=16278#p16278
Is that your issue? I have solved it this way: registered one callback function, and used it as common callback for all Hotkey, regulating required behaviour by specifying different param values.

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

Post by KDJ »

FeyFre

Script sample:

Code: Select all

var oSys         = AkelPad.SystemFunction();
var hInstanceDLL = AkelPad.GetInstanceDll();
var sClassName   = "AkelPad::Scripts::" + WScript.ScriptName + "::" + hInstanceDLL;
var hWndDlg;
var hWnd1;

AkelPad.WindowRegisterClass(sClassName);
hWndDlg = oSys.Call("user32::CreateWindowEx" + _TCHAR,
                    0,                //dwExStyle
                    sClassName,       //lpClassName
                    "Test F5 and F6", //lpWindowName
                    0x90CA0000,       //WS_VISIBLE|WS_POPUP|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX
                    300,              //x
                    300,              //y
                    300,              //nWidth
                    150,              //nHeight
                    0,                //hWndParent
                    0,                //ID
                    hInstanceDLL,     //hInstance
                    DialogCallback);

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

function DialogCallback(hWnd, uMsg, wParam, lParam)
{
  if (uMsg == 1) //WM_CREATE
  {
    hWnd1 = oSys.Call("user32::CreateWindowEx" + _TCHAR,
                      0,            //dwExStyle
                      "STATIC",     //lpClassName
                      0,            //lpWindowName
                      0x50000000,   //dwStyle
                      50,           //x
                      50,           //y
                      180,          //nWidth
                      20,           //nHeight
                      hWnd,         //hWndParent
                      -1,           //ID
                      hInstanceDLL, //hInstance
                      0);           //lpParam
    oSys.Call("user32::SetWindowText" + _TCHAR, hWnd1, "Press F5 or F6");
  }

  else if (uMsg == 7 /*WM_SETFOCUS*/)
    oSys.Call("user32::SetFocus", hWnd1);

  else if (uMsg == 256 /*WM_KEYDOWN*/)
  {
    if (wParam == 0x74 /*VK_F5*/)
      AkelPad.MessageBox(hWnd, "F5 was pressed", "Test", 0);
    else if (wParam == 0x75 /*VK_F6*/)
      AkelPad.MessageBox(hWnd, "F6 was pressed", "Test", 0);
    else if (wParam == 27 /*VK_ESCAPE*/)
      oSys.Call("user32::PostMessage" + _TCHAR, hWnd, 16 /*WM_CLOSE*/, 0, 0);
  }

  else if (uMsg == 16) //WM_CLOSE
    oSys.Call("user32::DestroyWindow", hWnd);

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

  return 0;
}


F5 works, but F6 does not work.
Locked