Posted: Fri Jul 28, 2006 7:30 pm
Thanks. Yes - it works now on when I switched from 16 to 32-bit. Thanks again.
http://www.purebasic.com
https://www.purebasic.fr/english/
Code: Select all
Declare UpdateClock(id.l,msg.l,dwUser.l,dw1.l,dw2.l)
;***** Windows Multimedia Timer *****
;***** by Psychophanta April 2006 *****
;***************************************
Global m_hWnd.l,m_timerId.l,m_timerRes.l
Procedure.l min(a.l,b.l)
If a<0
If b>0 Or a>b:ProcedureReturn b:EndIf
ElseIf b>0 And a>b:ProcedureReturn b
EndIf
ProcedureReturn a
EndProcedure
Procedure.l max(a.l,b.l)
If a<0
If b>0 Or a>b:ProcedureReturn a:EndIf
ElseIf b>0 And a>b:ProcedureReturn a
EndIf
ProcedureReturn b
EndProcedure
;/////////////////////////////////////////////////////////////////////////////////////////////
;// start mmTimer
;/////////////////////////////////////////////////////////////////////////////////////////////
Procedure.b StartTimer(period.l,oneShot.b=0,resolution.l=0)
tc.TIMECAPS
If timeGetDevCaps_(@tc,SizeOf(TIMECAPS))=#TIMERR_NOERROR
m_timerRes.l=min(max(tc\wPeriodMin,resolution),tc\wPeriodMax)
timeBeginPeriod_(m_timerRes);
Else
ProcedureReturn 0
EndIf
If oneShot:oneShot=#TIME_ONESHOT:Else:oneShot=#TIME_PERIODIC:EndIf
result.l=timeSetEvent_(period,m_timerRes,@UpdateClock(),0,oneShot);CALLBACK_EVENT_SET
If result.l
m_timerId=result.l
ProcedureReturn 1
EndIf
ProcedureReturn 0
EndProcedure
;/////////////////////////////////////////////////////////////////////////////////////////////
;// stop mmTimer
;// could be modified in XP with TIME_KILL_SYNCHRONOUS
;/////////////////////////////////////////////////////////////////////////////////////////////
Procedure.b StopTimer(bEndTime.b=0)
result.l=timeKillEvent_(m_timerId)
If result.l=#TIMERR_NOERROR
m_timerId=0
If bEndTime
For i.b=0 To 9
Sleep_(10); //TIME_KILL_SYNCHRONOUS
Next
EndIf
EndIf
If m_timerRes
timeEndPeriod_(m_timerRes)
m_timerRes=0
EndIf
If result.l=#TIMERR_NOERROR:ProcedureReturn 1:EndIf
ProcedureReturn 0
EndProcedure
;/////////////////////////////////////////////////////////////////////////////////////////////
;// Resume mmTimer
;/////////////////////////////////////////////////////////////////////////////////////////////
Procedure.b SafeStartTimer(period.l=2,oneShot.b=0,resolution.l=0)
If StartTimer(period,oneShot,resolution)=0
; PostMessage_(m_hWnd,#WM_CLOSE,0,0)
ProcedureReturn 0
EndIf
ProcedureReturn 1
EndProcedure
;END OF:
;***** Windows Multimedia Timer *****
;***** by Psychophanta April 2006 *****
;***************************************
#APPNAME = "CoolClock"
UseTIFFImageDecoder()
UsePNGImageDecoder()
Enumeration
#ImgCanvas
#ImgBack
#ImgBorder
#ImgGloss
#ImgLongPointer
#ImgMediumPointer
#ImgSmallPointer
EndEnumeration
Global Alpha = 255
OpenWindow(1, 0, 0, 0, 0, #APPNAME + " Parent", #PB_Window_Invisible)
OpenWindow(0, 0, 0, 512, 384, #APPNAME, #PB_Window_Invisible, WindowID(1))
SetWindowLong_(WindowID(0), #GWL_EXSTYLE, GetWindowLong_(WindowID(0), #GWL_EXSTYLE) | #WS_EX_LAYERED)
CreatePopupMenu(0)
MenuItem(0, "Stick to &desktop")
MenuItem(1, "Always on &top")
MenuItem(2, "&Normal")
MenuItem(6, "Get UTC (Universal Time Coordinated)")
MenuBar()
MenuItem(3, "&Change translucency")
MenuBar()
MenuItem(4, "&Exit")
MenuItem(5, "&About")
Procedure.l CheckinetConnection()
State.l
InternetGetConnectedState_(@State,0)
ProcedureReturn State
EndProcedure
If CheckinetConnection()=0:DisableMenuItem(0,6,1):EndIf
;
CatchImage(#ImgGloss, ?ClockGloss)
CatchImage(#ImgBack, ?ClockBack)
CatchImage(#ImgBorder, ?ClockBorder)
StartDrawing(ImageOutput(#ImgBack))
DrawAlphaImage(ImageID(#ImgGloss), 0, 0)
DrawAlphaImage(ImageID(#ImgBorder), 0, 0)
StopDrawing()
CatchImage(#ImgLongPointer, ?ClockLongPointer)
CatchImage(#ImgMediumPointer, ?ClockMediumPointer)
CatchImage(#ImgSmallPointer, ?ClockSmallPointer)
Procedure RotateDC(hDC.l, x0.l, y0.l, Degrees.d)
Static XFORM.XFORM
Protected Radians.d = Degrees*(#PI/180)
With XFORM
\eM11 = Cos(Radians)
\eM12 = Sin(Radians)
\eM21 = -\eM12
\eM22 = \eM11
\ex = x0 - Cos(Radians)*x0 + Sin(Radians)*y0
\ey = y0 - Cos(Radians)*y0 - Sin(Radians)*x0
EndWith
SetGraphicsMode_(hDC, #GM_ADVANCED)
SetWorldTransform_(hDC, XFORM)
EndProcedure
Procedure UpdateClock(id.l,msg.l,dwUser.l,dw1.l,dw2.l)
Date = Date()
Static hDC
Hour = Hour(Date)
Minute = Minute(Date)
Second = Second(Date)
; Fresh copy of background to draw on
CopyImage(#ImgBack, #ImgCanvas)
; Draw on the background
hDC = StartDrawing(ImageOutput(#ImgCanvas))
; Draw the large pointer
RotateDC(hDC, 128, 128, Minute*6)
DrawAlphaImage(ImageID(#ImgLongPointer),120,35)
; Draw the medium pointer
RotateDC(hDC, 128, 128, Hour*30+Minute/2)
DrawAlphaImage(ImageID(#ImgMediumPointer),120,66)
; Draw the small pointer
RotateDC(hDC, 128, 128, Second*6)
DrawAlphaImage(ImageID(#ImgSmallPointer),121,19)
; Update the window
Static ContextOffset.POINT
Static BlendMode.BLENDFUNCTION
Static BitmapInfo.BITMAP
GetObject_(ImageID(#ImgCanvas), SizeOf(BITMAP), @BitmapInfo)
BlendMode\SourceConstantAlpha = Alpha
BlendMode\AlphaFormat = 1
UpdateLayeredWindow_(WindowID(0), 0, 0, @BitmapInfo+4, hDC, @ContextOffset, 0, @BlendMode, 2)
StopDrawing()
EndProcedure
Procedure StickToDesktop()
StickyWindow(0, 0)
SetParent_(WindowID(0), GetShellWindow_())
EndProcedure
Procedure AlwaysOnTop()
SetParent_(WindowID(0), 0)
StickyWindow(0, 1)
EndProcedure
Procedure ChangeTranslucency()
OpenWindow(2,WindowX(0),WindowY(0)+WindowHeight(0),200,30,"Translucency",#PB_Window_SystemMenu,WindowID(1))
CreateGadgetList(WindowID(2))
TrackBarGadget(0,0,0,180,40,0,255):SetGadgetState(0,Alpha)
TextGadget(1,180,0,40,18,Str(GetGadgetState(0)))
EndProcedure
Procedure Normal()
SetParent_(WindowID(0), 0)
StickyWindow(0, 0)
EndProcedure
Procedure.b GetUTCTime()
Static Networkinitialized.b=0
If Networkinitialized.b=0
If InitNetwork()=0
MessageRequester("Error", "Can't initialize the network !",0):ProcedureReturn 0
Else:Networkinitialized.b=1
EndIf
EndIf
Datebuffer.s=Space(1000)
UTCServers.l=14:Dim UTC.s(UTCServers-1):port.w=13
UTC(0)="208.184.49.9"; "nist1.ny.glassey.com", "Abovenet, New York City"
UTC(1)="129.6.15.28"; "time-a.nist.gov", "NIST, Gaithersburg, Maryland"
UTC(2)="129.6.15.29"; "time-b.nist.gov", "NIST, Gaithersburg, Maryland"
UTC(3)="132.163.4.101"; "time-a.timefreq.bldrdoc.gov", "NIST, Boulder, Colorado"
UTC(4)="132.163.4.102"; "time-b.timefreq.bldrdoc.gov", "NIST, Boulder, Colorado"
UTC(5)="132.163.4.103"; "time-c.timefreq.bldrdoc.gov", "NIST, Boulder, Colorado"
UTC(6)="128.138.140.44"; "utcnist.colorado.edu", "University of Colorado, Boulder"
UTC(7)="192.43.244.18"; "time.nist.gov", "NCAR, Boulder, Colorado"
UTC(8)="131.107.1.10"; "time-nw.nist.gov", "Microsoft, Redmond, Washington"
UTC(9)="63.149.208.50"; "nist1.datum.com", "Datum, San Jose, California"
UTC(10)="216.200.93.8"; "nist1.dc.glassey.com", "Abovenet, Virginia"
UTC(11)="207.126.103.204"; "nist1.sj.glassey.com", "Abovenet, San Jose, California"
UTC(12)="207.200.81.113"; "nist1.aol-ca.truetime.com", "TrueTime, AOL facility, Sunnyvale, California"
UTC(13)="205.188.185.33"; "nist1.aol-va.truetime.com", "TrueTime, AOL facility, Virginia"
For t=0 To UTCServers-1
ConnectionID.l=OpenNetworkConnection(UTC(t),port.w)
If ConnectionID
ReceiveNetworkData(ConnectionID,@DateBuffer,1000)
date.l=ParseDate("%yy/%mm/%dd/%hh/%ii/%ss",Mid(DateBuffer,8,2)+"/"+Mid(DateBuffer,11,2)+"/"+Mid(DateBuffer,14,2)+"/"+Mid(DateBuffer,17,2)+"/"+Mid(DateBuffer,20,2)+"/"+Mid(DateBuffer,23,2))
Debug FormatDate("%yyyy/%mm/%dd/%hh/%ii/%ss",date)
systime.SYSTEMTIME
systime\wYear=Year(date)
systime\wMonth=Month(date)
systime\wDayOfWeek=DayOfWeek(date)
systime\wDay=Day(date)
systime\wHour=Hour(date)
systime\wMinute=Minute(date)
systime\wSecond=Second(date)
systime\wMilliseconds=0
SetSystemTime_(@systime)
CloseNetworkConnection(ConnectionID)
ProcedureReturn 1
ElseIf t>=UTCServers-1
MessageRequester("Error","Can't connect to UTC Server !",0):ProcedureReturn 0
EndIf
Next
EndProcedure
Procedure About()
Protected Text.s
Text+#APPNAME + #CRLF$
Text+"Copyright 2006 Trond Gundersen"+ #CRLF$
Text+"Enhanced & timered version by Albert (Psychophanta)"
MessageRequester("About", Text)
EndProcedure
UpdateClock(0,0,0,0,0)
HideWindow(0,0)
SafeStartTimer(1000)
Repeat
Select WaitWindowEvent()
Case #WM_RBUTTONUP
DisplayPopupMenu(0, WindowID(1))
Case #WM_LBUTTONDOWN
SendMessage_(WindowID(0), #WM_NCLBUTTONDOWN, #HTCAPTION, 0)
Case #PB_Event_Menu
Select EventMenu()
Case 0
StickToDesktop()
Case 1
AlwaysOnTop()
Case 2
Normal()
Case 6
GetUTCTime()
Case 3
ChangeTranslucency()
Case 4
Break
Case 5
About()
EndSelect
Case #PB_Event_Gadget
If IsWindow(2)
Alpha=GetGadgetState(0)
SetGadgetText(1,Str(Alpha))
EndIf
Case #PB_Event_CloseWindow
If IsWindow(2):CloseWindow(2)
Else:Break
EndIf
EndSelect
Delay(20)
ForEver
StopTimer()
DataSection
ClockBack:
IncludeBinary "Clock - Back.tiff"
ClockBorder:
IncludeBinary "Border.tiff"
ClockGloss:
IncludeBinary "gloss.png"
ClockLongPointer:
IncludeBinary "hour_pointer.tiff"
ClockMediumPointer:
IncludeBinary "minute_pointer.tiff"
ClockSmallPointer:
IncludeBinary "second_pointer.tiff"
EndDataSection
Uhhff! thanx!Joakim Christiansen wrote:Disable html Psychophanta
Well, that is possible to fix making some change.Trond wrote:The very nice think about your version, Psychophanta, is that the clock continues when menus and dialogs are displayed. However, it does not look the same any more. The hands are rendered in front of the glass. Obviously faster, but not as pretty.
ahhh! come on! that's not important. Keep in mind tha a timer is the more elegant solution for these kind of apps.Trond wrote:And it updates every second instead of when the next second starts. So it could update and move the second hand in the middle of a second.
Code: Select all
Procedure CallBack(hwnd, message, wparam, lparam)
Result = #PB_ProcessPureBasicEvents
If message=#WM_MOVING
If hwnd = WindowID(0)
ResizeWindow(2, WindowX(0),WindowY(0),#PB_Ignore,#PB_Ignore)
Else
ResizeWindow(0, WindowX(2),WindowY(2),#PB_Ignore,#PB_Ignore)
EndIf
EndIf
ProcedureReturn result
EndProcedure
#APPNAME = "CoolClock"
UseTIFFImageDecoder()
UsePNGImageDecoder()
Enumeration
#ImgCanvas
#ImgBack
#ImgBorder
#ImgGloss
#ImgLongPointer
#ImgMediumPointer
#ImgSmallPointer
#imgCover
EndEnumeration
Global Alpha = 255
OpenWindow(1, 0, 0, 0, 0, #APPNAME + " Parent", #PB_Window_Invisible)
OpenWindow(0, 0, 0, 512, 384, #APPNAME, #PB_Window_Invisible, WindowID(1))
SetWindowLong_(WindowID(0), #GWL_EXSTYLE, GetWindowLong_(WindowID(0), #GWL_EXSTYLE) | #WS_EX_LAYERED)
;//////////////////////////////////////////////////////////////////////////////////
OpenWindow(2, 0, 0, 512, 384, #APPNAME+" Cover",#PB_Window_Invisible,WindowID(0))
HideWindow(2, 0)
SetWindowCallback(@CallBack())
SetWindowLong_(WindowID(2), #GWL_EXSTYLE, GetWindowLong_(WindowID(2), #GWL_EXSTYLE) | #WS_EX_LAYERED)
;//////////////////////////////////////////////////////////////////////////////////
CreatePopupMenu(0)
MenuItem(0, "Stick to &desktop")
MenuItem(1, "Always on &top")
MenuItem(2, "&Normal")
MenuBar()
MenuItem(3, "&Change translucency")
MenuBar()
MenuItem(4, "&Exit")
MenuItem(5, "&About")
CatchImage(#ImgGloss, ?ClockGloss)
CatchImage(#ImgBack, ?ClockBack)
CatchImage(#ImgBorder, ?ClockBorder)
CatchImage(#ImgLongPointer, ?ClockLongPointer)
CatchImage(#ImgMediumPointer, ?ClockMediumPointer)
CatchImage(#ImgSmallPointer, ?ClockSmallPointer)
;//////////////////////////////////////////////////////////////////////
CreateImage(#imgCover, 512,384)
hdc=StartDrawing(ImageOutput(#imgCover))
DrawAlphaImage(ImageID(#ImgGloss), 0, 0)
DrawAlphaImage(ImageID(#ImgBorder), 0, 0)
ContextOffset.POINT
BlendMode.BLENDFUNCTION
BitmapInfo.BITMAP
GetObject_(ImageID(#Imgcover), SizeOf(BITMAP), @BitmapInfo)
BlendMode\SourceConstantAlpha = 255
BlendMode\AlphaFormat = 1
UpdateLayeredWindow_(WindowID(2), 0, 0, @BitmapInfo+4, hDC, @ContextOffset, 0, @BlendMode, 2)
StopDrawing()
;//////////////////////////////////////////////////////////////////////
Procedure RotateDC(hDC.l, x0.l, y0.l, Degrees.d)
Static XFORM.XFORM
Protected Radians.d = Degrees*(#PI/180)
With XFORM
\eM11 = Cos(Radians)
\eM12 = Sin(Radians)
\eM21 = -\eM12
\eM22 = \eM11
\ex = x0 - Cos(Radians)*x0 + Sin(Radians)*y0
\ey = y0 - Cos(Radians)*y0 - Sin(Radians)*x0
EndWith
SetGraphicsMode_(hDC, #GM_ADVANCED)
SetWorldTransform_(hDC, XFORM)
EndProcedure
Procedure UpdateClock()
Static OldDate
Protected Date = Date()
If Date = OldDate
ProcedureReturn 0
Else
OldDate = Date
EndIf
Static hDC
Protected Hour = Hour(Date)
Protected Minute = Minute(Date)
Protected Second = Second(Date)
; Fresh copy of background to draw on
CopyImage(#ImgBack, #ImgCanvas)
; Draw on the background
hDC = StartDrawing(ImageOutput(#ImgCanvas))
;SaveDC_(hDC) ; Save the state for restoring after rotation
; Draw the large pointer
RotateDC(hDC, 128, 128, Minute/60*360)
DrawAlphaImage(ImageID(#ImgLongPointer), 128-9, 35)
; Draw the medium pointer
RotateDC(hDC, 128, 128, Hour/12*360)
DrawAlphaImage(ImageID(#ImgMediumPointer), 128-7, 30+36)
; Draw the small pointer
RotateDC(hDC, 128, 128, Second/60*360)
DrawAlphaImage(ImageID(#ImgSmallPointer), 128-7, 19)
;RestoreDC_(hDC, -1)
;DrawAlphaImage(ImageID(#ImgGloss), 0, 0)
;DrawAlphaImage(ImageID(#ImgBorder), 0, 0)
; Update the window
Static ContextOffset.POINT
Static BlendMode.BLENDFUNCTION
Static BitmapInfo.BITMAP
GetObject_(ImageID(#ImgCanvas), SizeOf(BITMAP), @BitmapInfo)
BlendMode\SourceConstantAlpha = Alpha
BlendMode\AlphaFormat = 1
UpdateLayeredWindow_(WindowID(0), 0, 0, @BitmapInfo+4, hDC, @ContextOffset, 0, @BlendMode, 2)
StopDrawing()
EndProcedure
Procedure StickToDesktop()
StickyWindow(0, 0)
SetParent_(WindowID(0), GetShellWindow_())
EndProcedure
Procedure AlwaysOnTop()
SetParent_(WindowID(0), 0)
StickyWindow(0, 1)
EndProcedure
Procedure ChangeTranslucency()
Protected AStr.s
Protected VA
AStr = InputRequester(#APPNAME, "Set the translucency (1 - 255):", Str(Alpha))
VA = Val(AStr)
If VA > 0 And VA < 256
Alpha = VA
Else
MessageRequester(#APPNAME, "Invalid value: " + AStr, #MB_ICONINFORMATION)
EndIf
EndProcedure
Procedure Normal()
SetParent_(WindowID(0), 0)
StickyWindow(0, 0)
EndProcedure
Procedure About()
Protected Text.s
Text + #APPNAME + #CRLF$
Text + "Copyright 2006 Trond Gundersen"
MessageRequester("About", Text)
EndProcedure
UpdateClock()
HideWindow(0, 0)
Repeat
Select WaitWindowEvent(10)
Case #WM_RBUTTONUP
DisplayPopupMenu(0, WindowID(1))
Case #WM_LBUTTONDOWN
SendMessage_(WindowID(0), #WM_NCLBUTTONDOWN, #HTCAPTION, 0)
Case #PB_Event_Menu
Select EventMenu()
Case 0
StickToDesktop()
Case 1
AlwaysOnTop()
Case 2
Normal()
Case 3
ChangeTranslucency()
Case 4
Break
Case 5
About()
EndSelect
Case #PB_Event_CloseWindow
Break
EndSelect
UpdateClock()
ForEver
End
DataSection
ClockBack:
IncludeBinary "Clock - Back.tiff"
ClockBorder:
IncludeBinary "Border.tiff"
ClockGloss:
IncludeBinary "gloss.png"
ClockLongPointer:
IncludeBinary "hour_pointer.tiff"
ClockMediumPointer:
IncludeBinary "minute_pointer.tiff"
ClockSmallPointer:
IncludeBinary "second_pointer.tiff"
EndDataSection
netmaestro wrote:I felt that it was important to let the user feel that his finger has at least the power to stop a clock
No in the version i uploaded yesterday. Have you tried?Dano wrote:The only thing I would change is to have the hour hand update a quarter of the way to the next hour every 15 minutes. At 9:59 it looks still like 9:00 until it hits 10:00.