Autorun

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

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

Аватара пользователя
Orion9
Сообщения: 1283
Зарегистрирован: Пн янв 01, 2024 17:18

Сообщение Orion9 »

Loopback писал(а):Увы, идеально точно не получится
Да ладно. Говорю же, это мелочи. Всё-равно мне показалось, что лучше стало.
Loopback писал(а):Да, как и было задумано
Попробуем, когда доберуться руки.

В общем, поюзал я ТС с прозрачным окном в Win11... есть в этом что-то, но есть и недостаток. При посылке сообщения главному окну, оно скрывается и значок ТС на панели задач пропадает, затем снова появляется как ни в чем не бывало. Всё это напоминает, как ведет себя ТСх64 в аналогичной ситуации (без прозрачности), но там хотя бы окно не пропадает, а только значок, что не критично. Но здесь же... В общем, юзать такое сложно, если вообще возможно.

Сначала думал, что проблема в SendCommand или в WinRedraw(1), но дело не в этом. Ниже код для воспроизведения проблемы. Окно и значок на панели задач пропадают на секунду при условии, что установлена прозрачность:

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

RegisterCommand 60030 TestTransparencyBug

Func TestTransparencyBug(lParam)
    SendMessage(AUTORUN_TCHANDLE, 11, 0, 0)  
    Sleep(1000)
    SendMessage(AUTORUN_TCHANDLE, 11, 1, 0)
EndFunc
Loopback, можно что-то с этим сделать, есть мысли?

A55555, когда писал тот большой пост, не было времени сразу все проверить. Так и знал, что что-нибудь да упущу. В общем, для полноценной работы функций подсчета потребуется еще одна вспомогательная функция:
[cut]

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

Func ListDirectory(sPath, ByRef aList, nDepth = 1)
    Local sFile, nAttr
    Local ffd = Buffer(604)
    Local hf = DllCall("FindFirstFileW", "wstr", sPath & "\*.*", "ptr", ffd.Ptr)
    If hf <> 0 then 
        While True 
            sFile = ffd.GetStr(44)         # cFileName
            nAttr = ffd.GetNum(0, "dword") # dwFileAttributes
            If BitAND(nAttr, 16) Then 
               If Not ((sFile = ".") Or (sFile = "..")) Then 
                  aList.Add(sPath & "" & sFile)
                  If nDepth <> 1 Then
                     ListDirectory(sPath & "" & sFile, aList, nDepth - 1)
                  EndIf   
               EndIf
            Else
               aList.Add(sPath & "" & sFile)
            Endif     
            If DllCall("FindNextFileW", "handle", hf, "ptr", ffd.Ptr) = 0 Then Break
        Wend
        DllCall("FindClose", "handle", hf)
    Endif 
    Free(ffd)
EndFunc
[/cut]
Просто скопируйте ее в любое место файла конфигурации. Сейчас Autorun такие функции не нужны, у него есть свои более удобные функции для поиска и выборки файлов. Но это делалось давно, поэтому и забыл, т.к. она лежала у меня в совсем другом модуле.
AkulaBig
Сообщения: 639
Зарегистрирован: Ср дек 03, 2008 11:48

Сообщение AkulaBig »

Loopback писал(а):Т.е. в DebugView ничего не пишет? Потому что улетать сейчас окно в любом случае не будет
В текущей сборке просто это негде проверить. Хотя сейчас попробую на всякий случай.
Loopback писал(а):Залил временно к себе
Спасибо. Все, можно удалять. В прошлый раз вы так написали, что я решил удалить тестовую сборку. Вроде как в ближайшее время не удастся ошибку исправить. А в этой версии в хистори вроде про это было. Вот я и начал кипишить. Но оказывается не совсем про это. Ниче, пусть теперь сборка лежит. Не буду ее удалять.

Добавлено спустя 7 минут:

Проверил. В текущей версии сборки с последним Autorun DebugView не выдает вообще никаких сообщений. Но может это из-за того, что вы-же тогда спец версии плагина выкладывали? Мне кажется в обычной версии и раньше никаких сообщений дебага не было.

Добавлено спустя 2 минуты:

А у всех главная страница форума до авторизации стала англоязычной? Похоже косяки какие-то.

Добавлено спустя 22 минуты:

Ну вот и произошло чудо. В тестовой версии окно больше не улетает за экран. Я имею ввиду, что со старой версией Autorun. Значит либо Винда в этом участвовала и ее обновление убрало ошибку. Либо шаман в бубен постучал. Будем считать вопрос исчерпан. Я даже не стал тестить с новой версией плагина. Ну и версия плагина в сборке не отладочная была. Так что дебаг никаких сообще6ний так и не вывел.
Loopback
Сообщения: 1646
Зарегистрирован: Пн сен 07, 2009 09:29

Сообщение Loopback »

Orion9 писал(а):есть мысли?
Нет, понятия не имею. Тестировать сегодня не могу, нет под рукой 11. Но думаю Autorun тут вообще не при делах. SendMessage просто обертка над системной функцией. Но WM_SETREDRAW это вообще такая специфическая штука, она не предполагает отключение на большие интервалы времени. Когда перерисовка выключена, от окна по сути остается картинка на экране. Предполагаю, что если в этот момент картинка будет чем-то стерта (может софт какой-то специфический стоит), это будет выглядеть как исчезновение окна.
AkulaBig писал(а):В текущей версии сборки с последним Autorun DebugView не выдает вообще никаких сообщений. Но может это из-за того, что вы-же тогда спец версии плагина выкладывали?
Полную отладочную информацию я убрал, конечно, но одно сообщение в релизе оставил.
AkulaBig писал(а):В тестовой версии окно больше не улетает за экран. Я имею ввиду, что со старой версией Autorun.
Ну вот, а вы всё - чудес не бывает... :)
A55555
Сообщения: 72
Зарегистрирован: Вс фев 06, 2011 10:50

Сообщение A55555 »

Orion9 писал(а):
A55555 писал(а):У меня опыта прикручивания готовых кнопок нет, поучусь.
Не совсем понятно, что имеется в виду. Про копипрование кода кнопок на панель инструментов вы, наверное, знаете. А чтобы вызывать функции Autorun из кнопок ТС, для этого, как правило, регистрируется отдельный незанятый код в диапазоне 60000-100000 и указывается в соответствующей кнопке. Этот код можно использовать и в пользовательских em_командах, например, себе я сделал такую команду в файле usercmd.ini:
С кнопками я разобрался.
Но с регистрацией кода проблема, по обеим кнопкам выскакивает сообщение "Функция не реализована. 620..."
Orion9 писал(а):A55555, когда писал тот большой пост, не было времени сразу все проверить. Так и знал, что что-нибудь да упущу. В общем, для полноценной работы функций подсчета потребуется еще одна вспомогательная функция:
И добавление этой функции не изменило ситуацию.

К примеру. Папка TCTorrent плагина в моей готовой сборке находится в wlx плагинах по умолчанию.
Я отредактировал ваш код, сменив

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

ShowHint("TCTorrent.wdx plugin error " & ERROR) 
.......
"Powered by TCTorrent.wdx" & auCRLF & _ 
на

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

ShowHint("TCTorrent.wlx64 plugin error " & ERROR) 
.......
"Powered by TCTorrent.wlx64" & auCRLF & _ 
может проблема в том, что у меня 64bit сборка TC?

[cut]Изображение[/cut]
Аватара пользователя
Orion9
Сообщения: 1283
Зарегистрирован: Пн янв 01, 2024 17:18

Сообщение Orion9 »

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

A55555
Такая ошибка возникает, когда номер команды не зарегистрирован. Если вы скопировали все и сохранили в файл конфигурации, то, по идее, нужно только перезапустить ТС.

Допустим нужно зарегистровать команду с кодом 60100, которая будет вызывать функцию Test(). Тогда код на Autorun будет такой:

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

RegisterCommand 60100 Test

Func Test(lParam)
    MsgBox("Команда 60100 выполнена")
EndFunc
А кнопка такой:

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

TOTALCMD#BAR#DATA
60100

%COMMANDER_EXE%
Команда 60100


-1
Ваши изменения затрагивают только текст подсказки. Проблема незапуска в чем-то другом, на 64-битном ТС все работает. Попробуйте на таком простом коде, как 60100, сделать кнопку.
Аватара пользователя
Orion9
Сообщения: 1283
Зарегистрирован: Пн янв 01, 2024 17:18

Сообщение Orion9 »

Хорошая мысля приходит напосля.

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

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

Func CopyMonitor()
    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)
    # поиск и блокирование кнопки "В фоне"
    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)
    While hCopyWnd <> 0
        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
    # разблокирование кнопки "В фоне"    
    WinSetState(20, b)    
    If g_CopyMonitor Then
       g_CopyMonitor = false
       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)
