Dienstag, 26. Februar 2008

VFPx auf Codeplex aktualisiert / VFPx updated on Codeplex

Die VFPx Seite wurde generalüberholt. Hierbei hat Craig Boyd für eine bessere Übersicht der einzelnen Projekte und deren aktuelle Releasestati gesorgt.

aktualisiert am 26.06.2008  
aktualisiert am 04.08.2008  
aktualisiert am 23.10.2008  
aktualisiert am 04.11.2008  
aktualisiert am 08.01.2009  
aktualisiert am 02.02.2009  
aktualisiert am 05.03.2009  

Abgeschlossene Projekte

Sedna (Microsoft Visual FoxPro 9.0 "Sedna" Erweiterungen)
GDIPlusX (VFP 9.0 Klassenbibliotheken welche die 603 GDI+ Flat API Funktionen von GDIPlus.dll abbilden)
OOP Menu Project (Objektorientierte Menüs)
New Property and Method Replacement Update (Ersetzt die nativen VFP Dialoge zum erzeugen, editieren und verwalten von Eigenschaften und Methoden)
FFC (Die VFP 9 Foundation Klassen)
XSource (Die VFP9 SP2 XSource Projekte)
Alternate SCCText (von wOOdy bereitgestellte verbesserte Version des Programms Source Code Control to Text)
PEM Editor NEU (Ging aus dem New Property/New Method Replacement hervor und soll dieses letztlich ersetzen)  

Release Candidates

