Page 1 of 1

Resolve flickering gui attached to a window

Posted: 09 Apr 2019, 05:08
by alesyt0h
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

Re: Resolve flickering gui attached to a window

Posted: 09 Apr 2019, 07:10
by WalkerOfTheDay
I'm not seeing any flickering ?

Re: Resolve flickering gui attached to a window

Posted: 09 Apr 2019, 09:00
by just me
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.

Re: Resolve flickering gui attached to a window

Posted: 09 Apr 2019, 11:42
by swagfag
dont see any flickering same as walkeroftheday. ur timer refreshes too slowly = laggy appearance

Re: Resolve flickering gui attached to a window

Posted: 09 Apr 2019, 14:15
by lvalkov
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.