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

Добавлено: Ср сен 03, 2025 17:00
Orion9
A55555
Наверное, можно. Может быть, даже есть не один способ. Наверняка, Loopback знает некое эффективное и красивое решение, но как вариант можно отслеживать доступность окна копирования в отдельном потоке, и когда окно станет недоступным, т.е. закроется, можно приступать к выключению ПК простым выполнением команды shutdown.

Добавлено: Ср сен 03, 2025 17:33
A55555
Orion9
спасибо за ответ.

Готовое решение это только, если кому-то не лень будет сделать для того кто в этом не разбирается?

Добавлено: Ср сен 03, 2025 18:11
jentoso
A55555
Есть наверно ещё нюанс(ы). О каком именно копировании идёт речь.
Копирование с диска на диск или копирование по сети. А что делать, если сбой копирования, закрыть и выключить или ничего не делать.

Добавлено: Ср сен 03, 2025 18:13
Orion9
A55555
Думаю, результата при помощи Autorun можно достичь так или иначе, но не уверен, что такой результат (особенно если большой ценой) действительно нужен. По-моему, лучше использовать готовые решения в виде сторонних утилит, вроде TeraCopy или FastCopy, которые при желании можно использовать и из ТС, если такие операции, как выключение компьютера после копирования, требуются часто и на постоянной основе.

Добавлено: Ср сен 03, 2025 19:27
Loopback
Orion9 писал(а):Замутил я тут одну тему
Ну что сказать, весьма интересно, всё работает, положу в копилку. Хотя сейчас, при практически повсеместном распространении SSD проблема фрагментации, кажется, не очень актуальна. За последние лет десять мне Contig потребовался только пару раз для бокса Zalman VE200, там прошивка не читает iso-файлы, если число фрагментов больше какого-то количества. Но это всё же специфичный случай.
Orion9 писал(а):Иногда в поле попадают такие записи, как "1/3" или "10/42" и т.д. Первое число - количество фрагментов на разделе. Второе - в файловой записи. Вероятно, это следствие работы программ-дефрагментаторов, которые после дефрагментации файла
Что-то сомневаюсь, тестировал на дисках виртуалок, такая ситуация наблюдается почти везде, хотя я накопитель, где они находятся, никогда не дефрагментировал, даже системная задача дефрагментации отключена.
A55555 писал(а):При помощи данного плагина можно сделать выключение ПК после окончания копирования в TC?
Если без визуальных удобств в виде кнопочки "Выключить по завершении", то можно достаточно просто. Метод - как был предложен Orion9, это самое простое, остальное сложнее.

Включение мониторинга через горячую клавишу Ctrl+Alt+O, разумеется, ее можно поменять. При её нажатии, если обнаружено открытое окно копирования, функция начинает мониторить его, и когда оно закроется - запустит выключение компьютера.

По хорошему ещё надо бы учесть и как-то обрабатывать диалог, который может появляться при ошибке. Да и возможность отмены мониторинга не помешала бы.

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

LoadLibrary Plugins\Autorun_Runtime.dll
LoadLibrary Plugins\Autorun_Tweaks.dll

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

Func CopyMonitor()
    Static hCopyWnd = 0
    # Если монитор уже запущен - выходим
    If hCopyWnd <> 0 Then Return 
    hCopyWnd = WinFind(0, "TDLG2FILEACTIONMIN")
    If hCopyWnd = 0 Then
        ShowHint("Копирование не запущено", 0, 0, 1000, 1)
        WinAlign(LAST_HINT_WINDOW)
        Return
    EndIf
    ShowHint("Монитор выключения запущен, ожидание завершения копирования...", 0, 0, 5000, 1)
    WinAlign(LAST_HINT_WINDOW)
    While hCopyWnd <> 0
        Sleep(1000)
        hCopyWnd = WinFind(0, "TDLG2FILEACTIONMIN")
    Wend
    ShellExec("shutdown", "/s /t 60") # можно добавить /f для принудительного закрытия приложений
EndFunc 

Добавлено: Ср сен 03, 2025 22:41
A55555
Loopback
спасибо.

Где взять библиотеку Autorun_Runtime.dll, её нет по умолчанию в папке Plugins?

