1

Тема: AHK, GUI: Как вывести по верх всех окон изображение.

Нужно вывести изображение по верх всех окон.(Если можно вывести в определенном окне изображение через параметр #ifWinActive?)
И нужно чтобы изображение не взаимодействовало с мышкой и клавишами.

2

Re: AHK, GUI: Как вывести по верх всех окон изображение.


Gui,WinPicture: +AlwaysOnTop -Caption +ToolWindow +Disabled
Gui,WinPicture: Add, Picture,,C:\	image.png						; путь к файлу изображения
Gui,WinPicture: Show,x100 y200 NoActivate
Return
Esc::
	ExitApp

Почитайте так же про GUI.

3

Re: AHK, GUI: Как вывести по верх всех окон изображение.

Немного посложнее пример. При активации окна блокнота картинка будет показываться в его верхнем левом углу и следовать за ним при передвижении, при деактивации будет пропадать. Картинка будет пропускать через себя клики мыши.

#NoEnv
SetBatchLines, -1

sFile := A_ScriptDir . "\ahk.png"
if !FileExist(sFile)
   URLDownloadToFile, https://i.imgur.com/SUIJf6w.png, % sFile

pictureWidth := 150

hGui := CreatePicture(sFile, pictureWidth)
BindToWindow(hGui, "Notepad")

CreatePicture(sFile, winWidth)  {
   static WS_EX_LAYERED := 0x80000, WS_EX_TRANSPARENT := 0x20

   Gui, New, % "-Caption +AlwaysOnTop +ToolWindow +hwndhGui +E" . Format("{:#x}", WS_EX_LAYERED|WS_EX_TRANSPARENT)
   Gui, Show, Hide

   pToken := GDIp.Gdip_Startup()

   pBitmap := GDIp.Gdip_CreateBitmapFromFile(sFile)
   width := GDIp.Gdip_GetImageWidth(pBitmap)
   height := GDIp.Gdip_GetImageHeight(pBitmap)
   hbm := GDIp.CreateDIBSection(winWidth, winHeight := winWidth/width*height)
   hdc := GDIp.CreateCompatibleDC()
   obm := GDIp.SelectObject(hdc, hbm)

   G := GDIp.Gdip_GraphicsFromHDC(hdc)
   GDIp.Gdip_SetInterpolationMode(G, 7)
   GDIp.Gdip_DrawImage(G, pBitmap, 0, 0, winWidth, winHeight, 0, 0, width, height)

   GDIp.UpdateLayeredWindow(hGui, hdc, 0, 0, winWidth, winHeight)

   GDIp.SelectObject(hdc, obm), GDIp.DeleteObject(hbm), GDIp.DeleteDC(hdc)
   GDIp.Gdip_DeleteGraphics(G), GDIp.Gdip_DisposeImage(pBitmap)
   GDIp.Gdip_Shutdown(pToken)
   
   Return hGui
}

BindToWindow(bound, winClass)  {
   static EVENT_OBJECT_LOCATIONCHANGE := 0x800B, hHook, oInfo := {}
   
   DllCall("RegisterShellHookWindow", Ptr, A_ScriptHwnd) 
   OnMessage( DllCall("RegisterWindowMessage", Str, "SHELLHOOK"), Func("ShellProc").Bind(bound, winClass) )
   
   oInfo.bound := bound, oInfo.parentWinClass := winClass
   pInfo := Object(oInfo)
   hHook := SetWinEventHook( EVENT_OBJECT_LOCATIONCHANGE, EVENT_OBJECT_LOCATIONCHANGE, 0
                           , RegisterCallback("HookProc", "F", 3, pInfo), 0, 0, 0 )
   ObjRelease(pInfo)
   OnExit( Func("Exit").Bind(A_ScriptHwnd, hHook) )
}

ShellProc(bound, parentWinClass, nCode, wParam)  {
   if (nCode = 4)  {  ; HSHELL_WINDOWACTIVATED := 4
      hwnd := wParam
      WinGetClass, winClass, ahk_id %hwnd%
      if (winClass != parentWinClass)
         Gui, %bound%:Show, Hide
      else  {
         VarSetCapacity(WINDOWPLACEMENT, size := 4*11, 0)
         NumPut(size, WINDOWPLACEMENT)
         DllCall("GetWindowPlacement", Ptr, hwnd, Ptr, &WINDOWPLACEMENT)
         for k, v in ["x", "y"]
            %v% := NumGet(WINDOWPLACEMENT, 4*(k + 6), "Int")
         Gui, %bound%:Show, % "NA x" . (x + 5) . " y" (y + 5)
      }
   }
}

SetWinEventHook(eventMin, eventMax, hmodWinEventProc, lpfnWinEventProc, idProcess, idThread, dwFlags)  {
   return DllCall("SetWinEventHook", UInt, eventMin, UInt, eventMax
                                   , Ptr, hmodWinEventProc, Ptr, lpfnWinEventProc
                                   , UInt, idProcess , UInt, idThread, UInt, dwFlags, Ptr)
}

HookProc(hWinEventHook, event, hwnd)  {
   oInfo := Object(A_EventInfo)
   parentWinClass := oInfo.parentWinClass, bound := oInfo.bound
   WinGetClass, winClass, ahk_id %hwnd%
   if (winClass != parentWinClass)
      Return
   
   WinGetPos, x, y,,, ahk_id %hwnd%
   Gui, %bound%:Show, % "NA x" . (x + 5) . " y" (y + 5)
}

Exit(shellHookWindow, winEventHook)  {
   DllCall("DeregisterShellHookWindow", Ptr, shellHookWindow)
   DllCall("UnhookWinEvent", Ptr, winEventHook)
}

class GDIp   {
   Gdip_Startup()  {
      if !DllCall("GetModuleHandle", Str, "gdiplus", Ptr)
         DllCall("LoadLibrary", Str, "gdiplus")
      VarSetCapacity(si, A_PtrSize = 8 ? 24 : 16, 0), si := Chr(1)
      DllCall("gdiplus\GdiplusStartup", PtrP, pToken, Ptr, &si, Ptr, 0)
      return pToken
   }

   Gdip_CreateBitmapFromFile(sFile)  {
      DllCall("gdiplus\GdipCreateBitmapFromFile", WStr, sFile, PtrP, pBitmap)
      return pBitmap
   }

   Gdip_GetImageWidth(pBitmap)  {
      DllCall("gdiplus\GdipGetImageWidth", Ptr, pBitmap, UIntP, Width)
      return Width
   }
   
   Gdip_GetImageHeight(pBitmap)  {
      DllCall("gdiplus\GdipGetImageHeight", Ptr, pBitmap, UIntP, Height)
      return Height
   }

   CreateDIBSection(w, h, hdc="", bpp=32, ByRef ppvBits=0)  {
      hdc2 := hdc ? hdc : this.GetDC()
      VarSetCapacity(bi, 40, 0)
      
      NumPut(w, bi, 4, "UInt"), NumPut(h, bi, 8, "UInt"), NumPut(40, bi, 0, "UInt")
      NumPut(1, bi, 12, "ushort"), NumPut(0, bi, 16, "uInt"), NumPut(bpp, bi, 14, "ushort")
      
      hbm := DllCall("CreateDIBSection", Ptr, hdc2, Ptr, &bi, UInt, 0, PtrP, ppvBits, Ptr, 0, UInt, 0, Ptr)

      if !hdc
         this.ReleaseDC(hdc2)
      return hbm
   }

   GetDC(hwnd=0)  {
      return DllCall("GetDC", Ptr, hwnd)
   }
   
   CreateCompatibleDC(hdc=0)  {
      return DllCall("CreateCompatibleDC", Ptr, hdc)
   }

   SelectObject(hdc, hgdiobj)  {
      return DllCall("SelectObject", Ptr, hdc, Ptr, hgdiobj)
   }

   Gdip_GraphicsFromHDC(hdc)  {
       DllCall("gdiplus\GdipCreateFromHDC", Ptr, hdc, PtrP, pGraphics)
       return pGraphics
   }

   Gdip_SetInterpolationMode(pGraphics, InterpolationMode)  {
      return DllCall("gdiplus\GdipSetInterpolationMode", Ptr, pGraphics, Int, InterpolationMode)
   }
   
   Gdip_DrawImage(pGraphics, pBitmap, dx, dy, dw, dh, sx, sy, sw, sh)  {
      Return DllCall("gdiplus\GdipDrawImageRectRect", Ptr, pGraphics, Ptr, pBitmap
                                                    , Float, dx, Float, dy, Float, dw, Float, dh
                                                    , Float, sx, Float, sy, Float, sw, Float, sh
                                                    , Int, 2, Ptr, 0, Ptr, 0, Ptr, 0)
   }
   
   UpdateLayeredWindow(hwnd, hdc, x="", y="", w="", h="", Alpha=255)  {
      if ((x != "") && (y != ""))
         VarSetCapacity(pt, 8), NumPut(x, pt, 0, "UInt"), NumPut(y, pt, 4, "UInt")

      if (w = "") ||(h = "")
         WinGetPos,,, w, h, ahk_id %hwnd%
      
      return DllCall("UpdateLayeredWindow", Ptr, hwnd, Ptr, 0, Ptr, ((x = "") && (y = "")) ? 0 : &pt
                                          , Int64P, w|h<<32, Ptr, hdc, Int64P, 0, UInt, 0
                                          , "UInt*", Alpha<<16|1<<24, UInt, 2)
   }

   ReleaseDC(hdc, hwnd=0)  {
      return DllCall("ReleaseDC", Ptr, hwnd, Ptr, hdc)
   }

   DeleteDC(hdc)  {
      return DllCall("DeleteDC", Ptr, hdc)
   }

   DeleteObject(hObject)  {
      return DllCall("DeleteObject", Ptr, hObject)
   }

   Gdip_DeleteGraphics(pGraphics)  {
      return DllCall("gdiplus\GdipDeleteGraphics", Ptr, pGraphics)
   }

   Gdip_DisposeImage(pBitmap)  {
      return DllCall("gdiplus\GdipDisposeImage", Ptr, pBitmap)
   }
   
   Gdip_Shutdown(pToken)  {
      DllCall("gdiplus\GdiplusShutdown", Ptr, pToken)
      if hModule := DllCall("GetModuleHandle", Str, "gdiplus", Ptr)
         DllCall("FreeLibrary", Ptr, hModule)
   }
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Skype dmitry_fiveg

4 (изменено: qqlexa, 2018-07-20 02:46:33)

Re: AHK, GUI: Как вывести по верх всех окон изображение.

Alt + Tab:
https://i.imgur.com/9rpUrmY.png

5

Re: AHK, GUI: Как вывести по верх всех окон изображение.

Это у вас окно браузера внизу? А если по нему кликнуть?

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

6

Re: AHK, GUI: Как вывести по верх всех окон изображение.

Хотя, сейчас проверил — на семёрке работает, на десятке — нет почему-то.

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

7

Re: AHK, GUI: Как вывести по верх всех окон изображение.

У меня на семёрке такой же эффект.

8

Re: AHK, GUI: Как вывести по верх всех окон изображение.

Вот так должно работать:

#NoEnv
SetBatchLines, -1

sFile := A_ScriptDir . "\ahk.png"
if !FileExist(sFile)
   URLDownloadToFile, https://i.imgur.com/SUIJf6w.png, % sFile

pictureWidth := 150

hGui := CreatePicture(sFile, pictureWidth)
BindToWindow(hGui, "Notepad")

CreatePicture(sFile, winWidth)  {
   static WS_EX_LAYERED := 0x80000, WS_EX_TRANSPARENT := 0x20

   Gui, New, % "-Caption +AlwaysOnTop +ToolWindow +hwndhGui +E" . Format("{:#x}", WS_EX_LAYERED|WS_EX_TRANSPARENT)
   Gui, Show, Hide

   pToken := GDIp.Gdip_Startup()

   pBitmap := GDIp.Gdip_CreateBitmapFromFile(sFile)
   width := GDIp.Gdip_GetImageWidth(pBitmap)
   height := GDIp.Gdip_GetImageHeight(pBitmap)
   hbm := GDIp.CreateDIBSection(winWidth, winHeight := winWidth/width*height)
   hdc := GDIp.CreateCompatibleDC()
   obm := GDIp.SelectObject(hdc, hbm)

   G := GDIp.Gdip_GraphicsFromHDC(hdc)
   GDIp.Gdip_SetInterpolationMode(G, 7)
   GDIp.Gdip_DrawImage(G, pBitmap, 0, 0, winWidth, winHeight, 0, 0, width, height)

   GDIp.UpdateLayeredWindow(hGui, hdc, 0, 0, winWidth, winHeight)

   GDIp.SelectObject(hdc, obm), GDIp.DeleteObject(hbm), GDIp.DeleteDC(hdc)
   GDIp.Gdip_DeleteGraphics(G), GDIp.Gdip_DisposeImage(pBitmap)
   GDIp.Gdip_Shutdown(pToken)
   
   Return hGui
}

BindToWindow(bound, winClass)  {
   static EVENT_OBJECT_DESTROY := 0x8001, EVENT_OBJECT_FOCUS := 0x8005
        , EVENT_OBJECT_LOCATIONCHANGE := 0x800B, hHook, oInfo := {}
   
   oInfo.bound := bound, oInfo.parentWinClass := winClass
   pInfo := Object(oInfo)
   hHook := SetWinEventHook( EVENT_OBJECT_DESTROY, EVENT_OBJECT_LOCATIONCHANGE, 0
                           , RegisterCallback("HookProc", "F", 4, pInfo), 0, 0, 0 )
   ObjRelease(pInfo)
   OnExit( Func("Exit").Bind(hHook) )
}

HookProc(hWinEventHook, event, hwnd, idObject)  {
   static EVENT_OBJECT_DESTROY := 0x8001, EVENT_OBJECT_FOCUS := 0x8005, EVENT_OBJECT_LOCATIONCHANGE := 0x800B
        , OBJID_CLIENT := 0xFFFFFFFC, oInfo, parentWinClass, bound
   
   if !oInfo  {
      oInfo := Object(A_EventInfo)
      parentWinClass := oInfo.parentWinClass, bound := oInfo.bound
   }
   
   if (event = EVENT_OBJECT_DESTROY || event = EVENT_OBJECT_FOCUS || event = EVENT_OBJECT_LOCATIONCHANGE)  {
      if !(event = EVENT_OBJECT_LOCATIONCHANGE || idObject = OBJID_CLIENT)
         Return
      
      if !hParent := WinActive("ahk_class " . parentWinClass)
         Gui, %bound%:Show, Hide
      else  {
         WinGetPos, x, y,,, ahk_id %hParent%
         Gui, %bound%:Show, % "NA x" . (x + 5) . " y" (y + 5)
      }
   }
}

SetWinEventHook(eventMin, eventMax, hmodWinEventProc, lpfnWinEventProc, idProcess, idThread, dwFlags)  {
   return DllCall("SetWinEventHook", UInt, eventMin, UInt, eventMax
                                   , Ptr, hmodWinEventProc, Ptr, lpfnWinEventProc
                                   , UInt, idProcess , UInt, idThread, UInt, dwFlags, Ptr)
}

Exit(winEventHook)  {
   DllCall("UnhookWinEvent", Ptr, winEventHook)
}

class GDIp   {
   Gdip_Startup()  {
      if !DllCall("GetModuleHandle", Str, "gdiplus", Ptr)
         DllCall("LoadLibrary", Str, "gdiplus")
      VarSetCapacity(si, A_PtrSize = 8 ? 24 : 16, 0), si := Chr(1)
      DllCall("gdiplus\GdiplusStartup", PtrP, pToken, Ptr, &si, Ptr, 0)
      return pToken
   }

   Gdip_CreateBitmapFromFile(sFile)  {
      DllCall("gdiplus\GdipCreateBitmapFromFile", WStr, sFile, PtrP, pBitmap)
      return pBitmap
   }

   Gdip_GetImageWidth(pBitmap)  {
      DllCall("gdiplus\GdipGetImageWidth", Ptr, pBitmap, UIntP, Width)
      return Width
   }
   
   Gdip_GetImageHeight(pBitmap)  {
      DllCall("gdiplus\GdipGetImageHeight", Ptr, pBitmap, UIntP, Height)
      return Height
   }

   CreateDIBSection(w, h, hdc="", bpp=32, ByRef ppvBits=0)  {
      hdc2 := hdc ? hdc : this.GetDC()
      VarSetCapacity(bi, 40, 0)
      
      NumPut(w, bi, 4, "UInt"), NumPut(h, bi, 8, "UInt"), NumPut(40, bi, 0, "UInt")
      NumPut(1, bi, 12, "ushort"), NumPut(0, bi, 16, "uInt"), NumPut(bpp, bi, 14, "ushort")
      
      hbm := DllCall("CreateDIBSection", Ptr, hdc2, Ptr, &bi, UInt, 0, PtrP, ppvBits, Ptr, 0, UInt, 0, Ptr)

      if !hdc
         this.ReleaseDC(hdc2)
      return hbm
   }

   GetDC(hwnd=0)  {
      return DllCall("GetDC", Ptr, hwnd)
   }
   
   CreateCompatibleDC(hdc=0)  {
      return DllCall("CreateCompatibleDC", Ptr, hdc)
   }

   SelectObject(hdc, hgdiobj)  {
      return DllCall("SelectObject", Ptr, hdc, Ptr, hgdiobj)
   }

   Gdip_GraphicsFromHDC(hdc)  {
       DllCall("gdiplus\GdipCreateFromHDC", Ptr, hdc, PtrP, pGraphics)
       return pGraphics
   }

   Gdip_SetInterpolationMode(pGraphics, InterpolationMode)  {
      return DllCall("gdiplus\GdipSetInterpolationMode", Ptr, pGraphics, Int, InterpolationMode)
   }
   
   Gdip_DrawImage(pGraphics, pBitmap, dx, dy, dw, dh, sx, sy, sw, sh)  {
      Return DllCall("gdiplus\GdipDrawImageRectRect", Ptr, pGraphics, Ptr, pBitmap
                                                    , Float, dx, Float, dy, Float, dw, Float, dh
                                                    , Float, sx, Float, sy, Float, sw, Float, sh
                                                    , Int, 2, Ptr, 0, Ptr, 0, Ptr, 0)
   }
   
   UpdateLayeredWindow(hwnd, hdc, x="", y="", w="", h="", Alpha=255)  {
      if ((x != "") && (y != ""))
         VarSetCapacity(pt, 8), NumPut(x, pt, 0, "UInt"), NumPut(y, pt, 4, "UInt")

      if (w = "") ||(h = "")
         WinGetPos,,, w, h, ahk_id %hwnd%
      
      return DllCall("UpdateLayeredWindow", Ptr, hwnd, Ptr, 0, Ptr, ((x = "") && (y = "")) ? 0 : &pt
                                          , Int64P, w|h<<32, Ptr, hdc, Int64P, 0, UInt, 0
                                          , "UInt*", Alpha<<16|1<<24, UInt, 2)
   }

   ReleaseDC(hdc, hwnd=0)  {
      return DllCall("ReleaseDC", Ptr, hwnd, Ptr, hdc)
   }

   DeleteDC(hdc)  {
      return DllCall("DeleteDC", Ptr, hdc)
   }

   DeleteObject(hObject)  {
      return DllCall("DeleteObject", Ptr, hObject)
   }

   Gdip_DeleteGraphics(pGraphics)  {
      return DllCall("gdiplus\GdipDeleteGraphics", Ptr, pGraphics)
   }

   Gdip_DisposeImage(pBitmap)  {
      return DllCall("gdiplus\GdipDisposeImage", Ptr, pBitmap)
   }
   
   Gdip_Shutdown(pToken)  {
      DllCall("gdiplus\GdiplusShutdown", Ptr, pToken)
      if hModule := DllCall("GetModuleHandle", Str, "gdiplus", Ptr)
         DllCall("FreeLibrary", Ptr, hModule)
   }
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Skype dmitry_fiveg

9

Re: AHK, GUI: Как вывести по верх всех окон изображение.

Насколько помню LAYERED окно не может быть дочерним до win10.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.30.03 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

10 (изменено: stealzy, 2018-07-25 20:06:11)

Re: AHK, GUI: Как вывести по верх всех окон изображение.

На Win7 Transcolor нормально работает с дочерними окнами. Другое дело я забыл, что дочернее окно не перемещается самостоятельно за родительским, так что хук нужен.

UPD:
s/дочернее окно/окно, имеющее владельца

11

Re: AHK, GUI: Как вывести по верх всех окон изображение.

stealzy пишет:

дочернее окно не перемещается самостоятельно за родительским

Нет, как раз прекрасно перемещается.

stealzy пишет:

На Win7 Transcolor нормально работает с дочерними окнами

У меня не работает.

Gui, +hwndhGuiParent
Gui, Color, Black 
Gui, Show, w444 h444

Gui, New, -Caption +ToolWindow +hwndhGuiChild +Parent%hGuiParent%
Gui, Color, EEAA99 
Gui, Add, Edit, w222 h222 x55 y55  
Gui, Show, w333 h333
WinSet, TransColor, EEAA99, ahk_id %hGuiChild% 
Return
По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.30.03 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

12

Re: AHK, GUI: Как вывести по верх всех окон изображение.

stealzy,

Windows 8:  The WS_EX_LAYERED style is supported for top-level windows and child windows. Previous Windows versions support WS_EX_LAYERED only for top-level windows.

https://msdn.microsoft.com/en-us/library/ms633540.aspx

13

Re: AHK, GUI: Как вывести по верх всех окон изображение.

Видимо, stealzy перепутал дочернее окно, и окно, у которого есть владелец (owner).

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

14

Re: AHK, GUI: Как вывести по верх всех окон изображение.

Malcev, я тоже это читал, но использовать пока рано, многие же на семёрке.

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

15

Re: AHK, GUI: Как вывести по верх всех окон изображение.

В таких случаях можно делать проверку ОС, хоть у кого то будет работать как должно.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.30.03 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

16

Re: AHK, GUI: Как вывести по верх всех окон изображение.

Нет, просто если делаешь скрипт только для себя, то можно применять эту фичу.

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

17 (изменено: Malcev, 2018-07-20 15:51:21)

Re: AHK, GUI: Как вывести по верх всех окон изображение.

teadrinker, в твоём коде из 8 поста не всегда соблюдается условие "Нужно вывести изображение по верх всех окон."
1) Сдвигаем окно блокнота так, чтобы картинка "AHK" была над кнопкой Start.
2) Нажимаем кнопку  Start.
3) Активируем окно блокнота.
В результате кнопка Start будет поверх картинки "AHK" при активированном блокноте.
А на Win10 вообще глючит - при закрытии блокнота картинка остантся.

