Страница 190 из 243

Добавлено: Пт май 30, 2025 12:57
Orion9
Loopback писал(а):Как иначе объяснить такое поведение я не знаю.
Спасибо за объяснение в любом случае.
Loopback писал(а):Там много лет ничего практически не менялось. Перед релизом надо будет обновить, конечно.
Да. Видимо, меня память подвела. Кстати, у меня осталась старая версия 2.2.10 и 2.2.11 в прошлогоднем архиве, изменений там действительно никаких, если не считать, что в новом autorun.example.cfg убраны ключи /EV. Выходит, я просто подзабыл содержимое этого файла и что в нём были такие строки:

Код: Выделить всё

# The block below sets COMMANDER_PROGRAM environment variable
# to corresponding TC executable path depending on it's architecture
# Блок ниже устанавливает в переменную окружения COMMANDER_PROGRAM
# путь к исполняемому файлу TC в зависимости от его архитектуры
If %AUTORUN_TCARCH% = 32 Then 
  SetEnv /EV COMMANDER_PROGRAM %COMMANDER_PATH%\TOTALCMD.EXE
Else 
  SetEnv /EV COMMANDER_PROGRAM %COMMANDER_PATH%\TOTALCMD64.EXE
EndIf

Добавлено: Пн июн 02, 2025 13:28
Orion9
Loopback писал(а):Да и наличие DllCall теперь избавляет о необходимости делать мелкие функции с одним-двумя вызовами системных функций.
И вот отличная иллюстрация к данным словам )

[cut]

Код: Выделить всё

RegisterCommand 60025 "WindowTest"

Static hWnd = 0

Const PBM_SETPOS      =  1026, _
      PBM_SETRANGE    =  1025, _
      PBS_MARQUEE     =  0x08, _
      PBM_SETMARQUEE  =  1034
      
Func WindowTest()
    RunThread WinTest
EndFunc      

Func WinTest()
    If hWnd > 0 Then
       If WinGetState(1, hWnd) Then
          SendMessage(hWnd, 0x0010, 0, 0)
          Return
       EndIf   
       hWnd = 0
    Endif    
    hWnd = DllCall("CreateWindowExA", _
                   "dword", 0, _
                   "str", "msctls_progress32", _
                   "str", "", _
                   "dword", 0x10C80000, _
                   "int", 200, "int", 100, "int", 300, "int", 50, _
                   "handle", AUTORUN_TCHANDLE, _
                   "handle", 0, "handle", 0, "ptr", 0, _
                   "handle")    
    If hWnd = 0 Then Return
        
    hIco = SendMessage(AUTORUN_TCHANDLE, 0x7f, 2, 0)                     
    SendMessage(hWnd, 0x80, 0, hIco)       
                   
    WinSetStyle(PBS_MARQUEE, 2, hWnd)
    WinSetText("Estimating...", hWnd)
    
    SendMessage(hWnd, PBM_SETMARQUEE, 1, 0)
    Sleep(1300)
    SendMessage(hWnd, PBM_SETMARQUEE, 0, 0)
    
    WinSetStyle(PBS_MARQUEE, 4, hWnd) 
    SendMessage(hWnd, PBM_SETPOS, 0, 0)    
    For i = 1 to 10
        SendMessage(hWnd, PBM_SETPOS, i*10, 0) 
        WinSetText("Processed " & i*10 & "%", hWnd)
        Sleep(300)
    Next 
    If DllCall("DestroyWindow", "handle", hWnd) Then hWnd = 0
EndFunc
[/cut]
Создание окна прогресс-бара и имитация активности. Практически рабочий вариант, нужно только оконную фуцнкцию повесить через объект Callback, но у меня не получилось. Пример в справке рабочий:

[cut]

Код: Выделить всё

LoadLibrary "Plugins\Autorun_Runtime.dll"
 
Global lst = List()
Global ewp = Callback("EnumWindowsProc", "hwnd;lparam")
 
DllCall("EnumWindows", "ptr", ewp.Ptr, "lparam", 0)
 
MsgBox(lst.Text)
 
Free(lst, ewp)
 
Func EnumWindowsProc(wnd, lparam)
    # skip invisible windows
    If Not WinGetState(2, wnd) Then Return 1
    lst.Add(WinGetClass(wnd))
    # to continue enumerating return TRUE
    Return 1