Добавлено: Ср сен 03, 2025 23:16
Orion9
Loopback писал(а):Хотя сейчас, при практически повсеместном распространении SSD проблема фрагментации, кажется, не очень актуальна.
Так и есть. Хотя еще рано списывать HDD со счетов. Все зависит от задач и бюджета, но есть и долгожители, которые годами служат верой и правдой и которые, к сожалению, могут посыпаться. Вот тогда и будет нужна такая программа, как BadNTFS, чтобы продлить жизнь старичкам (не всем, конечно, а тем, кому поможет). По принципу работы она похожа ни Victoria, только работает на уровне кластеров, а не секторов. Так же делает скан поверхности и выявляет нестабильные участки, которые можно пометить как бэды на уровне файловой системы, чтобы ОС к ним больше не обращалась. Лог у этой утилиты примерно такой:

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

Unstable cluster detected in range 217616842-217616905 [226 ms] 

Unstable cluster detected in range 217619338-217619401 [125 ms] 
Unstable cluster: 217619838 [165 ms] [FREE]
Unstable cluster: 217620298 [852 ms] [FREE]
Unstable cluster: 217620305 [476 ms] [FREE]

Unstable cluster detected in range 217621450-217621513 [1506 ms] 

Unstable cluster detected in range 217622602-217622665 [1007 ms] 

Unstable cluster detected in range 217624202-217624265 [858 ms] 

Unstable cluster detected in range 217627402-217627465 [1736 ms] 
Если кластер ничем не занят, то она так и пишет [FREE], в противном случае остается не ясным, какие файлы могут находится в диапазоне. Вот здесь и может пригодится поле "FragEntry" для поиска таких файлов.
Loopback писал(а):Что-то сомневаюсь, тестировал на дисках виртуалок, такая ситуация наблюдается почти везде
Видимо, так и есть. Возможно система, сама создает такие цепочки, хотя они вообще-то смежные и являются одной непрерывной областью. Может быть, это обусловленно задержками во время записи или еще какой-то спецификой работы ОС, о которой простому пользователю не известно. Чтобы разбираться в таких тонкостях, нужны более глубокие знания.
Loopback писал(а):Да и возможность отмены мониторинга не помешала бы.
Это точно. Можно сделать еще одну переменную и добавить проверку в цикл, чтобы выходить из него при повторном нажатии, если он уже запущен. Также можно сделать задержку с 1-2 минуты после завершения непрерванного цикла, чтобы у пользователя была возможность отменить операцию после ее завершения. В общем, тема такая, что всегда найдется где и что улучшить.
A55555 писал(а):Где взять библиотеку Autorun_Runtime.dll, её нет по умолчанию в папке Plugins?
Какая у вас версия плагина? Возьмите Autorun 2.2.19.1 отсюда:
https://total.darkhost.ru/wiki/doku.php?id=ru:autorun

Добавлено: Чт сен 04, 2025 12:48
A55555
Orion9 писал(а):Какая у вас версия плагина? Возьмите Autorun 2.2.19.1 отсюда:
https://total.darkhost.ru/wiki/doku.php?id=ru:autorun
Спасибо. Скачал. Сегодня попробую.
У меня 2.1.1

Но очень удивительно, что за столько лет, такая функция не появилась в доп.опциях диалога копирования TC по умолчанию или готовым плагином, чтоб человек мог выбрать выключить/сон/выйти_из_TC и т.п. по окончании копирования и т.п.
Пусть не часто, но люди копируют время от времени бекапы на жестких дисках и т.д., пускай даже +-30 минут показывает, включил и пошел спать/по_делам, зная, что все выключится и т.п. сценарии.

Мой случай это копирование с SSD на большой жесткий диск накопившегося количества понравившегося кино/концертов.

Добавлено: Чт сен 04, 2025 19:45
Orion9
A55555 писал(а):Но очень удивительно, что за столько лет
Скорее всего фичу запрашивали, но Гислер отказался ее делать по какой-то причине. Если она вам действительно нужна, можете попробовать запросить ее на официальном форуме. А можете привлечь и сторонний софт, почему обязательно ТС.

Можно порешать и через Autorun, но у Гислера больше возможностей. Тут ведь опции в диалог нужно встраивать, чтобы все красиво было, а Autorun не может этого предложить. Работа с элементами интерфейса в Autorun требует больших усилий и по большому счету не стоит того. А управлять горячими клавишами процессом выключения ПК, ну не знаю... Не уверен, что это действительно удобно.

И всё же, если вы установили Autorun, попробуйте в качестве теста такой вариант:
[cut]

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

RegisterCommand 808000 "WinShutdown"

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

Global h_WinShutdown
Global g_WinShutdown, g_Shutdown = 0
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    
    h_WinShutdown = DllCall("CreateWindowExW", _
                            "dword", 0, _
                            "wstr", "msctls_progress32", _
                            "wstr", "", _
                            "dword", 0x10C80000, _
                            "int", 200, "int", 100, "int", 300, "int", 50, _
                            "handle", AUTORUN_TCHANDLE, _
                            "handle", 0, "handle", 0, "ptr", 0, _
                            "handle")
                   
    If h_WinShutdown = 0 Then Return 0
    
    WinAlign(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 
       MsgBox("Выключение ПК отменено", "", 48)
    Else       
       If DllCall("DestroyWindow", "handle", h_WinShutdown) Then h_WinShutdown = 0
       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

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
    ShowHint("Монитор выключения запущен, ожидание завершения копирования...", 0, 0, 1000, 1)
    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
    If g_CopyMonitor Then
       g_CopyMonitor = false
       WinShutdown()
    Else
       ShowHint("Монитор выключения остановлен", 0, 0, 1000, 1)
       WinAlign(LAST_HINT_WINDOW)
    EndIf   
    #ShellExec("shutdown", "/s /t 60") # можно добавить /f для принудительного закрытия приложений
EndFunc 
[/cut]
Это своего рода развите кода, предложенного Loopback.

Ctrl+Alt+O - включает и выключает ожидание завершения процесса копирования, чтобы после него выключить ПК. Если включено, то после завершения копирования появится дополнительное окно отсчета 100 секунд до выключения ПК с возможностью отмены. Самого выключения пока не произойдет, т.к. я его отключил (закомментировал строку) во избежания проблем на время тестов. Если всё устроит, можно будет включить назад.

Кстати, окно отсчета до завершения можно вызвать отдельной кнопкой для визуального теста:

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

TOTALCMD#BAR#DATA
808000

%COMMANDER_EXE%
808000


-1
Я бы поучавствовал глубже в разработке и тестах при прочих обстоятельствах, но сейчас у меня действительно много срочных дел, т.ч. если Loopback продолжит развивать эту тему, то расчитывать вам можно будет, наверное, только на него.

Добавлено: Чт сен 04, 2025 22:17
A55555
Loopback
спасибо, ваш код работает.

Orion9
[s]ругается при старте TC[/s]
[cut]Изображение[/cut]
[s]хотя эта строка идентична той что в коде Loopback[/s]
добавил строки из кода Loopback заработало,

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

LoadLibrary Plugins\Autorun_Runtime.dll
LoadLibrary Plugins\Autorun_Tweaks.dll
но очень маленькое окошко со строкой отсчета времени до выключения
[cut]Изображение[/cut]
и оно не появляется, если твое окно TC неактивно, например ты в браузере, а TC свётрнут, то этого окна не будет после окончания копирования при ранее запущенном процессе выключения (только восклицательный звук Windows), даже если активировать окно TC после окончания копирования, чтоб увидеть отсчет (сам процесс невидимо без этой визуализации идет и Windows сообщение Выключение ПК выскочит).
И раз этого окна нет, то и шанса остановить процесс выключения тоже нет.
Но это уже такое, большое спасибо за ваш вариант.

После нажатия Ctrl+Alt+O, пока идет копирование, сообщение о старте отсчета очень мелкое, как и о том что копирование не запущено :( Очень трудно заметить. Ещё и быстро исчезает.

Добавлено: Чт сен 04, 2025 23:37
Orion9
A55555 писал(а):но очень маленькое окошко со строкой отсчета времени до выключения
Окно в том виде, в котором оно есть, конечно, только для примера. Его размеры можно изменить. Но...
A55555 писал(а):и оно не появляется, если твое окно TC неактивно, например ты в браузере, а TC свётрнут
А какая у вас система? Что-то я не могу вот так с ходу определить ее по вашему окну.

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

Но если код будет развиваться, то вот пришла одна прикольная мысля. Замените у себя функцию 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)
    ShowHint("Монитор выключения запущен, ожидание завершения копирования...", 0, 0, 1000, 1)
    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
    If g_CopyMonitor Then
       g_CopyMonitor = false
       WinShutdown()
    Else
       ShowHint("Монитор выключения остановлен", 0, 0, 1000, 1)
       WinAlign(LAST_HINT_WINDOW)
    EndIf
    DllCall("SetLayeredWindowAttributes", "hwnd", AUTORUN_TCHANDLE, _ 
                                          "ptr", 0, "byte", 255, "dword", 2)
EndFunc 
[/cut]
Здесь я добавил переключение прозрачности окна ТС, взяв пример из справки. Теперь стало намного понятнее, когда включена функция отключения ПК. Если Loopback знает, как затенить окно, будет вообще супер.

P.S. у меня сечас просто период такой тяжелый, что со временем совсем туго, и это длится уже давно, и просвета не видно. Тот код, что я сбрасывал на предыдущей странице, я делал где-то дней 10, выкраивая буквально по часику в день. Но боюсь, сейчас и этого не смогу себе позволить. Т.ч. если Loopback или кто-то другой продолжит развитие данного кода, буду только "за" )

