Seite 1 von 2

Kleine Sammlung von Macros

Verfasst: 11.03.2006 22:45
von technicorn
Hier einige Macros die ich benutzt:

Code: Alles auswählen

#STD_WINFLAGS = #PB_Window_TitleBar|#PB_Window_SystemMenu|#PB_Window_SizeGadget|#PB_Window_MinimizeGadget|#PB_Window_MaximizeGadget
#STD_WINFLAGS_FIXEDSIZE = #PB_Window_TitleBar|#PB_Window_SystemMenu

#STD_BUFFERSIZE = 4096

Macro mHASH
  #
EndMacro

Macro mDQUOTE
  "
EndMacro

Macro mSQUOTE
  '
EndMacro

Macro EnumNextBit
  (#PB_Compiler_EnumerationValue & (((#PB_Compiler_EnumerationValue & 1) = 0) * -1)) | (((#PB_Compiler_EnumerationValue >> 1) << 2) & (((#PB_Compiler_EnumerationValue & 1) = 1) * -1)) | (#PB_Compiler_EnumerationValue < 2)
EndMacro

Macro Ubound(array)
  (PeekL(@array - 8) - 1)
EndMacro

Macro ArrayType(array)
  PeekL(@array - 4)
EndMacro

Macro Inc(v)
  v = (v) + 1
EndMacro

Macro Dec(v)
  v = (v) - 1
EndMacro

Macro ReturnZeroIfFalse(test)
  If Not (test): ProcedureReturn 0: EndIf
EndMacro

Macro GetStartTime(v)
  v = ElapsedMilliseconds(): While v = ElapsedMilliseconds(): Wend: v = ElapsedMilliseconds()
EndMacro

Macro SetEnumValue(a)
  Enumeration a
  EndEnumeration
EndMacro

Macro IncEnumValue()
  Enumeration #PB_Compiler_EnumerationValue + 1
  EndEnumeration
EndMacro

Macro DecEnumValue()
  Enumeration #PB_Compiler_EnumerationValue - 1
  EndEnumeration
EndMacro

Macro SetConstantToEnumValue(c)
  Enumeration #PB_Compiler_EnumerationValue
    c
  EndEnumeration
EndMacro

Macro DQtMe(v)
  mDQUOTE#v#mDQUOTE
EndMacro

Macro SQtMe(v)
  mSQUOTE#v#mSQUOTE
EndMacro

CompilerIf #PB_Compiler_Debugger
Macro DbgIf(v)
  If v: EndIf
EndMacro
CompilerElse
Macro DbgIf(v)
EndMacro
CompilerEndIf

Macro DbgMVarL(v1, v2=xzy3267, v3=xzy3267, v4=xzy3267)
  CompilerIf Defined(v2, #PB_Variable)
  CompilerIf Defined(v3, #PB_Variable)
  CompilerIf Defined(v4, #PB_Variable)
  Debug DQtMe(v1) + " = " +Str(v1) + ",  " + DQtMe(v2) + " = " + Str(v2) + ",  " + DQtMe(v3) + " = " + Str(v3) + ",  " + DQtMe(v4) + " = " + Str(v4)
  CompilerElse
  Debug DQtMe(v1) + " = " +Str(v1) + ",  " + DQtMe(v2) + " = " + Str(v2) + ",  " + DQtMe(v3) + " = " + Str(v3)
  CompilerEndIf
  CompilerElse
  Debug DQtMe(v1) + " = " +Str(v1) + ",  " + DQtMe(v2) + " = " + Str(v2)
  CompilerEndIf
  CompilerElse
  Debug DQtMe(v1) + " = " +Str(v1)
  CompilerEndIf
EndMacro

Macro DbgVarUB(v,lvl=0)
  Debug DQtMe(v) + " = " + StrU(v, 0), lvl
EndMacro

Macro DbgVarUW(v, lvl=0)
  Debug DQtMe(v) + " = " + StrU(v, 1), lvl
EndMacro

Macro DbgVarUL(v, lvl=0)
  Debug DQtMe(v) + " = " + StrU(v, 2), lvl
EndMacro

Macro DbgVarUQ(v, lvl=0)
  Debug DQtMe(v) + " = " + StrU(v, 4), lvl
EndMacro

Macro DbgVarB(v, lvl=0)
  Debug DQtMe(v) + " = " + Str(v), lvl
EndMacro

Macro DbgVarW(v, lvl=0)
  Debug DQtMe(v) + " = " + Str(v), lvl
EndMacro

Macro DbgVarL(v, lvl=0)
  Debug DQtMe(v) + " = " + Str(v), lvl
EndMacro

Macro DbgVarQ(v, lvl=0)
  Debug DQtMe(v) + " = " + StrQ(v), lvl
EndMacro

Macro DbgVarF(v, lvl=0, d=-1)
  CompilerIf d = -1
  Debug DQtMe(v) + " = " + StrF(v), lvl
  CompilerElse
  Debug DQtMe(v) + " = " + StrF(v, d), lvl
  CompilerEndIf
EndMacro

Macro DbgVarD(v, lvl=0, d=-1)
  CompilerIf d = -1
  Debug DQtMe(v) + " = " + StrD(v), lvl
  CompilerElse
  Debug DQtMe(v) + " = " + StrD(v, d), lvl
  CompilerEndIf
EndMacro

Macro DbgVarS(v, lvl=0)
  Debug DQtMe(v) + " = " + v, lvl
EndMacro

Macro DbgVarSDQT(v, lvl=0)
  Debug DQtMe(v) + " = " + #DQUOTE$ + v + #DQUOTE$, lvl
EndMacro

Macro DbgVarSSQT(v, lvl=0)
  Debug DQtMe(v) + " = " + "'" + v + "'", lvl
EndMacro

Structure CHAR
  c.c
EndStructure

Structure CHARARRAY
  c.c[0]
EndStructure

Structure BYTEARRAY
  b.b[0]
EndStructure

Structure WORDARRAY
  w.w[0]
EndStructure

Structure LONGARRAY
  l.l[0]
EndStructure

Structure QUADARRAY
  q.q[0]
EndStructure

Structure FLOATARRAY
  f.f[0]
EndStructure

Structure DOUBLEARRAY
  d.d[0]
EndStructure

Structure STRINGARRAY
  s.s[0]
EndStructure

Structure ADDRARRAY
  a.l[0]  ; We might get quad memory addresses with PB5 ?! ;)
EndStructure

CompilerSelect #PB_Compiler_OS
  CompilerCase #PB_OS_Linux
    ; Macro PathSlash$
      ; "/"
    ; EndMacro
    #PathSlash$ = "/"
    #PathSlash = '/'
    #FilenamesCaseSensitive = -1
  CompilerCase #PB_OS_Windows
    ; Macro PathSlash$
      ; "\"
    ; EndMacro
    #PathSlash$ = "\"
    #PathSlash = '\'
    #FilenamesCaseSensitive = 0
    CompilerCase #PB_OS_MacOS
    ; I don't know Mac
CompilerEndSelect
Und ein Programm zum testen:

Code: Alles auswählen

;IncludePath #STD_IncludePath
XIncludeFile "standard_de.pbi"

DebugLevel 5

Structure ZTESTSTRUC
  l.l
  s.s
EndStructure

Procedure ShowStrings(*pSA.STRINGARRAY)
  Protected i
  
  For i = 0 To PeekL(*pSA - 8) - 1
    Debug *pSA\s[i]
  Next i
EndProcedure

Dim vb.b(10)
Dim vw.w(11)
Dim vl.l(12)
Dim vq.q(13)
Dim vf.f(14)
Dim vd.d(15)
Dim vs.s(16)
Dim vs$(17)
Dim vzts.ZTESTSTRUC(18)
Dim vmd.d(2,3,4)

Debug "Ubound() und ArrayType()"
Debug ""
Debug "Ubount(vb())      : " + Str(Ubound(vb()))
Debug "ArrayType(vb())   : " + Str(ArrayType(vb()))

Debug ""
Debug "Ubount(vw())      : " + Str(Ubound(vw()))
Debug "ArrayType(vw())   : " + Str(ArrayType(vw()))

Debug ""
Debug "Ubount(vl())      : " + Str(Ubound(vl()))
Debug "ArrayType(vl())   : " + Str(ArrayType(vl()))

Debug ""
Debug "Ubount(vq())      : " + Str(Ubound(vq()))
Debug "ArrayType(vq())   : " + Str(ArrayType(vq()))

Debug ""
Debug "Ubount(vf())      : " + Str(Ubound(vf()))
Debug "ArrayType(vf())   : " + Str(ArrayType(vf()))

Debug ""
Debug "Ubount(vd())      : " + Str(Ubound(vd()))
Debug "ArrayType(vd())   : " + Str(ArrayType(vd()))

Debug ""
Debug "Ubount(vs())      : " + Str(Ubound(vs()))
Debug "ArrayType(vs())   : " + Str(ArrayType(vs()))

Debug ""
Debug "Ubount(vs$())     : " + Str(Ubound(vs$()))
Debug "ArrayType(vs$())  : " + Str(ArrayType(vs$()))

Debug ""
Debug "Ubount(vzts())    : " + Str(Ubound(vzts()))
Debug "ArrayType(vzts()) : " + Str(ArrayType(vzts()))

Debug ""
Debug "Ubount(vmd())     : " + Str(Ubound(vmd()))
Debug "ArrayType(vmd())  : " + Str(ArrayType(vmd()))


byteVar.b = $FF
wordVar.w = $FFFF
longVar.l = $FFFFFFFF
quadVar.q = $FFFFFFFFFFFFFFFF
floatVar.f = 1.234567891234
doubleVar.d = 1.234567891234
stringVar$ = "Dies ist ein String mit $"
stringVar.s = "Dies ist ein String ohne $"

Debug ""
Debug ""
Debug "DbgVarx()"
DbgVarUB(byteVar)
DbgVarB(byteVar)
DbgVarUW(wordVar)
DbgVarW(wordVar)
DbgVarUL(longVar)
DbgVarL(longVar)
DbgVarUQ(quadVar)
DbgVarQ(quadVar)
DbgVarF(floatVar)
DbgVarF(floatVar,0,3)  ; Zeige nur drei Dezimalstellen
DbgVarD(doubleVar)
DbgVarD(doubleVar,0,3)  ; Zeige nur drei Dezimalstellen
DbgVarS(stringVar$)
DbgVarSDQT(stringVar$)
DbgVarSSQT(stringVar$)
DbgVarS(stringVar)
DbgVarSDQT(stringVar)
DbgVarSSQT(stringVar)

Debug ""
Debug ""
Debug "DbgVarx() nun mit DebugLevel, wird angezeigt, oder nicht"
DbgVarUB(byteVar, 5)
DbgVarB(byteVar, 5)
DbgVarUW(wordVar, 5)
DbgVarW(wordVar, 5)
DbgVarUL(longVar, 5)
DbgVarL(longVar, 5)
DbgVarUQ(quadVar, 5)
DbgVarQ(quadVar, 5)
DbgVarF(floatVar, 5)
DbgVarF(floatVar,5, 3)  ; Show only three decimals
DbgVarD(doubleVar, 5)
DbgVarD(doubleVar, 5, 3)  ; Show only three decimals
DbgVarS(stringVar$, 5)
DbgVarSDQT(stringVar$, 5)
DbgVarSSQT(stringVar$, 5)
DbgVarS(stringVar, 5)
DbgVarSDQT(stringVar, 5)
DbgVarSSQT(stringVar, 5)

Debug ""
Debug ""
Debug "Enum bit masks"

Enumeration   ; Startwert muss 0,1 oder ein 2^x Wert sein, ergibt aufeinander folgende Bitmasken
  #FlagBit1 = EnumNextBit
  #FlagBit2 = EnumNextBit
  #FlagBit3 = EnumNextBit
  #FlagBit4 = EnumNextBit
  #FlagBit5 = EnumNextBit
EndEnumeration

DbgVarL(#FlagBit1)
DbgVarL(#FlagBit2)
DbgVarL(#FlagBit3)
DbgVarL(#FlagBit4)
DbgVarL(#FlagBit5)

Debug ""
Debug ""
Debug "Benutzung der ARRAY Structures"
For i = 0 To Ubound(vs$())
  vs$(i) = "String" + Str(i)
Next i
*pStrArray.STRINGARRAY = @vs$()
Debug "Zeige Strings direkt"
For i = 0 To Ubound(vs$())
  Debug *pStrArray\s[i]
Next i
Debug ""
Debug "Zeige Strings mit einer Procedure"
ShowStrings(*pStrArray)

Debug ""
Debug ""
Debug "Inc(c), Dec(v)"
x1.l = 0
Debug "Vor Inc(): " + Str(x1)
Inc(x1)
Debug "Nach Inc(): " + Str(x1)
Dec(x1): Dec(x1)
Debug "Nach 2 * Dec(): " + Str(x1)

Debug ""
Debug #LF$ + "Getan"
Hatte ich auch schon im englischen Forum geposted, habe aber die Namen
etwas verkürzt: DebugXXX -> DbgXXX

Viel Spaß damit

Verfasst: 12.03.2006 01:31
von Macros
Der Titel hat mich erst mal irritiert :wink:

Verfasst: 12.03.2006 09:40
von Sylvia
Na, wenn es für dich einfacher ist, mSQUOTE zu schreiben anstatt ',
dann mag die Sache ja einen Gewinn für dich bringen. Mein Ding wäre
das nicht.

Und hoffentlich kannst du dir all deine Macros merken. Wäre doch
schade, wenn du ein Macro 'mHASH' definiert hast und schreibst
trotzdem noch aus versehen #. :wink:

Verfasst: 12.03.2006 10:21
von technicorn
Über die Namensgebung läßt sich ja noch streiten, aber der Sinn
ist nicht im ganzen Programm die " durch mDQUETE zu erstzen,
sondern versuch mal in einem Macro einen Teil eines Strings durch
den übergebenen Parameter zu ersetzten:

Code: Alles auswählen

Macro ZeigeFehlerA(e)
  PrintN("Der Fehler e ist aufgetretten")
EndMacro

ZeigeFehlerA(Kein Speicher mehr übrig) ->
PrintN("Der Fehler ' e ' ist aufgetretten")


Macro ZeigeFehlerB(e)
  PrintN("Der Fehler ' " + mDQUETE#e#mDQUETE+ " ' ist aufgetretten")
EndMacro

ZeigeFehlerB(Kein Speicher mehr übrig) ->
PrintN("Der Fehler ' " + "Kein Speicher mehr übrig" + " ' ist aufgetretten") ->
Auch das Zusammenstellen von Konstanten ohne sowas wie mHASH
ist nicht möglich, weil der Compiler Konstanten mit führendem # nicht ersetzt, mit

mHASH#EinName = 12345 -> #EinName = 12345

geht es aber.

Noch einen schönen Sonntag
technicorn

Verfasst: 12.03.2006 10:33
von ts-soft

Code: Alles auswählen

Macro Ubound(array)
  (PeekL(@array - 8) - 1)
EndMacro 
Das letzte -1 ist mir nicht ganz klar. Arrays in PB sind doch nullbasiert.

Verfasst: 12.03.2006 10:55
von technicorn
Bei PB sind im Speicher die Anzahl der Arraystellen abgelegt, nicht das
was man mit dem Dim a(x) angibt,

Code: Alles auswählen

Dim a(9)
Debug Ubound(a) ; Ergibt ohne -1, 10
                          ; Als Endwert für eine For Next Schleife
                          ; würdest Du auf das 10., nicht vorhandene, Element
                          ; Zugreifen.
Ubound() funktioniert auch bei mehrdimensionalen Arrays,
hier bekommt man dann die Gesamtanzahl der Elemente züruck

Code: Alles auswählen

Dim a(9,99)
Debug Ubound(a) ; Ergibt 1000, (0-9) * (0-99)
Die Größe einzelner Dimensionen ist nicht so leicht zu ermitteln, da
PB sie nicht wie angegeben ablegt, sondern nach einem Schema, daß
die Berechnung der Speicherstelle vereinfacht,
eine Rückrechnung ist aber möglich.
Die tatsächlieche Dimensionsgröße wird nur bei eingeschaltetem Debugger
in den Speicher geschrieben, war zumindest bis PB3.94 so.

Ich finde das ist bis jetzt ein großes Manko, was nützt einem die Möglichkeit,
Arrays an Proceduren zu übergeben, wenn ich in der Proc. die Größe nicht weiß?
Und die Größe jedesmal als Parameter mitübergeben, finde ich nicht so toll.

Edit:
Jetzt hab ich mich selbst reingelegt, das obige Beispiel ergibt natürlich
999, nicht 1000

Verfasst: 12.03.2006 11:03
von ts-soft
Ubound ermittelt doch die größe des Arrays (Elemente)

Code: Alles auswählen

Macro Ubound(array)
  (PeekL(@array - 8) - 1)
EndMacro

Dim a.l(10) ; 11 Elemente
Debug Ubound(a()) ; 10, verkehrt

Verfasst: 12.03.2006 11:12
von technicorn
Nein, in anderen Basicdialekten gibt Ubound den Wert der höchsten Array stelle zurück, nicht die Größe und ich wollte mich hier an die Allgemeine Konventionen halten, für die, die von anderen Basicsprachen verwendet werde.

Siehe Auszug FreeBasic, was sich wiederumg an QBasic orientiert:

UBOUND
Syntax: UBOUND(Array[, Dimension])
Typ: Funktion
Kathegorie: Speicherverwaltung

UBOUND gibt den höchsten Index zurück der in dem Array 'Array' verwendet werden kann.
Den Parameter Dimension gibt es bei PB aus oben genannten gründen nicht.

Gruß
technicorn

Verfasst: 12.03.2006 11:23
von ts-soft
Habs in der FB Hilfe nachgelesen, insofern haste Recht. Aber da in PB Arrays
immer Nullbasiert sind, würde das andere für mich mehr Sinn machen.
Okay, den heißt meine Version: IndexCount(Array), so heißt es jedenfalls in
GFA32

Verfasst: 12.03.2006 14:35
von Falko
Und was sagt denn Deine Version in GB32 (GFA-Basic) in der Referenz zu
UBound() und UBound((),n) aus?
:mrgreen:

Viele Grüße
Falko