18

Re: AHK, GUI: Как вывести по верх всех окон изображение.

Первое, честно говоря, не понял, у меня всё нормально, да и нужно ли так заморачиваться. В любом случае, если есть окно, которое AlwaysOnTop, такие окна будут конкурировать.
На десятке у меня тоже нормально работает, при закрытии пропадает. Там это событие специально обрабатывается — EVENT_OBJECT_DESTROY.

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

19

Re: AHK, GUI: Как вывести по верх всех окон изображение.

Возможно у меня был глюк в системе, но в Win10 этого не удалось повторить.
На счет Вин7 этот недостаток остался (он есть только при активации окна мышью).

20

Re: AHK, GUI: Как вывести по верх всех окон изображение.

Подскажите пожалуйста, как сделать так, чтобы такое изображение следовало за курсором?
Моя попытка сильно жрёт процессор и постоянно дёргается:


#SingleInstance, Force
#NoEnv
SetBatchLines, -1

#Include <GDIP_All>

If !pToken := Gdip_Startup()
{
	MsgBox, 48, gdiplus error!, Gdiplus failed to start. Please ensure you have gdiplus on your system
	ExitApp
}
OnExit, Exit

Width := A_ScreenWidth, Height := A_ScreenHeight
WS_EX_LAYERED := 0x80000, WS_EX_TRANSPARENT := 0x20
Gui, New, % "-Caption +AlwaysOnTop +ToolWindow +hwndhGui +E" . Format("{:#x}", WS_EX_LAYERED|WS_EX_TRANSPARENT)
Gui, Show, NA

