Übersicht über die OLE-IDispatch-Schnittstelle
Die IDispatch -Schnittstelle ist, dass die Mittel, durch welche Anwendungen setzen Methoden, die und Eigenschaften so, dass andere Anwendungen wie Visual BASIC oder anderen Sprachen machen können, Features der Anwendung verwenden. Der wichtigste Teil dieser Schnittstelle ist die IDispatch:: Invoke -Funktion. MFC verwendet "Versand Karten" IDispatch:: Invokeimplementieren. Die Dispatchzuordnung stellt die MFC-Implementierungsinformationen auf das Layout oder die "Form" der Ihre CCmdTarget-abgeleiteten Klassen, so dass es kann direkt bearbeiten die Eigenschaften des Objekts, oder in Ihrem Objekt IDispatch:: Invoke Anforderungen erfüllen Memberfunktionen aufrufen.
Zum größten Teil, zusammenarbeiten Klassen-Assistent und der MFC um die meisten Details der OLE-Automatisierung aus der Anwendungsprogrammierer zu verbergen. Der Programmierer konzentriert sich auf die tatsächliche Funktionalität in der Anwendung verfügbar zu machen und nicht über die zugrunde liegenden Sanitär sorgen.
Es gibt Fälle, jedoch, wo es notwendig ist zu verstehen, was hinter den Kulissen MFC tut. Dieser Hinweis wird Adresse wie Rahmen DISPIDs Member-Funktionen und Eigenschaften zuweist. Kenntnisse über den Algorithmus, die, den MFC verwendet, für die Zuweisung von DISPIDs, ist nur erforderlich, wenn Sie für Ihre Anwendung Objekte die IDs, z. B. beim Erstellen einer Bibliothek"Typ" wissen müssen.
MFC DISPID-Zuordnung
Obwohl der Endbenutzer der Automatisierung (ein Visual Basic Benutzer, z. B.), sieht die tatsächlichen Namen der aktiviert der Automatisierung Eigenschaften und Methoden in ihrem Code (z. B. obj.ShowWindow), erhält die Implementierung von IDispatch:: Invoke nicht die tatsächlichen Namen. Aus Gründen der Optimierung erhält es eine DISPID, ist ein 32-Bit "magische Cookie", der beschreibt die Methode oder Eigenschaft abgerufen werden soll. Diese DISPID -Werte werden von der IDispatch -Implementierung durch eine andere Methode namens IDispatch:: GetIDsOfNameszurückgegeben. Eine Anwendung mit Automatisierungsclient wird rufen Sie GetIDsOfNames einmal für jeden Member oder die Eigenschaft, die sie zugreifen will, und Zwischenspeicherung für spätere Aufrufe IDispatch:: Invoke. Auf diese Weise wird die teure Zeichenfolge Suche nur einmal pro Objekt verwenden, anstatt einmal pro IDispatch:: Invoke -Aufruf durchgeführt.
MFC bestimmt die DISPIDs für jede Methode und Eigenschaft basierend auf zwei Dinge:
Die DISPID ist in zwei Teile gegliedert. Die LOWORD der die DISPID enthält die erste Komponente, den Abstand vom oberen Rand der Dispatchzuordnung. Die HIWORD enthält die Entfernung von der am meisten abgeleiteten Klasse. Zum Beispiel:
klasse CDispPoint: öffentliche CCmdTarget
{
Öffentliche:
&Nbsp; kurze M_x, M_y;
...
DECLARE_DISPATCH_MAP()
...
};
Klasse CDisp3DPoint: öffentliche CDispPoint
{
Öffentliche:
kurze M_y;
...
DECLARE_DISPATCH_MAP()
...
};
BEGIN_DISPATCH_MAP (CDispPoint, CCmdTarget)
DISP_PROPERTY (CDispPoint, "X", M_x, VT_I2)
DISP_PROPERTY (CDispPoint, "y", M_y, VT_I2)
END_DISPATCH_MAP()
BEGIN_DISPATCH_MAP (CDisp3DPoint, CDispPoint)
DISP_PROPERTY (CDisp3DPoint, "Z", M_z, VT_I2)
END_DISPATCH_MAP()
Wie Sie sehen können, gibt es zwei Klassen, die OLE-Automatisierungsschnittstellen verfügbar machen. Einer dieser Klassen ist abgeleitet von dem anderen und so nutzt die Funktionalität der Basisklasse, einschließlich des OLE-Automatisierung Teils ("X" und "y" Eigenschaften in diesem Fall).
MFC DISPIDs für Klasse CDispPoint generiert wie folgt:
eige&nschaft Xnbsp; (DISPID) 0 X 00000001
Eigenschaft Y (DISPID) 0 x 00000002
Da die Eigenschaften nicht in einer Basisklasse, ist die HIWORD von die DISPID immer NULL (ist der Abstand von der am meisten abgeleiteten Klasse für CDispPoint).
MFC DISPIDs für Klasse CDisp3DPoint generiert wie folgt:
eige&nschaft Znbsp; (DISPID) 0 X 00000001
Eigenschaft X (DISPID) 0x00010001
Eigenschaft Y (DISPID) 00010002
Die Z-Eigenschaft wird eine DISPID mit einer NULL HIWORD gegeben, da es in der Klasse definiert ist, die die Eigenschaften, CDisp3DPoint verfügbar macht. Da die X- und Y-Eigenschaften in einer Basisklasse definiert sind, ist die HIWORD von die DISPID 1, da die Klasse, in der diese Eigenschaften definiert sind, in einem Abstand von einer Ableitung von der am meisten abgeleiteten Klasse.
Hinweis&Nbsp; Die LOWORD wird immer bestimmt durch die Position in der Karte, auch wenn Einträge in der Karte mit expliziten DISPID existieren (siehe nächster Abschnitt Hinweise auf den introtext Versionen der DISP_PROPERTY und DISP_FUNCTION Makros).
Erweiterte MFC Dispatch-Map-Funktionen
Es gibt eine Reihe von zusätzlichen Funktionen, die Klassen-Assistent nicht unterstützt in dieser Version von Visual C++. Klassen-Assistent unterstützt DISP_FUNCTION, DISP_PROPERTYund DISP_PROPERTY_EX , die eine Methode, Member-Variable-Eigenschaft und Funktion Get/Set-Elementeigenschaft, bzw. zu definieren. Diese Funktionen sind in der Regel alles, die was notwendig ist, um die meisten Automatisierungsserver erstellen.
Die folgenden zusätzlichen Makros können verwendet werden, wenn der Klassen-Assistent unterstützt Makros nicht ausreichen: DISP_PROPERTY_NOTIFYund DISP_PROPERTY_NOTIFY.
DISP_PROPERTY_NOTIFY — Makrobeschreibung
DISP_PROPERTY_NOTIFY (TheClass,,, siehePszNameMemberName,PfnAfterSet,VtPropType)
theClass
Name der Klasse.
pszName
Externe Name der Eigenschaft.
mitgliedsname
Name der Member-Variablen, in denen die Eigenschaft gespeichert ist.
pfnAfterSet
Name der Member-Funktion aufrufen, wenn Eigenschaft geändert wird.
vtPropType
Ein Wert, den Typ der Eigenschaft angibt.
Hinweis&Nbsp; Dieses Makro ähnelt DISP_PROPERTY, außer dass es ein zusätzliches Argument akzeptiert. Das zusätzliche Argument, PfnAfterSet, sollte eine Memberfunktion sein, die gibt nichts zurück und akzeptiert keine Parameter, die 'void OnPropertyNotify()'. Es wird nach genannt werden, die die Member-Variable geändert wurde.
DISP_PROPERTY_NOTIFY — Makrobeschreibung
DISP_PROPERTY_NOTIFY (TheClass PszName, PfnGet, PfnSet, VtPropType, VtsParams)
theClass
Name der Klasse.
pszName
Externe Name der Eigenschaft.
memberGet
Name der Memberfunktion verwendet, um das Abrufen der Eigenschaft.
elementgruppe
Name der Memberfunktion verwendet, um die Eigenschaft festzulegen.
vtPropType
Ein Wert, den Typ der Eigenschaft angibt.
vtsParams
Eine Zeichenfolge mit Leerzeichen getrennt VTS_ für jeden parameter.
Hinweis&Nbsp; Viel wie das DISP_PROPERTY_EX -Makro definiert dieses Makro eine Eigenschaft, die mit separaten Get und Set Memberfunktionen zugegriffen. Dieses Makro ermöglicht jedoch eine Parameterliste für die Eigenschaft angeben. Dies ist nützlich zum Implementieren von Eigenschaften, die indiziert oder parametrisiert werden auf andere Weise. Die Parameter werden immer zuerst, gefolgt von den neuen Wert für die Eigenschaft platziert werden. Zum Beispiel:
DISP_PROPERTY_NOTIFY (CMyObject, "Element" GetItem, SetItem, VT_DISPATCH, VTS_I2 VTS_I2)
entspräche abrufen und festlegen von memberfunktionen:
LPDISPATCH CMyObject::GetItem(short row, short col)
void CMyObject::SetItem (kurze Zeile, kurze Col, LPDISPATCH NewValue)
DISP_XXXX_ID — Makro Beschreibungen
DISP_FUNCTION_ID (TheClass PszName, Dispid, PfnMember, VtRetVal, VtsParams)
DISP_PROPERTY_ID (TheClass, PszName, Dispid, MemberName, VtPropType)
DISP_PROPERTY_NOTIFY_ID (TheClass PszName, Dispid, MemberName, PfnAfterSet, VtPropType)
DISP_PROPERTY_EX_ID (TheClass PszName, Dispid, PfnGet, PfnSet, VtPropType)
DISP_PROPERTY_PARAM_ID (TheClass, PszName, Dispid, PfnGet, PfnSet, VtPropType, VtsParams)
theClass
Name der Klasse.
pszName
Externe Name der Eigenschaft.
dispid
Die festen DISPID der Eigenschaft oder Methode.
pfnGet
Name der Memberfunktion verwendet, um das Abrufen der Eigenschaft.
pfnSet
Name der Memberfunktion verwendet, um die Eigenschaft festzulegen.
mitgliedsname
Der Name der Member-Variable der Eigenschaft zuordnen
vtPropType
Ein Wert, den Typ der Eigenschaft angibt.
vtsParams
Eine Zeichenfolge mit Leerzeichen getrennt VTS_ für jeden parameter.
Hinweis&Nbsp; Diese Makros können Sie angeben, eine DISPID statt MFC automatisch zuweisen zu lassen. Diese erweiterten Makros haben dieselben Namen, mit der Ausnahme, dass ID an den Namen des Makros (z. B. DISP_PROPERTY_ID) angehängt wird und die ID wird durch die nur nach dem PszName -Parameter angegebene Parameter bestimmt. Finden Sie unter AFXDISP.H für weitere Informationen zu diesen Makros. Der introtext -Einträge müssen am Ende die Dispatchzuordnung platziert werden. Sie wirkt sich die automatische DISPID -Generation in der gleichen Weise wie ein nicht -introtext Version des Makros würde (die DISPID-s sind bestimmt durch Position). Zum Beispiel:
BEGI&N_DISPATCH_MAP (CDisp3DPoint, CCmdTarget)
Nbsp; DISP_PROPERTY (CDisp3DPoint, "y", M_y, VT_I2)
DISP_PROPERTY (CDisp3DPoint, "Z", M_z, VT_I2)
DISP_PROPERTY_ID (CDisp3DPoint, "X", 0x00020003, M_x, VT_I2)
END_DISPATCH_MAP()
MFC DISPIDs für Klasse CDisp3DPoint wie folgt generiert:
eige&nschaft Xnbsp; (DISPID) 0X00020003
Eigenschaft Y (DISPID) 0 x 00000002
Eigenschaft Z (DISPID) 0 x 00000001
Angabe einer festen DISPID ist nützlich zur Erhaltung der Abwärtskompatibilität eine bereits vorhandene Dispatch-Schnittstelle, oder bestimmte System implementieren Methoden oder Eigenschaften (in der Regel gekennzeichnet durch eine negative DISPID, z. B. die Auflistung DISPID_NEWENUM ) definiert.
Abrufen der IDispatch-Schnittstelle für ein COleClientItem
Viele Server unterstützen Automatisierung innerhalb ihrer Dokumentobjekte, zusammen mit den Funktionen des OLE-Servers. Um Zugriff auf diese Automatisierungsschnittstelle zu erlangen, ist es notwendig, direkt auf die COleClientItem::m_lpObject -Membervariable zugreifen. Der Code unten wird die IDispatch -Schnittstelle für ein Objekt, die von COleClientItemabgeleitet abrufen. Sie können den folgenden Code in Ihre Anwendung einschließen, wenn Sie diese Funktionalität erforderlich finden
LPDISPATCH CMyClientItem::GetIDispatch()
{
Nbsp; ASSERT_VALID(this);
ASSERT (M_lpObject! = NULL);
LpUnk LPUNKNOWN = M_lpObject;
Run(); / / muss ausgeführt werden
LPOLELINK LpOleLink = NULL;
Wenn (M_lpObject - > QueryInterface (IID_IOleLink, (LPVOID fernen **) & LpOleLink) == NOERROR)
{
ASSERT (LpOleLink! = NULL);
LpUnk = NULL;
Wenn (LpOleLink - > GetBoundSource(&lpUnk)! = NOERROR)
{
TRACE0 ("Warning: Link ist nicht angeschlossen! \n");
LpOleLink - > Release();
NULL zurück;
}
ASSERT (LpUnk! = NULL);
}
LPDISPATCH LpDispatch = NULL;
Wenn (LpUnk - > QueryInterface (IID_IDispatch, & LpDispatch)! = NOERROR)
{
TRACE0 ("Warning: unterstützt keine IDispatch! \n");
NULL zurück;
}
ASSERT (LpDispatch! = NULL);
Rückkehr LpDispatch;
}
Die Dispatch-Schnittstelle zurückgegeben von diese Funktion dann direkt verwendet oder an eine COleDispatchDriver für typsicheren Zugriff angeschlossen werden konnte. Wenn Sie es direkt verwenden, stellen Sie sicher, dass Sie die Release -Element aufrufen Wenn durch mit dem Mauszeiger (der Destruktor COleDispatchDriver tut dies standardmäßig).
Technische Hinweise von &Nummer |nbsp; Technische Hinweise nach Kategorie