TN039: MFC/OLE automatyzacji wdrożenia

Omówienie interfejsu IDispatch OLE

Interfejs IDispatch jest to środki, które aplikacje Uwidacznianie metod i właściwości takie mogą to innych aplikacji, takich jak Visual BASIC lub inne języki, należy użyć funkcji aplikacji. Najważniejszą częścią tego interfejsu jest funkcją funkcji IDispatch::Invoke . MFC używa "wysyłki mapy" do realizacji funkcji IDispatch::Invoke. Mapa wysyłki zawiera informacje wykonania MFC na układ lub "kształtu" z CCmdTarget-pochodzące klasy takie, że może bezpośrednio manipulować właściwości obiektu lub wywołać Członkowskie funkcji w obrębie obiektu do zaspokojenia żądania funkcji IDispatch::Invoke.

W większości przypadków ClassWizard i MFC współpracować, aby ukryć większość szczegółów automatyzacji OLE z programista aplikacji. Programator koncentruje się na rzeczywiste funkcje dostępne w aplikacji i nie musi się martwić o podstawowej instalacji wodociągowej.

Istnieją przypadki, gdzie jest to niezbędne do zrozumienia, co robi MFC za kulisami. Uwaga ta będzie dotyczyć, jak ramach przypisuje DISPIDs Członkowskich funkcje i właściwości. Wiedzy na temat algorytmu, który MFC używane do przypisywania DISPIDs jest niezbędne tylko, jeśli trzeba znać identyfikatorów, na przykład podczas tworzenia "biblioteki typów" dla obiektów aplikacji.

Przypisanie MFC DISPID

Chociaż użytkownika końcowego automatyzacji (Visual Basic użytkownika, na przykład), widzi rzeczywistej nazwy automatyzacji włączony właściwości i metod ich kodu (np obj.ShowWindow), wykonanie funkcji IDispatch::Invoke nie otrzymują rzeczywistej nazwy. Ze względów optymalizacji otrzyma DISPID, która jest 32-bitowy "magiczne cookie" opisujący metodę lub właściwość, która ma uzyskać dostęp. Te wartości DISPID są zwracane z implementacji interfejsu IDispatch za pośrednictwem innej metody, o nazwie IDispatch::GetIDsOfNames. Aplikacja klienta automatyzacji wywoływania funkcji GetIDsOfNames raz dla każdego Państwa lub właściwości, które zamierza uzyskać dostęp i pamięci podręcznej je później wywołania funkcji IDispatch::Invoke. Ten sposób wyszukiwania drogie ciąg jest wykonywane tylko raz na użycie obiektu, zamiast raz wywołanie funkcji IDispatch::Invoke.

MFC określa s DISPIDdla każdej metody i właściwości w oparciu o dwie rzeczy:

DISPID dzieli się na dwie części. LOWORD DISPID zawiera pierwszego składnika, odległość od góry mapę wysyłki. HIWORD zawiera odległość od najbardziej pochodną klasy. Na przykład:

klasa CDispPoint: CCmdTarget publicznych
{
publiczne:
 nbsp;  krótko m_x, m_y;
    ...
    DECLARE_DISPATCH_MAP()
    ...
};

Klasa CDisp3DPoint: CDispPoint publicznych
{
publiczne:
    krótkie m_y;
    ...
    DECLARE_DISPATCH_MAP()
    ...
};

BEGI&N_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 od drugiej i w ten sposób korzysta z klasy podstawowej funkcjonalności, wraz z częścią automatyzacji OLE ("x" i "y" właściwości w tym przypadku).

MFC wygeneruje s DISPIDdla klasy CDispPoint w następujący sposób:

właściwość X    (DISPID) 0X00000001
Właściwość Y (DISPID) 0x00000002

Ponieważ właściwości nie znajdują się w klasie podstawowej, HIWORD DISPID zawsze wynosi zero (odległość od najbardziej pochodną klasy dla CDispPoint jest równa zero).

