Немного посложнее пример. При активации окна блокнота картинка будет показываться в его верхнем левом углу и следовать за ним при передвижении, при деактивации будет пропадать. Картинка будет пропускать через себя клики мыши.
#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)
}
}