Freigeben über


TN039: MFC/OLE-Automatisierungsimplementierung

Hinweis

Der folgende technische Hinweis wurde seit dem ersten Erscheinen in der Onlinedokumentation nicht aktualisiert.Daher können einige Verfahren und Themen veraltet oder falsch sein.Um aktuelle Informationen zu erhalten, wird empfohlen, das gewünschte Thema im Index der Onlinedokumentation zu suchen.

Übersicht von IDispatch Schnittstelle OLE

Die IDispatch-Schnittstelle ist die Möglichkeit, durch die Anwendungen so Methoden und Eigenschaften verfügbar machen, dass andere Anwendungen wie Visual Basic oder andere Sprachen, die Funktionen der Anwendung nutzen können. Der wichtigste Teil dieser Schnittstelle ist die IDispatch::Invoke-Funktion. MFC verwendet "Dispatchzuordnungen", IDispatch::Invoke verwendet. Die Dispatchzuordnung stellt die MFC-Implementierungsinformationen auf das Layout oder "Form" der von CCmdTarget abgeleiteten Klassen, so, dass die Eigenschaften des Objekts direkt bearbeiten können, bereit oder ruft Memberfunktionen innerhalb des Objekts auf, um IDispatch::Invoke Anforderungen zu erfüllen.

In den meisten Fällen arbeitet Der Klassen-Assistent und MFC zusammen, um die meisten Details der OLE-Automatisierung vom Anwendungsprogrammierer auszublenden. Der Programmierer werden die tatsächlichen Funktionen, die in der Anwendung verfügbar gemacht und muss sich nicht um die zugrunde liegende Verkabelung kümmern.

Es gibt Fälle jedoch wenn es erforderlich ist, zu verstehen, die MFC im Hintergrund macht. Dieser Hinweis anspricht, wie das Framework DISPIDs zu Memberfunktionen und Eigenschaften zuweisen. Kenntnisse der Verwendung des Algorithmus MFC zum Zuweisen von DISPIDs ist nur erforderlich, wenn Sie die IDs wissen müssen, z, wenn Sie eine "Typbibliothek" für Objekte der Anwendung erstellen.

Zuweisung DISPID MFC

Obwohl der Endbenutzer mit Automatisierungsserver (ein Visual Basic-Benutzer, beispielsweise), die tatsächlichen Namen der Automatisierung aktivierten Eigenschaften und Methoden in ihrem Code (z obj.ShowWindow) erkennt, empfängt die Implementierung von IDispatch::Invoke nicht die tatsächlichen Namen. Für Optimierungsgründe erhält sie DISPID, das ein 32-Bit-" Magic Cookie" ist, das die Methode oder Eigenschaft beschreibt, auf die zugegriffen werden soll. DISPID Diese Werte werden von der IDispatch - Implementierung durch eine andere Methode zurückgegeben, genannt IDispatch::GetIDsOfNames. Eine Automatisierungsclientanwendung ruft GetIDsOfNames einmal für jeden Member oder Eigenschaft auf, die sie vorgesehen zuzugreifen und speichert sie für neuere IDispatch::Invoke- Aufrufe zwischen. Dadurch, die teure Zeichenfolgensuche ist nur einmal pro Objektverwendung, und nicht einmal pro Aufruf IDispatch::Invoke ausgeführt.

MFC bestimmt das DISPIDs für jede Methode und Eigenschaft basierend auf zwei Dinge:

  • Der Abstand zwischen dem oberen Rand der Dispatchzuordnung Verwandter (1)

  • Der Abstand der Dispatchzuordnung von der am stärksten abgeleiteten Klasse Verwandter (0)

DISPID wird in zwei Teilen. LOWORDDISPID enthält die erste Komponente, den Abstand zwischen dem oberen Rand der Dispatchzuordnung. HIWORD enthält den Abstand von der am stärksten abgeleiteten Klasse. Beispiel:

class CDispPoint : public CCmdTarget
{
public:
    short m_x, m_y;
    ...
    DECLARE_DISPATCH_MAP()
    ...
};