MFC wygeneruje s DISPIDdla klasy CDisp3DPoint w następujący sposób:

właściwość Z    (DISPID) 0X00000001
Właściwość X (DISPID) 0x00010001
Właściwość Y (DISPID) 0x00010002

Właściwości z podano DISPID z zerową HIWORD , ponieważ jest ona zdefiniowana w klasie, która jest ujawniany przez właściwości, CDisp3DPoint. Ponieważ właściwości x i y są zdefiniowane w klasie podstawowej, HIWORD DISPID jest 1, ponieważ klasa, w której określone są te właściwości w odległości jednej wyprowadzenie z najbardziej pochodną klasy.

Uwaganbsp;LOWORD zawsze jest określana przez pozycję w planie, nawet jeśli istnieją zapisy na mapie z wyraźną DISPID (zobacz następna sekcja Informacje w wersjach _ID makra DISP_PROPERTY i DISP_FU&NCTION ).

Zaawansowane funkcje mapę wysyłki MFC

Istnieje wiele dodatkowych funkcji, które nie obsługuje ClassWizard w tej wersji programu Visual C++. ClassWizard obsługuje DISP_FUNCTION, DISP_PROPERTYi DISP_PROPERTY_EX , które określają metody, Państwa zmienną właściwości i pobierać/przechowywać członek funkcji mienia, odpowiednio. Funkcje te są zazwyczaj wszystko, co jest potrzebne do tworzenia większości serwery automatyzacji.

Następujące dodatkowe makra mogą być używane podczas makra ClassWizard obsługiwane są nieodpowiednie: DISP_PROPERTY_NOTIFYi DISP_PROPERTY_PARAM.

DISP_PROPERTY_NOTIFY — Opis makra

DISP_PROPERTY_NOTIFY (theClass, pszName, NazwaCzłonka, pfnAfterSet, vtPropType)

theClass

Nazwa klasy.

pszName

Zewnętrzne nazwa właściwości.

nazwaCzłonka

Nazwa zmiennej Państwa, w którym znajduje się nieruchomość.

pfnAfterSet

Nazwa Państwa funkcji do wywołania po zmianie właściwości.

vtPropType

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

Uwaganbsp;  To makro jest, tak jak w DISP_PROPERTY, z tym wyjątkiem, że akceptuje dodatkowy argument. Dodatkowym argumentem, pfnAfterSet, powinny być funkcję Państwa, która zwraca nic i żadnych parametrów, "OnProperty&Notify() void". Zostanie on wywołany po zmodyfikowano zmienną.

DISP_PROPERTY_PARAM — Opis makra

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

theClass

Nazwa klasy.

pszName

Zewnętrzne nazwa właściwości.

memberGet

Nazwa funkcji członek używany do uzyskiwania właściwość.

zestaw składników wymiaru

Nazwa funkcji członek używany do ustawiania właściwości.

vtPropType

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

vtsParams

Ciąg miejsca oddzielone VTS_ dla każdego parametru.

Uwaganbsp;  Wiele takich jak makra DISP_PROPERTY_EX , to makro definiuje właściwości dostępne osobne Get i zestaw funkcji członek. 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, "pozycja", GetItem, SetItem, VT_DISPATCH, VTS_I2 VTS_I2)

odpowiadałby i ustawiania funkcje składowe:

LPDISPATCH CMyObject::GetItem(short row, short col)
void CMyObject::SetItem (krótkiego wiersza, kolumny krótkie LPDISPATCH newValue.)

DISP_XXXX_ID — Makra opisy

DISP_FUNCTION_ID (theClass, pszName, dispid, pfnMember, vtRetVal, vtsParams)

DISP_PROPERTY_ID (theClass, pszName, dispid NazwaCzłonka, vtPropType)

DISP_PROPERTY_NOTIFY_ID (theClass, pszName, dispid, NazwaCzłonka, pfnAfterSet, vtPropType)