EndFunc
[/cut]
Но список типов параметров функции Callback, перечисленных через ";", похоже, работает только с двумя параметрами. Если их больше, то появляется сообщение об ошибке. Баг?

Добавлено: Пн июн 02, 2025 21:48
Loopback
Orion9 писал(а):Но список типов параметров функции Callback, перечисленных через ";", похоже, работает только с двумя параметрами. Если их больше, то появляется сообщение об ошибке. Баг?
Да, и похоже он тут даже не один. Обойти не получится, только исправлять.

Добавлено: Вт июн 03, 2025 12:56
Orion9
Loopback писал(а):Обойти не получится, только исправлять.
Это не срочно, но хотелось бы попробовать.

Как я понял, сделать можно будет так:

Код: Выделить всё

Global oWP = Callback("TestWinProc", "hwnd;uint;wparam;lparam")

Func TestWinProc(hWnd, uMsg, wParam, lParam)
    If uMsg = 0x0010 Then 
       MsgBox("Exit")
       Return 0 
    EndIf
    Return DllCall("DefWindowProcA", "hwnd", hWnd, "uint", uMsg, "wparam", wParam, "lparam", lParam)
EndFunc
...
...
hWnd = DllCall("CreateWindowExA", _
...
...           )
DllCall("SetWindowLongPtrA", "hwnd", hWnd, "int", -4, "long_ptr", oWP.Ptr)

Или нет?

Попробовал сменить стиль окна сразу после его создания. Вызов с SetWindowLongPtrA не работает:

Код: Выделить всё

MsgBox(DllCall("SetWindowLongPtrA", "hwnd", hWnd, "int", -16, "long_ptr", 0x10C00000))
Hо работает SetWindowLongA

Код: Выделить всё

MsgBox(DllCall("SetWindowLongA", "hwnd", hWnd, "int", -16, "long", 0x10C00000))
Autorun тут ни при чём?

Добавлено: Вт июн 03, 2025 14:26
AkulaBig
Orion9
Мы с вами обсуждали проблемы uchardet при распознавании кодировок. Сегодня на ру-борде скрипт AkekPad для распознавания кодировок вспомнили. Посмотрите, не может-ли он нам быть полезным:
[cut="AutoScript-DetectEx.js"]

Код: Выделить всё

// http://akelpad.sourceforge.net/forum/viewtopic.php?p=27664#p27664
// Version: 1.0
// Author: Shengalts Aleksander aka Instructor
//
//
// Description(1033): Detect codepage by extension or by file content.
// Description(1049): Определить кодировку по расширению или по содержимому файла.
//
// Arguments:
// -DetectArray='[["ext1,ext2","ExpContent","ExpFlags","CodePage",BOM,DetectLang],["ext3",...]'
//
//              "ext1,ext2"  -extensions divided by semicolon. If "", any extension is matched.
//              "ExpContent" -search file content with regular expression. If "", not used.
//              "ExpFlags"   -regular expression flags.
//              "CodePage"   -default codepage specified as number, as IANA charset (e.g. "utf-8") or as regular expression backreference (e.g. "$1" or "\\1").
//              BOM          -byte order mark. If -1, it will be autodetected.
//              DetectLang   -detection language number (see LANGID_* defines). Special values:
//                              -1  don't change current detection language.
//                              -2  force to use specified "CodePage" without any detection.
// -ContentBuffer=1024  Content buffer size for regular expression search. Special values:
//                              0   use codepage recognition buffer size (default).
//                              -1  read entire file.
//
// Usage (add to "CmdLineBegin=" manual parameter):
//   /Call("Scripts::Main", 2, "AutoScript-DetectEx.js", `-DetectArray='[["cmd,bat","","","866",-1,0x0419],["xml,htm,html",".*?(encoding|charset)=([a-z\\d_\\-]+)","i","$2",-1,-2]]'`)

//Arguments
var pDetectArray=AkelPad.GetArgValue("DetectArray", "");
var nContentBuffer=AkelPad.GetArgValue("ContentBuffer", 0);