Добавлено: Пт сен 05, 2025 12:30
Orion9
A55555 писал(а):например ты в браузере, а TC свётрнут, то этого окна не будет после окончания копирования при ранее запущенном процессе выключения (только восклицательный звук Windows), даже если активировать окно TC после окончания копирования, чтоб увидеть отсчет (сам процесс невидимо без этой визуализации идет и Windows сообщение Выключение ПК выскочит).
Прикольный глюк. Как оказалось, он связан с функцией выравнивания окна "WinAlign". Может, Loopback глянет, в чём там может быть проблема, а пока можно выравнивать по центру рабочего стола. Для этого нужно заменить строку WinAlign(h_WinShutdown) на WinAlign(h_WinShutdown, 0, DllCall("GetDesktopWindow")). Я не буду скидывать весь код, просто замените фрагмент на новый:

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

    h_WinShutdown = DllCall("CreateWindowExW", _
                            "dword", 0, _
                            "wstr", "msctls_progress32", _
                            "wstr", "", _
                            "dword", 0x10C80000, _
                            "int", 200, "int", 100, "int", 500, "int", 55, _
                            "handle", AUTORUN_TCHANDLE, _
                            "handle", 0, "handle", 0, "ptr", 0, _
                            "handle")
                   
    If h_WinShutdown = 0 Then Return 0
    
    WinAlign(h_WinShutdown, 0, DllCall("GetDesktopWindow")) 

Здесь я также увеличил ширину и высоту окна соответственно на значения "int", 500, "int", 55.

Поменять стиль подсказки и время ее отображения также можно по вкусу. Вот например (снова замените всю функцию CopyMonitor):

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

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)
    #параметры подсказки                                      
    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
    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, 9)
    DllCall("SetLayeredWindowAttributes", "hwnd", AUTORUN_TCHANDLE, _ 
                                          "ptr", 0, "byte", 255, "dword", 2)
EndFunc 
Теперь действительно смотрится лучше. А вообще могу сказать, пока мне выдалась возможность "погонять" немножко, вещь-то получилась прикольная, но ее нужно доделывать и больше тестировать. Например, сейчас не предусмотрено, что делать, если нажать кнопку "В фоне", а ведь наверняка найдутся и прочие мелкие нюансы.

