ABOUT Visual Basic Programmieren Programmierung Download Downloads Tips & Tricks Tipps & Tricks Know-How Praxis VB VBA Visual Basic for Applications VBS VBScript Scripting Windows ActiveX COM OLE API ComputerPC Microsoft Office Microsoft Office 97 Office 2000 Access Word Winword Excel Outlook Addins ASP Active Server Pages COMAddIns ActiveX-Controls OCX UserControl UserDocument Komponenten DLL EXE
Diese Seite wurde zuletzt aktualisiert am 30.01.2001

Diese Seite wurde zuletzt aktualisiert am 30.01.2001
Aktuell im ABOUT Visual Basic-MagazinGrundlagenwissen und TechnologienKnow How, Tipps und Tricks rund um Visual BasicActiveX-Komponenten, Controls, Klassen und mehr...AddIns für die Visual Basic-IDE und die VBA-IDEVBA-Programmierung in MS-Office und anderen AnwendungenScripting-Praxis für IE, Windows Scripting Host und das Scripting-ControlTools, Komponenten und Dienstleistungen des MarktesRessourcen für Programmierer (Bücher, Job-Börse)Dies&Das...

Themen und Stichwörter im ABOUT Visual Basic-Magazin
Code, Beispiele, Komponenten, Tools im Überblick, Shareware, Freeware
Ihre Service-Seite, Termine, Job-Börse
Melden Sie sich an, um in den vollen Genuss des ABOUT Visual Basic-Magazins zu kommen!
Informationen zum ABOUT Visual Basic-Magazin, Kontakt und Impressum

Zurück...

Zurück...


Anzeige

(-hg) mailto:hg_cucl@aboutvb.de


Sind Sie auch schon an dieser Fehlermeldung verzweifelt, wenn Sie versucht haben, eine Referenz auf das UserControl-Objekt als Parameter einer Methode (etwa einer Klasse) oder Funktion (in einem Standard-Modul) zu übergeben? Wenn dieser Versuch nicht vergebens wäre, könnten Sie vom anvisierten Ziel aus über die Eigenschaften, Methoden und Ereignisse des UserControl-Objekts verfügen - gerade so, wie Sie etwa über ein Form verfügen können, dessen Referenz Sie weitergereicht haben. Damit wir uns nicht missverstehen: Gemeint ist der Zugriff auf das UserControl-Objekt selbst (zum Beispiel der Zugriff auf UserControl.BackColor usw.), und nicht auf das Control, das Sie damit gerade programmieren wollen.

Nach ein paar Experimenten werden auch Sie vielleicht darauf gekommen sein, dass die Übergabe funktioniert, wenn der Parameter als Variant deklariert und die Referenz als Wert (ByVal) übergeben wird:

Public Sub TuWas(ByVal UserControlObject As Variant)

Nun können Sie auf die Methoden und Eigenschaften des UserControl-Objekts zugreifen:

   UserControlObject.BackColor = vbRed
End Sub

Sogar das Ablegen der so übergebenen Referenz auf das UserControl-Objekt zur weiteren Verwendung in einer lokalen Objekt-Variablen des Datentyps Object funktioniert:

Private mUserControl As Object

Public Sub StoreUserControl(ByVal UserControlObject As Variant)
  Set mUserControl = UserControlObject
End Sub

Public Sub TuWas()
  mUserControl.BackColor = vbCyan
End Sub

Immerhin können wir so mit der Referenz einiges anfangen, auch wenn wir sie so leider nur in so genannter "später" Bindung verwenden können.

Damit bleibt nun noch ein Punkt zu knacken: die Deklaration der Objekt-Variablen "As UserControl". Damit würden wir zum einen die so genannte "frühe" (und wesentlich schnellere) Bindung erreichen.

Hoppla, Sie wissen nicht, was es mit dieser frühen oder späten "Pünktlichkeit" der Bindung anscheinend auf sich hat? Okay, entweder gedulden Sie sich, bis ich einmal die Muße finde, darüber einen Artikel zu schreiben. Oder Sie lesen baldmöglichst ein sehr empfehlenswertes Buch und lernen damit auch noch das gesamte Fundament der COM-/ActiveX-Programmierung mit Visual Basic kennen: Bibliothek - com/activex-komponenten..."com/activex-komponenten...".

Nun, weiter im Kontext: Zum anderen könnten wir aus der lokalen Objekt-Variablen auch einen Ereignisempfänger machen. Wie ich im Artikel KnowHow: Lausch-EingriffeLausch-Eingriffe gezeigt habe, können Sie ohne weiteres über eine als Ereignisempfänger per WithEvents ... As Form deklarierte Objekt-Variable die Ereignisse eines Forms außerhalb desselben abfangen. Doch der analoge Versuch, das gleiche mit einem UserControl-Objekt zu veranstalten (WithEvents ... As UserControl), geht schief.