//Defines
var LANGID_NONE     =0;      //None
var LANGID_RUSSIAN  =0x0419; //Cyrillic (1251, OEM, KOI8-R, UTF-8)
var LANGID_POLISH   =0x0415; //Eastern European (1250, OEM, UTF-8)
var LANGID_GERMAN   =0x0407; //Western European (1252, OEM, UTF-8)
var LANGID_TURKISH  =0x041F; //Turkish (1254, OEM, UTF-8)
var LANGID_CHINESE  =0x0404; //Chinese (ANSI, UTF-8)
var LANGID_JAPANESE =0x0411; //Japanese (932, UTF-8)
var LANGID_KOREAN   =0x0412; //Korean (949, UTF-8)

//Variables
var hMainWnd=AkelPad.GetMainWnd();
var hScript;
var lpdwFlags;
var dwFlags;
var lpFile;
var pFile;
var pExt="";
var lpnCodePage;
var lpbBOM;
var nDefaultCodepage;
var nLangCodepageRecognition;
var nNewDefaultCodepage;
var nNewBOM;
var nNewLangCodepageRecognition;
var pContent;
var pCharset;
var oPattern;
var aDetectArray=[];
var aMatch=[];
var nOffset;
var i;

if ((hScript=AkelPad.ScriptHandle(WScript.ScriptName, 3 /*SH_FINDSCRIPT*/)) && AkelPad.ScriptHandle(hScript, 13 /*SH_GETMESSAGELOOP*/))
{
  //Script is running, second call close it.
  AkelPad.ScriptHandle(hScript, 33 /*SH_CLOSESCRIPT*/);
}
else
{
  if (pDetectArray)
    eval("aDetectArray=" + pDetectArray + ";");
  if (!nContentBuffer)
    nContentBuffer=AkelPad.SendMessage(hMainWnd, 1222 /*AKD_GETMAININFO*/, 184 /*MI_CODEPAGERECOGNITIONBUFFER*/, 0);
  if (!aDetectArray.length)
  {
    AkelPad.MessageBox(hMainWnd, "Too few parameters", WScript.ScriptName, 16 /*MB_ICONERROR*/);
    WScript.Quit();
  }
  for (i=0; i < aDetectArray.length; ++i)
  {
    aDetectArray[i][0]=aDetectArray[i][0].toLowerCase();
  }

  if (AkelPad.WindowSubClass(1 /*WSC_MAINPROC*/, MainCallback, 0x435 /*AKDN_OPENDOCUMENT_START*/,
                                                               0x436 /*AKDN_OPENDOCUMENT_FINISH*/))
  {
    //Allow other scripts running and unlock main thread from waiting this script.
    AkelPad.ScriptNoMutex(0x3 /*ULT_UNLOCKSCRIPTSQUEUE|ULT_UNLOCKPROGRAMTHREAD*/);

    //Message loop
    AkelPad.WindowGetMessage();

    AkelPad.WindowUnsubClass(1 /*WSC_MAINPROC*/);
  }
}