VFP9 SP2 Help File (Community basierende korrigierte und verbesserte Hilfedatei
ThemedControls Update (OutlookNavBar und andere Controls um Outlook-ähnliche Optik in VFP Applikationen zu ermöglichen)
ctl32_statusbar (Ersatz für die VFP _Screen Statusleiste, kann auch in Forms genutzt werden)
ctl32_scontainer (Scrollbare Container in VFP Forms)
FoxCharts (ActiveX-freies erstellen von Charts mit Hilfe von GDIPlusX)
Automated Builds NEU (Automatisierter Projekt Builder mit Anbindung an CruiseControl.NET)  

Beta Releases

DeskTop Alerts (Popup Meldungen im Stil von Outlook)
FoxTabs Update (Erweiterung der VFP IDE zur besseren Navigation bei vielen geöffneten Fenstern)
Tab Menu (Ribbon Control à la Office2007 auf Basis von VFP Menüs)
Control Renamer Builder NEU (Builder zum Umbenennen von Controls und Referenzen innerhalb von Methoden)  

Alfa Releases

Code Analyst (Analyse Tool)
ClassBrowserX (Standard VFP Klassenkatalog mit Erweiterungen im Export-Bereich)
JustBehave (Funktionalität von Basis- und Framewordklassen ohne Zusatzcode problemlos erweitern)
PopMenu Project (Ähnlich dem OOP Menu Project mit zusätzlichen Funktionen)
Table Designer X (nicht-Modaler Ersatz für den Standard Tabellendesigner von VFP)
VFP Grid ManyHeader (Individueller Container als Ersatz und zur Verbesserung der Header-Funktionalitäten)
TabbingNavigation NEU (Ermöglicht eine Navigation ähnlich dem SQL Management Studio bzw. Visual Studio)
SubFox NEU (Nahtlose Integration des VFP Quellcodes in Subversion)

In Planung

VFP MSBuild Target (Ermöglicht automatisierte Compilerläufe)
VFP 9.0 Localization in French (Bietet eine französische Entwicklungsoberfläche und Tools)
VFP 9.0 Localization in Russian (Bietet eine russische Entwicklungsoberfläche und Hilfe)
VFP 9.0 Localization in Portuguese (Bietet eine portugisische Entwicklungsoberfläche und Hilfe)

Donnerstag, 21. Februar 2008

Erster Weblog zu VFP Studio

Craig Boyd hat in seinem Blog ein erstes Shockwave-Video zum Thema VFP Studio veröffentlicht, dem in der nächsten Zeit noch weitere Videobeiträge folgen sollen.  

VFP Studio basiert auf der Isolated Shell von Visual Studio und ermöglicht die VFP-Projektierung direkt im Visual Studio.

Im ersten Video ist zu sehen, wie der VS-Codeeditor im Zusammenspiel mit VFP-Code arbeitet. Bisher war ich mit dem integrierten Editor vom Fux noch ganz zufrieden. Nach diesem Video muss ich feststellen, das der VFP-Editor ziemlich angestaubt ist. Mit VFP Studio wird sich das hoffentlich bald ändern. Ich bin schon gespannt, was Craig in den folgenden Videos zeigen wird.

Hier der Link zu Craigs Blog

Hier gehts direkt zum Video

Mittwoch, 20. Februar 2008

Leerzeichen in Datei- und Verzeichnisnamen / Spaces in file- and directory names

Mit der Makrosubstitution stellt uns Visual FoxPro eine wirklich mächtige Funktion zur Verfügung. Sie bekommt jedoch früher oder später ein Problem in Bezug auf Verzeichnis- und Dateinamen.

Sobald in diesen ein Leerzeichen enthalten ist, erzeugt VFP beim Ausführen der substitutierten Variablen einen Fehler. Da wir dem Anwender üblicherweise nicht vorschreiben können, wie er bspw. seine Verzeichnisse oder Dateien benamen soll, müssen wir von Entwicklerseite sicherstellen, dass unsere Software damit zurecht kommt.

Beispiel:

cZielPfad = [D:\Eigene Dateien\Eigene Bilder\]
CHDIR &cZielPfad

VFP tauscht die Variable cZielPfad gegen deren Wert aus. Das Ergebnis dieses Vorgangs sieht somit wie folgt aus:


CHDIR D:\Eigene Dateien\Eigene Bilder\

Im Anschluss parst die VFP-Runtime den Code bis zum Leerzeichen und nimmt an, dass es sich um den Befehl "CHDIR D:\Eigene" handelt und dass sich daran ein zweiter Teilstring "Dateien\Eigene Bilder\" anschliesst, der jedoch keinen Sinn macht und somit einen Fehler erzeugt.

Uns stehen nun zwei Möglichkeiten offen, das Problem zu beseitigen.

Die schlechtere Variante ist, den Makro einfach in Anführungszeichen zu setzen:

CHDIR [&cZielPfad]

Dies stellt wirklich keine elegante Lösung dar. Letztlich wandeln wir auf diese Weise einen String in einen String um.
Da wir bereits einen String zur Verfügung haben, sollten wir diesen besser als Namensausdruck verwenden:


CHDIR (cZielPfad)

Dies funktioniert immer und überall dort wo der Fux den Namen (und/oder Pfad) von irgendetwas benötigt:

SET ... TO (cDateiname)
USE (cTabelle) ALIAS (cAlias)
CREATE TABLE/CURSOR (cName)
SELECT * FROM (cQuelle) INTO CURSOR/TABLE (cZiel)
SET PRINTER TO (cDruckername)
DIRECTORY(cPruefePfadname)
OPEN DATABASE (cDBPfadUndDatei)

usw.

Für den Einsatz von Namensausdrücken braucht es jedoch keine Leerzeichen in der Zeichenkette. Ganz im Gegenteil. Sie sollten grundsätzlich immer Verwendung finden! Bei dieser Vorgehensweise steht zudem die Tatsache auf der Habenseite, dass Namensausdrücke schneller sind als jedes Makro.

Montag, 4. Februar 2008

Bilder zur Laufzeit in einem Form bewegen / Moving images in a form at runtime

Zu o.a. Thema gibt es diverse, ziemlich aufwendige Codebeispiele. Je nach Aufgabenstellung macht es auch durchaus Sinn, einen etwas komplexeren Ansatz zu wählen. Wenn wir jedoch mit möglichst geringem Aufwand bspw. ein Image-Objekt zur Laufzeit bewegen möchten, dann läßt sich das auch mit wenig Code realisieren.

Für die Umsetzung benötigen wir jeweils eine Property für die X- und die Y-Achse, sprich image.Top und image.Left.

Der notwendige Code für die Repositionierung wird in der Methode image.MouseMove hinterlegt.

Im INIT-Ereignis des image-Objektes hinterlegen wir den folgenden Code:

WITH This

    .AddProperty([nxlast],0)
    .AddProperty([nylast],0)

    .Anchor = 0
    .Top    = 1
    .Left   = 1
    .Width  = .Parent.Width
    .Height = .Parent.Height
    .Anchor = 15
 
ENDWITH

Über die Funktion .AddProperty erzeugen wir die beiden notwendigen Eigenschaften für .Top und .Left. Die Folgezeilen stellen sicher, dass unser image korekt im übergeordneten Container positioniert wird.

An dieser Stelle noch eine kurze Bemerkung zur Anchor-Eigenschaft.

Wird die Position eines Objektes zur Laufzeit verändert und anschliessend die Form in ihrer Größe verändert, dann erfolgt der Resize auf Basis der ursprünglichen Position. Um dies zu vermeiden ist es zwingend notwendig, die Anchor-Eigenschaft des bewegten Objektes auf 0 zu setzen (dies initialisiert den Anchor-Speicher), anschliessend das Objekt neu zu positionieren und zum Schluss den Anchor-Wert wiederherzustellen.

Nun zurück zum eigentlichen Thema.

Nachdem die Init-Methode mit dem o.a. Code besetzt ist wenden wir uns dem Ereignis MouseMove zu. Eine 'Bewegungsaktion' macht hier nur dann Sinn, wenn die dargestellte Grafik auch größer als der übergeordnete Container ist. Befindet sich das image.Objekt jedoch im Modus 'Stretch = 1' dann erfolgt die Anzeige isometrisch angepasst auf die Abmessungen des übergeordneten Containers. Mit anderen Worten: Nur wenn sich das image-Objekt im Clip- oder im Stretch-Modus befindet (image.stretch = 0 -> Clip, 2 -> Stretch) erfolgt eine Neupositionierung des Objektes.

Wie dies vor sich geht zeigt der im folgenden angezeigte Code:

LPARAMETERS nButton, nShift, nXCoord, nYCoord

WITH This
    IF .Stretch = 0 ;
    OR (.Stretch = 2 AND (.Width > .Parent.Width OR .Height > .Parent.Height))
        IF m.nButton = 1
            IF .nxLast <> 0 AND .nyLast <> 0
                .Top = .Top - (.nyLast - (m.nYCoord))
                IF .Parent.Height - .Height > .Top
                    .Top = .Parent.Height - .Height
                ENDIF
                IF .Top > 1
                    .Top = 1
                ENDIF
              
                .Left = .Left - (.nxLast - (m.nXCoord))
                IF .Parent.Width - .Width > .Left
                    .Left = .Parent.Width - .Width
                ENDIF
                IF .Left > 1
                    .Left = 1
                ENDIF
            ENDIF
            .nxLast = m.nXCoord
            .nyLast = m.nYCoord
        ELSE
            .nxLast = 0
            .nyLast = 0
        ENDIF
    ENDIF
ENDWITH

Für die weitere Vorgehensweise erscheint es angeraten, als Parent-Objekt einen einfachen Container einzusetzen. Diesem können dann problemlos weitere Funktionen bzgl. der image-Handlings hinzugefügt werden. Möglich wären bspw. die Anzeige von Bildinformationen, Umschaltung zwischen .stretch = 0 und 1, eine Zoomfunktion über .stretch = 2 usw.

Im Zusammenspiel mit Craig Boyds scrollbarer Containerklasse macht das Ganze dann so richtig Spass.