1

Тема: AHK: Gdip_HBitmapFromScreen минуя окно

Моя задача взять центр экрана, увеличить и показать картинку в том же центре. Как я могу это сделать, чтобы мое окно было "невидимым" для "Gdip_HBitmapFromScreen"?

Win10: LTSC (21H2); AHK: ANSI (v1.1.36.02)

2

Re: AHK: Gdip_HBitmapFromScreen минуя окно

А сначала получить bitmap, а потом показать окно не вариант?

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

3

Re: AHK: Gdip_HBitmapFromScreen минуя окно

Мне нужна картинка в реал тайме.

Win10: LTSC (21H2); AHK: ANSI (v1.1.36.02)

4 (изменено: __Михаил__, 2022-02-16 22:28:50)

Re: AHK: Gdip_HBitmapFromScreen минуя окно

Phoenixxx_Czar
Вроде как Gdip позволяет такое организовать 'Gdip_BitmapFromHWND(hwnd)'.

Win10x64, AHK v1.1.37.01 (Unicode 64-bit) | AHK-Wiki | Переменные и выражения | RegEx101

5

Re: AHK: Gdip_HBitmapFromScreen минуя окно

Здесь где-то был пост malcev'а про magnifier (то же, что экранная лупа), думаю, это то, что надо.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

6

Re: AHK: Gdip_HBitmapFromScreen минуя окно

__Михаил__, данный код выдает черный экран:

WinGet, hwnd, ID, A
pBitmap := Gdip_BitmapFromHWND(hwnd)
Win10: LTSC (21H2); AHK: ANSI (v1.1.36.02)

7 (изменено: __Михаил__, 2022-02-16 22:52:56)

Re: AHK: Gdip_HBitmapFromScreen минуя окно

Насколько помню не все окна выйдет заскриншотить, скрипт запускать нужно от админа. Если найду пример - скину.

Win10x64, AHK v1.1.37.01 (Unicode 64-bit) | AHK-Wiki | Переменные и выражения | RegEx101

8

Re: AHK: Gdip_HBitmapFromScreen минуя окно

У меня отключен UAC, но скрипты все равно запускаются дополнительно от имени админа.

Win10: LTSC (21H2); AHK: ANSI (v1.1.36.02)

9 (изменено: __Михаил__, 2022-02-16 23:57:13)

Re: AHK: Gdip_HBitmapFromScreen минуя окно

pToken := Gdip_Startup()
OnExit, Exit

X := 0,	Y := 0	; Позиция отображения.
hwnd := WinExist("ahk_Class Notepad")	; Окно по умолчанию, если нужно.
Return
;---------------------------
F3::	; Выбрать текущее окно для отображения:
hwnd := WinExist("A")
Return

F2::	; Вкл. / Выкл. отображение выбранного окна:
If !hwnd{
 ToolTip, Окно не указано!
 Return
}
If !(SW := !SW){
 Gui Destroy
 Return
}
GoSub, Show
Return
;-------------------------------------------------------------------------------------------------------
Show:
pBitmap := Gdip_BitmapFromHWND(hwnd)
Gdip_GetDimensions(pBitmap, w, h)
hBitmap := Gdip_CreateHBITMAPFromBitmap(pBitmap)
Gui -SysMenu +AlwaysOnTop +ToolWindow -Caption
Gui Margin, 0, 0
Gui Add, Text, hWndPic w%w% h%h% +0xE
PostMessage, 0x172, 0, hBitmap,, ahk_id %Pic%
Gui, Show, % "NoActivate x" X " y" Y, [Testing]
Gdip_DisposeImage(pBitmap), DeleteObject(hBitmap)
Return

Exit:
Gdip_Shutdown(pToken)
ExitApp
Win10x64, AHK v1.1.37.01 (Unicode 64-bit) | AHK-Wiki | Переменные и выражения | RegEx101

10

Re: AHK: Gdip_HBitmapFromScreen минуя окно

К сожалению на нужном окне черный экран.

Win10: LTSC (21H2); AHK: ANSI (v1.1.36.02)

11

Re: AHK: Gdip_HBitmapFromScreen минуя окно

Возможно инжект в окно или другие манипуляции смогут получить желаемое. Это уже вопрос к знатокам.

Win10x64, AHK v1.1.37.01 (Unicode 64-bit) | AHK-Wiki | Переменные и выражения | RegEx101

12

Re: AHK: Gdip_HBitmapFromScreen минуя окно

Проверьте, работает ли скрипт malcev'а с вашим окном.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

13

Re: AHK: Gdip_HBitmapFromScreen минуя окно

Я думаю стоит тогда переместить тему в раздел с вопросами связанные с играми. Думал раз "Gdip_HBitmapFromScreen" может взять поверх игры, значит и другое функции без проблем, но видать глубоко ошибался.

Win10: LTSC (21H2); AHK: ANSI (v1.1.36.02)

14

Re: AHK: Gdip_HBitmapFromScreen минуя окно

