Animating a GUI with rounded corners not rendering properly.

Get help with using AutoHotkey (v2 or newer) and its commands and hotkeys
XMCQCX
Posts: 252
Joined: 14 Oct 2020, 23:44

Animating a GUI with rounded corners not rendering properly.

20 May 2024, 08:59

Hi,
I’m trying to animate a GUI with rounded corners using the FrameShadow function by Klark92 and the AnimateWindow function, but they don't seem to work well together. Only the "text layer" moves, not the entire GUI. Is there a solution? I'd like to know before I attempt to manually recreate the animations with loop and move. Thanks

Code: Select all

#Requires AutoHotkey v2
#SingleInstance

g := Gui('-Caption +AlwaysOnTop')
g.SetFont('s30')
g.Add('Text',, 'GUI with rounded corners`npositioned at the bottom right.')
g.Show('Hide')
WinGetPos(&gx, &gy, &gW, &gH, g)
FrameShadow(g.hwnd)
g.Show('x' A_ScreenWidth - gW - 15 'y' A_ScreenHeight - gH - 75)

SetTimer((*) => DllCall('AnimateWindow', 'Ptr', g.hwnd, 'Int', 1500, 'Int', '0x50001'), -3000) ; Slide out Left to Right. (AW_SLIDE | AW_HOR_POSITIVE | AW_HIDE) 

; SetTimer((*) => SlideoutLefttoRight(), -3000)

; FrameShadow by Klark92. https://www.autohotkey.com/boards/viewtopic.php?f=6&t=29117&hilit=FrameShadow
FrameShadow(hwnd)
{
    DllCall("dwmapi.dll\DwmIsCompositionEnabled", "int*", &dwmEnabled:=0)
    
    if !dwmEnabled {
        DllCall("user32.dll\SetClassLongPtr", "ptr", hwnd, "int", -26, "ptr", DllCall("user32.dll\GetClassLongPtr", "ptr", hwnd, "int", -26) | 0x20000)
    }
    else {
        margins := Buffer(16, 0)    
        NumPut("int", 1, "int", 1, "int", 1, "int", 1, margins)
        DllCall("dwmapi.dll\DwmSetWindowAttribute", "ptr", hwnd, "Int", 2, "Int*", 2, "Int", 4)
        DllCall("dwmapi.dll\DwmExtendFrameIntoClientArea", "ptr", hwnd, "ptr", margins)
    }
}

;============================================================================================

SlideoutLefttoRight() {
    
    g.GetPos(&ix, &iy, &w, &h)

    while (ix < A_ScreenWidth) {
        ix += 10
        g.Move(ix / (A_ScreenDPI / 96))
        Sleep(10)
    }

    ExitApp()
}
XMCQCX
Posts: 252
Joined: 14 Oct 2020, 23:44

Re: Animating a GUI with rounded corners not rendering properly.

21 May 2024, 15:53

I'm trying attempt to manually recreate this animation below with Loop and Move. At 100% scaling, it works without issues. However, there is a small problem when the scaling is not at 100%. Can anyone identify the issue?

Code: Select all

DllCall('AnimateWindow', 'Ptr', g.hwnd, 'Int', 1500, 'Int', '0x50001') ; Slide out Left to Right. (AW_SLIDE | AW_HOR_POSITIVE | AW_HIDE)
With edge corners and the AnimateWindow function. What I am trying to recreate.

Code: Select all

#Requires AutoHotkey v2
#SingleInstance

g := Gui('-Caption +AlwaysOnTop +Border')
g.SetFont('s30')
g.Add('Text',, 'GUI with rounded corners`npositioned at the bottom right.')
g.Show('Hide')
WinGetPos(&gx, &gy, &gW, &gH, g)
g.Show('x' A_ScreenWidth - gW - 15 'y' A_ScreenHeight - gH - 75) ; bottom right

SetTimer((*) => DllCall('AnimateWindow', 'Ptr', g.hwnd, 'Int', 1500, 'Int', '0x50001'), -3000) ; Slide out Left to Right. (AW_SLIDE | AW_HOR_POSITIVE | AW_HIDE)

My attempt to manually recreate the same effect with round corners. Scaling Issue when not at 100%.

Code: Select all

#Requires AutoHotkey v2
#SingleInstance

g := Gui('-Caption +AlwaysOnTop')
g.SetFont('s30')
g.Add('Text',, 'GUI with rounded corners`npositioned at the bottom right.')
g.Show('Hide')
WinGetPos(&gx, &gy, &gW, &gH, g)
FrameShadow(g.hwnd)

g.Show('x' A_ScreenWidth - gW - 15 'y' A_ScreenHeight - gH - 75) ; bottom right
SetTimer((*) => Slide(), -3000)


Slide()
{
    g.GetPos(&gX, &gY, &gW, &gH)
        
    g.pos := 'br' ; bottom right
    
    g.awhd := 2000 ; animation duration

    Switch g.pos {
            case 'br', 'tr': totalDistance := gW + 15
            case 'bl', 'tl': totalDistance := A_ScreenWidth
            case 'bc', 'tc', 'ct': totalDistance := A_ScreenWidth/2 + gW/2
    }

    stepDistance := 10
    totalSteps := totalDistance / stepDistance
    ms := g.awhd / totalSteps     

    Loop totalSteps          
        g.Move(Ds(gX += stepDistance), Ds(gY), Ds(gW -= stepDistance)), Sleep(ms)    
    
    ExitApp() 
}

;==============================================

; DPI scaling factor
Ds(value) => value / (A_ScreenDPI / 96)