hwnd1 := hGui

CallBack := RegisterCallback("MouseHook")
hook := SetWindowsHookEx(14, CallBack)
Return

DrawMyPic:
	hbm := CreateDIBSection(Width, Height)
	hdc := CreateCompatibleDC()
	obm := SelectObject(hdc, hbm)
	G := Gdip_GraphicsFromHDC(hdc)
	Gdip_SetSmoothingMode(G, 4)
	pBrush := Gdip_BrushCreateSolid(0x80ff0000)
	Gdip_FillEllipse(G, pBrush, xx-10, yy-10, 20, 20)
	Gdip_DeleteBrush(pBrush)
	UpdateLayeredWindow(hwnd1, hdc, 0, 0, Width, Height)
	SelectObject(hdc, obm)
	DeleteObject(hbm)
	DeleteDC(hdc)
	Gdip_DeleteGraphics(G)
Return

Esc::
Exit:
	if hook
		UnhookWindowsHookEx(hook)
	Gdip_Shutdown(pToken)
	ExitApp

MouseHook(nCode, wParam, lParam) {
    Global xx, yy
    Critical 1000
    if (nCode >= 0) {
        xx := NumGet(lParam+0, 0, "Int")
        yy := NumGet(lParam+0, 4, "Int")
        SetTimer, DrawMyPic, -1
    } Return CallNextHookEx(nCode, wParam, lParam)
}

