Advertisement
Alexey_B

runScript.js

Apr 10th, 2022
62
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // http://akelpad.sourceforge.net/forum/viewtopic.php?p=11863#11863
  2. // http://infocatcher.ucoz.net/js/akelpad_scripts/runScript.js
  3. // https://github.com/Infocatcher/AkelPad_scripts/blob/master/runScript.js
  4.  
  5. // (c) Infocatcher 2011, 2013-2014
  6. // Version: 0.2.8 - 2014-08-16
  7. // Author: Infocatcher
  8.  
  9. //===================
  10. //// Run script from AkelFiles\Plugs\Scripts\ directory
  11.  
  12. // Hotkeys:
  13. //   Enter                         - Ok
  14. //   Ctrl+Enter (Shift+Enter), F3  - Exec
  15. //   F4, Ctrl+E                    - Edit
  16. //   F2, Ctrl+S                    - Rewrite options (and remove arguments for removed files)
  17. //   F1, Shift+F1                  - Next/previous script
  18. //   F5                            - Refresh scripts list
  19. //   Escape                        - Cancel
  20.  
  21. // Arguments:
  22. //   -saveOptions=0               - don't save options
  23. //               =1               - save options only for runned scripts (default)
  24. //               =2               - always save options
  25. //   -savePosition=true           - allow store last window position
  26. //   -saveSize=true               - allow store last window size
  27. //   -script="someScript.js"      - select someScript.js in the list
  28.  
  29. // Usage:
  30. //   Call("Scripts::Main", 1, "runScript.js")
  31. //   Call("Scripts::Main", 1, "runScript.js", `-script="someScript.js" -saveOptions=0 -savePosition=false`)
  32. //===================
  33.  
  34. function _localize(s) {
  35.     var strings = {
  36.         "&Arguments": {
  37.             ru: "&Аргументы"
  38.         },
  39.         "OK": {
  40.             ru: "ОК"
  41.         },
  42.         "Exec": {
  43.             ru: "Запустить"
  44.         },
  45.         "Edit": {
  46.             ru: "Изменить"
  47.         },
  48.         "Cancel": {
  49.             ru: "Отмена"
  50.         }
  51.     };
  52.     var lng;
  53.     switch(AkelPad.GetLangId(1 /*LANGID_PRIMARY*/)) {
  54.         case 0x19: lng = "ru"; break;
  55.         default:   lng = "en";
  56.     }
  57.     _localize = function(s) {
  58.         return strings[s] && strings[s][lng] || s;
  59.     };
  60.     return _localize(s);
  61. }
  62.  
  63. var hMainWnd = AkelPad.GetMainWnd();
  64. if(!hMainWnd)
  65.     WScript.Quit();
  66.  
  67. var oSys = AkelPad.SystemFunction();
  68. var oSet = AkelPad.ScriptSettings();
  69. var fso = new ActiveXObject("Scripting.FileSystemObject");
  70. var scriptsDir = AkelPad.GetAkelDir(5 /*ADTYPE_SCRIPTS*/);
  71. var dialogTitle = WScript.ScriptName.replace(/^[!-\-_]+/, "");
  72. dialogTitle = dialogTitle.charAt(0).toUpperCase() + dialogTitle.substr(1);
  73.  
  74. function getPrefName(scriptName) {
  75.     return "/" + scriptName.replace(/=/g, "<equals>");
  76. }
  77.  
  78. // Read arguments:
  79. var scriptName   = AkelPad.GetArgValue("script", "");
  80. var saveOptions  = AkelPad.GetArgValue("saveOptions", 1);
  81. var savePosition = AkelPad.GetArgValue("savePosition", true);
  82. var saveSize     = AkelPad.GetArgValue("saveSize", true);
  83.  
  84. var filePath = AkelPad.GetEditFile(0);
  85. if(!scriptName && fso.GetParentFolderName(filePath).toLowerCase() == scriptsDir.toLowerCase())
  86.     scriptName = fso.GetFileName(filePath);
  87.  
  88. selectScriptDialog();
  89.  
  90. function isScript(path) {
  91.     return /\.(js|vbs)$/i.test(path);
  92. }
  93. function expandArgs(args) {
  94.     var wsh = new ActiveXObject("WScript.Shell");
  95.     expandArgs = function(args) {
  96.         var file = AkelPad.GetEditFile(0);
  97.         return wsh.ExpandEnvironmentStrings(args)
  98.             .replace(/%f/ig, file)
  99.             .replace(/%d/ig, fso.GetParentFolderName(file))
  100.             .replace(/%a/ig, AkelPad.GetAkelDir())
  101.             .replace(/%([^%]|$)/g, "$1")
  102.             .replace(/%%/g, "%");
  103.     };
  104.     return expandArgs(args);
  105. }
  106.  
  107. function selectScriptDialog(modal) {
  108.     var hInstanceDLL = AkelPad.GetInstanceDll();
  109.     var dialogClass = "AkelPad::Scripts::" + WScript.ScriptName + "::" + oSys.Call("kernel32::GetCurrentProcessId");
  110.     var hListBoxSubClass;
  111.  
  112.     var hWndDialog = oSys.Call("user32::FindWindowEx" + _TCHAR, 0, 0, dialogClass, 0);
  113.     if(hWndDialog) {
  114.         if(oSys.Call("user32::IsIconic", hWndDialog))
  115.             oSys.Call("user32::ShowWindow", hWndDialog, 9 /*SW_RESTORE*/);
  116.         AkelPad.SendMessage(hWndDialog, 7 /*WM_SETFOCUS*/, 0, 0);
  117.         return;
  118.     }
  119.  
  120.     if(
  121.         !AkelPad.WindowRegisterClass(dialogClass)
  122.         && ( // Previous script instance crashed
  123.             !AkelPad.WindowUnregisterClass(dialogClass)
  124.             || !AkelPad.WindowRegisterClass(dialogClass)
  125.         )
  126.     )
  127.         return;
  128.  
  129.     var curName = isScript(scriptName) && scriptName;
  130.  
  131.     var dlgX, dlgY;
  132.     var lastW, lastH;
  133.     if((saveOptions || savePosition || saveSize) && oSet.Begin(WScript.ScriptBaseName, 0x1 /*POB_READ*/)) {
  134.         if(saveOptions && !curName)
  135.             curName = oSet.Read("lastScript", 3 /*PO_STRING*/, "");
  136.         if(savePosition) {
  137.             dlgX = oSet.Read("windowLeft", 1 /*PO_DWORD*/);
  138.             dlgY = oSet.Read("windowTop",  1 /*PO_DWORD*/);
  139.         }
  140.         if(saveSize) {
  141.             lastW = oSet.Read("windowWidth",  1 /*PO_DWORD*/);
  142.             lastH = oSet.Read("windowHeight", 1 /*PO_DWORD*/);
  143.         }
  144.         oSet.End();
  145.     }
  146.     var _cleanup = {};
  147.     function saveSettings(rewrite) {
  148.         if(!saveOptions && !savePosition && !saveSize)
  149.             return;
  150.         if(!oSet.Begin(WScript.ScriptBaseName, 0x2 /*POB_SAVE*/ | (rewrite ? 0x4 /*POB_CLEAR*/ : 0)))
  151.             return;
  152.         if(saveOptions) {
  153.             if(runned || saveOptions == 2)
  154.                 oSet.Write("lastScript", 3 /*PO_STRING*/, saveOptions == 2 ? curName : runnedName);
  155.             var names = saveOptions == 2 ? argsObj : runned || {};
  156.             for(var name in names)
  157.                 saveArgs(name, argsObj[name]);
  158.             for(var name in _cleanup) {
  159.                 oSet.Delete("lastArgs-" + encodeURIComponent(name));
  160.                 !names[name] && saveArgs(name, _cleanup[name]);
  161.             }
  162.         }
  163.         if((savePosition || saveSize) && !oSys.Call("user32::IsIconic", hWndDialog)) {
  164.             var rcWnd = getWindowRect(hWndDialog);
  165.             if(rcWnd) {
  166.                 if(savePosition) {
  167.                     oSet.Write("windowLeft", 1 /*PO_DWORD*/, rcWnd.left);
  168.                     oSet.Write("windowTop",  1 /*PO_DWORD*/, rcWnd.top);
  169.                 }
  170.                 if(saveSize) {
  171.                     oSet.Write("windowWidth",  1 /*PO_DWORD*/, Math.round((rcWnd.right - rcWnd.left)/scale.x(10000)*10000) - sizeNonClientX);
  172.                     oSet.Write("windowHeight", 1 /*PO_DWORD*/, Math.round((rcWnd.bottom - rcWnd.top)/scale.y(10000)*10000) - sizeNonClientY);
  173.                 }
  174.             }
  175.         }
  176.         oSet.End();
  177.     }
  178.     function saveArgs(name, args) {
  179.         var prefName = getPrefName(name);
  180.         if(args)
  181.             oSet.Write(prefName, 3 /*PO_STRING*/, args);
  182.         else
  183.             oSet.Delete(prefName);
  184.     }
  185.  
  186.     var IDC_STATIC  = -1;
  187.     var IDC_LISTBOX = 1000;
  188.     var IDC_ARGS    = 1001;
  189.     var IDC_OK      = 1002;
  190.     var IDC_EXEC    = 1003;
  191.     var IDC_EDIT    = 1004;
  192.     var IDC_CANCEL  = 1005;
  193.  
  194.     var selfRun = false;
  195.     var runned, runnedName;
  196.     var argsObj = {};
  197.  
  198.     var hWndListBox, hWndGroupArgs, hWndArgs;
  199.     var hWndOK, hWndExec, hWndEdit, hWndCancel;
  200.  
  201.     var lbW = 260;
  202.     var lbH = 320;
  203.  
  204.     var btnW = 82;
  205.     var btnH = 23;
  206.     var btnSep = 4;
  207.  
  208.     var gbH = 48;
  209.     var gbW = lbW + 12 + btnW;
  210.  
  211.     var dlgW = 12 + lbW + 12 + btnW + 12;
  212.     var dlgH = 12 + lbH + 12 + gbH + 12;
  213.  
  214.     var dlgMinW = dlgW - lbW + 120;
  215.     var dlgMinH = 12 + btnH*4 + btnSep*3 + 12 + gbH + 12;
  216.  
  217.     if(lastW != undefined)
  218.         lastW = Math.max(dlgMinW, lastW);
  219.     if(lastH != undefined)
  220.         lastH = Math.max(dlgMinH, lastH);
  221.  
  222.     var scale = new Scale(0, hMainWnd);
  223.     var sizeNonClientX = oSys.Call("user32::GetSystemMetrics", 32 /*SM_CXSIZEFRAME*/) * 2;
  224.     var sizeNonClientY = oSys.Call("user32::GetSystemMetrics", 33 /*SM_CYSIZEFRAME*/) * 2 + oSys.Call("user32::GetSystemMetrics", 4 /*SM_CYCAPTION*/);
  225.  
  226.     // Create dialog
  227.     hWndDialog = oSys.Call(
  228.         "user32::CreateWindowEx" + _TCHAR,
  229.         0,                                       //dwExStyle
  230.         dialogClass,                             //lpClassName
  231.         0,                                       //lpWindowName
  232.         0x90CE0000,                              //WS_VISIBLE|WS_POPUP|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX|WS_THICKFRAME
  233.         scale.x(dlgX || 0),                      //x
  234.         scale.y(dlgY || 0),                      //y
  235.         scale.x(lastW || dlgW) + sizeNonClientX, //nWidth
  236.         scale.y(lastH || dlgH) + sizeNonClientY, //nHeight
  237.         hMainWnd,                                //hWndParent
  238.         0,                                       //ID
  239.         hInstanceDLL,                            //hInstance
  240.         dialogCallback                           //Script function callback. To use it class must be registered by WindowRegisterClass.
  241.     );
  242.     if(!hWndDialog)
  243.         return;
  244.  
  245.     function dialogCallback(hWnd, uMsg, wParam, lParam) {
  246.         switch(uMsg) {
  247.             case 1: //WM_CREATE
  248.                 dlgW = scale.x(dlgW) + sizeNonClientX;
  249.                 dlgH = scale.y(dlgH) + sizeNonClientY;
  250.                 dlgMinW = scale.x(dlgMinW) + sizeNonClientX;
  251.                 dlgMinH = scale.y(dlgMinH) + sizeNonClientY;
  252.  
  253.                 var hGuiFont = oSys.Call("gdi32::GetStockObject", 17 /*DEFAULT_GUI_FONT*/);
  254.  
  255.                 // Dialog caption
  256.                 oSys.Call("user32::SetWindowText" + _TCHAR, hWnd, dialogTitle);
  257.  
  258.                 hWndListBox = createWindowEx(
  259.                     0x204,        //WS_EX_CLIENTEDGE|WS_EX_NOPARENTNOTIFY
  260.                     "LISTBOX",    //lpClassName
  261.                     0,            //lpWindowName
  262.                     0x50210103,   //WS_VISIBLE|WS_CHILD|WS_VSCROLL|WS_TABSTOP|LBS_NOINTEGRALHEIGHT|LBS_SORT|LBS_NOTIFY
  263.                     12,           //x
  264.                     12,           //y
  265.                     lbW,          //nWidth
  266.                     lbH,          //nHeight
  267.                     hWnd,         //hWndParent
  268.                     IDC_LISTBOX,  //ID
  269.                     hInstanceDLL, //hInstance
  270.                     0             //lpParam
  271.                 );
  272.                 setWindowFont(hWndListBox, hGuiFont);
  273.                 hListBoxSubClass = AkelPad.WindowSubClass(hWndListBox, listBoxCallback, 258 /*WM_CHAR*/);
  274.  
  275.                 // GroupBox action
  276.                 hWndGroupArgs = createWindowEx(
  277.                     0,             //dwExStyle
  278.                     "BUTTON",      //lpClassName
  279.                     0,             //lpWindowName
  280.                     0x50000007,    //WS_VISIBLE|WS_CHILD|BS_GROUPBOX
  281.                     12,            //x
  282.                     12 + lbH + 12, //y
  283.                     gbW,           //nWidth
  284.                     gbH,           //nHeight
  285.                     hWnd,          //hWndParent
  286.                     IDC_STATIC,    //ID
  287.                     hInstanceDLL,  //hInstance
  288.                     0              //lpParam
  289.                 );
  290.                 setWindowFontAndText(hWndGroupArgs, hGuiFont, _localize("&Arguments"));
  291.  
  292.                 // Edit: arguments
  293.                 hWndArgs = createWindowEx(
  294.                     0x200,              //WS_EX_CLIENTEDGE
  295.                     "EDIT",             //lpClassName
  296.                     0,                  //lpWindowName
  297.                     0x50010080,         //WS_VISIBLE|WS_CHILD|WS_TABSTOP|ES_AUTOHSCROLL
  298.                     12 + 8,             //x
  299.                     12 + lbH + 12 + 18, //y
  300.                     gbW - 8*2,          //nWidth
  301.                     21,                 //nHeight
  302.                     hWnd,               //hWndParent
  303.                     IDC_ARGS,           //ID
  304.                     hInstanceDLL,       //hInstance
  305.                     0                   //lpParam
  306.                 );
  307.                 setWindowFont(hWndArgs, hGuiFont);
  308.                 setEditText(hWndArgs, "");
  309.  
  310.                 // OK button window
  311.                 hWndOK = createWindowEx(
  312.                     0,             //dwExStyle
  313.                     "BUTTON",      //lpClassName
  314.                     0,             //lpWindowName
  315.                     0x50010001,    //WS_VISIBLE|WS_CHILD|WS_TABSTOP|BS_DEFPUSHBUTTON
  316.                     12 + lbW + 12, //x
  317.                     12,            //y
  318.                     btnW,          //nWidth
  319.                     btnH,          //nHeight
  320.                     hWnd,          //hWndParent
  321.                     IDC_OK,        //ID
  322.                     hInstanceDLL,  //hInstance
  323.                     0              //lpParam
  324.                 );
  325.                 setWindowFontAndText(hWndOK, hGuiFont, _localize("OK"));
  326.  
  327.                 // Exec button window
  328.                 hWndExec = createWindowEx(
  329.                     0,                  //dwExStyle
  330.                     "BUTTON",           //lpClassName
  331.                     0,                  //lpWindowName
  332.                     0x50010000,         //WS_VISIBLE|WS_CHILD|WS_TABSTOP
  333.                     12 + lbW + 12,      //x
  334.                     12 + btnH + btnSep, //y
  335.                     btnW,               //nWidth
  336.                     btnH,               //nHeight
  337.                     hWnd,               //hWndParent
  338.                     IDC_EXEC,           //ID
  339.                     hInstanceDLL,       //hInstance
  340.                     0                   //lpParam
  341.                 );
  342.                 setWindowFontAndText(hWndExec, hGuiFont, _localize("Exec"));
  343.  
  344.                 // Edit button window
  345.                 hWndEdit = createWindowEx(
  346.                     0,                      //dwExStyle
  347.                     "BUTTON",               //lpClassName
  348.                     0,                      //lpWindowName
  349.                     0x50010000,             //WS_VISIBLE|WS_CHILD|WS_TABSTOP
  350.                     12 + lbW + 12,          //x
  351.                     12 + (btnH + btnSep)*2, //y
  352.                     btnW,                   //nWidth
  353.                     btnH,                   //nHeight
  354.                     hWnd,                   //hWndParent
  355.                     IDC_EDIT,               //ID
  356.                     hInstanceDLL,           //hInstance
  357.                     0                       //lpParam
  358.                 );
  359.                 setWindowFontAndText(hWndEdit, hGuiFont, _localize("Edit"));
  360.  
  361.                 // Cancel button window
  362.                 hWndCancel = createWindowEx(
  363.                     0,                      //dwExStyle
  364.                     "BUTTON",               //lpClassName
  365.                     0,                      //lpWindowName
  366.                     0x50010000,             //WS_VISIBLE|WS_CHILD|WS_TABSTOP
  367.                     12 + lbW + 12,          //x
  368.                     12 + (btnH + btnSep)*3, //y
  369.                     btnW,                   //nWidth
  370.                     btnH,                   //nHeight
  371.                     hWnd,                   //hWndParent
  372.                     IDC_CANCEL,             //ID
  373.                     hInstanceDLL,           //hInstance
  374.                     0                       //lpParam
  375.                 );
  376.                 setWindowFontAndText(hWndCancel, hGuiFont, _localize("Cancel"));
  377.  
  378.                 if(lastW != undefined || lastH != undefined)
  379.                     resizeDialog(hWnd, lastW || dlgW, lastH || dlgH);
  380.  
  381.                 fillListBox();
  382.                 updArgs();
  383.  
  384.                 //centerWindow(hWnd);
  385.                 //centerWindow(hWnd, hMainWnd);
  386.                 restoreWindowPosition(hWnd, hMainWnd);
  387.             break;
  388.             case 7: //WM_SETFOCUS
  389.                 oSys.Call("user32::SetFocus", curName ? hWndArgs : hWndListBox);
  390.             break;
  391.             case 256: //WM_KEYDOWN
  392.                 var ctrl = oSys.Call("user32::GetAsyncKeyState", 17 /*VK_CONTROL*/) & 0x8000;
  393.                 var shift = oSys.Call("user32::GetAsyncKeyState", 16 /*VK_SHIFT*/) & 0x8000;
  394.                 //var alt = oSys.Call("user32::GetAsyncKeyState", 18 /*VK_MENU*/) & 0x8000;
  395.                 if(wParam == 27) //VK_ESCAPE
  396.                     oSys.Call("user32::PostMessage" + _TCHAR, hWnd, 273 /*WM_COMMAND*/, IDC_CANCEL, 0);
  397.                 else if(wParam == 13) { //VK_RETURN
  398.                     if(ctrl || shift) // Ctrl+Enter, Shift+Enter
  399.                         oSys.Call("user32::PostMessage" + _TCHAR, hWnd, 273 /*WM_COMMAND*/, IDC_EXEC, 0);
  400.                     else // Enter
  401.                         oSys.Call("user32::PostMessage" + _TCHAR, hWnd, 273 /*WM_COMMAND*/, IDC_OK, 0);
  402.                 }
  403.                 else if(wParam == 114 /*VK_F3*/) // F3
  404.                     oSys.Call("user32::PostMessage" + _TCHAR, hWnd, 273 /*WM_COMMAND*/, IDC_EXEC, 0);
  405.                 else if(wParam == 112 /*VK_F1*/)
  406.                     navigate(ctrl || shift);
  407.                 else if(wParam == 113 /*VK_F2*/ || ctrl && wParam == 83 /*S*/) { // F2, Ctrl+S
  408.                     var so = saveOptions;
  409.                     saveOptions = 2;
  410.                     saveSettings(true);
  411.                     saveOptions = so;
  412.                 }
  413.                 else if(wParam == 115 /*VK_F4*/ || ctrl && wParam == 69 /*E*/) // F4, Ctrl+E
  414.                     oSys.Call("user32::PostMessage" + _TCHAR, hWnd, 273 /*WM_COMMAND*/, IDC_EDIT, 0);
  415.                 else if(wParam == 116 /*VK_F5*/)
  416.                     redrawListbox();
  417.  
  418.                 //else if(wParam != 16 /*VK_SHIFT*/ && wParam != 17 /*VK_CONTROL*/ && wParam != 18 /*VK_MENU*/)
  419.                 //  AkelPad.MessageBox(hWnd, wParam, dialogTitle, 0 /*MB_OK*/);
  420.             break;
  421.             case 273: //WM_COMMAND
  422.                 var idc = wParam & 0xffff;
  423.                 switch(idc) {
  424.                     case IDC_OK:
  425.                     case IDC_EXEC:
  426.                         var isSelf = curName == WScript.ScriptName;
  427.                         selfRun = false;
  428.                         if(!curName || isSelf && idc == IDC_EXEC)
  429.                             break;
  430.                         if(!runned)
  431.                             runned = {};
  432.                         runned[runnedName = curName] = true;
  433.                         if(isSelf)
  434.                             selfRun = true;
  435.                         else
  436.                             AkelPad.Call("Scripts::Main", 1, curName, expandArgs(argsObj[curName] || ""));
  437.                         if(idc == IDC_OK)
  438.                             closeDialog();
  439.                         else
  440.                             ensureVisibility();
  441.                     break;
  442.                     case IDC_EDIT:
  443.                         curName && AkelPad.Call("Scripts::Main", 3, curName);
  444.                     break;
  445.                     case IDC_CANCEL:
  446.                         closeDialog();
  447.                     break;
  448.                     case IDC_ARGS:
  449.                         argsObj[curName] = windowText(hWndArgs).replace(/^\s+|\s+$/g, "");
  450.                     break;
  451.                     case IDC_LISTBOX:
  452.                         updArgs();
  453.                         if((wParam >> 16 & 0xFFFF) == 2 /*LBN_DBLCLK*/)
  454.                             oSys.Call("user32::PostMessage" + _TCHAR, hWnd, 273 /*WM_COMMAND*/, IDC_EXEC, 0);
  455.                 }
  456.             break;
  457.             case 36: //WM_GETMINMAXINFO
  458.                 AkelPad.MemCopy(lParam + 24, dlgMinW, 3 /*DT_DWORD*/); //ptMinTrackSize.x
  459.                 AkelPad.MemCopy(lParam + 28, dlgMinH, 3 /*DT_DWORD*/); //ptMinTrackSize.y
  460.             break;
  461.             case 5: //WM_SIZE
  462.                 if(oSys.Call("user32::IsIconic", hWnd))
  463.                     break;
  464.                 var rcWnd = getWindowRect(hWnd);
  465.                 var curW = rcWnd.right - rcWnd.left;
  466.                 var curH = rcWnd.bottom - rcWnd.top;
  467.                 resizeDialog(hWnd, curW, curH);
  468.             break;
  469.             case 15: //WM_PAINT
  470.                 // Based on code of SearchReplace.js script
  471.                 var ps;
  472.                 var hDC;
  473.                 var lpGrip;
  474.                 var rcGrip;
  475.                 if(ps = AkelPad.MemAlloc(_X64 ? 72 : 64 /*sizeof(PAINTSTRUCT)*/)) {
  476.                     if(hDC = oSys.Call("user32::BeginPaint", hWnd, ps)) {
  477.                         if(lpGrip = AkelPad.MemAlloc(16 /*sizeof(RECT)*/)) {
  478.                             if(oSys.Call("user32::GetClientRect", hWnd, lpGrip)) {
  479.                                 rcGrip = parseRect(lpGrip);
  480.                                 rcGrip.left = rcGrip.right  - oSys.Call("user32::GetSystemMetrics", 2 /*SM_CXVSCROLL*/);
  481.                                 rcGrip.top  = rcGrip.bottom - oSys.Call("user32::GetSystemMetrics", 20 /*SM_CYVSCROLL*/);
  482.  
  483.                                 AkelPad.MemCopy(lpGrip,      rcGrip.left,   3 /*DT_DWORD*/);
  484.                                 AkelPad.MemCopy(lpGrip + 4,  rcGrip.top,    3 /*DT_DWORD*/);
  485.                                 AkelPad.MemCopy(lpGrip + 8,  rcGrip.right,  3 /*DT_DWORD*/);
  486.                                 AkelPad.MemCopy(lpGrip + 12, rcGrip.bottom, 3 /*DT_DWORD*/);
  487.  
  488.                                 oSys.Call("user32::DrawFrameControl", hDC, lpGrip, 3 /*DFC_SCROLL*/, 0x8 /*DFCS_SCROLLSIZEGRIP*/);
  489.                             }
  490.                             AkelPad.MemFree(lpGrip);
  491.                         }
  492.                         oSys.Call("user32::EndPaint", hWnd, ps);
  493.                     }
  494.                     AkelPad.MemFree(ps);
  495.                 }
  496.             break;
  497.             case 16: //WM_CLOSE
  498.                 saveSettings();
  499.                 modal && enabled(hMainWnd, true); // Enable main window
  500.                 oSys.Call("user32::DestroyWindow", hWnd); // Destroy dialog
  501.             break;
  502.             case 2: //WM_DESTROY
  503.                 oSys.Call("user32::PostQuitMessage", 0); // Exit message loop
  504.         }
  505.         return 0;
  506.     }
  507.    
  508.     function listBoxCallback(hWnd, uMsg, wParam, lParam) {
  509.         if (oSys.Call("user32::GetAsyncKeyState", 17 /*VK_CONTROL*/) & 0x8000)
  510.             AkelPad.WindowNoNextProc(hListBoxSubClass);
  511.     }
  512.  
  513.     function fillListBox() {
  514.         //var t = new Date().getTime();
  515.         var files = [];
  516.         // Foollowing is very slow (especially on slow devices like USB flash):
  517.         //var filesEnum = new Enumerator(fso.GetFolder(scriptsDir).Files);
  518.         //for(; !filesEnum.atEnd(); filesEnum.moveNext()) {
  519.         //  var name = filesEnum.item().Name;
  520.         //  if(isScript(name))
  521.         //      files[files.length] = name;
  522.         //}
  523.  
  524.         // Based on Instructor's code: http://akelpad.sourceforge.net/forum/viewtopic.php?p=12548#12548
  525.         var lpFindData = AkelPad.MemAlloc(592 /*sizeof(WIN32_FIND_DATAW)*/);
  526.         if(!lpFindData)
  527.             return;
  528.         var hSearch = oSys.Call("kernel32::FindFirstFile" + _TCHAR, scriptsDir + "\\*", lpFindData);
  529.         if(!hSearch)
  530.             return;
  531.         do {
  532.             var fName = AkelPad.MemRead(lpFindData + 44 /*offsetof(WIN32_FIND_DATAW, cFileName)*/, _TSTR);
  533.             if(fName == "." || fName == "..")
  534.                 continue;
  535.             if(isScript(fName))
  536.                 files[files.length] = fName;
  537.         }
  538.         while(oSys.Call("kernel32::FindNextFile" + _TCHAR, hSearch, lpFindData));
  539.         oSys.Call("kernel32::FindClose", hSearch);
  540.         AkelPad.MemFree(lpFindData);
  541.         //WScript.Echo(new Date().getTime() - t);
  542.         //files.sort();
  543.  
  544.         var lpStr = AkelPad.MemAlloc(256*_TSIZE);
  545.         if(!lpStr)
  546.             return;
  547.  
  548.         var read = oSet.Begin(WScript.ScriptBaseName, 0x1 /*POB_READ*/);
  549.  
  550.         var indx = 0;
  551.         for(var i = 0, l = files.length; i < l; ++i) {
  552.             var name = files[i];
  553.  
  554.             if(read) {
  555.                 var args = oSet.Read(getPrefName(name), 3 /*PO_STRING*/);
  556.                 var oldArgs = oSet.Read("lastArgs-" + encodeURIComponent(name), 3 /*PO_STRING*/);
  557.                 if(oldArgs != undefined)
  558.                     _cleanup[name] = oldArgs;
  559.                 argsObj[name] = args || oldArgs || "";
  560.             }
  561.  
  562.             AkelPad.MemCopy(lpStr, name.substr(0, 255), _TSTR);
  563.             AkelPad.SendMessage(hWndListBox,  0x180 /*LB_ADDSTRING*/, 0, lpStr);
  564.         }
  565.         AkelPad.MemFree(lpStr);
  566.         read && oSet.End();
  567.  
  568.         var indx = getIndexFromString(curName);
  569.         if(indx != undefined)
  570.             AkelPad.SendMessage(hWndListBox,  0x186 /*LB_SETCURSEL*/, indx, 0);
  571.         else
  572.             curName = "";
  573.     }
  574.     function redrawListbox() {
  575.         for(var name in argsObj)
  576.             delete argsObj[name];
  577.  
  578.         AkelPad.SendMessage(hWndDialog, 11 /*WM_SETREDRAW*/, false, 0);
  579.  
  580.         var maxIndx = AkelPad.SendMessage(hWndListBox,  0x18B /*LB_GETCOUNT*/, 0, 0) - 1;
  581.         for(var i = maxIndx; i >= 0; --i)
  582.             AkelPad.SendMessage(hWndListBox,  0x182 /*LB_DELETESTRING*/, i, 0);
  583.         fillListBox();
  584.  
  585.         AkelPad.SendMessage(hWndDialog, 11 /*WM_SETREDRAW*/, true, 0);
  586.         //var lpRect = AkelPad.MemAlloc(16); //sizeof(RECT)
  587.         //if(lpRect) {
  588.         //  var rc = getWindowRect(hWndListBox, hWndDialog);
  589.         //  AkelPad.MemCopy(lpRect,      rc.left,   3 /*DT_DWORD*/);
  590.         //  AkelPad.MemCopy(lpRect + 4,  rc.top,    3 /*DT_DWORD*/);
  591.         //  AkelPad.MemCopy(lpRect + 8,  rc.right,  3 /*DT_DWORD*/);
  592.         //  AkelPad.MemCopy(lpRect + 12, rc.bottom, 3 /*DT_DWORD*/);
  593.         //  oSys.Call("user32::InvalidateRect", hWndDialog, lpRect, true);
  594.         //  AkelPad.MemFree(lpRect);
  595.         //}
  596.         oSys.Call("user32::InvalidateRect", hWndListBox, 0, true);
  597.  
  598.         updArgs();
  599.     }
  600.     function updArgs() {
  601.         var str = getStringFromIndex(AkelPad.SendMessage(hWndListBox, 0x188 /*LB_GETCURSEL*/, 0, 0));
  602.         if(!str) {
  603.             enableControls({
  604.                 exec: false,
  605.                 edit: false,
  606.                 ok:   false
  607.             });
  608.             return;
  609.         }
  610.         curName = str;
  611.         setEditText(hWndArgs, argsObj[str] || "");
  612.         enableControls({
  613.             exec: str != WScript.ScriptName,
  614.             edit: true,
  615.             ok:   true
  616.         });
  617.     }
  618.     function enableControls(enable) {
  619.         var hWndFocused = oSys.Call("user32::GetFocus");
  620.         enabled(hWndExec, enable.exec);
  621.         enabled(hWndEdit, enable.edit);
  622.         enabled(hWndOK,   enable.ok);
  623.         if(
  624.             !enable.exec && hWndFocused == hWndExec
  625.             || !enable.edit && hWndFocused == hWndEdit
  626.             || !enable.ok && hWndFocused == hWndOK
  627.         )
  628.             oSys.Call("user32::SetFocus", hWndDialog);
  629.     }
  630.     function ensureVisibility() {
  631.         var indx = AkelPad.SendMessage(hWndListBox, 0x188 /*LB_GETCURSEL*/, 0, 0);
  632.         if(indx != -1)
  633.             AkelPad.SendMessage(hWndListBox,  0x186 /*LB_SETCURSEL*/, indx, 0);
  634.     }
  635.     function navigate(up) {
  636.         var i = AkelPad.SendMessage(hWndListBox,  0x188 /*LB_GETCURSEL*/, 0, 0);
  637.         var max = AkelPad.SendMessage(hWndListBox,  0x18B /*LB_GETCOUNT*/, 0, 0) - 1;
  638.         if(up) {
  639.             if(--i < 0)
  640.                 i = max;
  641.         }
  642.         else {
  643.             if(++i > max)
  644.                 i = 0;
  645.         }
  646.         AkelPad.SendMessage(hWndListBox,  0x186 /*LB_SETCURSEL*/, i, 0);
  647.         oSys.Call("user32::PostMessage" + _TCHAR, hWndDialog, 273 /*WM_COMMAND*/, IDC_LISTBOX, 0);
  648.     }
  649.  
  650.     function restoreWindowPosition(hWnd, hWndParent) {
  651.         if(dlgX == undefined || dlgY == undefined) {
  652.             centerWindow(hWnd, hWndParent);
  653.             return;
  654.         }
  655.  
  656.         var rcWnd = getWindowRect(hWnd);
  657.         if(!rcWnd)
  658.             return;
  659.  
  660.         var lpRect = AkelPad.MemAlloc(16); //sizeof(RECT)
  661.         if(!lpRect)
  662.             return;
  663.         AkelPad.MemCopy(lpRect,      dlgX,                              3 /*DT_DWORD*/);
  664.         AkelPad.MemCopy(lpRect + 4,  dlgY,                              3 /*DT_DWORD*/);
  665.         AkelPad.MemCopy(lpRect + 8,  dlgX + (rcWnd.right - rcWnd.left), 3 /*DT_DWORD*/);
  666.         AkelPad.MemCopy(lpRect + 12, dlgY + (rcWnd.top - rcWnd.bottom), 3 /*DT_DWORD*/);
  667.         var hMonitor = oSys.Call("user32::MonitorFromRect", lpRect, 0x2 /*MONITOR_DEFAULTTONEAREST*/);
  668.  
  669.         if(hMonitor) {
  670.             //typedef struct tagMONITORINFO {
  671.             //  DWORD cbSize;
  672.             //  RECT  rcMonitor;
  673.             //  RECT  rcWork;
  674.             //  DWORD dwFlags;
  675.             //} MONITORINFO, *LPMONITORINFO;
  676.             var sizeofMonitorInfo = 4 + 16 + 16 + 4;
  677.             var lpMi = AkelPad.MemAlloc(sizeofMonitorInfo);
  678.             if(lpMi) {
  679.                 AkelPad.MemCopy(lpMi, sizeofMonitorInfo, 3 /*DT_DWORD*/);
  680.                 oSys.Call("user32::GetMonitorInfo" + _TCHAR, hMonitor, lpMi);
  681.                 var rcWork = parseRect(lpMi + 4 + 16);
  682.                 AkelPad.MemFree(lpMi);
  683.             }
  684.         }
  685.         else { //?
  686.             oSys.Call("user32::SystemParametersInfo" + _TCHAR, 48 /*SPI_GETWORKAREA*/, 0, lpRect, 0);
  687.             var rcWork = parseRect(lpRect);
  688.         }
  689.         AkelPad.MemFree(lpRect);
  690.  
  691.         if(rcWork) {
  692.             var edge = Math.max(
  693.                 16,
  694.                 oSys.Call("user32::GetSystemMetrics", 33 /*SM_CYSIZEFRAME*/)
  695.                     + oSys.Call("user32::GetSystemMetrics", 4 /*SM_CYCAPTION*/)
  696.             );
  697.  
  698.             var minX = rcWork.left - (rcWnd.right - rcWnd.left) + edge;
  699.             var minY = rcWork.top;
  700.             var maxX = rcWork.right - edge;
  701.             var maxY = rcWork.bottom - edge;
  702.  
  703.             dlgX = Math.max(minX, Math.min(maxX, dlgX));
  704.             dlgY = Math.max(minY, Math.min(maxY, dlgY));
  705.         }
  706.  
  707.         moveWindow(hWnd, dlgX, dlgY);
  708.     }
  709.     function centerWindow(hWnd, hWndParent) {
  710.         var rcWnd = getWindowRect(hWnd);
  711.         var rcWndParent = getWindowRect(hWndParent || oSys.Call("user32::GetDesktopWindow"));
  712.         if(!rcWndParent || !rcWnd)
  713.             return;
  714.         var x = rcWndParent.left + ((rcWndParent.right  - rcWndParent.left) / 2 - (rcWnd.right  - rcWnd.left) / 2);
  715.         var y = rcWndParent.top  + ((rcWndParent.bottom - rcWndParent.top)  / 2 - (rcWnd.bottom - rcWnd.top)  / 2);
  716.         moveWindow(hWnd, x, y);
  717.     }
  718.     function moveWindow(hWnd, x, y, hWndParent) {
  719.         if(hWndParent) {
  720.             var rcWnd = getWindowRect(hWnd, hWndParent);
  721.             x += rcWnd.left;
  722.             y += rcWnd.top;
  723.         }
  724.         oSys.Call("user32::SetWindowPos", hWnd, 0, x, y, 0, 0, 0x15 /*SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOSIZE*/);
  725.     }
  726.     function resizeWindow(hWnd, dw, dh) {
  727.         var rcWnd = getWindowRect(hWnd);
  728.         var w = rcWnd.right - rcWnd.left + dw;
  729.         var h = rcWnd.bottom - rcWnd.top + dh;
  730.         oSys.Call("user32::SetWindowPos", hWnd, 0, 0, 0, w, h, 0x16 /*SWP_NOZORDER|SWP_NOACTIVATE|SWP_NOMOVE*/);
  731.     }
  732.     function resizeDialog(hWnd, curW, curH) {
  733.         var dw = curW - dlgW;
  734.         var dh = curH - dlgH;
  735.  
  736.         resizeWindow(hWndListBox, dw, dh);
  737.  
  738.         resizeWindow(hWndGroupArgs, dw, 0);
  739.         resizeWindow(hWndArgs,      dw, 0);
  740.         moveWindow(hWndGroupArgs, 0, dh, hWnd);
  741.         moveWindow(hWndArgs,      0, dh, hWnd);
  742.  
  743.         moveWindow(hWndOK,     dw, 0, hWnd);
  744.         moveWindow(hWndExec,   dw, 0, hWnd);
  745.         moveWindow(hWndEdit,   dw, 0, hWnd);
  746.         moveWindow(hWndCancel, dw, 0, hWnd);
  747.  
  748.         dlgW = curW;
  749.         dlgH = curH;
  750.     }
  751.     function getWindowRect(hWnd, hWndParent) {
  752.         var lpRect = AkelPad.MemAlloc(16); //sizeof(RECT)
  753.         if(!lpRect)
  754.             return null;
  755.         oSys.Call("user32::GetWindowRect", hWnd, lpRect);
  756.         hWndParent && oSys.Call("user32::ScreenToClient", hWndParent, lpRect);
  757.         var rcWnd = parseRect(lpRect);
  758.         AkelPad.MemFree(lpRect);
  759.         return rcWnd;
  760.     }
  761.     function parseRect(lpRect) {
  762.         return {
  763.             left:   AkelPad.MemRead(lpRect,      3 /*DT_DWORD*/),
  764.             top:    AkelPad.MemRead(lpRect +  4, 3 /*DT_DWORD*/),
  765.             right:  AkelPad.MemRead(lpRect +  8, 3 /*DT_DWORD*/),
  766.             bottom: AkelPad.MemRead(lpRect + 12, 3 /*DT_DWORD*/)
  767.         };
  768.     }
  769.  
  770.     function getStringFromIndex(i) {
  771.         if(i == -1 || i == undefined)
  772.             return "";
  773.         var len = AkelPad.SendMessage(hWndListBox, 0x18A /*LB_GETTEXTLEN*/, i, 0);
  774.         var lpString = AkelPad.MemAlloc((len + 1)*_TSIZE);
  775.         if(!lpString)
  776.             return "";
  777.         AkelPad.SendMessage(hWndListBox, 0x189 /*LB_GETTEXT*/, i, lpString);
  778.         var str = AkelPad.MemRead(lpString, _TSTR);
  779.         AkelPad.MemFree(lpString);
  780.         return str;
  781.     }
  782.     function getIndexFromString(str) {
  783.         for(var i = 0, l = AkelPad.SendMessage(hWndListBox, 0x18B /*LB_GETCOUNT*/, 0, 0); i < l; ++i) {
  784.             var s = getStringFromIndex(i);
  785.             if(s == str)
  786.                 return i;
  787.         }
  788.         return undefined;
  789.     }
  790.  
  791.     function windowText(hWnd, pText) {
  792.         if(arguments.length > 1)
  793.             return oSys.Call("user32::SetWindowText" + _TCHAR, hWnd, pText);
  794.         var len = oSys.Call("user32::GetWindowTextLength" + _TCHAR, hWnd);
  795.         var lpText = AkelPad.MemAlloc((len + 1)*_TSIZE);
  796.         if(!lpText)
  797.             return "";
  798.         oSys.Call("user32::GetWindowText" + _TCHAR, hWnd, lpText, len + 1);
  799.         pText = AkelPad.MemRead(lpText, _TSTR);
  800.         AkelPad.MemFree(lpText);
  801.         return pText;
  802.     }
  803.     function setWindowFont(hWnd, hFont) {
  804.         AkelPad.SendMessage(hWnd, 48 /*WM_SETFONT*/, hFont, true);
  805.     }
  806.     function setWindowFontAndText(hWnd, hFont, pText) {
  807.         setWindowFont(hWnd, hFont);
  808.         windowText(hWnd, pText);
  809.     }
  810.     function setEditText(hWnd, pText, selectAll) {
  811.         windowText(hWnd, pText);
  812.         pText && AkelPad.SendMessage(hWnd, 177 /*EM_SETSEL*/, selectAll ? 0 : pText.length, -1);
  813.     }
  814.     function enabled(hWnd, val) {
  815.         oSys.Call("user32::EnableWindow", hWnd, val);
  816.     }
  817.     function destroyWindow(hWnd) {
  818.         oSys.Call("user32::DestroyWindow", hWnd);
  819.     }
  820.     function closeDialog() {
  821.         oSys.Call("user32::PostMessage" + _TCHAR, hWndDialog, 16 /*WM_CLOSE*/, 0, 0);
  822.     }
  823.     function Scale(hDC, hWnd) {
  824.         var hNewDC = hDC || oSys.Call("user32::GetDC", hWnd);
  825.         if(hNewDC) {
  826.             this._x = oSys.Call("gdi32::GetDeviceCaps", hNewDC, 88 /*LOGPIXELSX*/);
  827.             this._y = oSys.Call("gdi32::GetDeviceCaps", hNewDC, 90 /*LOGPIXELSY*/);
  828.  
  829.             //Align to 16 pixel
  830.             this._x += (16 - this._x % 16) % 16;
  831.             this._y += (16 - this._y % 16) % 16;
  832.  
  833.             !hDC && oSys.Call("user32::ReleaseDC", hWnd, hNewDC);
  834.  
  835.             this.x = function(x) {
  836.                 return oSys.Call("kernel32::MulDiv", x, this._x, 96);
  837.             };
  838.             this.y = function(y) {
  839.                 return oSys.Call("kernel32::MulDiv", y, this._y, 96);
  840.             };
  841.         }
  842.         else {
  843.             this.x = this.y = function(n) {
  844.                 return n;
  845.             };
  846.         }
  847.     }
  848.     function createWindowEx(
  849.         dwExStyle, lpClassName, lpWindowName, dwStyle,
  850.         x, y, w, h,
  851.         hWndParent, id, hInstance, callback
  852.     ) {
  853.         return oSys.Call(
  854.             "user32::CreateWindowEx" + _TCHAR,
  855.             dwExStyle, lpClassName, lpWindowName, dwStyle,
  856.             scale.x(x), scale.y(y),
  857.             scale.x(w), scale.y(h),
  858.             hWndParent, id, hInstance, callback || 0
  859.         );
  860.     }
  861.  
  862.     modal && enabled(hMainWnd, false); // Disable main window, to make dialog modal
  863.  
  864.     AkelPad.ScriptNoMutex(); // Allow other scripts running
  865.     AkelPad.WindowGetMessage(); // Message loop
  866.  
  867.     AkelPad.WindowUnregisterClass(dialogClass);
  868.  
  869.     selfRun && AkelPad.Call("Scripts::Main", 1, WScript.ScriptName, expandArgs(argsObj[curName] || ""));
  870. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement