Autorun

Обсуждение только плагинов и утилит для Total Commander.

Модераторы: Avada, CaptainFlint, Nik, d-view, Моторокер

Аватара пользователя
jentoso
Сообщения: 443
Зарегистрирован: Чт дек 20, 2007 01:36

Сообщение jentoso »

Orion9 писал(а):Библиотеки должны быть такими:

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

MediaInfo.dll
MediaInfo_i386.dll
А почему именно такими, а не так, как в плагине TCMediaInfo?
TC 11.58 combo, Windows 11 x64
Mrak_Tlen
Сообщения: 30
Зарегистрирован: Вт окт 08, 2024 21:37

Сообщение Mrak_Tlen »

Orion9 писал(а):A55555
ТLoopback сделал классный режим просмотра. Его можно использовать и в быстром просмотре по CTRL+Q
А можно с этого места поподробнее? С помощью авторан можно в листер выводить информацию?
Аватара пользователя
Orion9
Сообщения: 1283
Зарегистрирован: Пн янв 01, 2024 17:18

Сообщение Orion9 »

Mrak_Tlen
Увы, нельзя. Недавно я тоже запрашивал такую фичу, хотя бы на уровне простого текста для начала, но там сложности серьезные. А было бы круто и полезно. Но речь шла о TCMediaInfo и его режимах просмотра.

jentoso
Я уже не помню откуда это пошло. Возможно, из-за того, что GUI версия MediaInfo.exe раньше использовала MediaInfo_i386.dll в своем каталоге. Но код определенно надо переделать и отвязать его от жесткой прописки. Да и вообще там есть что еще переделать и улучшить. Кстати, забыл написать, что длительные операции можно прерывать либо повторным нажатием на кнопку, либо Win+ESC.
A55555
Сообщения: 72
Зарегистрирован: Вс фев 06, 2011 10:50

Сообщение A55555 »

Orion9 писал(а):A55555
Теоритически можно сделать такое, но сначала посмотрите режим "Видео (компактный)" в плагине TCMediaInfo. Думаю, это то, что вам нужно. Loopback сделал классный режим просмотра. Его можно использовать и в быстром просмотре по CTRL+Q, если нужно группу файлов просмотреть.
Спасибо. Просмотр видео по CTRL+Q работает в моей сборке.
А вот как чтоб в подсказке віводило как у вас я не могу понять.

Добавьте пожалуйста настройку отображение подсказки для ваших Torrent и "Продолжительность медиафайлов" кнопок.
Orion9 писал(а):Хорошая мысля приходит напосля.

A55555
Добавил буквально три строчки к CopyMonitor(). Теперь при вкючении режима ожидания кнопка "В фоне" деактивируется, а при отключении режима ожидания снова активируется:

Одной проблемой меньше. Остались только диалоговые окна, которые могут неожиданно прервать операцию и оставить компьютер включенным до утра. Нужно подумать, что с этим делать, но на крайний случай можно добавить таймер, который будет в любом случае выключать компьютер через 2-3 часа после ухода.
У меня сразу была мысль блокировать эту кнопку в фоне, но т.к. я не знал на сколько это сложно, сказать про это я откладывал из-за на тот момент поважнее моментов.

Диалоговые окна на сколько я понимаю могут выскочить по поводу:
1. Файл с таким именем уже существует, заменить или пропустить и т.д.
2. Закончилось место на диске
- (ошибку копирования, невозможно прочитать, типа жесткий диск помирает я бы просто проигнорировал, пусть "до утра" висит, т.к. уж лучше пусть пользователь узнает о ней, чем она будет обойдена и ПК выключен)

Первый пункт, по моему мнению, если это возможно, в режиме мониторинга можно было бы решить ответом "Пропустить", это самый безобидный вариант, который пользователь при желании может заранее предусмотреть в начале копирования и настроить, что делать , если спросит "Заменить".
Второй пункт, по моему мнению, автоответ OK, и запуск процесса выключения, потому как и пользователь сделал бы тоже самое, вариантов других нет.
Аватара пользователя
Orion9
Сообщения: 1283
Зарегистрирован: Пн янв 01, 2024 17:18

Сообщение Orion9 »

A55555
Не совсем понял, что вы имеете в виду говоря:
Добавьте пожалуйста настройку отображение подсказки для ваших Torrent и "Продолжительность медиафайлов" кнопок
А что касается подсказки MediaInfo на панелях (если вы её имеете в виду), то ее нужно собирать из нескольких частей. Помимо кода Autorun, должны быть созданы 60 полей, т.е. в секции [HintsCustomField] должны быть два щаблона *.* по 30 полей каждый, которые должны ее замыкать. Т.е. цифры у 22exts и 22fields должны быть своими, как и у 23exts и 23fields.

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