SetWindowsHookEx(idHook, pfn) {
   Return DllCall("SetWindowsHookEx", "int", idHook, "Ptr", pfn, "Ptr", DllCall("GetModuleHandle", "Ptr", 0, "Ptr"), "UInt", 0)
}
CallNextHookEx(nCode, wParam, lParam, hHook = 0) {
   Return DllCall("CallNextHookEx", "Ptr", hHook, "int", nCode, "Ptr", wParam, "Ptr", lParam)
}
UnhookWindowsHookEx(hHook) {
   Return DllCall("UnhookWindowsHookEx", "Ptr", hHook)
}

21

Re: AHK, GUI: Как вывести по верх всех окон изображение.

Окно во весь экран заново переписывать, конечно тормозит.

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.30.03 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

22

Re: AHK, GUI: Как вывести по верх всех окон изображение.

Для начала так.

#SingleInstance, Force
#NoEnv
SetBatchLines, -1

#Include <GDIP_All>

If !pToken := Gdip_Startup()
{
	MsgBox, 48, gdiplus error!, Gdiplus failed to start. Please ensure you have gdiplus on your system
	ExitApp
}
OnExit, Exit

Width := 20, Height := 20
WS_EX_LAYERED := 0x80000, WS_EX_TRANSPARENT := 0x20
Gui, New, % "-Caption +AlwaysOnTop +ToolWindow +hwndhGui +E" . Format("{:#x}", WS_EX_LAYERED|WS_EX_TRANSPARENT)
Gui, Show, NA
hwnd1 := hGui 

hbm := CreateDIBSection(Width, Height)
hdc := CreateCompatibleDC()
obm := SelectObject(hdc, hbm)
G := Gdip_GraphicsFromHDC(hdc)
Gdip_SetSmoothingMode(G, 4)
pBrush := Gdip_BrushCreateSolid(0x80ff0000)
Gdip_FillEllipse(G, pBrush, 0, 0, 20, 20)
Gdip_DeleteBrush(pBrush) 
Gdip_DeleteGraphics(G)
DeleteObject(hbm)  
DeleteObject(obm)  

CallBack := RegisterCallback("MouseHook")
hook := SetWindowsHookEx(14, CallBack)
Return

DrawMyPic:
	UpdateLayeredWindow(hwnd1, hdc, xx, yy, Width, Height) 
Return

Esc::
Exit:
	if hook
		UnhookWindowsHookEx(hook)
	Gdip_Shutdown(pToken)
	DeleteDC(hdc)
	ExitApp

MouseHook(nCode, wParam, lParam) {
    Global xx, yy
    Critical 1000
    if (nCode >= 0) {
        xx := NumGet(lParam+0, 0, "Int")
        yy := NumGet(lParam+0, 4, "Int")
        SetTimer, DrawMyPic, -1
    } Return CallNextHookEx(nCode, wParam, lParam)
}

