Korrekturhinweis zum Tipp 1231 "UDT als Parameter einer Klassenprozedur'" per API-Funktion "rtlMoveMemory" Der Tipp UDT als Parameter einer Klassen-Prozedur ist irreführend. Bei der Festlegung des Geltungsbereichs von Prozeduren in Klassenmodulen stellt VB6 drei Möglichkeiten zur Verfügung:
Bei Klassen in Standard-Exe Projekten ist prinzipiell die Instancing-Eigenschaft 'Private'. Andere ActiveX-Objekte können nicht auf solche Klassen zugreifen. Dem EXE-Projekt fehlt ja die ActiveX-Umgebung. Es kann zwar selber ActiveX-Objekte ankoppeln - aber nicht an andere angekoppelt werden. Insofern ist das Schlüsselwort 'Public' für Prozeduren in Klassen, die in Standard-Exe-Projekten definiert sind, eigentlich sinnlos. Genau genommen werden deren Prozeduren wie 'Friend' behandelt, weil sie nur innerhalb des Projekts sichtbar sind. Aus dem Abschnitt 'Friend-Eigenschaften und -Methoden' in der VB6-Dokumentation: Soweit die Dokumentation. Damit wird die Lösung des Problems erkennbar. In Standard-Exe-Projekten akzeptieren als 'Friend' deklarierte Klassenprozeduren öffentliche UDTs, die in Standardmodulen definiert sind!! Bei der Deklaration von Ereignissen ist das Schlüsselwort 'Friend' nicht zulässig. Hier muss man sich tatsächlich mit der Ausgabe eines Pointers auf eine Variable des Datentyps behelfen und mit rtlMoveMemory kopieren, wie es in Tipp 1231 vorgemacht wird, was aber nur bei elementaren numerischen Datentypen zu empfehlen ist. Einige weitere nützliche Hinweise: Der Nachteil der Deklaration von Klassen-Prozeduren als 'Friend' besteht darin, dass auf sie nicht von anderen AktiveX-Objekten zugegriffen werden kann. Zudem gilt:
Klassen bieten gegenüber Datentypen zahlreiche Vorteile (die Initialisierung, díe Überwachung der Zuweisungen in Property-Prozeduren, die Definition von Ereignissen u.v.a.). Beispiel:
' --------------------------------------------------------- ' Code bitte in das Start-Formular Form1 einfügen Option Explicit ' Kopierfunktion Windows-API Private Declare Sub CopyMemory Lib "kernel32" _ Alias "RtlMoveMemory" ( _ ByVal Addr As Long, _ ByVal source As Long, _ ByVal bytes As Long) ' Zugriffsvariable zu einer Instanz der Klasse (mit Ereignissen) Dim WithEvents cl As Class1 Sub cl_Meldung(ByVal pointer As Long) ' Ereignis ' (ausgelöst von Instanz cl des Klassenmoduls class1) Dim t As MyTyp ' WARNUNG: Variable vom Typ String (Deskriptor-Kopie) ' sowie variable Arrays können hier ernste Probleme machen !!!! ' Die Anwendung ist deshalb nur bei numerischen Datentypen ' zu empfehlen CopyMemory VarPtr(t), pointer, Len(t) With t MsgBox "Meldung: " + vbCrLf + .comment + vbCrLf + _ .s + vbCrLf + CStr(.v) + vbCrLf + CStr(.z) + vbCrLf + CStr(.d) + vbCrLf + .st.s End With End Sub Private Sub Form_Load() ' Formular anzeigen Me.Show ' Instanz der Klasse erstellen Set cl = New Class1 ' Variable des Demotyps in 'Module1' deklarieren Dim t As MyTyp ' Variable mit Werten füllen With t .v = CDec("100,123") .s = "was man als Typ so braucht" .d = -1234567890.12346 .z = CDate("22:45:18") ' einige Werte des Untertyps füllen .st.z = CDate("14:20:25") .st.s = "Untertyp" .comment = "Ich möchte in cl eingetragen werden" End With ' Zuweisung der Eigenschaft (geschieht automatisch ByVal) cl.Eigenschaft = t ' der Inhalt des Elements 'Comment' hat sich nicht geändert ' obwohl in der Property eine Zuweisung erfolgt ist Debug.Print "Formular: "; t.comment ' Die abgefragten Daten anzeigen With cl.Eigenschaft MsgBox "Abgefragte Daten: " + vbCrLf + _ .s + vbCrLf + CStr(.d) + vbCrLf + CStr(.v) + _ vbCrLf + CStr(.z) + vbCrLf + CStr(.st.s) + vbCrLf + .comment End With ' Ereignismeldung im Klassenmodul auslösen cl.Melde ' Objekt wieder zerstören Set cl = Nothing End Sub ' Codeende - Formular Form1 ' -------------------------------------------------------- Code für Modul "Module1" ' ------------------------------------------------- ' Code bitte in Standardmodul Module1 einfügen Option Explicit ' in MyType enthaltener Untertyp ' (muss vor MyType deklariert werden) Public Type MySubTyp s As String d As Double v As Variant z As Date comment As String End Type ' öffentlicher Demo-Datentyp in Standardmodul ' Elemente bestehen aus diversen Datentypen Public Type MyTyp s As String d As Double v As Variant z As Date comment As String st As MySubTyp End Type ' Codeende - Standardmodul Module1 ' -------------------------------------------------------- Code für das Klassenmodul "Class1" ' -------------------------------------------------------- ' Code bitte einfügen in Klassenmodul Class1 Option Explicit ' Variablen zur Speicherung der Daten der Eigenschaft ' Variable zum Speichern des Inhalts eines Datentyps ' (Friend geht hier nicht, aber der ' öffentliche Datentyp steht zur Verfügung !!) Private gt As MyTyp ' Ereignis definieren ('Friend' nicht möglich) Public Event Meldung(ByVal pointer As Long) Friend Property Let Eigenschaft(ByRef t As MyTyp) ' Eigenschaft akzeptiert eine UDT, die an ein ' Klassenmodul übergeben wird ' Auslesen der Daten aus der übergebenen Datentyp-Variable ' und Speichern in der klasseninternen Datentyp-Variable gt = t ' Die folgende Zuweisung wird in LET_Property nicht zurückgegeben !! ' (byref wird ignoriert !) t.comment = "Ich war in Class1 / Eigenschaft LET" End Property Friend Property Get Eigenschaft() As MyTyp ' Abfrage der gespeicherten Daten ' aus der modulglobalen Variable Eigenschaft = gt Eigenschaft.comment = "Daten aus Class1 / abgefragt durch Eigenschaft GET" End Property Public Function Melde() ' Die Funktion löst das Ereignis 'Meldung' aus ' Die Meldung liefert nur einen Zeiger auf die internen Daten RaiseEvent Meldung(VarPtr(gt)) End Function ' Codeende - Klassenmodul Class1 ' -------------------------------------------------------- Dieser Tipp wurde bereits 14.766 mal aufgerufen. Voriger Tipp | Zufälliger Tipp | Nächster Tipp
Anzeige
Diesen und auch alle anderen Tipps & Tricks finden Sie auch auf unserer aktuellen vb@rchiv Vol.6 Ein absolutes Muss - Geballtes Wissen aus mehr als 8 Jahren vb@rchiv! - nahezu alle Tipps & Tricks und Workshops mit Beispielprojekten - Symbol-Galerie mit mehr als 3.200 Icons im modernen Look Weitere Infos - 4 Entwickler-Vollversionen (u.a. sevFTP für .NET), Online-Update-Funktion u.v.m. |
vb@rchiv CD Vol.6 Geballtes Wissen aus mehr als 8 Jahren vb@rchiv! Online-Update-Funktion Entwickler-Vollversionen u.v.m. Tipp des Monats Dezemeber 2024 Roland Wutzke MultiSort im ListView-Control Dieses Beispiel zeigt, wie sich verschiedene Sortierfunktionen für ein ListView Control realisieren lassen. Neu! sevPopUp 2.0 Dynamische Kontextmenüs! Erstellen Sie mit nur wenigen Zeilen Code Kontextmenüs dynamisch zur Laufzeit. Vordefinierte Styles (XP, Office, OfficeXP, Vista oder Windows 8) erleichtern die Anpassung an die eigenen Anwendung... |
||||||||||||||||
Microsoft, Windows und Visual Basic sind entweder eingetragene Marken oder Marken der Microsoft Corporation in den USA und/oder anderen Ländern. Weitere auf dieser Homepage aufgeführten Produkt- und Firmennamen können geschützte Marken ihrer jeweiligen Inhaber sein. |