function MainCallback(hWnd, uMsg, wParam, lParam)
{
  if (uMsg == 0x435 /*AKDN_OPENDOCUMENT_START*/)
  {
    nDefaultCodepage=0;
    nLangCodepageRecognition=-1;
    lpdwFlags=AkelPad.MemRead(lParam + (_X64?40:20) /*offsetof(NOPENDOCUMENT, dwFlags)*/, 3 /*DT_DWORD*/);
    dwFlags=AkelPad.MemRead(lpdwFlags, 3 /*DT_DWORD*/);

    if (!(dwFlags & 0x100 /*OD_REOPEN*/))
    {
      lpFile=AkelPad.MemRead(lParam + (_X64?16:8) /*offsetof(NOPENDOCUMENT, wszFile)*/, 2 /*DT_QWORD*/);
      pFile=AkelPad.MemRead(lpFile, 1 /*DT_UNICODE*/);
      pExt=AkelPad.GetFilePath(pFile, 4 /*CPF_FILEEXT*/).toLowerCase();
      pContent="";
      pCharset="";
      nNewDefaultCodepage=0;

      for (i=0; i < aDetectArray.length; ++i)
      {
        if (aDetectArray[i][0])
        {
          if ((nOffset=aDetectArray[i][0].indexOf(pExt)) != -1 &&
              (aDetectArray[i][0].substr(nOffset + pExt.length, 1) == "" ||
               aDetectArray[i][0].substr(nOffset + pExt.length, 1) == ","))
          {
            pCharset=aDetectArray[i][3];
          }
          else continue;
        }
        if (aDetectArray[i][1])
        {
          if (!pContent)
            pContent=AkelPad.ReadFile(pFile, 0x1C /*ADT_DETECTCODEPAGE|ADT_DETECTBOM|ADT_NOMESSAGES*/, 0, 0, nContentBuffer);
          oPattern=new RegExp(aDetectArray[i][1], aDetectArray[i][2]);
          if (aMatch=pContent.match(oPattern))
          {
            if (aDetectArray[i][3].substr(0, 1) == "$" || aDetectArray[i][3].substr(0, 1) == "\\")
              pCharset=aMatch[parseInt(aDetectArray[i][3].substr(1))];
            else
              pCharset=aDetectArray[i][3];
          }
          else continue;
        }
        if (pCharset)
        {
          nNewDefaultCodepage=parseInt(pCharset);
          if (isNaN(nNewDefaultCodepage))
          {
            pCharset=pCharset.toLowerCase();
            nNewDefaultCodepage=GetCodepageByName(pCharset);
          }
          break;
        }
      }
      if (i < aDetectArray.length && nNewDefaultCodepage)
      {
        nNewBOM=aDetectArray[i][4];
        nNewLangCodepageRecognition=aDetectArray[i][5];

        if (nNewLangCodepageRecognition != -1)
        {
          if (nNewLangCodepageRecognition == -2)
          {
            if (nNewBOM == -1)
              dwFlags|=0x8 /*OD_ADT_DETECTBOM*/;
            else
            {
              lpbBOM=AkelPad.MemRead(lParam + (_X64?32:16) /*offsetof(NOPENDOCUMENT, bBOM)*/, 2 /*DT_QWORD*/);
              AkelPad.MemCopy(lpbBOM, nNewBOM, 3 /*DT_DWORD*/);
              dwFlags&=~0x8 /*OD_ADT_DETECTBOM*/;
            }
            lpnCodePage=AkelPad.MemRead(lParam + (_X64?24:12) /*offsetof(NOPENDOCUMENT, nCodePage)*/, 2 /*DT_QWORD*/);
            AkelPad.MemCopy(lpnCodePage, nNewDefaultCodepage, 3 /*DT_DWORD*/);
            AkelPad.MemCopy(lpdwFlags, dwFlags & ~0x6 /*OD_ADT_REGCODEPAGE|OD_ADT_DETECTCODEPAGE*/, 3 /*DT_DWORD*/);
            nNewDefaultCodepage=0;
          }
          else
          {
            nLangCodepageRecognition=AkelPad.SendMessage(hMainWnd, 1222 /*AKD_GETMAININFO*/, 183 /*MI_LANGCODEPAGERECOGNITION*/, 0);
            AkelPad.SendMessage(hMainWnd, 1219 /*AKD_SETMAININFO*/, 183 /*MIS_LANGCODEPAGERECOGNITION*/, nNewLangCodepageRecognition);
          }
        }
        if (nNewDefaultCodepage)
        {
          nDefaultCodepage=AkelPad.SendMessage(hMainWnd, 1222 /*AKD_GETMAININFO*/, 177 /*MI_DEFAULTCODEPAGE*/, 0);
          AkelPad.SendMessage(hMainWnd, 1219 /*AKD_SETMAININFO*/, 177 /*MIS_DEFAULTCODEPAGE*/, nNewDefaultCodepage);
        }
      }
    }
  }
  else if (uMsg == 0x436 /*AKDN_OPENDOCUMENT_FINISH*/)
  {
    if (nDefaultCodepage)
      AkelPad.SendMessage(hMainWnd, 1219 /*AKD_SETMAININFO*/, 177 /*MIS_DEFAULTCODEPAGE*/, nDefaultCodepage);
    if (nLangCodepageRecognition != -1)
      AkelPad.SendMessage(hMainWnd, 1219 /*AKD_SETMAININFO*/, 183 /*MIS_LANGCODEPAGERECOGNITION*/, nLangCodepageRecognition);
  }
}