SetWindowsHookEx(idHook, pfn) {
   Return DllCall("SetWindowsHookEx", "int", idHook, "Ptr", pfn, "Ptr", DllCall("GetModuleHandle", "Ptr", 0, "Ptr"), "UInt", 0)
}
CallNextHookEx(nCode, wParam, lParam, hHook = 0) {
   Return DllCall("CallNextHookEx", "Ptr", hHook, "int", nCode, "Ptr", wParam, "Ptr", lParam)
}
UnhookWindowsHookEx(hHook) {
   Return DllCall("UnhookWindowsHookEx", "Ptr", hHook)
}
По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.30.03 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

23 (изменено: serzh82saratov, 2019-04-10 17:23:02)

Re: AHK, GUI: Как вывести по верх всех окон изображение.

Ну и hook тут неправильно использовать. Перехват тут не нужен, ожидание в хуке не есть хорошо, хотя и так "успевает":

#SingleInstance, Force
#NoEnv
SetBatchLines, -1

#Include <GDIP_All>

If !pToken := Gdip_Startup()
{
	MsgBox, 48, gdiplus error!, Gdiplus failed to start. Please ensure you have gdiplus on your system
	ExitApp
}
OnExit, Exit

Width := 20, Height := 20
WS_EX_LAYERED := 0x80000, WS_EX_TRANSPARENT := 0x20
Gui, New, % "-Caption +AlwaysOnTop +ToolWindow +hwndhGui +E" . Format("{:#x}", WS_EX_LAYERED|WS_EX_TRANSPARENT)
Gui, Show, NA
hwnd1 := hGui 

