Тема: AHK: Инвертирование цвета окна с magnification + UIACCESS
Тема для обсуждения "Инвертирование цвета окна с magnification + UIACCESS".
http://forum.script-coding.com/viewtopic.php?id=17661
Вы не вошли. Пожалуйста, войдите или зарегистрируйтесь.
Страницы 1
Чтобы отправить ответ, вы должны войти или зарегистрироваться
Тема для обсуждения "Инвертирование цвета окна с magnification + UIACCESS".
http://forum.script-coding.com/viewtopic.php?id=17661
Этот код у меня вызывает перманентное мелькание, если активное окно изначально развёрнуто в полный экран. Вместо цикла я бы использовал хук, будет быстрее реагировать на изменение размеров окна, и меньше грузить процессор (сейчас на 10-15%).
И вместо CreateWindowInBand не проще сделать целевое окно окном-владельцем?
Этот код у меня вызывает перманентное мелькание, если активное окно изначально развёрнуто в полный экран.
Я такого не обнаружил, но пока тестировал получил мелькание при перезапуске скрипта.
Вроде поправил.
Вместо цикла я бы использовал хук, будет быстрее реагировать на изменение размеров окна, и меньше грузить процессор (сейчас на 10-15%).
Можно и хук использовать, только процессор это не разгрузит, а запарок будет больше, так как надо отслеживать не только изменения, но и z-order, чтобы менять гуи.
Так-как первый гуи (ZBID_DESKTOP) создается для случаев, когда целевое окно перекрывается другими окнами, второй же создается для случаев когда целевое окно активно и в нем могут создаваться дополнительные дочерние окна, дабы избежать мельканий создаем гуи с ZBID_UIACCESS.
Вот загрузка процессора без отслеживания измененя размеров:
if !RegExMatch(DllCall("GetCommandLine", "str"), " /restart(?!\S)")
{
if A_Is64bitOS
RunWait "C:\Program Files\AutoHotkey\AutoHotkeyU64_UIA.exe" /restart "%A_ScriptFullPath%"
else
RunWait "C:\Program Files\AutoHotkey\AutoHotkeyU32_UIA.exe" /restart "%A_ScriptFullPath%"
}
Global hPic
#SingleInstance Force
#MaxThreadsPerHotkey 2
DetectHiddenWindows, On
SetBatchLines -1
SetWinDelay -1
OnExit, Uninitialize
return
f11::
hTarget := WinExist("A")
if (hTarget = hTargetPrev)
{
hTargetPrev := ""
count--
return
}
count++
hTargetPrev := hTarget
if (hGui = "")
{
DllCall("LoadLibrary", "str", "magnification.dll")
DllCall("magnification.dll\MagInitialize")
Matrix := "-1|0|0|0|0|"
. "0|-1|0|0|0|"
. "0|0|-1|0|0|"
. "0|0|0|1|0|"
. "1|1|1|0|1"
VarSetCapacity(MAGCOLOREFFECT, 100, 0)
Loop, Parse, Matrix, |
NumPut(A_LoopField, MAGCOLOREFFECT, (A_Index - 1) * 4, "float")
loop 2
{
Gui, %A_Index%: +HWNDhGui%A_Index% -DPIScale +toolwindow -Caption +E0x02000000 +E0x00080000 +E0x20 ; WS_EX_COMPOSITED := E0x02000000 WS_EX_LAYERED := E0x00080000
Gui, %A_Index%: Margin, 0,0
Gui, %A_Index%: Add, text, w1 h1 0xE hwndhPic ; SS_BITMAP
if (A_Index = 2)
{
Gui, %A_Index%: +AlwaysOnTop
Gui, %A_Index%: Show, NA
}
hChildMagnifier%A_Index% := DllCall("CreateWindowInBand", "uint", 0, "str", "Magnifier", "str", "MagnifierWindow", "uint", WS_CHILD := 0x40000000, "int", 0, "int", 0, "int", 1, "int", 1, "ptr", hGui%A_Index%, "uint", 0, "ptr", DllCall("GetWindowLong" (A_PtrSize=8 ? "Ptr" : ""), "ptr", hGui%A_Index%, "int", GWL_HINSTANCE := -6 , "ptr"), "uint", 0, "uint", A_Index, "ptr") ; ZBID_DESKTOP ZBID_UIACCESS
DllCall("magnification.dll\MagSetColorEffect", "ptr", hChildMagnifier%A_Index%, "ptr", &MAGCOLOREFFECT)
DllCall("magnification.dll\MagSetImageScalingCallback", "ptr", hChildMagnifier%A_Index%, "ptr", RegisterCallback("MagImageScalingCallback"))
}
}
hGui := hGui2
hChildMagnifier := hChildMagnifier2
WinMove, ahk_id %hGui%,, 0, 0, A_ScreenWidth, A_ScreenHeight
WinMove, ahk_id %hChildMagnifier%,, 0, 0, A_ScreenWidth, A_ScreenHeight
WinShow ahk_id %hGui%
WinShow, ahk_id %hChildMagnifier%
loop
{
if (A_PtrSize = 8)
{
VarSetCapacity(RECT, 16, 0)
NumPut(0, RECT, 0, "int")
NumPut(0, RECT, 4, "int")
NumPut(A_ScreenWidth, RECT, 8, "int")
NumPut(A_ScreenHeight, RECT, 12, "int")
DllCall("magnification.dll\MagSetWindowSource", "ptr", hChildMagnifier, "ptr", &RECT)
}
}
return
MagImageScalingCallback(hwnd, srcdata, srcheader, destdata, destheader, unclipped, clipped, dirty)
{
Static CBM_INIT := 6, DIB_RGB_COLORS := 0, STM_SETIMAGE := 0x172, IMAGE_BITMAP := 0x0, _ := VarSetCapacity(BITMAPV5HEADER, 124, 0), __ := VarSetCapacity(BITMAPINFO, 44, 0)
if (A_PtrSize = 8)
{
bV5Width := NumGet(srcheader + 0, 0, "uint")
bV5Height := NumGet(srcheader + 0, 4, "uint")
}
else
{
bV5Width := srcheader
bV5Height := destdata
}
NumPut(124, BITMAPV5HEADER, 0, "uint") ; DWORD bV5Size;
NumPut(bV5Width, BITMAPV5HEADER, 4, "uint") ; LONG bV5Width;
NumPut(bV5Height, BITMAPV5HEADER, 8, "uint") ; LONG bV5Height;
NumPut(1, BITMAPV5HEADER, 12, "short") ; WORD bV5Planes;
NumPut(32, BITMAPV5HEADER, 14, "short") ; WORD bV5BitCount;
NumPut(44, BITMAPINFO, 0, "uint") ; DWORD biSize;
NumPut(bV5Width, BITMAPINFO, 4, "uint") ; LONG biWidth;
NumPut(-bV5Height, BITMAPINFO, 8, "uint") ; LONG biHeight;
NumPut(1, BITMAPINFO, 12, "short") ; WORD biPlanes;
NumPut(32, BITMAPINFO, 14, "short") ; WORD biBitCount;
hDC := DllCall("GetDC", "ptr", hwnd, "ptr")
hBMP := DllCall("CreateDIBitmap", "ptr", hDC, "ptr", &BITMAPV5HEADER, "uint", CBM_INIT, "ptr", srcdata, "ptr", &BITMAPINFO, "uint", DIB_RGB_COLORS, "ptr")
SendMessage, STM_SETIMAGE, IMAGE_BITMAP, hBMP,, ahk_id %hPic%
DllCall("DeleteObject", "ptr", ErrorLevel)
DllCall("DeleteDC", "ptr", hDC)
DllCall("DeleteObject", "ptr", hBMP)
return
}
Uninitialize:
if (hGui != "")
DllCall("magnification.dll\MagUninitialize")
ExitApp
И вместо CreateWindowInBand не проще сделать целевое окно окном-владельцем?
Пример можешь привести?
Так у меня на весь экран получается, и не выключается по F11, и загрузка ещё больше почему-то.
Пример можешь привести?
С окном из кода не пробовал, но в принципе так:
Gui, New, +hwndhGui
Gui, Show, w300 h300
Run notepad,,, PID
WinWait, ahk_pid %PID%
DllCall("SetWindowLong" . (A_PtrSize = 4 ? "" : "Ptr"), "Ptr", hGui, "Int", GWLP_HWNDPARENT := -8, "Ptr", WinExist())
WinActivate, ahk_id %hGui%
Он и не должен выключаться.
Это просто пример загрузки процессора при инвертировании экрана целиком.
С окном из кода не пробовал, но в принципе так:
Так не подходит, так-как не перекрываются созданные дочерние окна.
Как я понимаю, загрузка из-за этого цикла:
loop
{
if (A_PtrSize = 8)
{
VarSetCapacity(RECT, 16, 0)
NumPut(0, RECT, 0, "int")
NumPut(0, RECT, 4, "int")
NumPut(A_ScreenWidth, RECT, 8, "int")
NumPut(A_ScreenHeight, RECT, 12, "int")
DllCall("magnification.dll\MagSetWindowSource", "ptr", hChildMagnifier, "ptr", &RECT)
}
}
А без него никак?
Не, без него никак, но зато можно обойтись без callback.
Поправил первый пост.
Почему? По идее MagSetWindowSource должна вызываться, только когда область нужно менять.
Ну а как узнать, что нужно менять область?
Без колбека вообще процессор не подгружает.
Я чувствовал, что какой-то затык в коде.
Ну а как узнать, что нужно менять область?
Когда целевое окно меняет расположение.
Так оно может и не менять расположения.
Например при проигрывании видео в плеере.
А, теперь понял. Ну сейчас действительно уже не грузит.
Страницы 1
Чтобы отправить ответ, вы должны войти или зарегистрироваться