22exts=*.*
22fields=[=autorun.C1]\n[=autorun.C2]\n[=autorun.C3]\n[=autorun.C4]\n[=autorun.C5]\n[=autorun.C6]\n[=autorun.C7]\n[=autorun.C8]\n[=autorun.C9]\n[=autorun.C10]\n[=autorun.C11]\n[=autorun.C12]\n[=autorun.C13]\n[=autorun.C14]\n[=autorun.C15]\n[=autorun.C16]\n[=autorun.C17]\n[=autorun.C18]\n[=autorun.C19]\n[=autorun.C20]\n[=autorun.C21]\n[=autorun.C22]\n[=autorun.C23]\n[=autorun.C24]\n[=autorun.C25]\n[=autorun.C26]\n[=autorun.C27]\n[=autorun.C28]\n[=autorun.C29]\n[=autorun.C30]
23exts=*.*
23fields=[=autorun.C31]\n[=autorun.C32]\n[=autorun.C33]\n[=autorun.C34]\n[=autorun.C35]\n[=autorun.C36]\n[=autorun.C37]\n[=autorun.C38]\n[=autorun.C39]\n[=autorun.C40]\n[=autorun.C41]\n[=autorun.C42]\n[=autorun.C43]\n[=autorun.C44]\n[=autorun.C45]\n[=autorun.C46]\n[=autorun.C47]\n[=autorun.C48]\n[=autorun.C49]\n[=autorun.C50]\n[=autorun.C51]\n[=autorun.C52]\n[=autorun.C53]\n[=autorun.C54]\n[=autorun.C55]\n[=autorun.C56]\n[=autorun.C57]\n[=autorun.C58]\n[=autorun.C59]\n[=autorun.C60]
Можно просто войти в Настройки -> Содержимое панелей -> Пользовательские и добавить там два шаблона *.*

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

[=autorun.C1]\n[=autorun.C2]\n[=autorun.C3]\n[=autorun.C4]\n[=autorun.C5]\n[=autorun.C6]\n[=autorun.C7]\n[=autorun.C8]\n[=autorun.C9]\n[=autorun.C10]\n[=autorun.C11]\n[=autorun.C12]\n[=autorun.C13]\n[=autorun.C14]\n[=autorun.C15]\n[=autorun.C16]\n[=autorun.C17]\n[=autorun.C18]\n[=autorun.C19]\n[=autorun.C20]\n[=autorun.C21]\n[=autorun.C22]\n[=autorun.C23]\n[=autorun.C24]\n[=autorun.C25]\n[=autorun.C26]\n[=autorun.C27]\n[=autorun.C28]\n[=autorun.C29]\n[=autorun.C30]

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

[=autorun.C31]\n[=autorun.C32]\n[=autorun.C33]\n[=autorun.C34]\n[=autorun.C35]\n[=autorun.C36]\n[=autorun.C37]\n[=autorun.C38]\n[=autorun.C39]\n[=autorun.C40]\n[=autorun.C41]\n[=autorun.C42]\n[=autorun.C43]\n[=autorun.C44]\n[=autorun.C45]\n[=autorun.C46]\n[=autorun.C47]\n[=autorun.C48]\n[=autorun.C49]\n[=autorun.C50]\n[=autorun.C51]\n[=autorun.C52]\n[=autorun.C53]\n[=autorun.C54]\n[=autorun.C55]\n[=autorun.C56]\n[=autorun.C57]\n[=autorun.C58]\n[=autorun.C59]\n[=autorun.C60]
Там же нужно поставить галочку "Объединять все подсказки, подходящие по типу файлов".

После перезагрузки ТС у плагина Autorun должно появится 60 дополнительных полей. Проверить это можно в WDX Guide.

Директива Pragma AutorunPluginFields должна находиться в первой строке главного скрипта autorun.cfg:
[cut]

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

Pragma AutorunPluginFields "C1:::MagicHint" "C2:::MagicHint" "C3:::MagicHint" "C4:::MagicHint" "C5:::MagicHint" "C6:::MagicHint" "C7:::MagicHint" "C8:::MagicHint" "C9:::MagicHint" "C10:::MagicHint" "C11:::MagicHint" "C12:::MagicHint" "C13:::MagicHint" "C14:::MagicHint" "C15:::MagicHint" "C16:::MagicHint" "C17:::MagicHint" "C18:::MagicHint" "C19:::MagicHint" "C20:::MagicHint" "C21:::MagicHint" "C22:::MagicHint" "C23:::MagicHint" "C24:::MagicHint" "C25:::MagicHint" "C26:::MagicHint" "C27:::MagicHint" "C28:::MagicHint" "C29:::MagicHint" "C30:::MagicHint" "C31:::MagicHint" "C32:::MagicHint" "C33:::MagicHint" "C34:::MagicHint" "C35:::MagicHint" "C36:::MagicHint" "C37:::MagicHint" "C38:::MagicHint" "C39:::MagicHint" "C40:::MagicHint" "C41:::MagicHint" "C42:::MagicHint" "C43:::MagicHint" "C44:::MagicHint" "C45:::MagicHint" "C46:::MagicHint" "C47:::MagicHint" "C48:::MagicHint" "C49:::MagicHint" "C50:::MagicHint" "C51:::MagicHint" "C52:::MagicHint" "C53:::MagicHint" "C55:::MagicHint" "C55:::MagicHint" "C56:::MagicHint" "C57:::MagicHint" "C58:::MagicHint" "C59:::MagicHint" "C60:::MagicHint"

