Mittwoch, 21. Dezember 2011

Datumsspielereien (Teil 8) / Date gadgets (Part 8)

Die TIME() Funktion von Visual Foxpro liefert uns eine Uhrzeit als Characterstring. Wenn wir zu dieser Zeit jedoch Stunden, Minuten oder Sekunden hinzuaddieren möchten, dann ist das bei einem String eine mühsame Arbeit.

Anstatt mit TIME() sollten wir für Berechnungen immer mit DATETIME() arbeiten. Hier steht uns neben dem Datum auch die Uhrzeit für Berechnungen zur Verfügung. Allerdings wird ein DATETIME() + 1 ein gänzlich anderes Ergebnis liefern als DATE() + 1. Wenn DATE() grundsätzlich auf Tagesbasis seine Berechnungen durchführt, so reagiert DATETIME() auf Sekundenbasis.
Um mit DATETIME() also Stunden oder Minuten zu berechnen müssen wir entweder x * 60 * 60 für Stunden oder x * 60 für Minuten eingeben.

Zur Extraktion der Uhrzeit vom Datum/Zeit-Wert steht uns dann im Anschluß die Funktion TTOC() zur Verfügung. Wichtig hierbei ist der zweite Parameterwert den wir zwingend auf 2 setzen müssen.

CLEAR
ltDatetime = DATETIME()
? ltDatetime
? CalcTime( 5 , 0 , 0 , ltDatetime )
? CalcTime( 0 , 5 , 0 , ltDatetime )
? CalcTime( 0 , 0 , 5 , ltDatetime )
? CalcTime( 5 , 5 , 5 , ltDatetime )

? CalcTime( -5 )


FUNCTION CalcTime as String
LPARAMETERS vHours as Integer, vMinutes as Integer, vSeconds as Integer, vDatetime as Datetime

    vHours      = EVL( vHours    , 0 )
    vMinutes    = EVL( vMinutes  , 0 )
    vSeconds    = EVL( vSeconds  , 0 )
    vDatetime   = EVL( vDatetime , DATETIME() )

    vDatetime = vDatetime + ( vHours   * 60 * 60 )
    vDatetime = vDatetime + ( vMinutes * 60 )
    vDatetime = vDatetime + ( vSeconds )

    RETURN TTOC( vDatetime , 2 )

ENDFUNC 

Mittwoch, 14. Dezember 2011

Erstellen von Tablet-PC Anwendungen mit VFP / Creating Tablet-PC Applications with VFP

Vor ein paar Wochen stolperte ich bei der Suche nach Informationen zur Erstellung von Tablet PC Anwendungen mit Visual Foxpro über den folgenden Blogbeitrag:

http://www.tabletpcblog.de/2010/03/11/erstellen-von-tablet-pc-anwendungen-mit-visual-foxpro/

Bei diesem Posting handelt es sich um eine Übersetzung eines MSDN Artikels von Mike Stewart aus dem Jahr 2004:

http://msdn.microsoft.com/en-us/library/ms965060

Damals, zu XP Zeiten waren die notwendigen Vorbereitungen noch ein wenig aufwändiger als heute unter Windows 7, welches die benötigten Bibliotheken bereits 'ab Werk' mit sich führt. Und erstaunlicherweise funktioniert der in den Beiträgen enthaltene Beispielcode unter Windows 7 ohne Probleme.

Wer also mit dem Gedanken spielt, seine Anwendung für Touchscreens fit zu machen, der sollte sich die Beiträge einmal genauer zu Gemüte führen!

Montag, 5. Dezember 2011

Zwei Forms gleichzeitig bewegen / Moving two forms simultaneously

Wer noch die alte Version von WinAMP(R) kennt weiß, dass dort insgesamt zwei zusätzliche, an die Hauptform andockbare Fenster zur Verfügung standen.

Einen solchen Effekt können wird in Visual FoxPro ebenfalls erzielen. Hierzu binden wir den 'Moved' Event der Hauptform einfach an die zugehörigen Unterforms.

Der für die Repositionierung benötigte Code befindet sich in der Prozedur 'MoveSubForm':

oFrmSub.Top = oFrmMain.Top
IF    ( oFrmMain.Left + oFrmMain.Width + 15 + oFrmSub.Width ) > _screen.Width
    oFrmSub.Left = oFrmMain.Left - oFrmSub.Width
ELSE 
    oFrmSub.Left = oFrmMain.Left + oFrmMain.Width + 15
ENDIF 

Da das MOVED() Event feuert, sobald wir die Hauptform verschieben, sorgt der o.a. Code für die Repositionierung der Unterform auf Basis der aktuellen Position der Hauptform.


Hier nun der vollständige Mustercode:

CLEAR ALL 
PUBLIC oFrmMain as Form, oFrmSub as Form, oHandler as Object 
* // Forms und Handler erzeugen                        
* // create forms and handler                        
oFrmMain            = CREATEOBJECT( [form] )
oFrmSub             = CREATEOBJECT( [form] )
oHandler            = CREATEOBJECT( [oHandlerObj] )
* // Hauptform positionieren und konfigurieren        
* // positioning and configureing the main form        
oFrmMain.Top        = 100 
oFrmMain.Left       = 100 
oFrmMain.AddObject([cmdReleaseAll],[commandbutton])
oFrmMain.cmdReleaseAll.Caption  = [Exit]
oFrmMain.cmdReleaseAll.Height   = 25
oFrmMain.cmdReleaseAll.Visible  = .T. 
oFrmMain.Visible                = .T.
* // Unterform konfigurieren                        
* // configureing the subform                        
oFrmSub.BorderStyle             = 0 
oFrmSub.TitleBar                = 0
oFrmSub.BackColor               = RGB( 128 , 128 , 128 )
oFrmSub.Visible                 = .T. 
* // Unterform direkt neben Hauptform platzieren    
* // place the subform right beside the main form    
oHandler.MoveSubForm() 
* // Handler an relevante Events binden                
* // bind the handler to essential events            
BINDEVENT( oFrmMain , [Moved] , oHandler , [MoveSubForm] )
BINDEVENT( oFrmMain.cmdReleaseAll , [Click] , oHandler , [CloseSubForm] )


DEFINE CLASS oHandlerObj AS custom

    Name = [ohandler]

    PROCEDURE MoveSubForm
        oFrmSub.Top = oFrmMain.Top
        IF    ( oFrmMain.Left + oFrmMain.Width + 15 + oFrmSub.Width ) > _screen.Width
            oFrmSub.Left = oFrmMain.Left - oFrmSub.Width
        ELSE 
            oFrmSub.Left = oFrmMain.Left + oFrmMain.Width + 15
        ENDIF 
    ENDPROC

    PROCEDURE CloseSubForm 
        UNBINDEVENT( oFrmMain , [Moved] , oHandler , [MoveSubForm] )
        UNBINDEVENT( oFrmMain.cmdReleaseAll , [Click] , oHandler , [CloseSubForm] )
        oFrmMain.Release
        oFrmSub.Release
        oFrmMain    = .Null.
        oFrmSub     = .Null.
        RELEASE oFrmMain, oFrmSub
    ENDPROC 
    
ENDDEFINE