;==============================================

; FrameShadow by Klark92. https://www.autohotkey.com/boards/viewtopic.php?f=6&t=29117&hilit=FrameShadow
FrameShadow(hwnd)
{
    DllCall("dwmapi.dll\DwmIsCompositionEnabled", "int*", &dwmEnabled:=0)
    
    if !dwmEnabled {
        DllCall("user32.dll\SetClassLongPtr", "ptr", hwnd, "int", -26, "ptr", DllCall("user32.dll\GetClassLongPtr", "ptr", hwnd, "int", -26) | 0x20000)
    }
    else {
        margins := Buffer(16, 0)    
        NumPut("int", 1, "int", 1, "int", 1, "int", 1, margins)
        DllCall("dwmapi.dll\DwmSetWindowAttribute", "ptr", hwnd, "Int", 2, "Int*", 2, "Int", 4)
        DllCall("dwmapi.dll\DwmExtendFrameIntoClientArea", "ptr", hwnd, "ptr", margins)
    }
}
Any help would be greatly appreciated. Best Regards.
User avatar
rommmcek
Posts: 1480
Joined: 15 Aug 2014, 15:18

Re: Animating a GUI with rounded corners not rendering properly.

22 May 2024, 02:34

Try:

Code: Select all

    Loop totalSteps          
        g.Move(Ds((gX += stepDistance)*A_ScreenDPI/96), Ds(gY*A_ScreenDPI/96), Ds(gW -= stepDistance)*A_ScreenDPI/96), Sleep(ms)
XMCQCX
Posts: 252
Joined: 14 Oct 2020, 23:44

Re: Animating a GUI with rounded corners not rendering properly.

22 May 2024, 13:00

@rommmcek Thanks for the help. The same issue: it works at 100% scaling, but not at any other scaling. I believe I've identified the problem: using GetPos instead of WinGetPos. GetPos seems to work better with controls, while WinGetPos seems to work better with windows. This works at any scaling.

Code: Select all

#Requires AutoHotkey v2
#SingleInstance

g := Gui('-Caption +AlwaysOnTop')
g.BackColor := '1F1F1F'
g.SetFont('s30')
g.Add('Text', 'cWhite', 'The quick brown fox jumps over the lazy dog.')
g.Show('Hide')
WinGetPos(&gx, &gy, &gW, &gH, g)
FrameShadow(g.hwnd)

g.Show('x' A_ScreenWidth - gW 'y' A_ScreenHeight - gH - 75 ' NoActivate Hide') ; bottom right
DllCall('AnimateWindow', 'Ptr', g.hwnd, 'Int', 500, 'Int', '0x80000')
SetTimer((*) => SlideoutLefttoRight('br'), -2000)

; g.Show('x0 y10 NoActivate Hide') ; top left
; DllCall('AnimateWindow', 'Ptr', g.hwnd, 'Int', 500, 'Int', '0x80000')
; SetTimer((*) => SlideoutRighttoLeft('tl'), -2000)

;==============================================

; DPI scaling factor
Ds(value) => value / (A_ScreenDPI / 96)

;==============================================

SlideoutLefttoRight(pos)
{
    WinGetPos(&gX, &gY, &gW, &gH, g)
        
    Switch pos {
        case 'br', 'tr': totalDistance := gW
        case 'bl', 'tl': totalDistance := A_ScreenWidth
        case 'bc', 'tc', 'ct': totalDistance := A_ScreenWidth/2 + gW/2
    }

    stepDistance := 1
    totalSteps := totalDistance / stepDistance
    ms := 125 / totalSteps     

    Loop totalSteps      
        g.Move(Ds(gX += stepDistance), Ds(gY), Ds(gW -= stepDistance)), Sleep(ms)

    ExitApp() 
}

;==============================================

SlideoutRighttoLeft(pos) 
{
    WinGetPos(&gX, &gY, &gW, &gH, g)
    
    Switch pos {
        case 'br', 'tr': totalDistance := A_ScreenWidth
        case 'bl', 'tl': totalDistance := gW
        case 'bc', 'tc', 'ct': totalDistance := A_ScreenWidth/2 + gW/2
    }

    stepDistance := 1
    totalSteps := totalDistance / stepDistance
    ms := 125 / totalSteps

    Loop totalSteps          
        g.Move(Ds(gX), Ds(gY), Ds(gW -= stepDistance)), Sleep(ms)  
    
    ExitApp()    
}

;==============================================

; FrameShadow by Klark92. https://www.autohotkey.com/boards/viewtopic.php?f=6&t=29117&hilit=FrameShadow
FrameShadow(hwnd)
{
    DllCall("dwmapi.dll\DwmIsCompositionEnabled", "int*", &dwmEnabled:=0)
    
    if !dwmEnabled {
        DllCall("user32.dll\SetClassLongPtr", "ptr", hwnd, "int", -26, "ptr", DllCall("user32.dll\GetClassLongPtr", "ptr", hwnd, "int", -26) | 0x20000)
    }
    else {
        margins := Buffer(16, 0)    
        NumPut("int", 1, "int", 1, "int", 1, "int", 1, margins)
        DllCall("dwmapi.dll\DwmSetWindowAttribute", "ptr", hwnd, "Int", 2, "Int*", 2, "Int", 4)
        DllCall("dwmapi.dll\DwmExtendFrameIntoClientArea", "ptr", hwnd, "ptr", margins)
    }
}

Return to “Ask for Help (v2)”

Who is online

Users browsing this forum: No registered users and 63 guests