Func MagicHint(FileName, FieldIndex, UnitIndex)
    If StrPos(FileGetAttr(FileName), "D") Then Return "" 
    Local bCaps = DllCall("GetKeyState", "int", 0x14, "short")
    Local b_CTRL = BitAND(bCaps, 1), b_Shift = IsPressed(0x10)
    
    If Not b_CTRL then b_CTRL = IsPressed (0x11)
    If Not b_CTRL Then Return
    
    Static Pipe, Idx = 0, _
           sPath = COMMANDER_PATH & "\Ini\Tools\Libs\", _
           sLang ="file://" & sPath & "ru.csv", _         
           sHint ="file://" & sPath & "hint.txt", _
           sSize ="file://" & sPath & "size.txt", _                        
           sLib = "MediaInfo" & (auX64 ? "" : "_i386") & ".dll", _
           hLib = DllCall("LoadLibrary", "Wstr",  sPath & sLib, "Ptr"), _
           pNew, pOpen, pDel, pOpt, pInfo
           
    If hLib = 0 And FieldIndex > 1 Then Return
    
    If FieldIndex = 1 Then

       If hLib = 0 Then Return "Error LoadLibrary " & sLib
       
       Idx = 0
       pNew = DllCall("GetProcAddress", "Ptr", hLib, "Str", "MediaInfo_New", "Ptr")
       pOpen = DllCall("GetProcAddress", "Ptr", hLib, "Str", "MediaInfo_Open", "Ptr")
       pDel = DllCall("GetProcAddress", "Ptr", hLib, "Str", "MediaInfo_Delete", "Ptr")
       pOpt = DllCall("GetProcAddress", "Ptr", hLib, "Str", "MediaInfo_Option", "Ptr")
       pInfo = DllCall("GetProcAddress", "Ptr", hLib, "Str", "MediaInfo_Inform", "Ptr")
              
       Local hMI = DllCall(pNew, "Ptr")
       If hMI = 0 Then Return "MediaInfo.dll couldn't create new object"
              
       If DllCall(pOpen, 'Ptr', hMI, "Wstr", FileName, "Uint") <> 1 Then
          DllCall(pDel, "Ptr", hMI)        
          Return "MediaInfo.dll couldn't open file " &  FileName
       EndIf

       Local x, y, w, bHint = 0
       Local hWnd = RequestInfo(ItemAtCursor("panel"))
       WinGetPos("", "", "w", "", hWnd)
       If w > 0 Then
          MouseGetPos("x","y")          
          Static buf = Buffer(8)	# POINT
          buf.Zero()
          buf.SetNum(0, "long", x, "long", y)
          DllCall("ScreenToClient", "hwnd", hWnd, "ptr", buf.ptr)
          x = buf.GetNum(0)
          Switch Round(x/w*100,0)
             Case 1 To 10
                b_Shift = 1
             Case 10 To 90
                #Pipe = ''
                #Return
             Case 90 To 100
                bHint = true
                Pipe = StrReplace(Pipe, Chr(32), Chr(160))            
          EndSwitch          
       EndIf                         

       DllCall(pOpt, 'Ptr', hMI, "Wstr", "Language", "Wstr", sLang, "Wstr")      
       If b_Shift Then 
          DllCall(pOpt, 'Ptr', hMI, "Wstr", "Complete", "Wstr", "1", "Wstr")
       Else
          DllCall(pOpt, 'Ptr', hMI, "Wstr", "Complete", "Wstr", "0", "Wstr")       
       EndIf
       If bHint Then
          DllCall(pOpt, "Ptr", hMI, "Wstr", "Output", "Wstr", sHint, "Wstr")
       ElseIf b_Shift Then
          DllCall(pOpt, "Ptr", hMI, "Wstr", "Output", "Wstr", sSize, "Wstr")           
       Else
          DllCall(pOpt, "Ptr", hMI, "Wstr", "Output", "Wstr", "", "Wstr")    
       EndIf              
       Pipe = DllCall(pInfo, 'Ptr', hMI, "Uint", 0, "Wstr")
       DllCall(pDel, "Ptr", hMI)
       If IsPressed(0x5B) Then Idx = 50
    Endif
    Return FixSpaces(StrPart(Pipe, auLF, FieldIndex + Idx))
EndFunc

Func FixSpaces(String)
    Local a, b
    If Not StrPos(String, ":") Then Return String    
    a = StrPart(String, ":", 1)
    b = StrPart(String, ":", 2) & StrPart(String, ":", 3)    
    Return StrTrim(a) & ":  " & FixCodePage(StrTrim(b)) 
EndFunc

Func FixCodePage(String)
   Local bUsedRepl
   # iso-8859-1 = 28591
   DllCall("WideCharToMultiByte", _
           "uint", 28591, _
           "dword", 0, _
           "wstr", String, _
           "int", -1, _
           "ptr", 0, _
           "int", 0, _
           "ptr", 0, _
           "bool*", @bUsedRepl)
    If bUsedRepl Then Return String
    Local nSize = StrLen(String)
    Local buf = Buffer(nSize)
    buf.Zero()
    DllCall("WideCharToMultiByte", _
            "uint", 28591, _
            "dword", 0, _
            "wstr", String, _
            "int", -1, _
            "ptr", buf.ptr, _
            "int", nSize, _
            "ptr", 0, _
            "ptr", 0)
    Local fixed = buf.GetStr(0, nSize, "ANSI")       
    Free(buf)
    Return fixed
EndFunc
[/cut]
После всех манипуляций подсказка должна заработать либо после удержания CTRL в 32-битном ТС, либо после включения CapsLock в ТСх64. CapsLock работает и в 32-битной версии. Окно панели делится на 3 части: 10% справа, 80% центр, 10% слева. В каждой области отображается своя подсказка, но все они завязаны на MediaInfo.dll. Для работы двух боковых подсказок потребуется положить в каталог библиотеки два дополнительных файла шаблона: hint.txt и size.txt
[cut="hint.txt"]General;Name: %FileName%.%FileExtension%\r\nSize: %FileSize/String4%\r\n[Duration: %Duration%]\r\n[Duration: %Duration/String1%]\r\n[Duration: %Duration/String5%]\r\n[General: %BitRate/String%][(%BitRate_Mode%)][, %Format%][(%Format/Family%)]$if(%Cover%,\, Cover)[, %Width%x%Height%pix][, AR:%AspectRatio%=~%AspectRatio/String%][, %Channel(s)%ch][, %Resolution/String%][, %FrameRate/String%][, %SamplingRate/String%][, %Bits-(Pixel*Frame)%bpf][, %Language%]\r\n

