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 den 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...

UserDocument unter Kontrolle

Zurück...


Anzeige

(-hg) mailto:hg_cudoc@aboutvb.de


Sind Sie auch schon an dieser Fehlermeldung verzweifelt, wenn Sie versucht haben, eine Referenz auf das UserDocument-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 UserDocument-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 UserDocument-Objekt selbst (zum Beispiel der Zugriff auf UserDocument.BackColor usw.), und nicht auf das Dokument-Objekt, das Sie so 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 UserDocumentObject As Variant)

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

  UserDocumentObject.BackColor = vbRed
End Sub

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

Private mUserDocument As Object

Public Sub StoreUserDocument(ByVal UserDocumentObject As Variant)
  Set mUserDocument = UserDocumentObject
End Sub

Public Sub TuWas()
  mUserDocument.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 UserDocument". Damit würden wir zum einen die so genannte "frühe" (und wesentlich schnellere) Bindung erreichen.

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 UserDocument-Objekt zu veranstalten (WithEvents ... As UserDocument), 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 UserDocument 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 CUDoc 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 CUDoc(ByVal iUDoc As Variant) As UserDocument
  Dim nUDoc As UserDocument
  
  CopyMemory nUDoc, ObjPtr(iUDoc), 4
  Set CUDoc = nUDoc
  CopyMemory nUDoc, 0&, 4
End Function

Das Belauschen der inneren Ereignisse eines UserDocuments in einer Klasse, einem auf dem UserDocument platzierten Steuerelement (UserControl) oder in anderen UserDocument geht nun wie gewohnt und fast wie von selbst vonstatten. In einer lauschenden Klasse (etwa namens cHookUserDocument) sähe der Code beispielsweise so aus:

Private WithEvents eUserDocument As UserDocument

Public Sub Init(UserDocumentObject As UserDocument)
  Set eUserDocument = UserDocumentObject
End Sub

Private eUserDocument_Click()
  MsgBox "Extern abgefangener Click auf ein UserDocument"
End Sub

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

Private pHookUDoc As cHookUserDocument

Private Sub UserDocument_ReadProperties(PropBag As PropertyBag)
  Set pHookUDoc = New cHookUserDocument
  pHookUDoc.Init CUDoc(UserDocument)
End Sub

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


Test-Projekt zu CUDoc (cudoc.zip - ca. 2,7 KB)


Artikel
Zum Download-Bereich dieses Artikel
Mail an den Autor dieses Artikels

KnowHow
Zur KnowHow-Übersicht

KnowHow-Themen
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