function GetCodepageByName(pName)
{
  switch (pName)
  {
    case "ibm037": return 37;
    case "ibm437": return 437;
    case "ibm500": return 500;
    case "asmo-708": return 708;
    case "dos-720": return 720;
    case "ibm737": return 737;
    case "ibm775": return 775;
    case "ibm850": return 850;
    case "ibm852": return 852;
    case "ibm855": return 855;
    case "ibm857": return 857;
    case "ibm00858": return 858;
    case "ibm860": return 860;
    case "ibm861": return 861;
    case "dos-862": return 862;
    case "ibm863": return 863;
    case "ibm864": return 864;
    case "ibm865": return 865;
    case "cp866": return 866;
    case "ibm869": return 869;
    case "ibm870": return 870;
    case "windows-874": return 874;
    case "cp875": return 875;
    case "shift_jis": return 932;
    case "gb2312": return 936;
    case "ks_c_5601-1987": return 949;
    case "big5": return 950;
    case "ibm1026": return 1026;
    case "ibm01047": return 1047;
    case "ibm01140": return 1140;
    case "ibm01141": return 1141;
    case "ibm01142": return 1142;
    case "ibm01143": return 1143;
    case "ibm01144": return 1144;
    case "ibm01145": return 1145;
    case "ibm01146": return 1146;
    case "ibm01147": return 1147;
    case "ibm01148": return 1148;
    case "ibm01149": return 1149;
    case "utf-16le": return 1200;
    case "utf-16be": return 1201;
    case "windows-1250": return 1250;
    case "windows-1251": return 1251;
    case "windows-1252": return 1252;
    case "windows-1253": return 1253;
    case "windows-1254": return 1254;
    case "windows-1255": return 1255;
    case "windows-1256": return 1256;
    case "windows-1257": return 1257;
    case "windows-1258": return 1258;
    case "johab": return 1361;
    case "macintosh": return 10000;
    case "x-mac-japanese": return 10001;
    case "x-mac-chinesetrad": return 10002;
    case "x-mac-korean": return 10003;
    case "x-mac-arabic": return 10004;
    case "x-mac-hebrew": return 10005;
    case "x-mac-greek": return 10006;
    case "x-mac-cyrillic": return 10007;
    case "x-mac-chinesesimp": return 10008;
    case "x-mac-romanian": return 10010;
    case "x-mac-ukrainian": return 10017;
    case "x-mac-thai": return 10021;
    case "x-mac-ce": return 10029;
    case "x-mac-icelandic": return 10079;
    case "x-mac-turkish": return 10081;
    case "x-mac-croatian": return 10082;
    case "utf-32le": return 12000;
    case "utf-32be": return 12001;
    case "x-chinese_cns": return 20000;
    case "x-cp20001": return 20001;
    case "x_chinese-eten": return 20002;
    case "x-cp20003": return 20003;
    case "x-cp20004": return 20004;
    case "x-cp20005": return 20005;
    case "x-ia5": return 20105;
    case "x-ia5-german": return 20106;
    case "x-ia5-swedish": return 20107;
    case "x-ia5-norwegian": return 20108;
    case "us-ascii": return 20127;
    case "x-cp20261": return 20261;
    case "x-cp20269": return 20269;
    case "ibm273": return 20273;
    case "ibm277": return 20277;
    case "ibm278": return 20278;
    case "ibm280": return 20280;
    case "ibm284": return 20284;
    case "ibm285": return 20285;
    case "ibm290": return 20290;
    case "ibm297": return 20297;
    case "ibm420": return 20420;
    case "ibm423": return 20423;
    case "ibm424": return 20424;
    case "x-ebcdic-koreanextended": return 20833;
    case "ibm-thai": return 20838;
    case "koi8-r": return 20866;
    case "ibm871": return 20871;
    case "ibm880": return 20880;
    case "ibm905": return 20905;
    case "ibm00924": return 20924;
    case "euc-jp": return 20932;
    case "x-cp20936": return 20936;
    case "x-cp20949": return 20949;
    case "cp1025": return 21025;
    case "koi8-u": return 21866;
    case "iso-8859-1": return 28591;
    case "iso-8859-2": return 28592;
    case "iso-8859-3": return 28593;
    case "iso-8859-4": return 28594;
    case "iso-8859-5": return 28595;
    case "iso-8859-6": return 28596;
    case "iso-8859-7": return 28597;
    case "iso-8859-8": return 28598;
    case "iso-8859-9": return 28599;
    case "iso-8859-13": return 28603;
    case "iso-8859-15": return 28605;
    case "x-europa": return 29001;
    case "iso-8859-8-i": return 38598;
    case "iso-2022-jp": return 50220;
    case "csiso2022jp": return 50221;
    case "iso-2022-jp": return 50222;
    case "iso-2022-kr": return 50225;
    case "x-cp50227": return 50227;
    case "euc-jp": return 51932;
    case "euc-cn": return 51936;
    case "euc-kr": return 51949;
    case "hz-gb-2312": return 52936;
    case "gb18030": return 54936;
    case "x-iscii-de": return 57002;
    case "x-iscii-be": return 57003;
    case "x-iscii-ta": return 57004;
    case "x-iscii-te": return 57005;
    case "x-iscii-as": return 57006;
    case "x-iscii-or": return 57007;
    case "x-iscii-ka": return 57008;
    case "x-iscii-ma": return 57009;
    case "x-iscii-gu": return 57010;
    case "x-iscii-pa": return 57011;
    case "utf-7": return 65000;
    case "utf-8": return 65001;
  }
  return 0;
}
[/cut]