Video;Video #%StreamKindID%: [%Width%x%Height%pix][, AR:%AspectRatio%=~%AspectRatio/String%][, %Resolution/String%][, %FrameRate/String%][, %BitRate/String%][(%BitRate_Mode%)][, %Bits-(Pixel*Frame)%bpf][, %Format%][(%Format/Family%)][, %Language%][, %Channel(s)%ch][, %SamplingRate/String%]\r\n

Audio;Audio #%StreamKindID%: [%Channel(s)%ch][, %Resolution/String%][, %SamplingRate/String%][, %BitRate/String%][(%BitRate_Mode%)][, %Format%][(%Format/Family%)][, %Format_Profile%][, %Language%][, %Width%x%Height%pix][, AR:%AspectRatio%=~%AspectRatio/String%][, %FrameRate/String%][, %Bits-(Pixel*Frame)%bpf]\r\n
;
Text;Text #%StreamKindID%: %Format%[(%Format/Family%)][@%Language%][, %StreamSize/String4%][, %BitRate/String%][(%BitRate_Mode%)][, %Width%x%Height%pix][, AR:%AspectRatio%=~%AspectRatio/String%][, %Channel(s)%ch][, %Resolution/String%][, %FrameRate/String%][, %SamplingRate/String%][, %Bits-(Pixel*Frame)%bpf]\r\n

Chapters;Chapters #%StreamKindID%: %Format%[(%Format/Family%)][@%Language%][, %Total% entries][, %StreamSize/String4%][, %BitRate/String%][(%BitRate_Mode%)][, %Width%x%Height%pix][, AR:%AspectRatio%=~%AspectRatio/String%][, %Channel(s)%ch][, %Resolution/String%][, %FrameRate/String%][, %SamplingRate/String%][, %Bits-(Pixel*Frame)%bpf]\r\n
;
Image;Image #%StreamKindID%: [%Width%x%Height%pix][, AR:%AspectRatio%=~%AspectRatio/String%][, %Resolution/String%][, %FrameRate/String%][, %StreamSize/String4%][, %BitRate/String%][(%BitRate_Mode%)][, %Bits-(Pixel*Frame)%bpf][, %Format%][(%Format/Family%)][, %Language%][, %Channel(s)%ch][, %SamplingRate/String%]\r\n
;
Menu;Menu #%StreamKindID%: [%MenuID/String%][, %Duration% Format:%Format/String%]
;[/cut]
[cut="size.txt"]General;Name: %FileName%.%FileExtension%\r\nSize: %FileSize/String4%\r\nGeneral: [%StreamSize/String%]\r\n

Video;Video #%StreamKindID%: [%StreamSize/String%]\r\n
Audio;Audio #%StreamKindID%: [%StreamSize/String%]\r\n[/cut]
Это стандартные шаблоны MediaInfo. Можете поправить их как будет удобно, или можете создать свои.

Loopback
Попробовал попутно "CP:". Вот такое использование крашит плагин:
[cut]

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

Func FixCodePage(String)
   Local bUsedRepl
   # iso-8859-1 = 28591
   DllCall("WideCharToMultiByte", _
           "uint", 28591, _
           "dword", 0, _
           "wstr", String, _
           "int", -1, _
           "ptr", 0, _
           "int", 0, _
           "ptr", 0, _
           "bool*", @bUsedRepl)
    If bUsedRepl Then Return String
    Local nSize = StrLen(String)
    Local buf = Buffer(nSize)
    buf.Zero()
    buf.SetStr(String, 0, nSize, "CP:28591")
    Local fixed = buf.GetStr(0, nSize, "ANSI")       
    Free(buf)
    Return fixed
EndFunc
[/cut]

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

Crash in plugin Autorun.wdx:
Access violation at address 04AF3DF2. Read of address 00000000
Пришлось откатится на старый и проверенный вариант, как в полном коде выше.

Что же касается монитора выключения, то вот какие идеи у меня были на этот счет. Скорее всего помешать процессу копирования смогут только два диалога - ExtMsgForm и TOverWriteForm. Это две формы, которые объединяют в себе все, что вы перечислили выше. Можно было бы просто искать эти окна и следить за ними, но мне не понравился этот подход. Кроме того нужно учитывать, что окна могут быть открыты в других процессах ТС, поэтому нужно что-то более универсальное. Если допустить, что перекрывающее окно диалога будет иметь владельцем окно копирования (а судя по всему так оно и есть), то достаточно просто проверять окна первого уровня на наличие такого владельца. Пример такого перечисления окон первого уровня есть в справке к объекту Callback, его я и взял. Остальное, как говорится, дело техники. Полный код всего:
[cut]

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

LoadLibrary Plugins\Autorun_Tweaks.dll
LoadLibrary Plugins\Autorun_Sysinfo.dll
LoadLibrary Plugins\Autorun_Runtime.dll
LoadLibrary Plugins\Autorun_Process.dll

Const PBM_SETPOS      =  1026, _
      PBM_SETRANGE    =  1025, _
      PBS_MARQUEE     =  0x08, _
      PBM_SETMARQUEE  =  1034 

Func GetDPI()
  Local DC = DllCall("GetDC", "int", 0)
  Local lpy = DllCall("GetDeviceCaps", "handle", DC, "int", 88) # LOGPIXELSX
  DllCall("ReleaseDC", "int", 0, "handle", DC)
  Return lpy
EndFunc

Func Scale(nValue)
  Static dpi = GetDPI()
  Return DllCall("MulDiv", "int", nValue, "int", dpi, "int", 96)
