Scripts discussion (3)

Discuss and announce AkelPad plugins
  • Author
  • Message
Offline
Posts: 30
Joined: Sat Nov 26, 2011 1:52 pm

Post by Egor »

opk44 wrote:А вы примеры использования скрипта (стр. 12-16) посмотрели?
Всё я посмотрел, вызываю как положено, с параметрами. Сделал кнопку для тулбара с выпадающим списком (для плагина ContextMenu) из трёх пунктов (путь к иконкам я тут опустил для краткости):

Code: Select all

"Тест"
{
-"Выделить двойные кавычки" Call("Scripts::Main", 1, "QuoteExtend.js", "") Icon(…)
-"Выделить одинар. кавычки" Call("Scripts::Main", 1, "QuoteExtend.js", "'") Icon(…)
-"Выделить круглые скобки" Call("Scripts::Main", 1, "QuoteExtend.js", "()") Icon(…)
}
Двойные кавычки и круглые скобки выделяет нормально, а одинарные кавычки — нет (вернее выделяет, но не между кавычками, а каким-то случайным куском.

Offline
Posts: 874
Joined: Sat Jan 16, 2010 2:03 pm

Post by opk44 »

Egor
Да, есть проблема с получением аргумента, состоящего из одних кавычек (выделение двойных кавычек тоже срабатывает только за счет дефолтного поведения). С кавычкой нужно сделать "тройную матрёшку":

Code: Select all

-"Выделить одинар. кавычки" Call("Scripts::Main", 1, "QuoteExtend.js", `"'"`) Icon(0) 

Offline
Posts: 30
Joined: Sat Nov 26, 2011 1:52 pm

Post by Egor »

opk44 wrote:Да, есть проблема с получением аргумента, состоящего из одних кавычек … С кавычкой нужно сделать "тройную матрёшку": `"'"`
Благодарю, теперь работает нормально.

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

Post by KDJ »

How many windows you can create simultaneously?
For me AkelPad crashes when trying to create the fifth window.

Script for test:

Code: Select all

var oSys     = AkelPad.SystemFunction();
var hInstDLL = AkelPad.GetInstanceDll();
var sClass   = "AkelPad::Scripts::" + WScript.ScriptName + "::" + hInstDLL;
var hFont    = oSys.Call("Gdi32::GetStockObject", 17 /*DEFAULT_GUI_FONT*/);
var nCounter = 0;

var IDCLOSE   = 2;
var IDNEW     = 1000;
var IDCHECK1  = 1001;
var IDCHECK2  = 1002;
var IDCHECK3  = 1003;
var IDCHECK4  = 1004;
var IDCHECK5  = 1005;
var IDCHECK6  = 1006;
var IDCHECK7  = 1007;
var IDCHECK8  = 1008;
var IDCHECK9  = 1009;
var IDCHECK10 = 1010;
var IDCHECK11 = 1011;
var IDCHECK12 = 1012;
var IDCHECK13 = 1013;
var IDCHECK14 = 1014;
var IDCHECK15 = 1015;

if (AkelPad.WindowRegisterClass(sClass))
{
  CreateNewWindow(0);
  AkelPad.WindowUnregisterClass(sClass);
}

function CreateNewWindow(hParent)
{
  var lpRect = AkelPad.MemAlloc(16 /*sizeof(RECT)*/);
  var nX, nY;
  var hFocus;

  oSys.Call("User32::GetWindowRect", hParent, lpRect);
  nX = AkelPad.MemRead(lpRect,     3 /*DT_DWORD*/) + 15;
  nY = AkelPad.MemRead(lpRect + 4, 3 /*DT_DWORD*/) + 35;
  oSys.Call("User32::GetWindowRect", oSys.Call("User32::GetDesktopWindow"), lpRect);
  if (nY > AkelPad.MemRead(lpRect + 12, 3 /*DT_DWORD*/) - 100)
    nY = 35;
  AkelPad.MemFree(lpRect);

  if (oSys.Call("User32::CreateWindowExW",
        0,               //dwExStyle
        sClass,          //lpClassName
        0,               //lpWindowName
        0x90CA0000,      //dwStyle=WS_VISIBLE|WS_POPUP|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX
        nX,              //x
        nY,              //y
        216,             //nWidth
        379,             //nHeight
        hParent,         //hWndParent
        0,               //hMenu
        hInstDLL,        //hInstance
        DialogCallback)) //Script function callback. To use it class must be registered by WindowRegisterClass.
  {
    oSys.Call("user32::EnableWindow", hParent, 0);

    if (nCounter == 1)
      AkelPad.WindowGetMessage();
  }

  function DialogCallback(hWnd, uMsg, wParam, lParam)
  {
    if (uMsg == 1 /*WM_CREATE*/)
    {
      var i;

      oSys.Call("User32::SetWindowTextW", hWnd, "Window " + ++nCounter);

      for (i = 0; i < 15; ++i)
      {
        oSys.Call("User32::CreateWindowExW",
          0,                    //dwExStyle
          "BUTTON",             //lpClassName
          "CheckBox" + (i + 1), //lpWindowName
          0x50010003,           //dwStyle=WS_VISIBLE|WS_CHILD|WS_TABSTOP|BS_AUTOCHECKBOX
          60,                   //x
          10 + 20 * i,          //y
          100,                  //nWidth
          16,                   //nHeight
          hWnd,                 //hWndParent
          IDCHECK1 + i,         //ID
          hInstDLL,             //hInstance
          0);                   //lpParam
        AkelPad.SendMessage(oSys.Call("User32::GetDlgItem", hWnd, IDCHECK1 + i), 48 /*WM_SETFONT*/, hFont, 0);
      }

      oSys.Call("User32::CreateWindowExW",
        0,             //dwExStyle
        "BUTTON",      //lpClassName
        "&New Window", //lpWindowName
        0x50010001,    //dwStyle=WS_VISIBLE|WS_CHILD|WS_TABSTOP|BS_DEFPUSHBUTTON
        10,            //x
        315,           //y
        90,            //nWidth
        23,            //nHeight
        hWnd,          //hWndParent
        IDNEW,         //ID
        hInstDLL,      //hInstance
        0);            //lpParam
      AkelPad.SendMessage(oSys.Call("User32::GetDlgItem", hWnd, IDNEW), 48 /*WM_SETFONT*/, hFont, 0);

      oSys.Call("User32::CreateWindowExW",
        0,          //dwExStyle
        "BUTTON",   //lpClassName
        "Close",    //lpWindowName
        0x50010000, //dwStyle=WS_VISIBLE|WS_CHILD|WS_TABSTOP
        110,        //x
        315,        //y
        90,         //nWidth
        23,         //nHeight
        hWnd,       //hWndParent
        IDCLOSE,    //ID
        hInstDLL,   //hInstance
        0);         //lpParam
      AkelPad.SendMessage(oSys.Call("User32::GetDlgItem", hWnd, IDCLOSE), 48 /*WM_SETFONT*/, hFont, 0);

      hFocus = oSys.Call("User32::GetDlgItem", hWnd, IDNEW);
    }

    else if ((uMsg == 6 /*WM_ACTIVATE*/) && (wParam == 0 /*WA_INACTIVE*/))
      hFocus = oSys.Call("User32::GetFocus");
  
    else if (uMsg == 7 /*WM_SETFOCUS*/)
      oSys.Call("User32::SetFocus", hFocus);

    else if (uMsg == 273 /*WM_COMMAND*/)
    {
      var nLowParam = wParam & 0xFFFF;

      if (nLowParam == IDNEW)
        CreateNewWindow(hWnd);
      else if (nLowParam == IDCLOSE)
        oSys.Call("User32::PostMessageW", hWnd, 16 /*WM_CLOSE*/, 0, 0);
    }

    else if (uMsg == 16 /*WM_CLOSE*/)
    {
      oSys.Call("user32::EnableWindow", hParent, 1);
      oSys.Call("User32::DestroyWindow", hWnd);
    }

    else if (uMsg == 2 /*WM_DESTROY*/)
    {
      if (nCounter-- == 1)
        oSys.Call("User32::PostQuitMessage", 0);
    }

    return 0;
  }
}
Last edited by KDJ on Sun May 04, 2014 9:19 am, edited 1 time in total.

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

Post by FeyFre »

In my situation it crashes when creating 4th window.
Debugger shows crash in IDocument.c line 3160 on dereferencing objFunction interface pointer(memory inspections shows refrenced memory already freed(feeefeee pattern))

Code: Select all

  if ((hr=objFunction->lpVtbl->Invoke(objFunction, DISPID_VALUE, &IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &dispp, &vtInvoke, 0, 0)) == S_OK)
  {
    if (vtInvoke.vt == VT_BOOL)
PS: it seems smb forgot AddRef call at line 1935(или 2597)?

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

Post by Instructor »


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

Post by KDJ »

Instructor
Splendidly, now you can create 50 Windows. Thank you very much.

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

Post by Instructor »

KDJ
About CreateDialog_functions.js and all scripts with dialogs. If user use screen DPI other then 96, then controls needs alignment, like, it does in SearchReplace.js - functions ScaleInit, ScaleX, ScaleY.

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

Post by KDJ »

Instructor
Thanks for the remark.

Code: Select all

//Align to 16 pixel
ptScale.x+=ptScale.x % 16;
ptScale.y+=ptScale.y % 16;
I don't understand why it has to be aligned to 16 pixels, and why this algorithm?

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

Post by Instructor »

KDJ
Aligned to 16 pixels empirically. As remember I changed screen DPI and call CreateDialog from resources. CreateDialog moved controls and I checked the multiplier value.

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

Post by KDJ »

Instructor
This algorithm is a strange:

Code: Select all

ptScale.x+=ptScale.x % 16;

//  96 ->  96
// 100 -> 104
// 104 -> 112
// 108 -> 120
// 110 -> 124
// 112 -> 112

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

Post by FeyFre »

Действительно %) Надо ведь ptScale.x+= 16 - (ptScale.x % 16); т.е. добавить то чего не хватает до кратности а не то что уже есть.

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

Post by KDJ »

Code: Select all

ptScale.x+= 16 - (ptScale.x % 16);
// 96 -> 112 wrong
//100 -> 112
//104 -> 112
//108 -> 112
//112 -> 128 wrong

//Maybe in this way:
ptScale.x += (ptScale.x % 16) ? (16 - ptScale.x % 16) : 0;
//or
if (ptScale.x % 16) ptScale.x += 16 - ptScale.x % 16;

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

Post by Infocatcher »

KDJ wrote:

Code: Select all

if (ptScale.x % 16)

Code: Select all

if (ptScale.x & 0xf)
:D

Code: Select all

var c = 500e3;

var i = c + 1, t = new Date().getTime();
while(--i)
	i % 16;
var dt1 = new Date().getTime() - t;

var i = c + 1, t = new Date().getTime();
while(--i)
	i & 0xf;
var dt2 = new Date().getTime() - t;

WScript.Echo("%: " + dt1 + " ms\n&: " + dt2 + " ms");
/*
%: 1071 ms
&: 1027 ms
*/


P.S.

Code: Select all

Math.ceil(ptScale.x/16)*16;

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

Post by Instructor »

KDJ, FeyFre
Yep, corrected. :)

Добавлено:
Infocatcher wrote:%: 1071 ms
&: 1027 ms
Этож разовый вызов, но читается лучше (для меня).
Locked