Вот попробуйте, это для win8+ чтоб было поверх всех окон.
Не будет работать с полноэкранными directx и с окнами у которых установлен SetWindowDisplayAffinity.

x := 500
y := 500
w := 320
h := 240

Gui, +HWNDhGui +AlwaysOnTop
DllCall("GetWindowBand", "ptr", hGui, "uint*", band)
Gui, Destroy
hGui := ""
if (band = 1)
{
   If (A_PtrSize = 8)
      RunWait "C:\Program Files\AutoHotkey\AutoHotkeyU64_UIA.exe" "%A_ScriptFullPath%"
   Else If A_IsUnicode
      RunWait "C:\Program Files\AutoHotkey\AutoHotkeyU32_UIA.exe" "%A_ScriptFullPath%"
   Else
      RunWait "C:\Program Files\AutoHotkey\AutoHotkeyA32_UIA.exe" "%A_ScriptFullPath%"
}
#SingleInstance Force
SetBatchLines -1
SetWinDelay -1
OnExit, Uninitialize 
Gui, +HWNDhGui -DPIScale -Caption +AlwaysOnTop +E0x02000000 +E0x00080000 +E0x20 ;  WS_EX_COMPOSITED := E0x02000000  WS_EX_LAYERED := E0x00080000
Gui, Show, x%x% y%y% w%w% h%h% NA

DllCall("LoadLibrary", "str", "magnification.dll")
DllCall("magnification.dll\MagInitialize")
hChildMagnifier := DllCall("CreateWindowEx", "UInt", 0, "Str", "Magnifier", "Str", "MagnifierWindow", "UInt", (WS_CHILD := 0x40000000)|(MS_INVERTCOLORS := 0x0004), "Int", 0, "Int", 0, "Int", w, "Int", h, "Ptr", hGui, "UInt", 0, "Ptr", DllCall("GetWindowLong" (A_PtrSize=8 ? "Ptr" : ""), "Ptr", hGui, "Int", GWL_HINSTANCE := -6 , "ptr"), "UInt", 0, "ptr")
WinShow, ahk_id %hChildMagnifier%
Loop
{
   if (A_PtrSize = 8)
   {
      VarSetCapacity(RECT, 16, 0)
      NumPut(x, RECT, 0, "Int")
      NumPut(y, RECT, 4, "Int")
      NumPut(w, RECT, 8, "Int")
      NumPut(h, RECT, 12, "Int")
      DllCall("magnification.dll\MagSetWindowSource", "Ptr", hChildMagnifier, "Ptr", &RECT)
   }
   else
      DllCall("magnification.dll\MagSetWindowSource", "Ptr", hChildMagnifier, "Int", x, "Int", y, "Int", w, "Int", h)
}
Return 

Uninitialize: 	
DllCall("magnification.dll\MagUninitialize")
ExitApp

15

Re: AHK: Gdip_HBitmapFromScreen минуя окно

Что-то такое появилось: http://s01.geekpic.net/di-FJUM06.png

Win10: LTSC (21H2); AHK: ANSI (v1.1.36.02)

16

Re: AHK: Gdip_HBitmapFromScreen минуя окно

Значит работает.
Размер изменяется примерно так:

x := 500
y := 500
w := 320
h := 240
ScaleFactor := 2

Gui, +HWNDhGui +AlwaysOnTop
DllCall("GetWindowBand", "ptr", hGui, "uint*", band)
Gui, Destroy
hGui := ""
if (band = 1)
{
   If (A_PtrSize = 8)
      RunWait "C:\Program Files\AutoHotkey\AutoHotkeyU64_UIA.exe" "%A_ScriptFullPath%"
   Else If A_IsUnicode
      RunWait "C:\Program Files\AutoHotkey\AutoHotkeyU32_UIA.exe" "%A_ScriptFullPath%"
   Else
      RunWait "C:\Program Files\AutoHotkey\AutoHotkeyA32_UIA.exe" "%A_ScriptFullPath%"
}
#SingleInstance Force
SetBatchLines -1
SetWinDelay -1
OnExit, Uninitialize 
Gui, +HWNDhGui -DPIScale -Caption +AlwaysOnTop +E0x02000000 +E0x00080000 +E0x20 ;  WS_EX_COMPOSITED := E0x02000000  WS_EX_LAYERED := E0x00080000
Gui, Margin, 0,0
Gui, Show, x%x% y%y% w%w% h%h% NA

DllCall("LoadLibrary", "str", "magnification.dll")
DllCall("magnification.dll\MagInitialize")
hChildMagnifier := DllCall("CreateWindowEx", "UInt", 0, "Str", "Magnifier", "Str", "MagnifierWindow", "UInt", (WS_CHILD := 0x40000000), "Int", 0, "Int", 0, "Int", w, "Int", h, "Ptr", hGui, "UInt", 0, "Ptr", DllCall("GetWindowLong" (A_PtrSize=8 ? "Ptr" : ""), "Ptr", hGui, "Int", GWL_HINSTANCE := -6 , "ptr"), "UInt", 0, "ptr")
Matrix := ScaleFactor "|0|0|"
        . "0|" ScaleFactor "|0|"
        . "0|0|1"  