EndFunc 

RegisterCommand 808000 "WinShutdown"

Global h_WinShutdown
Global g_WinShutdown, g_Shutdown = 0
Global g_LogShutdown = COMMANDER_PATH & "\Shutdown.log"
Global o_WinShutdown = Callback("WinShutdownProc", "hwnd;uint;wparam;lparam")

Func WinShutdownProc(hWnd, uMsg, wParam, lParam)
    Static WM_CLOSE = 0x0010
    If uMsg = WM_CLOSE Then
       If DllCall("DestroyWindow", "handle", hWnd) Then 
          g_Shutdown = 0
       EndIf   
       Return 0
    EndIf
    Return DllCall("CallWindowProcW", "ptr", g_WinShutdown, _
                                      "hwnd", hWnd, "uint", uMsg, "wparam", wParam, "lparam", lParam)
EndFunc

Func WinShutdown()
    Local hIco
    If h_WinShutdown > 0 Then
       If WinGetState(1, h_WinShutdown) Then
          SendMessage(h_WinShutdown, 0x0010, 0, 0)
          Return
       EndIf   
       h_WinShutdown = 0
    Endif
    # дескриптор монитора окна ТС
    Local hMon = DllCall("MonitorFromWindow", "hwnd", AUTORUN_TCHANDLE, "dword", 2)
    # информация о масштабировании экрана
    Local nMonScale = 0, nTextScale
    DllCall("Shcore.dll\GetScaleFactorForMonitor", "hwnd", hMon, "dword*", @nMonScale)
    If nMonScale < 100 Then nMonScale = 100
    # информация о размере текста
    RegRead nTextScale "HKCU\Software\Microsoft\Accessibility" "TextScaleFactor" 100
    nTextScale = Round(nTextScale/100,2)
    Local nWidth = Round(3*nMonScale*nTextScale,0)
    # создание окна прогресс-бара
    h_WinShutdown = DllCall("CreateWindowExW", _
                            "dword", 0, _
                            "wstr", "msctls_progress32", _
                            "wstr", "", _
                            "dword", 0x00C80000, _
                            "int", 200, "int", 100, "int", Round(Scale(300)*nTextScale,0), "int", Scale(50), _
                            "handle", , _
                            "handle", 0, "handle", 0, "ptr", 0, _
                            "handle")
    If h_WinShutdown = 0 Then Return 0
    # поверх всех окон
    WinSetState(30, h_WinShutdown)
    # WinAlign(h_WinShutdown, 0, DllCall("GetDesktopWindow"), 0, 100, -100)    
    # выравнивание по центру рабочего стола    
    WinAlign(h_WinShutdown, 0, DllCall("GetDesktopWindow"))
    # перемещение окна вверх на 50 пикселей    
    WinSetPos("", -Scale(50), "", "", 1, h_WinShutdown)
    # перемещение окна вправо на 50 пикселей
    # WinSetPos(Scale(50), "", "", "", 1, h_WinShutdown)
    # показ окна    
    WinSetState(5, h_WinShutdown)

    g_WinShutdown = DllCall("SetWindowLong" & (auX64 ? "PtrW" : "W"), _
                            "hwnd", h_WinShutdown, _
                            "int", -4, _
                            "long_ptr", o_WinShutdown.Ptr, _
                            "ptr")  
    
    hIco = SendMessage(AUTORUN_TCHANDLE, 0x7f, 2, 0)                     
    SendMessage(h_WinShutdown, 0x80, 0, hIco)       
                   
    g_Shutdown = 1           
    WinSetStyle(PBS_MARQUEE, 4, h_WinShutdown) 
    SendMessage(h_WinShutdown, PBM_SETPOS, 0, 0)   
    For i = 1 to 100
        SendMessage(h_WinShutdown, PBM_SETPOS, i, 0) 
        WinSetText("Выключение через " & 100-i & " сек.", h_WinShutdown)
        Sleep(900)
        If g_Shutdown = 0 Then Break
    Next 
       
    If g_Shutdown = 0 Then    
       FileAppend(g_LogShutdown, StrFormat("%s %s Выключение отменено", Date(), Time()))     
       MsgBox("Выключение ПК отменено", "", 48)
    Else       
       If DllCall("DestroyWindow", "handle", h_WinShutdown) Then h_WinShutdown = 0
       FileAppend(g_LogShutdown, StrFormat("%s %s Выключение ПК...", Date(), Time()))            
       #MsgBox("Выключение ПК", "", 64)
       #ShellExec("shutdown", "/s /t 60") # можно добавить /f для принудительного закрытия приложений
    EndIf   
EndFunc

# Ctrl+Alt+O
SetHotkeyAction /K:C /K:A /H:O /DM "RunThread" "CopyMonitor"

Global g_CopyMonitor = false, g_CopyWndOwner = false, g_DialogWnd = ""

