Orion9

|
Posted: Sat Sep 06, 2025 00:42 Post subject: |
|
|
Loopback
Помнится, делал корректировку на масштабирование экрана в подсказке к главной панели инструментов несколько страниц назад, тогда использовал такой метод:
Code: | # дескриптор монитора окна ТС
Local hMon = DllCall("MonitorFromWindow", "hwnd", AUTORUN_TCHANDLE, "dword", 2)
# информация о масштабировании экрана
Local nScale = 0, bRes
bRes = DllCall("Shcore.dll\GetScaleFactorForMonitor", "hwnd", hMon, "dword*", @nScale)
|
Но предложенные вами функции выглядят более основательно, поэтому буду использовать их. Слышал, что для полноты картины нужно ещё учитывать размер текста, который пользователь тоже может увеличить в настройках системы в разделе специальных возможностей. Один из способов - чтение значения из реестра:
Code: | RegRead nTextScale "HKCU\Software\Microsoft\Accessibility" "TextScaleFactor" 100
nTextScale = Round(nTextScale/100,2) |
Далее умножить полученный коэффициент на необходимое значение, т.е.
Code: | h_WinShutdown = DllCall("CreateWindowExW", _
"dword", 0, _
"wstr", "msctls_progress32", _
"wstr", "", _
"dword", 0x10C80000, _
"int", 200, "int", 100, "int", Round(Scale(300)*nTextScale,0), "int", Scale(50), _
"handle", AUTORUN_TCHANDLE, _
"handle", 0, "handle", 0, "ptr", 0, _
"handle") |
В общем, вот полный обновленный код всего, что ранее было, включая две разные функции для получения значения масштабирования:  Hidden text Code: | 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 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", 0x10C80000, _
"int", 200, "int", 100, "int", Round(Scale(300)*nTextScale,0), "int", Scale(50), _
"handle", AUTORUN_TCHANDLE, _
"handle", 0, "handle", 0, "ptr", 0, _
"handle")
If h_WinShutdown = 0 Then Return 0
WinAlign(h_WinShutdown, 0, DllCall("GetDesktopWindow"))
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
# установка значения прозрачности
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 |
Loopback wrote: | В каком смысле затенить? |
Как было в ХР при выключении системы: фон затенялся и становился нецветным, а окно с выбором действия оставалось в цвете поверх него. Но думаю, сейчас это не надо - прозрачность даже лучше. Словно призрак остается от комманндера, стоящий лишь в один шаг от полного исчезновения вместе с системой ))
A55555 wrote: | Но этому окну отсчета напрашивается отображение поверх всех окон. |
Наверное, можно. Надо глянуть. Может, автор плагина ответ уже знает? |
|