class CDisp3DPoint : public CDispPoint
{
public:
    short m_z;
    ...
    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, gibt es zwei Klassen, die OLE-Automatisierungs-Schnittstellen verfügbar machen. Eine dieser Klassen wird von der anderen abgeleitet und folglich die Funktionen der Basisklasse, einschließlich des OLE-Automatisierungs-Teil nutzt (x- "" und "y " Eigenschaften in diesem Fall).

MFC generiert DISPIDs für Klasse CDispPoint, wie folgt:

property X    (DISPID)0x00000001
property Y    (DISPID)0x00000002

Da die Eigenschaften in einer Basisklasse nicht sind, ist HIWORDDISPID immer null (der Abstand von der am stärksten abgeleiteten Klasse für CDispPoint ist null).

MFC generiert DISPIDs für Klasse CDisp3DPoint, wie folgt:

property Z    (DISPID)0x00000001
property X    (DISPID)0x00010001
property Y    (DISPID)0x00010002

Die Z-Eigenschaft wird DISPID mit null HIWORD angegeben, wie es in der Klasse, die die Eigenschaften verfügbar macht, CDisp3DPoint definiert wird. Da den x- und Y-Eigenschaften werden in einer Basisklasse, HIWORDDISPID ist 1, seit der Klasse, in der diese Eigenschaften ist in einem bestimmten Abstand von einer Ableitung von der am stärksten abgeleiteten Klasse definiert werden.

Hinweis

LOWORD wird immer durch die Position in der Zuordnung bestimmt, wenn Einträge in der Zuordnung mit explizitem DISPID vorhanden sind (siehe nächsten Abschnitt zu Informationen über das _ID-Versionen der Makros DISP_PROPERTY und DISP_FUNCTION ).

Erweiterte MFC-Dispatchzuordnungs-Funktionen

Es gibt verschiedene weitere Funktionen, die die nicht in dieser Version von Visual C++ unterstützt. Der Klassen-Assistent unterstützt DISP_FUNCTION, DISP_PROPERTY und DISP_PROPERTY_EX, die eine Methode, eine Membervariableneigenschaft definieren und/eine Funktionseigenschaft des festgelegten Members, bzw. abrufen. Diese Funktionen sind normalerweise alle, die erforderlich ist, um die meisten Automatisierungsserver zu erstellen.

Die folgenden zusätzlichen Makros können verwendet werden, wenn die die unterstützten Makros nicht angemessen sind: DISP_PROPERTY_NOTIFY und DISP_PROPERTY_PARAM.

DISP_PROPERTY_NOTIFY - Makrobeschreibung

DISP_PROPERTY_NOTIFY( 
   theClass, 
   pszName, 
   memberName, 
   pfnAfterSet, 
   vtPropType 
)

Hinweise

Parameter

  • theClass
    Name der Klasse.

  • pszName
    Externer Name der Eigenschaft.

  • memberName
    Name der Membervariable, in der die Eigenschaft gespeichert wird.

  • pfnAfterSet
    Name der Memberfunktion, der aufgerufen werden soll, wenn Eigenschaft geändert wird.

  • vtPropType
    Ein Wert, der den Typ der Eigenschaft an.

Hinweise

Dieses Makro ist ähnlich wie DISP_PROPERTY, außer dass es akzeptiert ein zusätzliches Argument. Das zusätzliche Argument, pfnAfterSet, sollte eine Memberfunktion sein, die ausschließlich zurückgibt und keine Parameter annimmt, OnPropertyNotify() "null". Sie wird aufgerufen, nachdem die Membervariable geändert wurde.

DISP_PROPERTY_PARAM - Makrobeschreibung

DISP_PROPERTY_PARAM( 
   theClass,
   pszName,
   pfnGet,
   pfnSet,
   vtPropType,
   vtsParams 
)

Hinweise

Parameter

  • theClass
    Name der Klasse.

  • pszName
    Externer Name der Eigenschaft.

  • memberGet
    Name der Memberfunktion verwendet, um die Eigenschaft abzurufen.

  • memberSet
    Name der Memberfunktion verwendet, um die Eigenschaft festzulegen.

  • vtPropType
    Ein Wert, der den Typ der Eigenschaft an.

  • vtsParams
    Eine Zeichenfolge des Leerzeichens getrennt VTS_ für jeden Parameter.

Hinweise

Ähnlich wie das DISP_PROPERTY_EX-Makro wird in Makro eine Eigenschaft, die mit separatem zugegriffen wird, abrufen und des festgelegten Members Funktionen. Dieses Makro können Sie jedoch, um einer Parameterliste für die Eigenschaft an. Dies ist für die Implementierung von Eigenschaften sinnvoll, die auf andere Weise indiziert oder parametrisiert werden. Die Parameter immer zuerst platziert, gefolgt durch den neuen Wert für die Eigenschaft. Beispiel:

DISP_PROPERTY_PARAM(CMyObject, "item", GetItem, SetItem, VT_DISPATCH,    VTS_I2 VTS_I2)

würde entsprechen, abzurufen und um Features des festgelegten Members:

LPDISPATCH CMyObject::GetItem(short row, short col)
void CMyObject::SetItem(short row, short col, LPDISPATCH newValue)

DISP_XXXX_ID - Makrobeschreibungen

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 
)