Func CopyMonitor()
    Local bWmi = true            # показывать объем в заголовке
    Local bTransCopyWin = true   # прозрачность окна копирования
    Local wait_seconds = 300     # время ожидания при появлении диалога
    Static hCopyWnd = 0
    # Если монитор уже запущен - остановить
    If g_CopyMonitor Then 
       g_CopyMonitor = false
       Return
    EndIf
    # поиск окна копирования
    hCopyWnd = WinFind(0, "TDLG2FILEACTIONMIN")
    If hCopyWnd = 0 Then
        ShowHint("Копирование не запущено", 0, 0, 1000, 1)
        WinAlign(LAST_HINT_WINDOW)
        Return
    EndIf
    # текущее состояние монитора    
    g_CopyMonitor = true
    # установка прозрачности окна ТС
    WinSetStyle(0x80000, 3)
    DllCall("SetLayeredWindowAttributes", "hwnd", AUTORUN_TCHANDLE, _ 
                                          "ptr", 0, "byte", 192, "dword", 2)
    # опциональная прозрачность окна копирования                                       
    If bTransCopyWin Then                                      
       WinSetStyle(0x80000, 3, hCopyWnd)
       DllCall("SetLayeredWindowAttributes", "hwnd", hCopyWnd, _ 
                                             "ptr", 0, "byte", 192, "dword", 2)
    EndIf                                                      
    # поиск и блокировка кнопки "В фоне"
    Local b = WinFind(hCopyWnd, _
                     (AUTORUN_TCARCH = 32 ? "TButton" : "Button"), (AUTORUN_TCARCH = 32 ? 2 : 1))
    WinSetState(21, b)                                      
    # параметры подсказки                                      
    SetHintParam("ShowHint", "Font", 15, "Arial")
    SetHintParam("ShowHint", "BackColor", 0xFF0000)
    SetHintParam("ShowHint", "Text", 0xFFFFFF)
    ShowHint("Монитор выключения запущен, ожидание завершения копирования", 0, 0, 1000, 1)
    # сброс параметров подсказки                                          
    SetHintParam("ShowHint", "Reload")
    # центрирование подсказки
    WinAlign(LAST_HINT_WINDOW)
    Local wmi, wmq, txt = WinGetText(hCopyWnd)
    # wmi запрос к процессу ТС
    wmq = "SELECT IOWriteBytesPersec FROM Win32_PerfRawData_PerfProc_Process WHERE IDProcess=" & AUTORUN_TCPID
    # функция обратного вызова 
    Local ewp = Callback("IsCopyWndOwner", "hwnd;lparam")
    Local hang = 0
    # цикл ожидания периодический поиск окна копирования
    While hCopyWnd <> 0
        g_CopyWndOwner = false
        # проверить статус владельца окна копирования
        DllCall("EnumWindows", "ptr", ewp.Ptr, "lparam", hCopyWnd)        
        # записано байт процессом опционально
        If bWmi Then wmi = SizeFormat(GetWMIValue("IOWriteBytesPersec", wmq), 1, "G", 2)
        WinSetText("Shutdown " & (Not g_CopyWndOwner ? "in effect" : "paused for " & hang & " сек.") _
                               & (Not bWmi ? "" : ": " & wmi), hCopyWnd)
        hang = (g_CopyWndOwner ? hang + 1 : 0)
        If hang > wait_seconds Then Break   
        For i = 1 To 10
            If Not g_CopyMonitor Then Break
            Sleep(100)
        Next        
        If Not g_CopyMonitor Then Break
        hCopyWnd = WinFind(0, "TDLG2FILEACTIONMIN")
    Wend
    Free(ewp)
    WinSetText(txt, hCopyWnd)
    # разблокирование кнопки "В фоне"    
    WinSetState(20, b)
    # цикл не был прерван повторным нажатием Ctrl+Alt+O
    If g_CopyMonitor Then
       g_CopyMonitor = false
       ShutdownLog(hang)
       WinShutdown()
    Else
       SetHintParam("ShowHint", "Font", 15, "Arial")
       SetHintParam("ShowHint", "BackColor", 0xFF0000)
       SetHintParam("ShowHint", "Text", 0xFFFFFF)    
       ShowHint("Монитор выключения остановлен", 0, 0, 1000, 1)
       SetHintParam("ShowHint", "Reload") 
       WinAlign(LAST_HINT_WINDOW)
    EndIf
    # отключение прозрачности    
    WinSetStyle(0x80000, 5)
    If bTransCopyWin Then WinSetStyle(0x80000, 5, hCopyWnd)        
EndFunc 

Func IsCopyWndOwner(wnd, lparam)
    If Not WinGetState(2, wnd) Then Return 1
    Local h = DllCall("GetWindow", "hwnd", wnd, "uint", 4, "hwnd")
    If h = lparam Then
       g_CopyWndOwner = true
       g_DialogWnd = WinGetClass(wnd) & " - " & WinGetText(wnd)
       Return 0
    EndIf
    Return 1
EndFunc

Func ShutdownLog(CopyHang)
    Local sLog
    Local status = "операция копирования " & (CopyHang = 0 ? "завершена" :"прервана")
    sLog &= auCRLF & auCRLF
    sLog &= StrFormat("%s %s Окно выключения ПК\r\n", Date(), Time())
    sLog &= StrFormat("%s %s Статус: %s\r\n", Date(), Time(), status)
    If CopyHang > 0 Then sLog &= StrFormat("%s %s Диалог: %s\r\n", Date(), Time(), g_DialogWnd)
    FileAppend(g_LogShutdown, sLog) 
EndFunc
[/cut]
Переменная wait_seconds задает, сколько секунд ждать, если диалог прервал операцию (пока стоит 300). Ну, и сделал лог-файл, потому как опять подумал, что без него "не торт" будет. Лог сохраняется в корень ТС, т.ч. должны быть права на запись. Еще пару прикольных визуальных фишек добавил в заголовок окна копирования, надеюсь, понравятся. А не понравятся, кое-что можно отключить через переменную bWmi.
Аватара пользователя
yozhik
Сообщения: 353
Зарегистрирован: Вс май 04, 2014 20:34
Откуда: Электросталь

Сообщение yozhik »

Loopback

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

VAR = RegExpReplace(VAR, "a", "b")
работает.

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

