Udostępnij za pośrednictwem


TN039: Wdrożenie automatyzacji MFC/OLE

[!UWAGA]

Następujące Uwaga techniczna została zaktualizowana, ponieważ najpierw została uwzględniona w dokumentacji online.W rezultacie niektóre procedur i tematów może być nieaktualne lub nieprawidłowe.Najnowsze informacje zaleca się wyszukać temat zainteresowanie Indeks dokumentacji online.

Omówienie interfejsu IDispatch OLE

IDispatch Interfejsu jest środków, które aplikacje naraża metod i właściwości takich wchodzące w innych aplikacji, takich jak Visual BASIC lub w innych językach, użyj funkcji aplikacji.Najważniejszą częścią tego interfejsu jest IDispatch::Invoke funkcji.MFC używa "mapy wysyłki" do wdrożenia IDispatch::Invoke.Mapę wysyłki zawiera informacje implementacji MFC na układ lub "kształt" your CCmdTarget-uzyskane klas, takie, że można bezpośrednio manipulować właściwości obiektu lub wywołanie funkcji w obrębie obiektu, aby spełniać Członkowskie uwzględniając żądań.

W większości, ClassWizard i MFC współpracują w celu ukrycia większość szczegółów automatyzacji OLE z programista aplikacji.Programista koncentruje się na rzeczywiste funkcje dostępne w aplikacji i nie trzeba się martwić o podstawowej instalacji wodociągowej.

Istnieją przypadki, jednak gdy jest niezbędne do zrozumienia, co robi MFC w tle.Uwaga ta będzie dotyczyć jak przypisuje ramach DISPIDs do funkcji elementów członkowskich i właściwości.Znajomość algorytm MFC używane do przypisywania DISPIDs jest niezbędne tylko, gdy trzeba znać identyfikatorów, na przykład podczas tworzenia "biblioteki typów" obiekty aplikacji.

Przypisanie MFC DISPID

Chociaż końcowemu automatyzacji (Visual Basic użytkownika, na przykład), widzi rzeczywistej nazwy automatyzacji włączone właściwości i metod ich kodu (takich jak celShowWindow) wykonania IDispatch::Invoke nie otrzyma rzeczywistej nazwy.Ze względów optymalizacji odbiera DISPID, który jest 32-bitowych "magiczne cookie" opisujący metodę lub właściwość, która ma być dostępny.Te DISPID wartości są zwracane z IDispatch wykonania za pomocą innej metody, o nazwie IDispatch::GetIDsOfNames.Wywoła aplikację klienta automatyzacji GetIDsOfNames po dla każdego członka lub właściwość zamierza udzielić dostępu i buforowania ich później wywołań do IDispatch::Invoke.W ten sposób kosztowne ciąg wyszukiwania jest wykonywane tylko raz na użycie obiektu zamiast raz na IDispatch::Invoke wywołania.

Określa MFC DISPIDs dla każdej metody i właściwości na podstawie dwie rzeczy:

  • Odległość od góry mapę wysyłki (względem 1)

  • Odległość mapę wysyłki z najbardziej pochodna klasy (0 względnej)

DISPID jest podzielony na dwie części.LOWORD z DISPID zawiera pierwszego składnika, odległość od góry mapę wysyłki.HIWORD zawiera odległość od najbardziej pochodnej.Na przykład:

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()

Jak widać, istnieją dwie klasy, które narażają interfejsów automatyzacji OLE.Jeden z tych klas pochodzi z drugiego i zatem wpływa na funkcje klasy podstawowej, włącznie z częścią automatyzacji OLE ("x" i "y" właściwości w tym przypadku).

Wygeneruje MFC DISPIDs dla klasy CDispPoint w następujący sposób:

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

Ponieważ właściwości nie są w klasie bazowej, HIWORD z DISPID zawsze wynosi zero (odległość od najbardziej pochodna klasy dla CDispPoint jest równa zero).

Wygeneruje MFC DISPIDs dla klasy CDisp3DPoint w następujący sposób:

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

Biorąc pod uwagę właściwości z DISPID z zero HIWORD , ponieważ jest ona zdefiniowana w klasie, która jest ujawniany właściwości CDisp3DPoint.Ponieważ właściwości x i y są zdefiniowane w klasie bazowej, HIWORD z DISPID ma wartość 1, ponieważ klasa, w którym te właściwości są definiowane jest w odległości jednego wyprowadzenie z najbardziej pochodna klasy.

[!UWAGA]

LOWORD zawsze ustalona przez położenie na mapie, nawet jeśli istnieją zapisy w mapie z jawne DISPID (zobacz następna sekcja Informacje o _ID wersji DISP_PROPERTY i DISP_FUNCTION makr).

Zaawansowane funkcje mapę wysyłki MFC

Istnieje wiele dodatkowych funkcji, które nie obsługuje ClassWizard w tej wersji programu Visual C++.Obsługuje ClassWizard DISP_FUNCTION, DISP_PROPERTY, i DISP_PROPERTY_EX który zdefiniować metodę, zmienna właściwość elementu członkowskiego i właściwości funkcji get i set elementu członkowskiego, odpowiednio.Funkcje te są zazwyczaj wszystko, co jest potrzebne do tworzenia większości serwery automatyzacji.