Добавлено: Пт сен 05, 2025 12:50
A55555
Orion9 писал(а): А какая у вас система? Что-то я не могу вот так с ходу определить ее по вашему окну.
Win11
Монитор 2560*1440
TC 11.51 (64bit)
Orion9 писал(а):Но если код будет развиваться, то вот пришла одна прикольная мысля. Замените у себя функцию CopyMonitor() на эту:
Orion9 писал(а):Прикольный глюк. Как оказалось, он связан с функцией выравнивания окна "WinAlign". Может, Loopback глянет, в чём там может быть проблема, а пока можно выравнивать по центру рабочего стола. Для этого нужно заменить строку WinAlign(h_WinShutdown) на WinAlign(h_WinShutdown, 0, DllCall("GetDesktopWindow")). Я не буду скидывать весь код, просто замените фрагмент на новый:
Orion9 писал(а):Поменять стиль подсказки и время ее отображения также можно по вкусу. Вот например (снова замените всю функцию CopyMonitor):
Спасибо. Я сегодня попробую.

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

 #параметры подсказки                                     
    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) 
Каким параметром время отображения подсказки устанавливается?
Я не смог понять как например увеличить.

Добавлено: Пт сен 05, 2025 18:31
Loopback
Orion9 писал(а):Его размеры можно изменить. Но...
Да, таких заморочек возникает масса. По скрину видно, что стоит большое значение масштабирования в системе, при динамическом создании окна это надо учитывать и корректировать его размеры. Чтобы хорошо смотрелось везде, можно примерно такой алгоритм использовать:

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

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
Использовать так:

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

    h_WinShutdown = DllCall("CreateWindowExW", _
                            "dword", 0, _
                            "wstr", "msctls_progress32", _
                            "wstr", "", _
                            "dword", 0x10C80000, _
                            "int", 200, "int", 100, _
                            "int", Scale(300), "int", Scale(50), _
                            "handle", AUTORUN_TCHANDLE, _
                            "handle", 0, "handle", 0, "ptr", 0, _
                            "handle")
Кстати, добавлю макрос для DPI в sysinfo. Тогда GetDPI будет не нужна.
Orion9 писал(а):как затенить окно
В каком смысле затенить?
Orion9 писал(а): Может, Loopback глянет, в чём там может быть проблема
Да тут и смотреть нечего, очевидно что проблема в том, что для свернутого окна возвращаются такие координаты, что при расчёте окно улетает за пределы экрана. Надо добавить проверку в WinAlign и для свёрнутого базового окна ничего не делать.
A55555 писал(а):Каким параметром время отображения подсказки устанавливается?
ShowHint("Монитор выключения запущен, ожидание завершения копирования", 0, 0, 1000, 1)

Время задержки в мс.

Добавлено: Пт сен 05, 2025 23:20
A55555
Orion9 писал(а):Прикольный глюк. Как оказалось, он связан с функцией выравнивания окна "WinAlign". Может, Loopback глянет, в чём там может быть проблема, а пока можно выравнивать по центру рабочего стола. Для этого нужно заменить строку WinAlign(h_WinShutdown) на WinAlign(h_WinShutdown, 0, DllCall("GetDesktopWindow")). Я не буду скидывать весь код, просто замените фрагмент на новый:
Спасибо, теперь окно видно нормально и когда TC был свернут в момент исчезновения окна копирования TC.
Но этому окну отсчета напрашивается отображение поверх всех окон.
Loopback писал(а): По скрину видно, что стоит большое значение масштабирования в системе, при динамическом создании окна это надо учитывать и корректировать его размеры. Чтобы хорошо смотрелось везде, можно примерно такой алгоритм использовать:

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

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
Использовать так:

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

    h_WinShutdown = DllCall("CreateWindowExW", _
                            "dword", 0, _
                            "wstr", "msctls_progress32", _
                            "wstr", "", _
                            "dword", 0x10C80000, _
                            "int", 200, "int", 100, _
                            "int", Scale(300), "int", Scale(50), _
                            "handle", AUTORUN_TCHANDLE, _
                            "handle", 0, "handle", 0, "ptr", 0, _
                            "handle")
Loopback
Спасибо. Ваш вариант тоже работает.
Orion9 писал(а):Теперь действительно смотрится лучше.
Да, ничего не скажешь, наглядно и прикольно прозрачность смотрится, аж захотелось на постоянно добавить окну TC прозрачности немного.