EndFunc 
[/cut]
Одной проблемой меньше. Остались только диалоговые окна, которые могут неожиданно прервать операцию и оставить компьютер включенным до утра. Нужно подумать, что с этим делать, но на крайний случай можно добавить таймер, который будет в любом случае выключать компьютер через 2-3 часа после ухода.
Loopback
Сообщения: 1646
Зарегистрирован: Пн сен 07, 2009 09:29

Сообщение Loopback »

Orion9 писал(а):В общем, как будет возможность, посмотрите - увидите о чем речь.
Не понадобилась даже 11, на десятке ведет себя ровно так же, и на 7, и даже XP. Сходу найти информацию по теме классическим методом не удалось, а нейросеть утверждает, что это несовместимость WS_EX_COMPOSITED и WM_SETREDRAW:

[cut]
Сочетание WS_EX_COMPOSITED и WM_SETREDRAW с параметром 0 приводит к исчезновению окна из-за фундаментального конфликта этих двух механизмов.

Стиль WS_EX_COMPOSITED переводит окно в режим двойной буферизации на уровне системы. Вся его отрисовка происходит в отдельном буфере в памяти, который затем целиком выводится на экран. Этот процесс требует, чтобы система постоянно могла обновлять этот буфер в ответ на любые изменения.

Сообщение WM_SETREDRAW с параметром 0 является директивой полностью заблокировать все процессы перерисовки для окна. Когда это сообщение применяется к окну с WS_EX_COMPOSITED, система лишается возможности поддерживать его буфер в актуальном состоянии. В результате она продолжает отображать последний известный "снимок" буфера, который, если обновления были заблокированы в самом начале, часто оказывается пустым или невалидным. Это приводит к визуальному исчезновению как самого окна, так и его значка в панели задач, который является его представлением.

Отправка WM_SETREDRAW с параметром 1 снимает блокировку. Система немедленно инициирует полную перерисовку, восстанавливая актуальное состояние буфера в памяти, что моментально возвращает окно и его значок на экран.

Вывод: Эти две технологии несовместимы. WS_EX_COMPOSITED требует постоянной фоновой перерисовки, которую WM_SETREDRAW явно запрещает. Для массовых обновлений в таком окне следует использовать другие методы (например, скрытие окна или методы конкретных контролов).
[/cut]

К таким ответам следует относиться с осторожностью, но насколько я могу судить, выглядит похоже на правду.

К слову, если не выполнять SetLayeredWindowAttributes, а только добавить WS_EX_COMPOSITED - окно тотала просто пропадает...
Аватара пользователя
Orion9
Сообщения: 1283
Зарегистрирован: Пн янв 01, 2024 17:18

Сообщение Orion9 »

Быстренько пробежался еще раз. Добавил комментариев и важную переменную bTransCopyWin, которой можно управлять прозрачностью окна копирования. По умолчанию выключена. Если нужно, чтобы во время копирования окно копирования тоже становилось прозрачным, включение через Local bTransCopyWin = true.
[cut]

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

Func CopyMonitor()
    Local bTransCopyWin = false   # прозрачность окна копирования
    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)
    # цикл ожидания периодический поиск окна копирования    
    While hCopyWnd <> 0
        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
    # разблокирование кнопки "В фоне"    
    WinSetState(20, b)
    # цикл не был прерван повторным нажатием Ctrl+Alt+O
    If g_CopyMonitor Then
       g_CopyMonitor = false
       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 
[/cut]

Добавлено спустя 2 минуты:

Loopback
А что делать-то? :)
Loopback
Сообщения: 1646
Зарегистрирован: Пн сен 07, 2009 09:29

Сообщение Loopback »

Orion9 писал(а):А что делать-то?
Orion9 писал(а):И если будет стоять выбор между прозрачностью и гладкостью перерисовки, то я однозначно выберу второе.
Ну это же очевидно - использовать то, что нужнее.

Впрочем, технология в том числе предназначена и для уменьшения мерцания, попробуйте убрать функции отключения/включения перерисовки, возможно что самой двойной буферизации окажется достатчоно, чтобы WM_SETREDRAW не использовать.
A55555
Сообщения: 72
Зарегистрирован: Вс фев 06, 2011 10:50

Сообщение A55555 »

Orion9 писал(а):Добавил буквально три строчки к CopyMonitor(). Теперь при вкючении режима ожидания кнопка "В фоне" деактивируется, а при отключении режима ожидания снова активируется:
Спасибо. Деактивируется.
Orion9 писал(а):Быстренько пробежался еще раз. Добавил комментариев и важную переменную bTransCopyWin, которой можно управлять прозрачностью окна копирования. По умолчанию выключена. Если нужно, чтобы во время копирования окно копирования тоже становилось прозрачным, включение через Local bTransCopyWin = true.
Спасибо. Прозрачность работает для окна копирования.