Добавлено: Вт июн 03, 2025 14:45
Loopback
Orion9 писал(а):Как я понял, сделать можно будет так:
Да, примерно так.
Orion9 писал(а):Autorun тут ни при чём?
Нет, SetWindowLongPtr работает только в x64, в 32-битной используется SetWindowLong. Придется как-то так писать DllCall("SetWindowLong" & (auX64 ? "PtrA" : "A"), ...) .

Добавлено: Вт июн 03, 2025 23:34
Orion9
AkulaBig писал(а):Посмотрите, не может-ли он нам быть полезным:
Такие скрипты за пределами моих возможностей, но одно мне не понятно: зачем нужен данный скрипт, если AkelPad и без него нормально детектит кодировки? Да, возможно, не все, но с русскими он неплохо справляется, а другого мне не нужно. Как говорил Остап Бендер "Другие кодировки мне тоже интересны, но меньше" )

Ждать чуда от детекта UTF-16, видимо, не стоит. Парав был CaptainFlint Если бы это было так просто, рабочие решения давно бы уже лежали на поверхности. Одлнако даже у uchardet с UTF-16 есть проблемы.

И все же AkelPad его как-то детектит. Чтобы в этом убедиться, достаточно просто сохранить любой русский текст в блокноте как UTF-16 BE и убрать маркер бом из полученного файла. AkelPad нормально откроет это файл и внизу напишет (UTF-16 BE) без BOM.
Loopback писал(а): Придется как-то так писать DllCall("SetWindowLong" & (auX64 ? "PtrA" : "A"), ...)
Да, так работает. Я уже понял, что нужно глубже курить WinAPI, но как и известно, курение - это яд ) Дело это интересное и увлекательное, но, к сожалению, трудоемкое и времязатратное. Но раз уж Autorun даёт такую возможность, нужно уметь ей пользоваться, особенно если это помогает добиться нужного результата. Вот еще пример использования:
[cut]

Код: Выделить всё

RegisterCommand 60026 "TaskDialog"

Func TaskDialog()
   Local hRes, bn
   hRes = DllCall("TaskDialog", _
                   "hwnd", AUTORUN_TCHANDLE, _
                   "handle", 0, _
                   "wstr", "Auto", _
                   "wstr", "Task", _
                   "wstr", "Content", _
                   "dword", 15, _
                   "ptr", 65535, _
                   "int*", @bn, _
                   "hresult")
   MsgBox(bn)   
EndFunc
[/cut]
Это очень простенький вариант, а вот посложнее:
[cut]

Код: Выделить всё

RegisterCommand 60027 "TaskDialogIndirect"