Das heißt, nicht ganz - bei der Deklaration der Objekt-Variablen macht uns Visual Basic nämlich noch keinen Strich durch die Rechnung. Aber beim Versuch der Zuweisung der doch so elegant übergebenen Referenz bekommen wir wieder eine frustrierende Fehlermeldung vor die Nase gesetzt: "Laufzeitfehler 13 - Typen unverträglich". Ich habe wohl so ziemlich alle Möglichkeiten durchgespielt - Deklarationen variiert, mit Konvertierfunktionen und deren Parametern herumgespielt, mit ByVal und ByRef... - eine letztlich so simple Möglichkeit wie das obenstehende "ByVal As Variant" scheint es hierfür nicht zu geben - oder kennen Sie zufällig eine? Dann nichts wie her damit...!

Schließlich habe ich aber doch noch eine Lösung gefunden. Sie beruht darauf, die übergebene Objekt-Referenz per Zeiger-Kopie einer als UserControl deklarierten Objekt-Variablen unterzujubeln und damit zugleich von allem Ballast, der zuvor bei unseren Versuchen die VB-Alarmglocke schrillen ließ, zu befreien. Dazu verwenden wir die API-Funktion MSDN Library - API RtlMoveMemoryRtlMoveMemory (die üblicherweise wie auch sinnfälligerweise per Alias-Deklaration in CopyMemory umgetauft wird) und die undokumentierte VB-Funktion ObjPtr, die den Referenz-Zeiger auf eine Objekt-Variable liefert. Dieses Kopier-Verfahren wird in der COM-Programmierung des öfteren genutzt, wenn mit nicht gerade VB-freundlichen bzw. nicht VB-konformen COM-Schnittstellen und Typbibliotheken hantiert wird. Erwarten Sie aber bitte nicht, dass ich hier weiter darauf eingehe - das würde an dieser Stelle zu weit führen.

Jedoch habe ich, wie immer, für Sie die notwendigen Code-Zeilen in eine Hilfsfunktion gepackt. Damit wir unser Gedächtnis nicht überstrapazieren, wenn wir die Funktion benötigen, habe ich sie CUcl genannt - ganz auf der Linie von CInt, CVar, CDate und dergleichen.

Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _
 (VarDest As Any, VarSource As Any, ByVal BytesToCopy As Long)

Public Function CUcl(ByVal iUCL As Variant) As UserControl
  Dim nUCL As UserControl
  
  CopyMemory nUCL, ObjPtr(iUCL), 4
  Set CUcl = nUCL
  CopyMemory nUCL, 0&, 4
End Function

Das Belauschen der inneren Ereignisse eines UserControls in einer Klasse oder einem anderen UserControl geht nun wie gewohnt und fast wie von selbst vonstatten. In einer lauschenden Klasse (etwa namens cHookUserControl) sähe der Code beispielsweise so aus:

Private WithEvents eUserControl As UserControl

Public Sub Init(UserControlObject As UserControl)
  Set eUserControl = UserControlObject
End Sub

Private eUserControl_Click()
  MsgBox "Extern abgefangener Click auf ein UserControl"
End Sub

Und im UserControl konvertieren Sie das UserControl-Objekt mit CUcl, bevor Sie die Referenz an eine Klasse nach dem obenstehenden Muster übergeben:

Private pHookUCL As cHookUserControl

Private Sub UserControl_ReadProperties(PropBag As PropertyBag)
  Set pHookUCL = New cHookUserControl
  pHookUCL.Init CUcl(UserControl)
End Sub

Das gleiche Verfahren können Sie übrigens auch für das KnowHow: UserDocument unter KontrolleUserDocument-Objekt verwenden.


Beispiel-Projekt zu CUcl (cucl.zip - ca. 3,5 KB)






Themen - Allgemeines
Themen - Entwicklungsumgebung (VB-IDE)
Themen - Forms
Themen - Steuerelemente (Controls)
Themen - Grafik
Themen - Dateien
Themen - UserControls
Themen - Einsteiger-Tipps
Themen - Wussten Sie...?

Übersicht nach Titeln in alphabetischer Reihenfolge
Übersicht nach Erscheinungsdatum

Schnellsuche




Zum Seitenanfang

Copyright © 1999 - 2017 Harald M. Genauck, ip-pro gmbh  /  Impressum

Zum Seitenanfang

Zurück...

Zurück...

Download Internet Explorer