Scripts discussion (4)
- Author
- Message
-
Offline
- Posts: 142
- Joined: Fri Aug 15, 2008 8:58 am
I tryed to reuse it but i'm not able.
How to set f.e. a hotkey for ctrl-b ?
How to set f.e. a hotkey for ctrl-b ?
Code: Select all
var HOTKEYF_CONTROL = 0x02;
var HOTKEYF_ALT = 0x04;
function MAKEWORD(lo,hi)
{
return (lo & 0xFF) + ((hi & 0xFF)<<8);
}
var _HK_SH = MAKEWORD(0x48,HOTKEYF_ALT|HOTKEYF_CONTROL);
var g_hAkelPad = AkelPad.GetMainWnd();
var WM_USER = 0x0400;
var DT_QWORD = 2;
var DT_WORD = 4;
var AKD_DLLADD = WM_USER + 308;
function test(a){
alert(a);
}
AddFunction("test",_HK_SH,test,33)
function AddFunction(name,hk,proc,param)
{
var szof = _X64?8:4;
var func = AkelPad.MemAlloc(5*szof);
var mn = AkelPad.MemAlloc((name.length+1)*_TSIZE);
AkelPad.MemCopy(mn, name, _TSTR);
AkelPad.MemCopy(func, mn, DT_QWORD); //name
AkelPad.MemCopy(func+szof, hk, DT_WORD); //hotkey
AkelPad.MemCopy(func+2*szof, 0, DT_WORD); //FALSE
AkelPad.MemCopy(func+3*szof, proc, DT_QWORD); //proc
AkelPad.MemCopy(func+4*szof, param, DT_QWORD); //param
var res = AkelPad.SendMessage(g_hAkelPad, AKD_DLLADD, 0, func);
AkelPad.MemFree(mn);
AkelPad.MemFree(func);
return res;
}
function DelFunction(prs)
{
AkelPad.SendMessage(g_hAkelPad, AKD_DLLDELETE, 0, prs);
}
-
Offline
- Posts: 2247
- Joined: Tue Aug 07, 2007 2:03 pm
- Location: Vinnitsa, Ukraine
First of all, you cannot give reference to javascript object(function test) into AKD_DLLADD call. That particular parameter must be raw (low level) code address of stdcall call convention. If you pass object as you did, you'll pass address of data associated with object(i.e. raw internal metadata of javascript interpreter).. and when AP try to call it - you will get access violation. You probably missed it in code: You see, 1st line "converts" javascript function into "native" function address, and only then we register hotkey(in this case we reuse the same function).
Second: script must be resident. Once you registered hotkey, your script must not finish until it unregisters it, or else in best case it will not work, in worst - crash on hotkey activation. The code below is typical pattern of creating resident scripts
In script you see:
HK_CallBack - javascript function which we want to be called on hotkey event
HK_CallBackAddr - PROPER low level function address which (and only it) can be passed to AddFunction.
AkelPadCallBack - handler of AkelPad internal events.. You should rewrite it for your needs. But at least handling of AKDN_MAIN_ONFINISH must be done (to save your time of analysis: call PostQuitMessage(0); must be performed)
When you successfully register script as resident, you will see 'Running' label in script list on it. And if hotkey registered successfully, you will see it in HotKeys plugin in list of "All keys..." (your "test" label will be there).
Why it is so sophisticated? Well, it is one of oldest resident scripts which never was rewritten for new API (+code to handle business logic is not light). I have not followed Scripts plugin development much lately, I suspect there are some easy to use functions introduced, I never rewritten script, because it works as is. Actually this code more or less equal to code on pure C used in plugins (i.e. plugin API used directly). Few magic functions of AkelPad object made it possible to create such complex functionally, which was possible implement only as plugin.
Code: Select all
HK_CallBackAddr = oSys.RegisterCallback(HK_CallBack);
func_opentop = AddFunction(rott,_HK_RT,HK_CallBackAddr,CBC_OPENTOP);
func_openall = AddFunction(rota,_HK_RA,HK_CallBackAddr,CBC_OPENALL);
func_showhide = AddFunction(showhide,_HK_SH,HK_CallBackAddr,CBC_SHOWHIDE);
Second: script must be resident. Once you registered hotkey, your script must not finish until it unregisters it, or else in best case it will not work, in worst - crash on hotkey activation. The code below is typical pattern of creating resident scripts
Code: Select all
//! INITIALIZATION OF SCRIPT BUSINESS LOGIC: EACH SCRIPT DO IT DIFFERENTLY. WE - PREPARE HOTKEYS
HK_CallBackAddr = oSys.RegisterCallback(HK_CallBack);
func_opentop = AddFunction(rott,_HK_RT,HK_CallBackAddr,CBC_OPENTOP);
func_openall = AddFunction(rota,_HK_RA,HK_CallBackAddr,CBC_OPENALL);
func_showhide = AddFunction(showhide,_HK_SH,HK_CallBackAddr,CBC_SHOWHIDE);
//! HOOK AKELPAD EVENT QUEUE - THIS GIVES SCRIPT ABILITY REACT ON EVENTS
if(AkelPad.WindowSubClass( WSC_MAINPROC, AkelPadCallBack,
AKDN_OPENDOCUMENT_FINISH, // THIS IS EVENT RELATED TO BUSINESS LOGIC OF SCRIPT
AKDN_MAIN_ONFINISH, // THIS EVENT SHOULD BE HOOKED BY ALL RESIDENT SCRIPTS - FIRED WHEN AKELPAD ABOUT TO CLOSE, SO SCRIPT MUST FINISH ITSELF
AKDN_FRAME_DESTROY // THIS IS EVENT RELATED TO BUSINESS LOGIC OF SCRIPT
))
{
//! DECLARED OURSELF(SCRIPT) RESIDENT
AkelPad.ScriptNoMutex();
//! PROCESS EVENT QUEUE (SCRIPT SITS HERE UNTIL IT IS TIME TO FINISH)
AkelPad.WindowGetMessage();
//! UNHOOK EVENT QUEUE - SCRIPTS FINISHES, NOT INTRESTED IN EVENT ANYMORE
AkelPad.WindowUnsubClass( WSC_MAINPROC );
}
//! CLEANUP EVERYTHING HERE: WE UNREGISTER
DelFunction(func_opentop);
DelFunction(func_openall);
DelFunction(func_showhide);
oSys.UnregisterCallback(HK_CallBackAddr);
HK_CallBack - javascript function which we want to be called on hotkey event
HK_CallBackAddr - PROPER low level function address which (and only it) can be passed to AddFunction.
AkelPadCallBack - handler of AkelPad internal events.. You should rewrite it for your needs. But at least handling of AKDN_MAIN_ONFINISH must be done (to save your time of analysis: call PostQuitMessage(0); must be performed)
When you successfully register script as resident, you will see 'Running' label in script list on it. And if hotkey registered successfully, you will see it in HotKeys plugin in list of "All keys..." (your "test" label will be there).
Why it is so sophisticated? Well, it is one of oldest resident scripts which never was rewritten for new API (+code to handle business logic is not light). I have not followed Scripts plugin development much lately, I suspect there are some easy to use functions introduced, I never rewritten script, because it works as is. Actually this code more or less equal to code on pure C used in plugins (i.e. plugin API used directly). Few magic functions of AkelPad object made it possible to create such complex functionally, which was possible implement only as plugin.
-
Offline
- Posts: 269
- Joined: Mon Jun 20, 2011 8:33 am
- Location: Электросталь
Подскажите, пожалуйста, чайнику: как получить аргументы, переданные скрипту, если скрипт начинается с
AkelPad.GetArgValue в этом случае не работает (выдает ошибку AkelPad is undefined).
Code: Select all
if (typeof AkelPad == "object")
-
Online
- Posts: 1250
- Joined: Thu Nov 16, 2006 11:53 am
- Location: Kyiv, Ukraine
Кажется, нашёл ошибку в скрипте SearchReplace.js:
1. Запускаем AkelPad (я запускаю в режиме MDI);
2. Пусть мы редактируем файл с такими четырьмя строками:
3. Запускаем SearchReplace.js, режим поиска: все галочки сняты, выбрано "С начала", в строке "Что" печатаем "1" (без кавычек) и нажимаем кнопку "Найти все";
4. Как результат, окно Log::Output показывает два найденных вхождения строки "1";
5. Теперь - внимание! - кликаем мышкой в окно Log::Output;
6. Кликаем в окно SearchReplace.js, печатаем "2" (без кавычек) и нажимаем кнопку "Найти все".
7. Результат: ничего не найдено!
1. Запускаем AkelPad (я запускаю в режиме MDI);
2. Пусть мы редактируем файл с такими четырьмя строками:
Code: Select all
1
2
1
2
4. Как результат, окно Log::Output показывает два найденных вхождения строки "1";
5. Теперь - внимание! - кликаем мышкой в окно Log::Output;
6. Кликаем в окно SearchReplace.js, печатаем "2" (без кавычек) и нажимаем кнопку "Найти все".
7. Результат: ничего не найдено!
-
Offline
- Site Admin
- Posts: 6311
- Joined: Thu Jul 06, 2006 7:20 am
DV
Всё верно.
Всё верно.
Правда ошибка всё же была: не возвращался поиск на окно редактирования программы с окна редактирования плагином. Скрипт обновил.Добавлено: SearchReplace.js - возможность использования скрипта в окнах редактирования плагинов, таких как, ContextMenu, ToolBar, Log::Output, Clipboard::Capture, HexSel::Main. >>>
-
Online
- Posts: 1250
- Joined: Thu Nov 16, 2006 11:53 am
- Location: Kyiv, Ukraine
Поиск текста в окне Log::Output с выводом результатов поиска в то же самое окно Log::Output в принципе может работать? У меня ни разу ничего не находил.Instructor wrote:Добавлено: SearchReplace.js - возможность использования скрипта в окнах редактирования плагинов, таких как, ContextMenu, ToolBar, Log::Output, Clipboard::Capture, HexSel::Main. >>>
-
Online
- Posts: 1250
- Joined: Thu Nov 16, 2006 11:53 am
- Location: Kyiv, Ukraine
-
Offline
- Posts: 1949
- Joined: Sat Mar 06, 2010 7:40 pm
- Location: Poland
-
Online
- Posts: 1250
- Joined: Thu Nov 16, 2006 11:53 am
- Location: Kyiv, Ukraine
Напомню про SearchReplace.js:
Точнее, не так. Оно якобы находит, только все найденные вхождения в окне Log::Output представляют собой пустые строки!DV wrote:Поиск текста в окне Log::Output с выводом результатов поиска в то же самое окно Log::Output в принципе может работать? У меня ни разу ничего не находил.