Scripts discussion (3)

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

Post by FeyFre »

Code: Select all

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

Code: Select all

ptScale.x+= (16 - (ptScale.x % 16) ) % 16 ; 
:lol:
No "if" and no "?" so no jumps - faster code.

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

Post by Infocatcher »

Instructor wrote:но читается лучше (для меня).
Да, потому и смайлик. Кстати, ceil() меня разочаровал:

Code: Select all

var c = 500e3;

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

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

var i = c + 1, t = new Date().getTime();
while(--i)
   Math.ceil(i/16)*16;
var dt3 = new Date().getTime() - t;

WScript.Echo("%: " + dt1 + " ms\n&: " + dt2 + " ms\nceil: " + dt3 + " ms");
/*
%: 1655 ms
&: 1523 ms
ceil: 1795 ms
*/
В виде

Code: Select all

var ceil = Math.ceil;
while(--i)
   ceil(i/16)*16;
будет чуть быстрее.


А выигрывает пока что и правда

Code: Select all

(16 - (i & 16)) & 16; // (16 - (i % 16)) % 16
:)

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

Post by KDJ »

If you use Math.round method (with expression) instead of MulDiv function, the difference is significant.

Infocatcher's test:

Code: Select all

var oSys = AkelPad.SystemFunction();
var c = 500e3;

var i = c + 1, t = new Date().getTime();
while(--i)
   oSys.Call("kernel32::MulDiv", i, 80, 96);
var dt1 = new Date().getTime() - t;

var i = c + 1, t = new Date().getTime();
while(--i)
   Math.round(i * 80 / 96);
var dt2 = new Date().getTime() - t;

WScript.Echo("MulDiv: " + dt1 + " ms\nMath.round: " + dt2 + " ms");
/*
MulDiv: 4250 ms
Math.round: 609 ms
*/


Result:
MulDiv: 4250 ms
Math.round: 609 ms

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

Post by FeyFre »

People, what do you talking about?
You doing this scaling operation few times per scripts. Do you really care of its performance?

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

Post by opk44 »

FeyFre
1. Формально: Есть разница 4 или 0,6
2. Спекулятивно: Насколько я понял, речь изначально о библиотеке для чужих (пользовательских) скриптов
3. cheerfully: Пользователям представилась возможность получить удовольствие наблюдая за общением гиков.

Offline
Posts: 366
Joined: Mon Jan 10, 2011 5:28 pm
Contact:

Post by Lenchik »

Да ладно, полезная инфа. Вдруг я как-нибудь забацать скрипт какой-нибудь и вспомню, что где-то в недрах этой темы были такие вот тесты и я сразу либо свой скрипт тестировать буду, либо учту эти выводы. Вообще можно было бы результаты тестов в шапку темы вынести.
И как-то проанализировать или собрать статистику по всем актуальным пользовательским скриптам.
И вообще, для некоторых, пользователь Акельпада сам гик - чего он только не вытворяет с текстами с помощью Акельпада.

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

Post by Infocatcher »


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

Post by KDJ »

OK, solved the matter of creating dialog windows by using CreateWindowEx function.
Now about creating modeless dialog boxes by using CreateDialogIndirectParam function.
The problem is similar - AkelPad crashes when trying to create the fifth dialog box.

Script for test:

Code: Select all

if (typeof AkelPad == "undefined")
{
  try
  {
    AkelPad = new ActiveXObject("AkelPad.Document");
  }
  catch (oError)
  {
    WScript.Echo("You need register Scripts.dll");
    WScript.Quit();
  }
}

var WS_CAPTION       = 0x00C00000;
var WS_CHILD         = 0x40000000;
var WS_MINIMIZEBOX   = 0x00020000;
var WS_OVERLAPPED    = 0x00000000;
var WS_POPUP         = 0x80000000;
var WS_SYSMENU       = 0x00080000;
var WS_TABSTOP       = 0x00010000;
var WS_VISIBLE       = 0x10000000;
var DS_SETFONT       = 0x0040;
var BS_AUTOCHECKBOX  = 0x0003;
var BS_DEFPUSHBUTTON = 0x0001;

var oSys      = AkelPad.SystemFunction();
var nCounter  = 0;
var IDCANCEL  = 2;
var IDNEW     = 1000;
var IDCLOSE   = 1001;
var IDCHECK1  = 1002;
var IDCHECK2  = 1003;
var IDCHECK3  = 1004;
var IDCHECK4  = 1005;
var IDCHECK5  = 1006;
var IDCHECK6  = 1007;
var IDCHECK7  = 1008;
var IDCHECK8  = 1009;
var IDCHECK9  = 1010;
var IDCHECK10 = 1011;
var IDCHECK11 = 1012;
var IDCHECK12 = 1013;
var IDCHECK13 = 1014;
var IDCHECK14 = 1015;
var IDCHECK15 = 1016;

CreateNewDialog(0);