Func TaskDialogIndirect()
   Local hRes, bn
   Local buf = Buffer(96)
   Local sTitle = "Title"
   Local sInstr = "Instruction"
   Local sContn = "Content"
   Local sExpand = "Expanded text"
   Local sFooter = "Autorun " &  FileGetVersion(AUTORUN_PATH & "\Autorun.wdx", "FileVersion")
   Local ttl = Buffer(StrLen(sTitle)*2+2), _
         ins = Buffer(StrLen(sInstr)*2+2), _
         con = Buffer(StrLen(sContn)*2+2), _
         exp = Buffer(StrLen(sExpand)*2+2), _
         ftr = Buffer(StrLen(sFooter)*2+2)
   ttl.SetStr(sTitle & Chr(0))
   ins.SetStr(sInstr & Chr(0))
   con.SetStr(sContn & Chr(0))
   exp.SetStr(sExpand & Chr(0))
   ftr.SetStr(sFooter & Chr(0))
   buf.Zero()
   buf.SetNum(0, "uint", buf.size, _   
                 "hwnd", AUTORUN_TCHANDLE, _
                 "handle", 0, _
                 "dword", 0x0408, _
                 "dword", 21, _
                 "ptr", ttl.ptr, _
                 "ptr", 65535, _
                 "ptr", ins.ptr, _
                 "ptr", con.ptr, _
                 "uint", 0, _
                 "ptr", 0, _
                 "int", 0, _
                 "uint", 0, _
                 "ptr", 0, _
                 "int", 0, _
                 "ptr", 0, _
                 "ptr", exp.ptr, _
                 "ptr", 0, _
                 "ptr", 0, _
                 "ptr", 65533, _
                 "ptr", ftr.ptr, _
                 "ptr", 0, _
                 "long_ptr", 0, _
                 "uint", 0)
   RunThread ProgressMove
   hRes = DllCall("TaskDialogIndirect", _
                   "ptr", buf.ptr, _   
                   "int*", @bn, _   
                   "int*", 0, _   
                   "bool*", 0)
   MsgBox(bn)
EndFunc

Func ProgressMove()
    While 1
        Local hWnd = WinFind(0, "#32770")
        If hWnd > 0 Then SendMessage(hWnd, 1131, 1, 0)
        Sleep(1500)
    Wend  
EndFunc
[/cut]
Подробнее:
https://learn.microsoft.com/en-us/windo ... s-overview
Loopback, может сделать в Autorun вызов такого диалога в дополнение к стандартному MsgBox? Тут и прогресс-бар имеется, и другие плюшки.

Добавлено: Ср июн 04, 2025 11:14
Loopback
Orion9 писал(а):может сделать в Autorun вызов такого диалога в дополнение к стандартному MsgBox
Занятная штука. Вот только сомневаюсь, что польза будет соразмерна затраченным на реализацию усилиям. Причем тут сложность не столько в самой реализации, сколько в том, чтобы сделать удобный интерфейс для всего этого разнообразия. Это обычно отнимает едва ли не больше времени, чем сама реализация. В общем занесу в todo на "подумать", но это вещь далеко не первой необходимости.

Добавлено: Ср июн 04, 2025 13:03
Orion9
Loopback
Какие-то части этого диалога точно бы пригодились. На сайте microsoft показаны все элементы сразу, но по факту можно использовать лишь малую их часть.

От простых и стандартных кнопок похожих на MsgBox:
Изображение
Изображение
И кастомных кнопок с футером и линком:
Изображение
Изображение
Изображение
Изображение
Изображение
До радиокнопок и чекбокса:
Изображение
Изображение
Вот последний точно не помешал бы. А на счёт прогресс-бара не уверен, без оконной функции потестировать TaskDialogIndirect как следует пока не получилось. Кстати, попробовал вставить вызов диалога TaskDialog в самое начало autorun.cfg. Как и ожидалось, TC x64 закрывает это окно при старте. Шутки от маэстро, или очередные приколы от Lazarus? )

Добавлено: Ср июн 04, 2025 22:01
Loopback
Orion9 писал(а): Как и ожидалось, TC x64 закрывает это окно при старте. Шутки от маэстро, или очередные приколы от Lazarus? )
Это всё та же проблема. При запуске иногда приходит сообщение WM_COMMAND с IDCANCEL. Любой майкрософтовский диалог, открытый в этот момент его ловит и воспринимает как нажатие "Отмена" или ESC.

Добавлено: Чт июн 05, 2025 13:02
Orion9
Loopback
Не похоже, что это Гислер так шутит. Скорее очередной прикол "ленивого" Lazarus. Поставил Sleep 1000 перед диалогом - проблема больше не появляется. К MsgBox тоже относится.

