Resolve flickering gui attached to a window

Get help with using AutoHotkey and its commands and hotkeys
alesyt0h
Posts: 194
Joined: 28 Jan 2015, 20:37

Resolve flickering gui attached to a window

09 Apr 2019, 05:08

Hello

I have this script

Code: Select all

SetBatchLines -1
SetWinDelay,0
WinWaitActive, Documentos
WinGetActiveStats,Title, Width,Height,X,Y 
Gui,+AlwaysOnTop +ToolWindow -Caption
Gui, Add,Picture,x1 y1 w32 h32,C:\Users\alesyt0h\Downloads\ExampleImage.jpg
Gui, Show,% "x" X + Width - 145 "." "y" Y + Height - 35 "." "w32 h32 NA",
SetTimer,MoveW,100
Return

MoveW:
IfWinNotActive, Documentos
Gui,Hide
Else
{
WinGetActiveStats,Title, Width,Height,X,Y
Gui, Show,% "x" X + Width - 145 "." "y" Y + Height - 35 "." "w32 h32 NA",
}
Return

Home::
Reload
Return

GuiClose:
ExitApp
Is working fine, but when I drag the main window it happens this:

Image

How I can fix this?

Thank you
WalkerOfTheDay
Posts: 471
Joined: 24 Mar 2016, 03:01

Re: Resolve flickering gui attached to a window

09 Apr 2019, 07:10

I'm not seeing any flickering ?
just me
Posts: 6557
Joined: 02 Oct 2013, 08:51
Location: Germany

Re: Resolve flickering gui attached to a window

09 Apr 2019, 09:00

You might want to try

Code: Select all

SetTimer, MoveW, 1
and check within the timer whether the position and/or size of the Documentos window have actually changed.
swagfag
Posts: 3075
Joined: 11 Jan 2017, 17:59

Re: Resolve flickering gui attached to a window

09 Apr 2019, 11:42

dont see any flickering same as walkeroftheday. ur timer refreshes too slowly = laggy appearance
User avatar
lvalkov
Posts: 39
Joined: 08 Mar 2019, 16:39

Re: Resolve flickering gui attached to a window

09 Apr 2019, 14:15

Below are three ways of approaching the task of "attaching an overlay window to another window". The easiest and most straightforward way of implementing this is simply endlessly polling for the dimensions of your main window and readjusting the overlay window accordingly. In essence, all examples hinge on this method, though there are some subtle differences. While an infinite loop might yield the smoothest results, babysitting one in a larger script might prove challenging, not to mention the spike in CPU usage if not managed properly.

Code: Select all

#NoEnv
SetBatchLines -1
SetWinDelay -1

Run % "notepad", , , pid
WinWait % "ahk_pid" pid
hNotepad := WinExist("ahk_pid" pid)

Gui New, % "+HwndhGui +Owner" hNotepad
Gui Show, w100 h100

Loop
{
    if !WinExist("ahk_id" hNotepad)
        ExitApp

    WinGetPos x, y, , , % "ahk_id" hNotepad
    WinMove % "ahk_id " hGui, , x, y
}


The second approach utilizes timers. Again same as the loops, they are relatively simple to setup, though not necessarily to manage. Resource usage is lower than that of loops, however, you might find the overlay window lagging behind when the main window is subject to both extremely jerky and gentle motions.

Code: Select all

#NoEnv
SetBatchLines -1
SetWinDelay -1

Run % "notepad", , , pid
WinWait % "ahk_pid" pid
hNotepad := WinExist("ahk_pid" pid)

Gui New, % "+HwndhGui +Owner" hNotepad
Gui Show, w100 h100

SetTimer MoveWindow, 1

MoveWindow:
    if !WinExist("ahk_id" hNotepad)
        ExitApp

    WinGetPos x, y, , , % "ahk_id" hNotepad
    WinMove % "ahk_id " hGui, , x, y
Return


Lastly, a WinEventHook, though arguably requiring more effort upfront to setup, is the most resource efficient and borders the loop in terms of responsiveness. Error handling and unhooking omitted for brevity in this example.

Code: Select all

#NoEnv
SetBatchLines -1
SetWinDelay -1

Run % "notepad", , , pid
WinWait % "ahk_pid" pid
hNotepad := WinExist("ahk_pid" pid)

DllCall("SetWinEventHook"
    , "UInt", 0x800B ; EVENT_OBJECT_LOCATIONCHANGE
    , "UInt", 0x800B ; EVENT_OBJECT_LOCATIONCHANGE
    , "Ptr", 0
    , "Ptr", RegisterCallback("WinEventProc")
    , "UInt", pid
    , "UInt", 0
    , "UInt", 0x0001 ; WINEVENT_OUTOFCONTEXT | WINEVENT_SKIPOWNTHREAD
    , "Ptr")

Gui New, % "+HwndhGui +Owner" hNotepad
Gui Show, w100 h100

WinWaitClose % "ahk_pid" pid
ExitApp

WinEventProc(hWinEventHook, event, hwnd, idObject, idChild, idEventThread, dwmsEventTime) {
    global hNotepad, hGui

    if (hwnd = hNotepad)
    {
        WinGetPos x, y, , , % "ahk_id" hNotepad
        WinMove % "ahk_id " hGui, , x, y
    }
}
At any rate, whichever method you decide to go for, don't forget to adjust A_WinDelay and A_BatchLines accordingly. I have disabled them altogether in all of the above examples.

Return to “Ask For Help”

Who is online

Users browsing this forum: ArkuS, DMDComposer and 247 guests