Hinweise

Parameter

  • theClass
    Name der Klasse.

  • pszName
    Externer Name der Eigenschaft.

  • dispid
    Das festgelegte DISPID für die Eigenschaft oder Methode.

  • pfnGet
    Name der Memberfunktion verwendet, um die Eigenschaft abzurufen.

  • pfnSet
    Name der Memberfunktion verwendet, um die Eigenschaft festzulegen.

  • memberName
    Der Name der der Eigenschaft zuzuweisen Membervariable,

  • vtPropType
    Ein Wert, der den Typ der Eigenschaft an.

  • vtsParams
    Eine Zeichenfolge des Leerzeichens getrennt VTS_ für jeden Parameter.

Hinweise

Diese Makros bieten die Möglichkeit, DISPID, anstatt, MFC werden, anzugeben zuweisen automatisch ein. Diese erweiterte Makros haben die gleichen Namen, außer dass ID wird dem Makronamen angefügt (z. DISP_PROPERTY_ID) und die ID wird vom Parameter ermittelt, der gleich nach dem Parameter pszName angegeben wird. Siehe AFXDISP.H weitere Informationen zu diesen Makros. Die _ID Einträge müssen am Ende der Dispatchzuordnung platziert werden. Sie beeinflussen die automatische DISPID Generation, ebenso wie eine Nicht-_ID-Version des Makros wurde (das DISPIDs werden durch die Position festgelegt). Beispiel:

BEGIN_DISPATCH_MAP(CDisp3DPoint, CCmdTarget)
    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 generiert DISPID für Klasse CDisp3DPoint, wie folgt:

property X    (DISPID)0x00020003
property Y    (DISPID)0x00000002
property Z     (DISPID)0x00000001

Festen DISPID festzulegen ist nützlich, die Abwärtskompatibilität zu einer bereits vorhandenen Dispatchschnittstelle beizubehalten, oder das Implementieren definierte bestimmtes System die Methoden oder Eigenschaften (normalerweise angegeben durch negatives DISPID, wie die DISPID_NEWENUM-Auflistung).

Abrufen der IDispatch-Schnittstelle für ein COleClientItem

Viele Server unterstützen Automatisierung in ihrer Dokumentobjekte, zusammen mit der OLE-Serverfunktionalität. Um zu dieser Automatisierungsschnittstelle zu erhalten, müssen auf die COleClientItem::m_lpObject-Membervariable direkt zugreifen. Der Code unten wird die IDispatch-Schnittstelle für ein Objekt ab, das von COleClientItem abgeleitet wird. Sie können den folgenden Code in die Anwendung aufnehmen, wenn die erforderliche Funktionalität finden:

LPDISPATCH CMyClientItem::GetIDispatch()
{
    ASSERT_VALID(this);
    ASSERT(m_lpObject != NULL);

    LPUNKNOWN lpUnk = m_lpObject;

    Run();    // must be running

    LPOLELINK lpOleLink = NULL;
    if (m_lpObject->QueryInterface(IID_IOleLink, 
        (LPVOID FAR*)&lpOleLink) == NOERROR)
    {
        ASSERT(lpOleLink != NULL);
        lpUnk = NULL;
        if (lpOleLink->GetBoundSource(&lpUnk) != NOERROR)
        {
            TRACE0("Warning: Link is not connected!\n");
            lpOleLink->Release();
            return NULL;
        }
        ASSERT(lpUnk != NULL);
    }

    LPDISPATCH lpDispatch = NULL;
    if (lpUnk->QueryInterface(IID_IDispatch, &lpDispatch) 
        != NOERROR)
    {
        TRACE0("Warning: does not support IDispatch!\n");
        return NULL;
    }

    ASSERT(lpDispatch != NULL);
    return lpDispatch;
}

Die Dispatchschnittstelle, die von dieser Funktion zurückgegeben wurde, könnte dann direkt verwendet werden oder COleDispatchDriver für typsicheren Zugriff angefügt werden. Wenn Sie diese direkt verwenden, überprüfen Sie, ob Sie deren Member von Version wenn mit den Zeiger aufrufen (Destruktor der COleDispatchDriver führt dies standardmäßig).

Siehe auch

Weitere Ressourcen

Technische Hinweise – nach Nummern geordnet

Technische Hinweise – nach Kategorien geordnet