* // Funktionstest Start
CLEAR
?GetFullUNCPath( [H:] )
?GetFullUNCPath( [H:\] )
?GetFullUNCPath( [H:\Foxprogs] )
?GetFullUNCPath( [H:\Foxprogs\] )
?GetFullUNCPath( [H:\Foxprogs\mware71] )
?GetFullUNCPath( [H:\Foxprogs\mware71\] )
?GetFullUNCPath( [H:\Foxprogs\mware71\konf.exe] )
* // Funktionstest Ende
FUNCTION GetFullUNCPath as String
LPARAMETERS vMappedName as String
* // Datendeklaration und Initialisierung
LOCAL lcUNCBuffer as String, liLength as Integer, ;
lcUNCName as String, llContinue as Boolean, ;
lcMessage as String, lcPath as String
lcUNCBuffer = []
liLength = 0
lcUNCName = []
llContinue = .T.
lcMessage = []
vMappedName = IIF(DIRECTORY( vMappedName ) , ADDBS( vMappedName ) , vMappedName )
lcPath = IIF( LEN( vMappedName ) > 2 , SUBSTR( vMappedName , 3 ) , [] )
vMappedName = JUSTDRIVE( vMappedName )
* // Deklaration der API-Funktion
TRY
DECLARE INTEGER WNetGetConnection IN WIN32API ;
STRING @ lpLocalName, ;
STRING @ lpRemoteName, ;
INTEGER @ lpliLength
CATCH
TEXT TO lcMessage NOSHOW TEXTMERGE PRETEXT 2
Deklaration von WNetGetConnection in WIN32API
ist fehlgeschlagen. Funktion wird vorzeitig beendet.
ENDTEXT
MESSAGEBOX(lcMessage,0+16+0,[Information])
llContinue = .F.
ENDTRY
* // Umsetzung des lokalen Pfades in einen UNC Pfad
IF llContinue
IF !EMPTY( vMappedName ) AND VARTYPE( [vMappedName] ) = [C]
lcUNCBuffer = REPL( CHR( 0 ) , 261 )
liLength = LEN( lcUNCBuffer )
vMappedName = ALLTRIM( vMappedName )
IF LEN( vMappedName ) = 1
vMappedName = vMappedName + [:]
ENDIF
TRY
IF WNetGetConnection( vMappedName , @lcUNCBuffer , @liLength ) = 0
lcUNCName = LEFT( lcUNCBuffer , AT( CHR( 0 ) , lcUNCBuffer ) - 1 )
ENDIF
CATCH
TEXT TO lcMessage NOSHOW TEXTMERGE PRETEXT 2
Aufruf von WNetGetConnection in WIN32API
ist fehlgeschlagen. UNC-Pfad konnte nicht
generiert werden.
ENDTEXT
MESSAGEBOX( lcMessage , 0+16+0 , [Information] )
ENDTRY
ENDIF
ENDIF
RETURN lcUNCName + lcPath
ENDFUNC
Freitag, 25. Juni 2010
Erzeugen von UNC Pfadnamen / Creating UNC Pathnames (Revisited)
Nachdem ich heute zufälligerweise in eine alte Funktion von mir reingeschaut habe (Erzeugen von UNC-Pfadnamen), gab es auch gleich Verbesserungsbedarf. Im Blogeintrag vom September 2008 konnte nur ein Laufwerksbuchstabe (bspw. H:) übergeben werden. Die neue Funktion habe ich nun dahingehend erweitert, dass es jetzt sowohl reine Laufwerksbuchstaben, als auch komplette Verzeichnis- und/oder Dateinamen sein dürfen. Die verschiedenen Möglichkeiten sind im vorgelagerten Funktionstest zu ersehen.
Dienstag, 15. Juni 2010
Marquee Texte schnell und einfach erzeugen / Creating marquee texts quick and easy
Wenn wir mit einfachen Mitteln einen Lauftext (Marquee) erzeugen bzw. darstellen wollen, dann ist alles, was wir benötigen eine Containerklasse mitsamt Label- und Timerobjekt. Dem Container verpassen wir noch einen Eigenschaft, mit welcher die Laufrichtung bzw. das Verhalten beim Verlassen des sichtbaren Bereiches gesteuert wird und fertig ist die Laube.
Der folgende Mustercode kann, wenn als PRG in Foxpro gestartet, über das Befehlsfenster direkt beeinflußt werden. Ausschlaggebend hierfür ist die Eigenschaft _screen.oMover._Mode. Sie verarbeitet die Werte 1 - 4 (Siehe Kommentare im Block Funktionstest des Codebeispiels). Defaultwert ist die 2 (Von rechts nach links bewegen).
Der folgende Mustercode kann, wenn als PRG in Foxpro gestartet, über das Befehlsfenster direkt beeinflußt werden. Ausschlaggebend hierfür ist die Eigenschaft _screen.oMover._Mode. Sie verarbeitet die Werte 1 - 4 (Siehe Kommentare im Block Funktionstest des Codebeispiels). Defaultwert ist die 2 (Von rechts nach links bewegen).
* // Funktionstest -START-
_screen.AddObject([oMover],[cntMover]) _screen.oMover.Visible = .T. * // kontinuierlich nach rechts scrollen * _screen.oMover._Mode = 1 * // kontinuierlich nach links scrollen * _screen.oMover._Mode = 2 * // JoJo-Effekt nach links initiieren * _screen.oMover._Mode = 3 * // JoJo-Effekt nach rechts initiieren * _screen.oMover._Mode = 4 * // Mover-Objekt entsorgen... *_screen.RemoveObject([oMover])
* // Funktionstest -ENDE-
DEFINE CLASS cntmover AS container Anchor = 14 Width = 570 Height = 20 BackColor = RGB(128,128,128) Name = [cntmover] _Mode = 2 ADD OBJECT lblmove AS label WITH ; AutoSize = .T., ; BackStyle = 0, ; Caption = [Timer basierender Marquee Text], ; Height = 17, ; Left = 1, ; Top = 3, ; Width = 280, ; ForeColor = RGB(255,255,255), ; Name = [lblMove] ADD OBJECT tmrmove AS timer WITH ; Top = 1, ; Left = 1, ; Height = 23, ; Width = 23, ; Interval = 20, ; Name = [tmrMove] PROCEDURE tmrmove.Timer WITH This.Parent DO CASE CASE ._Mode = 1 .lblMove.Left = .lblMove.Left - 1 IF .lblMove.Left < .lblMove.Width * (-1) .lblMove.Left = .Width ENDIF CASE ._Mode = 2 .lblMove.Left = .lblMove.Left + 1 IF .lblMove.Left > .Width .lblMove.Left = .lblMove.Width * (-1) ENDIF CASE ._Mode = 3 .lblMove.Left = .lblMove.Left - 1 IF .lblMove.Left + .lblMove.Width < 1 ._Mode = 4 ENDIF CASE ._Mode = 4 .lblMove.Left = .lblMove.Left + 1 IF .lblMove.Left > .Width ._Mode = 3 ENDIF ENDCASE ENDWITH ENDPROC ENDDEFINE
Freitag, 4. Juni 2010
Digitale Anzeige selbst gebaut / Self made digital display
Vor einiger Zeit hatte ich an dieser Stelle über mein Problem mit dem richtigen Timing bei meinem Tee geschrieben. Thema war damals das Abspielen von WAV-Dateien in VFP.
Was mich ursprünglich dazu veranlasst hatte, mir einen Teatimer zu programmieren war, dass ich einfach mal ausprobieren wollte, wie aufwändig die Erstellung einer digitalen Zahlenanzeige ist, OHNE einen ensprechenden Font einzusetzen. Mit anderen Worten: Welche Grafiken benötige ich und wie blende ich wann die richtigen image-Objekte ein, damit auch alles nach einer altmodischen LED-Anzeige aussieht.
Als erstes legte ich mich auf eine Zahlendarstellung mit Hilfe von 7 Elementen fest, schliesslich ging es nicht um Schönheit sondern um einen grundsätzlichen Funktionstest.
1 -
2u3 | |
4 -
5u6 | |
7 -
Als Grafiken benötigte ich somit 2 Basiselemente ( - und | ), einen Doppelpunkt als Trenner für Minuten und Sekunden sowie eine Hintergrundgrafik, welche in dunkelgrau die ausgeblendeten Elemente visualisieren sollte.
Nachdem die vier Grafiken verfügbar waren musste ich diese nur noch mit Hilfe von Image-Objekten in einen Container verfrachten und sauber positionieren. Der Container bekam den Namen 'cntDigit' und enthielt anschliessend sieben image-Objekte. Der Doppelpunkt und die Hintergrundgrafik kommen in meinem Code erst in einem Hauptcontainer zum Zuge, in dem mehrere 'cntDigit' Container nebeneinander positioniert werden und erkennbar als Stunde : Minute dargestellt werden sollen. Es spricht jedoch nichts dagegen, die 8er-Template bereits im Basiscontainer einzufügen. Der verwendete Code läßt dies ohne Änderung zu.
Optisch war nun alles in Butter. Nun kam die Ausprogrammierung der Klasse 'cntDigit' an die Reihe.
Zunächst war die Image-Klasse an der Reihe. Hier musste zwar kein Code hinterlegt werden, aber sowohl die waagerechten als auch die senkrechten Balken benötigten Eigenschaften, mit deren Hilfe eine Sichtbarkeit in Abhängigkeit von der anzuzeigenden Zahl möglich war. Hierfür erstellte ich 10 individuell zu setzende Eigenschaften die je nach Image-Position gefüllt werden.
Wie die 10 Eigenschaften vom Typ Boolean (-> _0, _1, _2, _3, ..., _9) zu füllen sind liegt letztlich an der Position des jeweiligen Image-Objektes. Wird das Objekt zur Darstellung der anzuzeigenden Zahl benötigt, erhält die Eigenschaft ein .T. andernfalls ein .F. (-> Default). Vorteil diese Methodik ist, dass eine Erweiterung auf eine komplexere Darstellung bzw. Erweiterung auf Buchstaben problemlos umzusetzen ist.
Um eine wertbezogene Anzeige zu generieren erhielt cntDigit zunächst einmal die Eigenschaft '_DisplayDigit' inkl. einer dazugehörigen Assign-Methode '_DisplayDigit_assign'. Zusätzlich kam noch die Methode 'initdigit' dazu, um den Container 'NICHTS' anzeigen zu lassen (Diese Methode wird im Teatimer immer nach dem Ablauf des Timers aufgerufen).
Innerhalb von '_DisplayDigit_assign' wird eine FOR..EACH Schleife durchlaufen, in der mit Hilfe von PEMSTATUS() überprüft wird, ob die zusammengesetzte Eigenschaft im Zielobjekt vorhanden ist. Anschliessend wird deren Wert einfach der Visible-Eigenschaft des Imageobjektes zugewiesen. Voilà, fertig war die digitale Zahlenanzeige. Da kommt einem doch sofort der Werbespruch eines ehemaligen Tennisprofis in den Sinn: Das ging ja einfach!! ;-)
Hier nun das Codesegment von cntDigit:
Was mich ursprünglich dazu veranlasst hatte, mir einen Teatimer zu programmieren war, dass ich einfach mal ausprobieren wollte, wie aufwändig die Erstellung einer digitalen Zahlenanzeige ist, OHNE einen ensprechenden Font einzusetzen. Mit anderen Worten: Welche Grafiken benötige ich und wie blende ich wann die richtigen image-Objekte ein, damit auch alles nach einer altmodischen LED-Anzeige aussieht.
Als erstes legte ich mich auf eine Zahlendarstellung mit Hilfe von 7 Elementen fest, schliesslich ging es nicht um Schönheit sondern um einen grundsätzlichen Funktionstest.
1 -
2u3 | |
4 -
5u6 | |
7 -
Als Grafiken benötigte ich somit 2 Basiselemente ( - und | ), einen Doppelpunkt als Trenner für Minuten und Sekunden sowie eine Hintergrundgrafik, welche in dunkelgrau die ausgeblendeten Elemente visualisieren sollte.
Nachdem die vier Grafiken verfügbar waren musste ich diese nur noch mit Hilfe von Image-Objekten in einen Container verfrachten und sauber positionieren. Der Container bekam den Namen 'cntDigit' und enthielt anschliessend sieben image-Objekte. Der Doppelpunkt und die Hintergrundgrafik kommen in meinem Code erst in einem Hauptcontainer zum Zuge, in dem mehrere 'cntDigit' Container nebeneinander positioniert werden und erkennbar als Stunde : Minute dargestellt werden sollen. Es spricht jedoch nichts dagegen, die 8er-Template bereits im Basiscontainer einzufügen. Der verwendete Code läßt dies ohne Änderung zu.
Optisch war nun alles in Butter. Nun kam die Ausprogrammierung der Klasse 'cntDigit' an die Reihe.
Zunächst war die Image-Klasse an der Reihe. Hier musste zwar kein Code hinterlegt werden, aber sowohl die waagerechten als auch die senkrechten Balken benötigten Eigenschaften, mit deren Hilfe eine Sichtbarkeit in Abhängigkeit von der anzuzeigenden Zahl möglich war. Hierfür erstellte ich 10 individuell zu setzende Eigenschaften die je nach Image-Position gefüllt werden.
Wie die 10 Eigenschaften vom Typ Boolean (-> _0, _1, _2, _3, ..., _9) zu füllen sind liegt letztlich an der Position des jeweiligen Image-Objektes. Wird das Objekt zur Darstellung der anzuzeigenden Zahl benötigt, erhält die Eigenschaft ein .T. andernfalls ein .F. (-> Default). Vorteil diese Methodik ist, dass eine Erweiterung auf eine komplexere Darstellung bzw. Erweiterung auf Buchstaben problemlos umzusetzen ist.
Um eine wertbezogene Anzeige zu generieren erhielt cntDigit zunächst einmal die Eigenschaft '_DisplayDigit' inkl. einer dazugehörigen Assign-Methode '_DisplayDigit_assign'. Zusätzlich kam noch die Methode 'initdigit' dazu, um den Container 'NICHTS' anzeigen zu lassen (Diese Methode wird im Teatimer immer nach dem Ablauf des Timers aufgerufen).
Innerhalb von '_DisplayDigit_assign' wird eine FOR..EACH Schleife durchlaufen, in der mit Hilfe von PEMSTATUS() überprüft wird, ob die zusammengesetzte Eigenschaft im Zielobjekt vorhanden ist. Anschliessend wird deren Wert einfach der Visible-Eigenschaft des Imageobjektes zugewiesen. Voilà, fertig war die digitale Zahlenanzeige. Da kommt einem doch sofort der Werbespruch eines ehemaligen Tennisprofis in den Sinn: Das ging ja einfach!! ;-)
Hier nun das Codesegment von cntDigit:
* // Funktionstest -START-
WITH _screen
.AddObject ( [oShape] , [Shape] )
.oShape.Width = 48
.oShape.Height = 82
.oShape.BackColor = RGB( 0 , 0 , 0 )
.oShape.Visible = .T.
.AddObject ( [oTemplate], [imgTemplate] )
.oTemplate.Top = 5
.oTemplate.Left = 5
.oTemplate.Visible = .T.
.AddObject ( [oDigit] , [cntDigit] )
ENDWITH
WITH _screen.oDigit
.Top = 5
.Left = 5
.Visible = .T.
._DisplayDigit = [1]
WAIT WINDOW [Taste für 2]
._DisplayDigit = [2]
WAIT WINDOW [Taste für 3]
._DisplayDigit = [3]
WAIT WINDOW [Taste für 4]
._DisplayDigit = [4]
WAIT WINDOW [Taste für 5]
._DisplayDigit = [5]
WAIT WINDOW [Taste für 6]
._DisplayDigit = [6]
WAIT WINDOW [Taste für 7]
._DisplayDigit = [7]
WAIT WINDOW [Taste für 8]
._DisplayDigit = [8]
WAIT WINDOW [Taste für 9]
._DisplayDigit = [9]
WAIT WINDOW [Taste für 0]
._DisplayDigit = [0]
WAIT WINDOW [Schliessen]
ENDWITH
WITH _screen
.RemoveObject( [oDigit] )
.RemoveObject( [oTemplate] )
.RemoveObject( [oShape] )
ENDWITH
* // Funktionstest -ENDE-
DEFINE CLASS cntdigit AS container
Width = 38
Height = 71
BackStyle = 0
BorderWidth = 0
_displaydigit = ""
Name = "cntdigit"
ADD OBJECT imgom AS imgdigithorizontal WITH ;
Left = 5, ;
Top = 0, ;
Visible = .F., ;
_0 = .T., ;
_1 = .F., ;
_2 = .T., ;
_3 = .T., ;
_4 = .F., ;
_5 = .T., ;
_6 = .T., ;
_7 = .T., ;
_8 = .T., ;
_9 = .T.
ADD OBJECT imgum AS imgdigithorizontal WITH ;
Left = 5, ;
Top = 62, ;
Visible = .F., ;
_0 = .T., ;
_1 = .F., ;
_2 = .T., ;
_3 = .T., ;
_4 = .F., ;
_5 = .T., ;
_6 = .T., ;
_7 = .F., ;
_8 = .T., ;
_9 = .T.
ADD OBJECT imgmm AS imgdigithorizontal WITH ;
Left = 5, ;
Top = 31, ;
Visible = .F., ;
_0 = .F., ;
_1 = .F., ;
_2 = .T., ;
_3 = .T., ;
_4 = .T., ;
_5 = .T., ;
_6 = .T., ;
_7 = .F., ;
_8 = .T., ;
_9 = .T.
ADD OBJECT imgol AS imgdigitvertical WITH ;
Left = 0, ;
Top = 6, ;
Visible = .F., ;
_0 = .T., ;
_1 = .F., ;
_2 = .F., ;
_3 = .F., ;
_4 = .T., ;
_5 = .T., ;
_6 = .T., ;
_7 = .F., ;
_8 = .T., ;
_9 = .T.
ADD OBJECT imgur AS imgdigitvertical WITH ;
Left = 29, ;
Top = 37, ;
Visible = .F., ;
_0 = .T., ;
_1 = .T., ;
_2 = .F., ;
_3 = .T., ;
_4 = .T., ;
_5 = .T., ;
_6 = .T., ;
_7 = .T., ;
_8 = .T., ;
_9 = .T.
ADD OBJECT imgul AS imgdigitvertical WITH ;
Left = 0, ;
Top = 37, ;
Visible = .F., ;
_0 = .T., ;
_1 = .F., ;
_2 = .T., ;
_3 = .F., ;
_4 = .F., ;
_5 = .F., ;
_6 = .T., ;
_7 = .F., ;
_8 = .T., ;
_9 = .F.
ADD OBJECT imgor AS imgdigitvertical WITH ;
Left = 29, ;
Top = 6, ;
Visible = .F., ;
_0 = .T., ;
_1 = .T., ;
_2 = .T., ;
_3 = .T., ;
_4 = .T., ;
_5 = .F., ;
_6 = .F., ;
_7 = .T., ;
_8 = .T., ;
_9 = .T.
PROCEDURE _displaydigit_assign
LPARAMETERS vNewVal
* // Einblenden der für die darzustellende Zahl
* // benötigten Bits. Gesteuert wird dies über
* // die Properties _0 - _9 die über die
* // FOR...EACH Schleife direkt ausgewertet werden.
IF This._DisplayDigit <> m.vNewVal
LOCAL lcProperty as String
This._DisplayDigit = m.vNewVal
FOR EACH oDigit IN This.Controls
lcProperty = [_] + This._DisplayDigit
IF PEMSTATUS(oDigit,lcProperty,5)
oDigit.Visible = oDigit.&lcProperty
ENDIF
ENDFOR
ENDIF
ENDPROC
PROCEDURE initdigit
* // Ausblenden sämtlicher Bits
FOR EACH oDigit IN This.Controls
oDigit.Visible = .F.
ENDFOR
ENDPROC
ENDDEFINE
DEFINE CLASS imgdigithorizontal AS image
Picture = "..\_bitmaps\inf_digit_horizontal.bmp"
BackStyle = 0
Height = 9
Width = 28
_1 = .F.
_2 = .F.
_3 = .F.
_4 = .F.
_5 = .F.
_6 = .F.
_7 = .F.
_8 = .F.
_9 = .F.
_0 = .F.
ENDDEFINE
DEFINE CLASS imgdigitvertical AS image
Picture = "..\_bitmaps\inf_digit_vertical.bmp"
Height = 28
Width = 9
_1 = .F.
_2 = .F.
_3 = .F.
_4 = .F.
_5 = .F.
_6 = .F.
_7 = .F.
_8 = .F.
_9 = .F.
_0 = .F.
ENDDEFINE
DEFINE CLASS imgTemplate AS image
Picture = "..\_bitmaps\inf_digit_template.bmp"
Height = 71
Width = 38
ENDDEFINE
Abonnieren
Posts (Atom)