RegExpReplace VAR %VAR% "a" "b"
не работает — записывает в файл литерально "%VAR%" вместо содержимого. Хотя StrReplace при точно такой же записи работает исправно. Я, наверное, что-то пропустил? Скорее всего, прошу пардону. Вы мне только маякните мой ли косяк — сам хочу разобраться что не так делаю, а то в памяти не отложится.

Orion9
Новые ключевые слова добавлять в подсветку не долго, и это я делаю по мере их появления, только не обнародую нигде. Долго для меня вникать в изменения синтаксиса, чтобы исправлять подсветку ошибок. Это не сложно, просто нужно время, а с ним беда, учитывая, что основной род деятельности у меня далёк от физики.
Amo ergo sum
Аватара пользователя
Orion9
Сообщения: 1283
Зарегистрирован: Пн янв 01, 2024 17:18

Сообщение Orion9 »

Loopback
Забыл написать. При использовании buf.SetStr(String, 0, nSize, "CP:28591") плагин не на всех файлах крашится. Например, на MP3 он вполне работает и фиксит кракозябры как ожидается. Но на видео-файлах заваливается. Сами видео файлы вряд ли при чем. Просто на таких файлах подсказка бывает больше, т.ч. возможно, с этим как-то связано.

yozhik
Будем надеяться, что когда Loopback выпустит Finalè версию плагина, вы тоже обнародуете финальную версию хайлайтера. Я регулярно им пользуюсь, мне нравится. Спасибо.
Loopback
Сообщения: 1646
Зарегистрирован: Пн сен 07, 2009 09:29

Сообщение Loopback »

Orion9 писал(а):Попробовал попутно "CP:". Вот такое использование крашит плагин:
Ага, действительно. Это не связано непосредственно с указанием кодировки в виде CP, к примеру, c "ANSI" будет то же самое. Проблема с преобразованием в однобайтные кодировки строк длиной в 1 символ. В данном примере, когда доходит до первого такого значения (поле "ID") - на нём и крашится.

Пока хотфикс делать не буду, просто выложу исправленную версию.

Версия от 11.09.2025
yozhik писал(а):не работает — записывает в файл литерально "%VAR%" вместо содержимого. Хотя StrReplace при точно такой же записи работает исправно.
Да, подавляющее большинство функций в командной записи не поддерживают разворачивание переменных непосредственно в параметрах. Те что поддерживают - это ограниченный набор "старых" функций из ранних версий Autorun (строчные, ini и еще некоторые). Я бы с радостью убрал эту функциональность и из них, поскольку это довольно корявый навесной механизм, который необходимо применять отдельно к каждому параметру. Останавливает лишь вопрос совместимости со старым кодом. В новых функциях, конечно, этого уже не делается.

А для использования значения переменной в командной записи в этой и любой другой функции без встроенного разворачивания, есть простой универсальный способ - вычисляемые строки:

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

RegExpReplace VAR %"VAR" "a" "b"
Но я всё же призываю для таких функций использовать функциональную запись. По-моему, для них она просто более естественна.
Аватара пользователя
Orion9
Сообщения: 1283
Зарегистрирован: Пн янв 01, 2024 17:18

Сообщение Orion9 »

Loopback
Обновил, проверил, всё работает. Спасибо. Надо будет ещё на UTF-8 и cp866 проверить, когда будет возможность.

Ну, так когда Finalè всем стоит ждать? Видны горизонты? Крутые фичи добавляются и стабильность растёт, а финале всё нет и нет )
A55555
Сообщения: 72
Зарегистрирован: Вс фев 06, 2011 10:50

Сообщение A55555 »

Orion9 писал(а):A55555
Не совсем понял, что вы имеете в виду говоря:
Добавьте пожалуйста настройку отображение подсказки для ваших Torrent и "Продолжительность медиафайлов" кнопок
Имею ввиду, чтоб подсказка при нажатии этих кнопок была более крупным шрифтом. Вы добавляли настройку подсказки в мониторинг выключения ПК после окончания копирования.

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

#параметры подсказки                                     
    SetHintParam("ShowHint", "Font", 15, "Arial")
    SetHintParam("ShowHint", "BackColor", 0xFF0000)
    SetHintParam("ShowHint", "Text", 0xFFFFFF) 
Я скопировал те строки из мониторинга выключения, по логике, в TorrentSize, но оно не заработало, подсазка возле курсора осталась по умолчанию крошечной.

Добавлено спустя 35 минут:
Orion9 писал(а):Что же касается монитора выключения, то вот какие идеи у меня были на этот счет. Скорее всего помешать процессу копирования смогут только два диалога - ExtMsgForm и TOverWriteForm. Это две формы, которые объединяют в себе все, что вы перечислили выше. Можно было бы просто искать эти окна и следить за ними, но мне не понравился этот подход. Кроме того нужно учитывать, что окна могут быть открыты в других процессах ТС, поэтому нужно что-то более универсальное. Если допустить, что перекрывающее окно диалога будет иметь владельцем окно копирования (а судя по всему так оно и есть), то достаточно просто проверять окна первого уровня на наличие такого владельца. Пример такого перечисления окон первого уровня есть в справке к объекту Callback, его я и взял. Остальное, как говорится, дело техники. Полный код всего:
Переменная wait_seconds задает, сколько секунд ждать, если диалог прервал операцию (пока стоит 300). Ну, и сделал лог-файл, потому как опять подумал, что без него "не торт" будет. Лог сохраняется в корень ТС, т.ч. должны быть права на запись. Еще пару прикольных визуальных фишек добавил в заголовок окна копирования, надеюсь, понравятся. А не понравятся, кое-что можно отключить через переменную bWmi.
Спасибо. Попробую сегодня.
Согласно логике этого кода, после ожидания 300 секунд, что произойдет, если выскочил TOverWriteForm, пропущено просто без действия, ничего не будет перезаписано поверх?
Аватара пользователя
yozhik
Сообщения: 353
Зарегистрирован: Вс май 04, 2014 20:34
Откуда: Электросталь