hbm := CreateDIBSection(Width, Height)
hdc := CreateCompatibleDC()
obm := SelectObject(hdc, hbm)
G := Gdip_GraphicsFromHDC(hdc)
Gdip_SetSmoothingMode(G, 4)
pBrush := Gdip_BrushCreateSolid(0x80ff0000)
Gdip_FillEllipse(G, pBrush, 0, 0, 20, 20)
Gdip_DeleteBrush(pBrush) 
Gdip_DeleteGraphics(G)
DeleteObject(hbm)  
DeleteObject(obm)  

CallBack := RegisterCallback("MouseHook")
hook := SetWindowsHookEx(14, CallBack)
Return 

Esc::
Exit:
	if hook
		UnhookWindowsHookEx(hook)
	Gdip_Shutdown(pToken)
	DeleteDC(hdc)
	ExitApp

MouseHook(nCode, wParam, lParam) {
    Global hwnd1, hdc, Width, Height
    if (nCode >= 0) {
        xx := NumGet(lParam+0, 0, "Int")
        yy := NumGet(lParam+0, 4, "Int")
        UpdateLayeredWindow(hwnd1, hdc, xx, yy, Width, Height) 
		; Gui, % hwnd1 ": +AlwaysOnTop"
    } Return CallNextHookEx(nCode, wParam, lParam)
}

SetWindowsHookEx(idHook, pfn) {
   Return DllCall("SetWindowsHookEx", "int", idHook, "Ptr", pfn, "Ptr", DllCall("GetModuleHandle", "Ptr", 0, "Ptr"), "UInt", 0)
}
CallNextHookEx(nCode, wParam, lParam, hHook = 0) {
   Return DllCall("CallNextHookEx", "Ptr", hHook, "int", nCode, "Ptr", wParam, "Ptr", lParam)
}
UnhookWindowsHookEx(hHook) {
   Return DllCall("UnhookWindowsHookEx", "Ptr", hHook)
}

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

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.30.03 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui

24

Re: AHK, GUI: Как вывести по верх всех окон изображение.

serzh82saratov пишет:

Я бы ещё на HID попробовал отследить

Буду Вам благодарен за пример!

25

Re: AHK, GUI: Как вывести по верх всех окон изображение.

Последний нормально работает?

По вопросам возмездной помощи пишите на E-Mail: serzh82saratov@mail.ru
OS: Win7x64, AutoHotkey_L v1.1.30.03 (Unicode 32-bit). AhkSpy, Hotkey, ClockGui