Добавлено: Сб июн 07, 2025 23:38
Orion9
Loopback
Может TCx64 так пытается предотвратить взаимную блокировку? Верится с трудом, но должно быть какое-то объяснение феномену.

Оказывается, в ТСх86 инстанс тоже может поменяться в ходе выполнения. Например, если отключить главную панель инструментов, а затем снова ее включить, то инстанс панели станет другим. Видимо, объясняется это тем, что при старте ТС главная панель - это TButtonBar1, а вертикальная - TButtonBar2. При скрытии главной панели, окно ТС обновляется и вертикальная панель становится TButtonBar1. При повторном включении, главная панель становится TButtonBar2.

Добавлено: Пн июн 09, 2025 11:03
Loopback
Orion9 писал(а):Может TCx64 так пытается предотвратить взаимную блокировку? Верится с трудом, но должно быть какое-то объяснение феномену.
Верится с трудом, вот именно. Не представляю, как сюда блокировку притянуть.
Orion9 писал(а):Оказывается, в ТСх86 инстанс тоже может поменяться в ходе выполнения.
Значит, тотал при отключении панели удаляет её. А когда потом создаёт повторно - она в списке контролов оказывается уже после вертикальной, и при поиске TButtonBar находится второй. Экземпляр контрола штука не всегда надёжная. Он постоянен только тогда, когда количество созданных контролов в процессе работы не изменяется, т.е. они не удаляются и не создаются новые.

В Лазарусе к этому добавляется ещё и проблема растянутости формирования окна во времени. Т.е. номер экземпляра контрола в момент отображения формы может отличаться от номера того же контрола через, скажем, 100мс.

Так что оконная автоматизация с использованием экземпляров должна быть последним решением, только когда других вариантов не остаётся. Для получения хэндлов элементов главного окна лучше пользоваться RequestInfo.

Добавлено: Пн июн 09, 2025 15:59
AkulaBig
Не понятная ситуация какая-то. Возникает ошибка после установки некоторых плагинов ТС. Пытаюсь перезагрузится сразу после установки плагина, появляется ошибка при нажатии на кнопку перезагрузки:
Изображение
[cut="Restart.aucfg"]

Код: Выделить всё

RegisterCommand 60000 "Restart"

Func Restart(lParam)
	If IsPressed (0x11) Then
		Switch AUTORUN_TCLANG
			Case 'RUS'
				ShellExec(COMMANDER_PATH & "\Utilities\MENUIMG\MENUIMG.exe", COMMANDER_PATH & "\Bars\RESTART_RUS.BAR", "INPUT")
			Case 'ENG'
				ShellExec(COMMANDER_PATH & "\Utilities\MENUIMG\MENUIMG.exe", COMMANDER_PATH & "\Bars\RESTART_ENG.BAR", "INPUT")
			Else
				ShellExec(COMMANDER_PATH & "\Utilities\MENUIMG\MENUIMG.exe", COMMANDER_PATH & "\Bars\RESTART_ENG.BAR", "INPUT")
		EndSwitch
	Else
		ShellExec(COMMANDER_PATH & "\Utilities\TCPlugman\Plugman.exe", "/Restart")
	Endif
EndFunc
[/cut]
Но не всех плагинах так. Из простых архивах вообще все нормально перезагружается.
Подождал некоторое время. Вроде перезагрузился. Похоже надо WAIT прописать. А как в этой записи правильно WAIT подставить? Я до сих пор не могу понять правильный синтаксис.

Добавлено: Пн июн 09, 2025 20:41
Loopback
AkulaBig писал(а):Не понятная ситуация какая-то
Такое сообщение может появиться только в одном случае - если в момент нажатия по какой-то причине ещё не выполнилась RegisterCommand, которая регистрирует эту команду (скрипт не выполнился, или был прерван). Может тотал выгружает Autorun при установке плагинов? В этом случае Autorun не загрузится снова, пока его не дёрнет цветовая схема, если в этот момент нажать кнопку - будет ошибка. Очень похоже на наблюдаемое поведение.
AkulaBig писал(а):Похоже надо WAIT прописать.
Прописать где и зачем?