Сообщение yozhik »

Loopback писал(а):есть простой универсальный способ - вычисляемые строки
Здесь и они не работают. Я их сразу попробовал ещё перед предыдущим постом (эх, надо было мне сразу же и про них тоже написать). В VAR я считываю содержимое одного 13-строчного xml: FileRead -> RegExpReplace -> FileWrite. Так вот у меня после применения

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

RegExpReplace VAR %"VAR" "a" "b"
в xml записывается только одна строка — самая первая — остальные «исчезают».
Loopback писал(а):Но я всё же призываю для таких функций использовать функциональную запись. По-моему, для них она просто более естественна.
С этим я не просто полностью согласен, а согласен даже с радостью )) Функциональная запись в таких случаях даже более очевидна. Но я гляжу в справку, а там про командную запись — ну, значит и она должна работать. А у меня не сработало ни %VAR%, ни %"VAR". Подожду пока Вашего ответа про вычисляемые строки...
Amo ergo sum
AkulaBig
Сообщения: 639
Зарегистрирован: Ср дек 03, 2008 11:48

Сообщение AkulaBig »

Помогите человеку:

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

Кто понимает в Autorun.wdx ? Нужна помощь.

Код:
 
# Active path panel. SCROLL WHEEL - open Downloads folder
ControlSetMouseAction /M:U 10005 OpenDownloads
 
Func OpenDownloads()
    If RequestInfo(1000) = 1 Then
        CommandExec /CD %'GetKnownFolderPath("Downloads")'
    Else
        CommandExec /CD '' %'GetKnownFolderPath("Downloads")'
    Endif
EndFunc

 
Все хорошо, но нужно чтобы открывало и в неактивной тоже. В теории

Код:
ControlSetMouseAction /M:U 10006 OpenDownloads

..не прокатывает.
 
Нужно чтобы по щелчку по неактивному заголовку панели перешло в папку и осталось неактивной.
Аватара пользователя
Orion9
Сообщения: 1283
Зарегистрирован: Пн янв 01, 2024 17:18

Сообщение Orion9 »

A55555 писал(а):Я скопировал те строки из мониторинга выключения, по логике, в TorrentSize, но оно не заработало, подсазка возле курсора осталась по умолчанию крошечной.
Вы правильно сделали, но в теле функции подсказка вызывается два раза, если не считать подсказки об ошибках (Файл не существует, Каталог и т.д.). Возможно, вы вставили строки перед одной подсказкой, но вызывалась другая. Первая подсказка вызывается для одиночных файлов, вторая - для выделенных. По сути, нужно и перед той, и перед другой сделать. Но не забудьте после каждого ShowHint() добавить строку сброса параметров SetHintParam("ShowHint", "Reload"), поскольку изменение параметров происходить глобально и затрагивает все подсказки в плагине.
A55555 писал(а):что произойдет, если выскочил TOverWriteForm, пропущено просто без действия, ничего не будет перезаписано поверх?
Просто продолжится выключение ПК после отведенных секунд ожидания, но в лог запишется, что операция была прервана, и добавится информация о классе окна диалога, перекрывшего окно копирования, и заголовке его окна, например:

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

12.09.2025 19:06:41 Окно выключения ПК
12.09.2025 19:06:41 Статус: операция копирования прервана
12.09.2025 19:06:41 Диалог: TOverWriteForm - Total Commander
12.09.2025 19:06:51 Выключение ПК...
Если будете эксперементировать, то wait_seconds лучше поставить по минимуму, а Sleep(900) заменить на Sleep(90) временно.
AkulaBig писал(а):Помогите человеку:
Эх, где же Flasher... Он щёлкал такие примеры как орехи.

Вариантов, наверное, есть несколько, но если так?

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

ControlSetMouseAction /M:U 10005 OpenDownloads 1
ControlSetMouseAction /M:U 10006 OpenDownloads 2
 
Func OpenDownloads(Panel)
    If RequestInfo(1000) = Panel Then
        CommandExec /CD %'GetKnownFolderPath("Downloads")'
    Else
        CommandExec /CD '' %'GetKnownFolderPath("Downloads")'
    Endif
EndFunc
AkulaBig
Сообщения: 639
Зарегистрирован: Ср дек 03, 2008 11:48

Сообщение AkulaBig »

Orion9
Спасибо, переправил.
Loopback
Сообщения: 1646
Зарегистрирован: Пн сен 07, 2009 09:29

Сообщение Loopback »

yozhik писал(а):Здесь и они не работают.
Теперь понятно. Действительно, баг. Причём такой, что за пять минут и не исправишь, и менять придется там, куда уже совсем не хочется залезать :)
Orion9 писал(а):Ну, так когда Finalè всем стоит ждать? Видны горизонты?
Ну вот какой тут "Finalè", когда до сих пор такие вещи всплывают...

На самом деле свет в конце туннеля виден. Хотя находиться в состоянии вечной беты, надо признаться, удобно. Но синтаксис зафиксирован, оптимизация потихоньку идёт, в todo осталась в основном мелочевка. Cамое главное устаканить API плагинов, потом будет сильно сложнее что-то изменить. Правда, последние два месяца я всем этим занимался мало.
Ответить