Montag, 12. Juli 2010

Links zu Visual Foxpro im Web / Links about Visual Foxpro on the web

Im folgenden gibt es eine (ganz bestimmt nicht vollständige) Liste mit Quellen und Foren rund um den Fuchs. Diese Liste berücksichtigt nicht die vielen Blogs rund um VFP. Eine Blogliste werde ich demnächst gesondert posten.

Diese Liste darf von Euch gerne per Kommentar ergänzt werden.

deutschsprachige Foxpro User Group

Foxite (englisch)

(Chris Wollenhaupt's) Guineu (englisch)

Microsofts deutschsprachiges Visual Foxpro Forum

Microsofts Visual Foxpro General Forum (englisch)

Universal Thread (englisch)

News2News - Using Win32 functions in Visual Foxpro (englisch)

VFPx auf Codeplex (englisch)

(Steven Black's) Visual Foxpro Wiki (englisch)

Freitag, 9. Juli 2010

Microsofts neue Diskussionsforen / Microsoft's new forums

Nachdem Microsoft vor einigen Wochen die alten Newsgroups und somit auch die darauf basierenden Webforen geschlossen hat, dachte ich zunächst, was solls, im deutschen Forum war in den letzten Jahren sowieso nicht so richtig was los und die Präsentation der Webforen war nicht wirklich geglückt.
ABER: Für den Fall der Fälle standen die alten VFP Hasen immer Gewehr bei Fuss um bei einfachen und auch schwierigeren Problemen den Fragestellern unter die Arme zu greifen.

Mit der Ankündigung, im MSDN Bereich eine modernere Oberfläche zum Informationsaustausch bereit zu stellen, haben sich viele entrüstet abgewandt, zumindest laut entsprechender Kommentare im alten Foxpro Forum...

Jetzt, ein paar Wochen später, und dem kontinuierlichen Beobachten des neuen deutschsprachigen VFP Forums auf MSDN muss ich feststellen, dass es entweder tatsächlich von vielen gezielt ignoriert wird oder noch gar nicht entdeckt wurde?

Eigentlich schade, denn die neue Oberfläche empfinde ich als eine deutliche Verbesserung. Mal ganz davon abgesehen, dass VFP als Entwicklungsumgebung nun wirklich nichts dafür kann, dass es nun bei Microsoft einen neuen Platz zum Informationsaustausch gibt. Es hätte auch David nicht geholfen, wenn er Goliath einfach ignoriert hätte. Aber wozu eine Schleuder gut ist, das wissen heute fast alle... ;-)

Ich kann mir nicht vorstellen, dass es rund um Foxpro keine Fragen und Probleme mehr zu stellen oder zu schildern gibt. Und auch wenn das Web viele Antworten per Google, Bing, Yahoo usw. zu unseren Fragen findet, so werden viele davon, auch heute noch, zum ersten Mal gestellt.

Aus meiner Sicht gibt es also eigentlich keinen Grund, NICHT im Forum aktiv vorbei zu schauen, zu Helfen, zu Fragen und immer wieder etwas Neues zu erfahren, oder?

-> http://social.msdn.microsoft.com/Forums/de-DE/foxprode/

Mittwoch, 7. Juli 2010

Analoge Uhr selbst gebaut / Self made analog clock

Nachdem ich im letzten Monat einen Eintrag bzgl. einer digitalen Anzeige gepostet habe fiel mir jetzt wieder ein altes Stück Code in die Finger, bei dem es sich um eine analoge Uhrzeitanzeige dreht. Nachdem ich den Staub entfernt und den Code ein wenig optimiert habe steht einem neuen Blogeintrag nichts mehr im Wege.

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