Damit das Codemuster funktioniert (und natürlich, damit die Analoguhr dem eigenen Geschmack angepaßt werden kann), sollten die u.a. Grafiken in einen Unterordner namens _bitmaps kopiert werden, der sinnvollerweise im VFP-Suchpfad liegt. Ist dies nicht so ohne weiteres möglich, dann muss halt ein wenig am Code rumgeschraubt werden ;-)
(Die beiden Pfeile sind für die Imageobjekte zum Wechsel des Hintergrundbilds gedacht.)
Das aus meiner Sicht interessante an diesem Codemuster dürfte, neben dem Algorithmus zum Positionieren der drei Line-Objekte, das minimalistische Dateihandling der Hintergrundbilder sein.
Diese werden im INIT in eine Array-Property (.PictureArray) eingelesen und über eine zweite Property (.CurrentImage) verwaltet. CurrentImage verfügt über eine _Assign-Methode, in welcher das jeweils nächste oder vorherige Bild zugewiesen wird.
Diese Vorgehensweise ermöglicht es uns, jederzeit neue Hintergrundbilder bereitzustellen. Sie müssen nur mit 'Clock' beginnen, vom Typ BMP sein und 100 * 100 Pixel messen.
Im u.a. Funktionstest ist die Entfernung des Objekts auskommentiert. Die Zeile kann jedoch problemlos über die Zwischenablage ins Befehlsfenster kopiert werden.
* // Funktionstest START
_screen.AddObject([oClock],[cClock])
_screen.oClock.Visible = .T.
*_screen.removeobject([oClock])
* // Funktionstest ENDE
DEFINE CLASS cClock AS container
Width = 100
Height = 100
BackStyle = 0
BorderWidth = 0
currentimage = 0
Name = "cClock"
twopi = .F.
DIMENSION picturearray[1,5]
ADD OBJECT imgclock AS image WITH ;
Stretch = 1, ;
Height = 100, ;
Left = 0, ;
Top = 0, ;
Width = 100, ;
Name = "imgClock"
ADD OBJECT timer1 AS timer WITH ;
Top = 0, ;
Left = 77, ;
Height = 23, ;
Width = 23, ;
Interval = 1000, ;
Name = "Timer1"
ADD OBJECT lineh AS line WITH ;
BorderWidth = 4, ;
Height = 50, ;
Left = 50, ;
Top = 24, ;
Width = 0, ;
Name = "LineH"
ADD OBJECT linem AS line WITH ;
BorderWidth = 2, ;
Height = 50, ;
Left = 50, ;
Top = 24, ;
Width = 0, ;
Name = "LineM"
ADD OBJECT lines AS line WITH ;
BorderWidth = 1, ;
Height = 50, ;
Left = 50, ;
Top = 24, ;
Width = 0, ;
BorderColor = RGB(128,0,0), ;
Name = "LineS"
ADD OBJECT imgnext AS image WITH ;
Picture = "_bitmaps\next.bmp", ;
Height = 5, ;
Left = 90, ;
MousePointer = 15, ;
Top = 90, ;
Width = 6, ;
Name = "imgNext"
ADD OBJECT imgprev AS image WITH ;
Picture = "_bitmaps\prev.bmp", ;
Height = 5, ;
Left = 5, ;
MousePointer = 15, ;
Top = 90, ;
Width = 6, ;
Name = "imgPrev"
PROCEDURE calcanddraw
LPARAMETERS nPartOf as Integer , nLineLen as Integer , oLine as Object
LOCAL liX as Integer , liY as Integer
* // Berechnung der x- und y- Koordinaten
WITH This
liX = 50 + COS( .TwoPi * ( -.25 + nPartOf ) ) * nLineLen
liY = 50 + SIN( .TwoPi * ( -.25 + nPartOf ) ) * nLineLen
ENDWITH
* // Berechnete Daten zuweisen
WITH oLine
.Top = MIN( liY , 50 )
.Left = MIN( liX , 50 )
.Height = ABS( liY - 50 )
.Width = ABS( liX - 50 )
.LineSlant = IIF( ( liY > 50 ) # ( liX > 50 ) , [/] , [\] )
ENDWITH
ENDPROC
PROCEDURE drawtime
LPARAMETERS lFromInit as Boolean
LOCAL lcTime as String, liHour as Integer, liMinute as Integer, liSecond as Integer
* // Uhrzeit zerlegen. Um sicherzustellen, dass mit
* // einem einheitlichen Wert gearbeitet wird er-
* // folgt dies mit einer Stringvariablen
lcTime = TIME()
liHour = VAL( GETWORDNUM( lcTime , 1 , [:] ) ) % 12
liMinute = VAL( GETWORDNUM( lcTime , 2 , [:] ) )
liSecond = VAL( GETWORDNUM( lcTime , 3 , [:] ) )
WITH This
* // Sekundenzeiger Position berechnen
.CalcAndDraw( liSecond / 60 , 45 , .LineS )
IF liSecond = 0 OR lFromInit
* // Minutenzeiger Position berechnen
.CalcAndDraw( liMinute / 60 , 40 , .LineM )
* // Stundenzeiger Position berechnen
.CalcAndDraw( ( liHour + liMinute / 60 ) / 12 , 30 , .LineH )
ENDIF
ENDWITH
RELEASE lcTime , liHour , liMinute, liSecond
ENDPROC
PROCEDURE currentimage_assign
LPARAMETERS vNewVal
LOCAL lcPic as String
WITH This
.CurrentImage = ICASE( ;
vNewVal < 1 , ALEN( .PictureArray , 1 ) , ;
vNewVal > ALEN( .PictureArray , 1 ) , 1 , ;
vNewVal ;
)
.imgClock.Picture = [_bitmaps\] + .PictureArray( .CurrentImage , 1 )
.Refresh
ENDWITH
ENDPROC
PROCEDURE Init
WITH This
* // Alle Objekte einblenden
.SetAll( [visible] , .T. , [line] )
* // Arbeitsvariable füllen
.TwoPi = 2 * PI()
* // Uhrzeit initialisieren
.DrawTime( .T. )
* // Vorhandene Hintergrundbilder einlesen
ADIR(.PictureArray,[_bitmaps\clock*.bmp],[],1)
* // auf 1. Bild im Vektor positionieren
.CurrentImage = 1
ENDWITH
ENDPROC
PROCEDURE timer1.Timer
This.Parent.DrawTime
ENDPROC
PROCEDURE imgnext.Click
WITH This.Parent
.CurrentImage = .CurrentImage - 1
ENDWITH
ENDPROC
PROCEDURE imgprev.Click
WITH This.Parent
.CurrentImage = .CurrentImage + 1
ENDWITH
ENDPROC
ENDDEFINE
Danke! sieht gut aus, funktioniert prima!
AntwortenLöschen