AutoHotkey Homepage AutoHotkey Community
Let's help each other out
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

moon phase
Goto page Previous  1, 2
 
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions
View previous topic :: View next topic  
Author Message
Laszlo



Joined: 14 Feb 2005
Posts: 4517
Location: Boulder, CO

PostPosted: Sat Jul 04, 2009 6:54 pm    Post subject: Reply with quote

Lexikos: I tried to test the flicker with your function above, with this script:
Code:
OnMessage(0x14, "WM_ERASEBKGND")

splash = 28
SetTimer Animate, 50
Gui +ToolWindow
Gui add, pic, h100 w100, %splash%.gif
Gui Show,,Lunar Phase

Animate:
   GuiControl,,Static1, % "*w100 *h100 " (splash := mod(splash,28)+1) ".gif"
   WinSetTitle Lunar Phase,,Lunar Phase - %splash%
   GuiControl,,Static1, *w100 *h100 %splash%.gif
Return

WM_ERASEBKGND(wParam) {
    if (A_Gui = 1) {
        Gui, +LastFound
        hwnd := WinExist()
       
        GuiControlGet, pic, Pos, Static1
        ; these are sometimes 0 when the background is erased!
        ; (it seems to be erased while the picture is changing)
        picW := 100
        picH := 100
       
        hdc := DllCall("GetDC", "uint", hwnd)
       
        ; Exclude the picture control from the clipping region.
        DllCall("ExcludeClipRect", "uint", hdc
            , "int", picX, "int", picY, "int", picX+picW, "int", picY+picH)
       
        ; Draw a black rectangle over the whole GUI.
        VarSetCapacity(rect, 16)
        DllCall("GetClientRect", "uint", hwnd, "uint", &rect)
        DllCall("FillRect", "uint", hdc
            , "uint", &rect
            , "uint", DllCall("GetStockObject", "int", 0x4))
       
        DllCall("ReleaseDC", "uint", hwnd, "uint", hdc)
        return 1
    }
}

GuiClose:
ExitApp
For some reason, in the Animate timer I have to update the picture twice (best seen with a timer period of 500 or larger), otherwise only every other picture is shown. However, I see absolutely no flicker in my Vista32 system. Could we modify WM_ERASEBKGND() such that this double update will not be necessary?
Back to top
View user's profile Send private message
Laszlo



Joined: 14 Feb 2005
Posts: 4517
Location: Boulder, CO

PostPosted: Sat Jul 04, 2009 7:57 pm    Post subject: Reply with quote

I spent an hour figuring out how to get rid of the flicker more easily. It turned out that in my Vista32 PC it is enough to have OnMessage(0x14, "WM_ERASEBKGND") with a WM_ERASEBKGND function, which just returns 0, or anything non-blank. Maybe the little added delay of calling an AHK function is enough for Windows to draw the picture properly?
Code:
OnMessage(0x14, "WM_ERASEBKGND")

splash = 28
SetTimer Animate, 50
Gui +ToolWindow
Gui add, pic, h100 w100, %splash%.gif
Gui Show,,Lunar Phase

Animate:
   WinSetTitle Lunar Phase,,% "Lunar Phase - " (splash := mod(splash,28)+1)
   GuiControl,,Static1, *w100 *h100 %splash%.gif
Return

WM_ERASEBKGND() {
   return 0
}

GuiClose:
ExitApp
In this case Windows seems to cache all pictures, because after a few seconds there is no measurable CPU load, the moon phases just roll smoothly. I wonder if these are true on Win7 or XP.
Back to top
View user's profile Send private message
Lexikos



Joined: 17 Oct 2006
Posts: 4472
Location: Qld, Australia

PostPosted: Sun Jul 05, 2009 5:46 am    Post subject: Reply with quote

Laszlo wrote:
For some reason, in the Animate timer I have to update the picture twice (best seen with a timer period of 500 or larger), otherwise only every other picture is shown.
I see that on my Win7-64 system with both our scripts. I wouldn't have noticed had you not pointed it out.
Quote:
Could we modify WM_ERASEBKGND() such that this double update will not be necessary?
After a bit more testing, I found that referencing A_Gui within WM_ERASEBKGND() causes GuiControl to fail every second call. For instance,
Code:
; OK:
WM_ERASEBKGND(wParam) {
    return 0
}

; FAIL:
WM_ERASEBKGND(wParam) {
    g := A_Gui
    return 0
}
Btw, simply returning/disabling WM_ERASEBKGND is not sufficient if there are margins around the picture control and desktop composition is not enabled/available (i.e. Win7 or WinVista with Classic theme, or WinXP with any theme).

Edit: Shocked Shocked Shocked Shocked Shocked
OK, now I'm sure there's a bug:
Code:
WM_ERASEBKGND(wParam) {
    wtf := A_AhkPath
    return 0
}
On my system, this causes the picture control to CHANGE TO THE AHK ICON.
Edit2: Changes to Explorer's icon:
Code:
WM_ERASEBKGND(wParam) {
    ErrorLevel := "C:\Windows\explorer.exe"
    ErrorLevel := ErrorLevel
}

Edit3: I've posted a bug report.
Back to top
View user's profile Send private message Visit poster's website
Display posts from previous:   
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions All times are GMT
Goto page Previous  1, 2
Page 2 of 2

 
Jump to:  
You can post new topics in this forum
You can reply to topics in this forum


Powered by phpBB © 2001, 2005 phpBB Group