Następujące dodatkowe makra można używać, gdy makra ClassWizard obsługiwane są nieodpowiednie: DISP_PROPERTY_NOTIFY, i DISP_PROPERTY_PARAM.

DISP_PROPERTY_NOTIFY — Opis makra

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

Uwagi

w7a36sdf.collapse_all(pl-pl,VS.110).gifParametry

  • theClass
    Nazwa klasy.

  • pszName
    Zewnętrzne nazwę właściwości.

  • memberName
    Nazwa zmiennej Członkowskie, w którym przechowywany jest właściwość.

  • pfnAfterSet
    Nazwa funkcji składowej do wywołania, gdy właściwość jest zmieniana.

  • vtPropType
    Wartość określająca typ właściwości.

Uwagi

Jest to makro, tak jak w DISP_PROPERTY, chyba że akceptuje dodatkowy argument.Dodatkowy argument pfnAfterSet, powinny być funkcji Członkowskich, która zwraca wartość nothing i nie ma parametrów "OnPropertyNotify() void".Zostanie wywołany po zmienna członka została zmodyfikowana.

DISP_PROPERTY_PARAM — Opis makra

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

Uwagi

w7a36sdf.collapse_all(pl-pl,VS.110).gifParametry

  • theClass
    Nazwa klasy.

  • pszName
    Zewnętrzne nazwę właściwości.

  • memberGet
    Nazwa funkcji składowej używane pobrać właściwości.

  • memberSet
    Nazwa funkcji składowej używany do ustawiania właściwości.

  • vtPropType
    Wartość określająca typ właściwości.

  • vtsParams
    Ciąg miejsca rozdzielone VTS_ dla każdego parametru.

Uwagi

Podobnie jak DISP_PROPERTY_EX makro, to makro określa właściwości, z oddzielnym Get i zestaw funkcji elementów członkowskich.To makro umożliwia jednak określić listę parametrów dla właściwości.Jest to użyteczne przy implementowaniu właściwości, które są indeksowane lub sparametryzowana w inny sposób.Parametry będą zawsze umieszczane najpierw następuje nową wartość dla właściwości.Na przykład:

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

odpowiadałby i ustawiania funkcji elementów członkowskich:

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

DISP_XXXX_ID — Makro opisy

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 
)

Uwagi

w7a36sdf.collapse_all(pl-pl,VS.110).gifParametry

  • theClass
    Nazwa klasy.

  • pszName
    Zewnętrzne nazwę właściwości.

  • dispid
    Stałe DISPID do właściwości lub metody.

  • pfnGet
    Nazwa funkcji składowej używane pobrać właściwości.

  • pfnSet
    Nazwa funkcji składowej używany do ustawiania właściwości.

  • memberName
    Nazwa zmiennej Członkowskie mapować do właściwości

  • vtPropType
    Wartość określająca typ właściwości.

  • vtsParams
    Ciąg miejsca rozdzielone VTS_ dla każdego parametru.

Uwagi

Te makra umożliwiają określenie DISPID zamiast pozwolić MFC automatycznie przypisać jeden.Te zaawansowane makra tych samych nazwach, z wyjątkiem, że ten identyfikator jest dołączana do nazwy makra (np.DISP_PROPERTY_ID) a identyfikator jest określona przez parametr tylko po pszName parametru.Zobacz AFXDISP.H więcej informacji na temat tych makr._ID zapisy muszą być umieszczone na końcu mapę wysyłki.Wpływają one automatycznego DISPID generacji w taki sam sposób jak innego niż-_ID wersji makro będzie ( DISPIDs są określane według pozycji).Na przykład:

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 wygeneruje identyfikatory DISPID dla klasy CDisp3DPoint w następujący sposób:

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

Określanie stałym DISPID jest przydatna do zachowania zgodności z poprzednimi wersjami istniejących wcześniej interfejsu wysyłki lub do wdrożenia niektórych właściwości lub metod zdefiniowany system (wskazywany zwykle przez negatywny DISPID, takich jak DISPID_NEWENUM kolekcji).

w7a36sdf.collapse_all(pl-pl,VS.110).gifTrwa pobieranie interfejsu IDispatch dla COleClientItem

Wiele serwerów będzie obsługiwać automatyzacji w ramach ich obiektów dokumentu, wraz z funkcjami serwera OLE.W celu uzyskania dostępu do tego interfejsu automatyzacji, jest niezbędne do dostępu bezpośrednio COleClientItem::m_lpObject zmienną.Poniższy kod pobiera IDispatch interfejsu dla obiektu pochodzące z COleClientItem.Jeśli ta funkcja Znajdź niezbędne w aplikacji można umieścić poniższy kod:

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;
}

Interfejs wysyłki zwrócony z tej funkcji można następnie używane bezpośrednio lub dołączone do COleDispatchDriver dla typu bezpiecznego dostępu.Jeśli używasz go bezpośrednio, upewnij się, że wywołanie jego wersji Członkowskich kiedy za pomocą wskaźnika ( COleDispatchDriver destruktora nie wpływa).

Zobacz też

Inne zasoby

Uwagi techniczne przez liczbę

Uwagi techniczne według kategorii