function CreateNewDialog(hParent)
{
  try
  {
    oSys.RegisterCallback(DialogCallback);
  }
  catch (oError)
  {
    return;
    WScript.Echo("Unable to register callback function.");
  }

  var aDlg = [];
  var lpTemp;
  var hDlg;
  var i;

  aDlg.Title    = "Dialog box " + ++nCounter;
  aDlg.Style    = WS_VISIBLE | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX;
  aDlg.X        = 5;
  aDlg.Y        = 5;
  aDlg.W        = 125;
  aDlg.H        = 208;
  aDlg.CtlFirst = IDNEW;
  aDlg.CtlStyle = WS_VISIBLE | WS_TABSTOP;
  aDlg.CtlFontN = "MS Shell Dlg";

  aDlg[IDNEW]   = {X:  5, Y: 190, W: 55, H: 14, Title: "&New dialog", Style: BS_DEFPUSHBUTTON};
  aDlg[IDCLOSE] = {X: 65, Y: 190, W: 55, H: 14, Title: "Close"};
  for (i = 0; i < 15; ++i)
    aDlg[IDCHECK1 + i] = {X: 36, Y: 5 + 12 * i, W: 60, H: 10, Title: "CheckBox" + (i + 1), Style: BS_AUTOCHECKBOX};

  lpTemp = GetDialogTemplate(aDlg);

  hDlg = oSys.Call("User32::CreateDialogIndirectParamW",
    AkelPad.GetInstanceDll(), //hInstance
    lpTemp,                   //lpTemplate
    hParent,                  //hWndParent
    DialogCallback,           //lpDialogFunc
    0);                       //lParamInit

  AkelPad.MemFree(lpTemp);

  if (hDlg)
  {
    AkelPad.WindowRegisterDialog(hDlg);
    if (nCounter == 1)
      AkelPad.WindowGetMessage();
  }
  else
  {
    --nCounter;
    oSys.UnregisterCallback(DialogCallback);
  }

  function DialogCallback(hWnd, uMsg, wParam, lParam)
  {
    if (uMsg == 273 /*WM_COMMAND*/)
    {
      var nLowParam = wParam & 0xFFFF;

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

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

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

    return 0;
  }
}

function GetDialogTemplate(aDlg)
{
  var nCtlCount = 0;
  var sTitle    = aDlg.Title || "";
  var nCtlFontS = aDlg.CtlFontS || 8;
  var nTempLen  = 30 + (sTitle.length + 1) * 2;
  var lpTemp;
  var lpItem;
  var sCtlClass;
  var sCtlTitle;
  var i;

  if (aDlg.Style & WS_CHILD) aDlg.Style ^= WS_CHILD;

  if (aDlg.CtlFontN)
  {
    aDlg.Style |= DS_SETFONT;
    nTempLen   += 6 + (aDlg.CtlFontN.length + 1) * 2;
  }
  else if (aDlg.Style & DS_SETFONT)
    aDlg.Style ^= DS_SETFONT;

  nTempLen += (4 - nTempLen % 4) % 4; //align to DWORD

  for (i = aDlg.CtlFirst; i < aDlg.length; ++i)
  {
    if (aDlg[i])
    {
      sCtlClass = aDlg[i].Class || aDlg.CtlClass || "BUTTON";
      sCtlTitle = aDlg[i].Title || "";

      aDlg[i].Style |= aDlg.CtlStyle | WS_CHILD;
      if (aDlg[i].Style & WS_POPUP) aDlg[i].Style ^= WS_POPUP;

      nTempLen += 26 + (sCtlClass.length + 1) * 2 + (sCtlTitle.length + 1) * 2;
      nTempLen += (4 - nTempLen % 4) % 4; //align to DWORD
      ++nCtlCount;
    }
  }

  lpTemp = AkelPad.MemAlloc(nTempLen);
  lpItem = lpTemp;

  //fill DLGTEMPLATEEX
  AkelPad.MemCopy(lpItem,                     1, 4 /*DT_WORD*/);    //dlgVer
  AkelPad.MemCopy(lpItem +  2,           0xFFFF, 4 /*DT_WORD*/);    //signature
  AkelPad.MemCopy(lpItem +  8,     aDlg.ExStyle, 3 /*DT_DWORD*/);   //exStyle
  AkelPad.MemCopy(lpItem + 12,       aDlg.Style, 3 /*DT_DWORD*/);   //style
  AkelPad.MemCopy(lpItem + 16,        nCtlCount, 4 /*DT_WORD*/);    //cDlgItems
  AkelPad.MemCopy(lpItem + 18,           aDlg.X, 4 /*DT_WORD*/);    //x
  AkelPad.MemCopy(lpItem + 20,           aDlg.Y, 4 /*DT_WORD*/);    //y
  AkelPad.MemCopy(lpItem + 22, Math.abs(aDlg.W), 4 /*DT_WORD*/);    //cx
  AkelPad.MemCopy(lpItem + 24, Math.abs(aDlg.H), 4 /*DT_WORD*/);    //cy
  AkelPad.MemCopy(lpItem + 30,           sTitle, 1 /*DT_UNICODE*/); //title
  lpItem += 30 + (sTitle.length + 1) * 2;

  if (aDlg.CtlFontN)
  {
    AkelPad.MemCopy(lpItem,         nCtlFontS, 4 /*DT_WORD*/);    //pointsize
    AkelPad.MemCopy(lpItem + 4, aDlg.CtlFontI, 5 /*DT_BYTE*/);    //italic
    AkelPad.MemCopy(lpItem + 5,             1, 5 /*DT_BYTE*/);    //charset=DEFAULT_CHARSET
    AkelPad.MemCopy(lpItem + 6, aDlg.CtlFontN, 1 /*DT_UNICODE*/); //typeface
    lpItem += 6 + (aDlg.CtlFontN.length + 1) * 2;
  }

  lpItem += (4 - lpItem % 4) % 4; //align to DWORD

  //fill DLGITEMTEMPLATEEX
  for (i = aDlg.CtlFirst; i < aDlg.length; ++i)
  {
    if (aDlg[i])
    {
      sCtlClass = aDlg[i].Class || aDlg.CtlClass || "BUTTON";
      sCtlTitle = aDlg[i].Title || "";
      AkelPad.MemCopy(lpItem +  4,     aDlg[i].ExStyle, 3 /*DT_DWORD*/);   //exStyle
      AkelPad.MemCopy(lpItem +  8,       aDlg[i].Style, 3 /*DT_DWORD*/);   //style
      AkelPad.MemCopy(lpItem + 12,           aDlg[i].X, 4 /*DT_WORD*/);    //x
      AkelPad.MemCopy(lpItem + 14,           aDlg[i].Y, 4 /*DT_WORD*/);    //y
      AkelPad.MemCopy(lpItem + 16, Math.abs(aDlg[i].W), 4 /*DT_WORD*/);    //cx
      AkelPad.MemCopy(lpItem + 18, Math.abs(aDlg[i].H), 4 /*DT_WORD*/);    //cy
      AkelPad.MemCopy(lpItem + 20,                   i, 3 /*DT_DWORD*/);   //id
      AkelPad.MemCopy(lpItem + 24,           sCtlClass, 1 /*DT_UNICODE*/); //windowClass
      lpItem += 24 + (sCtlClass.length + 1) * 2;
      AkelPad.MemCopy(lpItem,                sCtlTitle, 1 /*DT_UNICODE*/); //title
      lpItem += (sCtlTitle.length + 1) * 2 + 2;
      lpItem += (4 - lpItem % 4) % 4; //align to DWORD
    }
  }

  return lpTemp;
}


-----

And about RegisterCallback method.
Example from Scripts-Eng.txt:

Code: Select all

  if (lpEnumWindowsCallback=oSys.RegisterCallback(EnumWindowsProc))
  {
    ...
  }
If RegisterCallback fails, generates run time error.
It seems to me that in this case this method should return 0.

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

Post by FeyFre »

Та же причина IDocuemnt.c Line 3098

Code: Select all

    if (msgs->lpCallback->objFunction->lpVtbl->Invoke(msgs->lpCallback->objFunction, DISPID_VALUE, &IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, dispp, &vtInvoke, 0, 0) == S_OK)
    {
      if (vtInvoke.vt == VT_BOOL)

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

Post by Instructor »

KDJ
You should make "function DialogCallback(hWnd, uMsg, wParam, lParam)" global (move it outside CreateNewDialog) - more economy or make some connection of callback with global context - less economy:

Code: Select all

...
var aRegCount=[];
var nRegCount=0;

CreateNewDialog(0);

function CreateNewDialog(hParent)
{
  try
  {
    aRegCount[nRegCount++]=oSys.RegisterCallback(DialogCallback);
...
If RegisterCallback fails, generates run time error.
Run time error generated by JScript engine.

Offline
Posts: 1161
Joined: Sun Oct 20, 2013 11:44 am

Post by Skif_off »

Подскажите, пожалуйста, название скрипта для раскладывание чисел на члены, типа 1809=1+16+256+512+1024. Где-то видел краем глаза, что-то не соображу как найти.

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

Post by Instructor »


Offline
Posts: 1161
Joined: Sun Oct 20, 2013 11:44 am

Post by Skif_off »

Instructor
Спасибо.

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

Post by KDJ »

Instructor wrote:
If RegisterCallback fails, generates run time error.
Run time error generated by JScript engine.
In which case, RegisterCallback returns false (0)?

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

Post by KDJ »

CreateDialog_functions.js
Added: alignment of window size and position according to screen DPI.
Added: Scale object.
Fixed: some bugs.
Fixed: CreateDialog_example.js.
Locked