Orion9 писал(а):A55555
Такая ошибка возникает, когда номер команды не зарегистрирован. Если вы скопировали все и сохранили в файл конфигурации, то, по идее, нужно только перезапустить ТС.

Допустим нужно зарегистровать команду с кодом 60100, которая будет вызывать функцию Test(). Тогда код на Autorun будет такой:
[cut]

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

RegisterCommand 60100 Test

Func Test(lParam)
    MsgBox("Команда 60100 выполнена")
EndFunc
[/cut]
А кнопка такой:
[cut]

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

TOTALCMD#BAR#DATA
60100

%COMMANDER_EXE%
Команда 60100


-1
[/cut]
Ваши изменения затрагивают только текст подсказки. Проблема незапуска в чем-то другом, на 64-битном ТС все работает. Попробуйте на таком простом коде, как 60100, сделать кнопку.
Заработали кнопки, переносом этих команд в самое начало файла конфигурации Autorun.

RegisterCommand 62014 "TorrentSize" работает, показывает размер в подсказке возле курсора.
RegisterCommand 62013 "Duration" работает по Alt, остальные режимы по кнопке Ctrl_Shift_CapsLock выдают Error LoadLibrary MediaInfo.dll
Путь к своей библиотеке MediaInfo_x64.dll указал

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

Static sLib = "MediaInfo" & (auX64 ? "" : "_i386") & ".dll", _
           hLib = DllCall("LoadLibrary", "wstr", COMMANDER_PATH & "\Plugins\wdx\TCMediaInfo" & sLib, "ptr")
[cut]Изображение[/cut]
Последний раз редактировалось A55555 Вт сен 09, 2025 23:05, всего редактировалось 1 раз.
Аватара пользователя
Orion9
Сообщения: 1283
Зарегистрирован: Пн янв 01, 2024 17:18

Сообщение Orion9 »

Loopback
Убрал для эксперемента. Окно и значок на панели задач теперь не пропадают, но перерисовывается всё с заметными артефактами, как и ожидалось. Ладно, не беда. Прозрачность мне понравилась как лекарство от однообразия, буду юзать время от времени. Спасибо вам, что нашли причину и объяснение. Думаю, со временем добавлю в код проверку на стиль WS_EX_COMPOSITED, и если он включен, то не посылать WM_SETREDRAW.

A55555
Это значит, что путь к библиотеке MediaInfo.dll неправильно указан, скорее всего. К сожалению, его нужно указывать явно, как я и писал выше.

Добавлено спустя 4 минуты:
Путь к своей библиотеке MediaInfo_x64.dll указал
Нет, такое не предусмотрено. Библиотеки должны быть такими:

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

MediaInfo.dll
MediaInfo_i386.dll
Просто создайте пока копию с такими именами.
A55555
Сообщения: 72
Зарегистрирован: Вс фев 06, 2011 10:50

Сообщение A55555 »

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

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

MediaInfo.dll
MediaInfo_i386.dll
Просто создайте пока копию с такими именами.
Этим способом заработало. Спасибо.
Аватара пользователя
Orion9
Сообщения: 1283
Зарегистрирован: Пн янв 01, 2024 17:18

Сообщение Orion9 »

A55555
Да не за что. Надеюсь, вам эти функции еще не раз пригодятся, как и мне (а они мне очень даже зашли). Вот именно такими фичами и должен обрастаться коммандер - фичами, которые создают удобства и скрашивают повседневную жизнь. К сожалению, маэстро уже стар, чтобы это понимать, а ведь к таким проблемам и нуждам пользователей следует подходить с чистым и открытым умом ребенка )
A55555
Сообщения: 72
Зарегистрирован: Вс фев 06, 2011 10:50

Сообщение A55555 »

Orion9
если это не космически времязатратно, ваш механизм, который использует MediaInfo.dll, можно сделать чтоб он показывал какие аудиодорожки в видеофайле есть? Примерно вот так.

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

AUDIO
1. RUS, DTS-HD, 3386 Kbs
2. RUS, AC3, 128 Kbs
3. ENG, AC3, 256 Kbs
...
Может и видеопоток, примерно вот так

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

VIDEO
1. H265, 50 fps, 33850 Kbs 
Аватара пользователя
Orion9
Сообщения: 1283
Зарегистрирован: Пн янв 01, 2024 17:18

Сообщение Orion9 »

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