DISP_PROPERTY_EX_ID (theClass, pszName, dispid, pfnGet, pfnSet, vtPropType)

DISP_PROPERTY_PARAM_ID (theClass, pszName, dispid, pfnGet, pfnSet, vtPropType, vtsParams)

theClass

Nazwa klasy.

pszName

Zewnętrzne nazwa właściwości.

dispid

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

pfnGet

Nazwa funkcji członek używany do uzyskiwania właściwość.

pfnSet

Nazwa funkcji członek używany do ustawiania właściwości.

nazwaCzłonka

Nazwa zmiennej Państwa do mapowania właściwości

vtPropType

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

vtsParams

Ciąg miejsca oddzielone VTS_ dla każdego parametru.

Uwaganbsp;  Te makra umożliwiają określenie DISPID zamiast najmu MFC automatycznie przypisywać jeden. Te zaawansowane makra mają takie same nazwy, chyba że ten identyfikator jest dołączana do nazwy makr (np. DISP_PROPERTY_ID) i identyfikator jest określona przez parametr tuż po parametrze psz&Name . Patrz AFXDISP.H więcej informacji na temat tych makr. Wpisy _ID muszą być umieszczone na końcu mapę wysyłki. One wpłynie na automatyczne generowanie DISPID w taki sam sposób jak innych niż - wersja_ID makra będzie ( DISPIDs są określane według pozycji). Na przykład:

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

właściwość X    (DISPID) 0X00020003
Właściwość Y (DISPID) 0x00000002
Właściwość Z (DISPID) 0x00000001

Określenie stałej DISPID jest przydatne do zachowania zgodności z poprzednimi wersjami wcześniej istniejących interfejsu wysyłki lub wprowadzenia w życie niektórych systemu określone metody lub właściwości (wskazywany zwykle przez ujemne DISPID, takich jak kolekcja DISPID_NEWENUM ).

Trwa pobieranie interfejsu IDispatch COleClientItem

Wiele serwerów będzie wspierać automatyzacji w ich obiektów dokumentu, wraz z funkcjami serwera OLE. W celu uzyskania dostępu do tego interfejsu automatyzacji, należy uzyskać bezpośredni dostęp COleClientItem::m_lpObject Państwa zmienną. Poniższy kod pobierze interfejsu IDispatch dla obiektu pochodzące z COleClientItem. Mogą obejmować poniższy kod w aplikacji, jeśli ta funkcja Znajdź niezbędne

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

LPUNKNOWN lpUnk = m_lpObject;

Run();    / / musi być uruchomiony

LPOLELINK lpOleLink = NULL;
    Jeżeli (m_lpObject - > QueryInterface (IID_IOleLink, elementem LPVOID FAR ** & lpOleLink) == NOERROR)
    {
        ASSERT (lpOleLink! = NULL);
        lpUnk = NULL;
        Jeżeli (lpOleLink - > GetBoundSource(&lpUnk)! = NOERROR)
        {
            TRACE0 ("Ostrzeżenie: łącze nie jest podłączony! \n");
            lpOleLink - > Release();
            Zwraca wartość NULL;
        }
        ASSERT (lpUnk! = NULL);
    }

LPDISPATCH lpDispatch = NULL;
    Jeżeli (lpUnk - > QueryInterface (IID_IDispatch & lpDispatch)! = NOERROR)
    {
        TRACE0 ("Ostrzeżenie: nie obsługuje interfejsu IDispatch! \n");
        Zwraca wartość NULL;
    }

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

Interfejs wysyłki wrócił z tej funkcji można następnie używane bezpośrednio lub podłączone do COleDispatchDriver dla typu bezpieczny dostęp. Jeśli używasz go bezpośrednio, upewnij się, wywołać jej Członkowskich wydanie kiedy za pomocą wskaźnika (destruktor COleDispatchDriver jest to domyślnie).

Uwagi techniczne przez liczbę |nbsp; Uwagi techniczne według kategorii

Index