VarSetCapacity(MAGTRANSFORM, 36, 0)
Loop, Parse, Matrix, |  
   NumPut(A_LoopField, MAGTRANSFORM, (A_Index - 1) * 4, "Float")
DllCall("magnification.dll\MagSetWindowTransform", "Ptr", hChildMagnifier, "Ptr", &MAGTRANSFORM)
WinShow, ahk_id %hChildMagnifier%
Loop
{
   if (A_PtrSize = 8)
   {
      VarSetCapacity(RECT, 16, 0)
      NumPut(x, RECT, 0, "Int")
      NumPut(y, RECT, 4, "Int")
      NumPut(w, RECT, 8, "Int")
      NumPut(h, RECT, 12, "Int")
      DllCall("magnification.dll\MagSetWindowSource", "Ptr", hChildMagnifier, "Ptr", &RECT)
   }
   else
      DllCall("magnification.dll\MagSetWindowSource", "Ptr", hChildMagnifier, "Int", x, "Int", y, "Int", w, "Int", h)
}
Return 

Uninitialize: 	
DllCall("magnification.dll\MagUninitialize")
ExitApp

17 (изменено: Phoenixxx_Czar, 2022-02-17 02:26:47)

Re: AHK: Gdip_HBitmapFromScreen минуя окно

Подскажите, зачем эти строки?

if (band = 1)
{
   If (A_PtrSize = 8)
      RunWait "C:\Program Files\AutoHotkey\AutoHotkeyU64_UIA.exe" "%A_ScriptFullPath%"
   Else If A_IsUnicode
      RunWait "C:\Program Files\AutoHotkey\AutoHotkeyU32_UIA.exe" "%A_ScriptFullPath%"
   Else
      RunWait "C:\Program Files\AutoHotkey\AutoHotkeyA32_UIA.exe" "%A_ScriptFullPath%"
}
Win10: LTSC (21H2); AHK: ANSI (v1.1.36.02)

18 (изменено: Malcev, 2022-02-17 02:33:43)

Re: AHK: Gdip_HBitmapFromScreen минуя окно

Чтобы было поверх всех окон.
https://blog.adeltax.com/window-z-order-in-windows-10/
Как обнаружил teadrinker запуск скрипта через AutoHotkey_UIA.exe with +AlwaysOnTop равносильно CreateWindowInBand with ZBID_UIACCESS.

19 (изменено: Phoenixxx_Czar, 2022-02-17 02:37:28)

Re: AHK: Gdip_HBitmapFromScreen минуя окно

Я закоментировал данные строки и все по прежнему работает.
У меня тут вопрос, я так понимаю обновляется оно в том вечном loop? Достаточно будет тот код вызывать по таймеру?
И тут еще такое дело.. Почему-то оно зумит со смещением:

+ открыть спойлер

http://s01.geekpic.net/di-ZLC78J.png

Так же хотелось бы узнать, как можно поменять scale в real time.

Win10: LTSC (21H2); AHK: ANSI (v1.1.36.02)

20

Re: AHK: Gdip_HBitmapFromScreen минуя окно

Phoenixxx_Czar пишет:

Я закоментировал данные строки и все по прежнему работает.

Я дал вам ссылку, где описано, где работать не будет.

Достаточно будет тот код вызывать по таймеру?

Да.

Почему-то оно зумит со смещением:

Не знаю почему. Может в игре меняются координаты, протестируйте с обычной картинкой.

как можно поменять scale в real time.

MagSetWindowTransform

21

Re: AHK: Gdip_HBitmapFromScreen минуя окно

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

Win10: LTSC (21H2); AHK: ANSI (v1.1.36.02)

22 (изменено: Phoenixxx_Czar, 2022-02-17 04:34:33)

Re: AHK: Gdip_HBitmapFromScreen минуя окно

Кхм.. У меня получилось сместить картинку с помощью:

DllCall("magnification.dll\MagSetWindowSource", "Ptr", hChildMagnifier, "Int", x + 18, "Int", y + 18, "Int", w, "Int", h)

Но выглядит что-то очень костыльно, размеры w, h по 100, scale 1.5. Как высчитать теперь эти 18 не особо понимаю.

UPD:
Кажется до меня долшло..

w := 100
h := 100
ScaleFactor := 2
winX := (A_ScreenWidth / 2) - (w / 2)
winY := (A_ScreenHeight / 2) - (h / 2)
x := (A_ScreenWidth / 2) -  ((w / 2) / ScaleFactor)
y := (A_ScreenHeight / 2) - ((h / 2) / ScaleFactor)
Win10: LTSC (21H2); AHK: ANSI (v1.1.36.02)