TN039: MFC/OLE автоматизації виконання

Огляд інтерфейсу OLE IDispatch

IDispatch інтерфейс є засоби, які застосування викрити методи і властивості, такі що інші застосунки, наприклад, Visual BASIC або іншими мовами, можна зробити за допомогою функцій програми. Найбільш важливою частиною цього інтерфейсу є IDispatch::Invoke функції. MFC використовує "відправлення карти" для здійснення IDispatch::Invoke. Відправлення Карта надає MFC реалізації інформацію про макет або "форму" ваш CCmdTarget-отриманих класи, така, що вона безпосередньо можна маніпулювати властивості об'єкта, або зателефонуйте член функцій в ваш об'єкт, щоб задовольнити побажання IDispatch::Invoke.

Здебільшого, ClassWizard MFC співпрацюють і приховати більшість деталей автоматизації OLE від застосування програміста. Програміст концентрується на фактичний функціональності, щоб викрити у програмі і не доведеться турбуватися про основні сантехніка.

Є випадки, однак, де це необхідно, щоб зрозуміти, що робить MFC за лаштунками. Ця Примітка будуть вирішувати, як рамках призначає DISPIDs методи і властивості. Знання алгоритму MFC використовується для призначення DISPIDs необхідний лише коли потрібно знати ідентифікатори, такі, як під час створення бібліотеки"типів" для вашого застосування об'єктів.

MFC DISPID збірки

Хоча ліцензійну автоматизації (Visual Basic користувач, наприклад), бачить фактичного імена автоматизації включений властивості і методи в свій код (наприклад obj.ShowWindow), здійснення IDispatch::Invoke не отримує фактичних імен. Для оптимізації причин він отримує в DISPID, яка є 32-розрядних "magic cookie" що описує метод або властивість, яка повинна бути доступна. Ці значення DISPID повертаються з реалізації IDispatch через інший метод, званий IDispatch::GetIDsOfNames. Застосунку клієнт автоматизації називають GetIDsOfNames один раз для кожного члена або власності, що він має намір отримати доступ і кеш їх пізніше дзвінків на IDispatch::Invoke. Таким чином, дорогі рядок підстановки зробити тільки один раз за використання об'єкта, замість того, щоб один раз на IDispatch::Invoke виклику.

MFC визначає DISPIDs для кожного методу і власності на основі дві речі:

DISPID ділиться на дві частини. LOWORD з DISPID містить перший компонент, відстань від верхньої частини Відправлення Карта. HIWORD містить відстань від найбільш похідних класів. Наприклад:

клас CDispPoint: Громадська CCmdTarget
{
готелю:
 nbsp;  короткий m_x, m_y;
    ...
    DECLARE_DISPATCH_MAP()
    ...
};

клас CDisp3DPoint: Громадська CDispPoint
{
готелю:
    короткий 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()

Як ви бачите, існують два, обидва з яких викрити інтерфейсів автоматизації OLE. Один з цих класів походить від інших і таким чином використовує базового класу функціональність, включаючи участь автоматизації OLE ("x" та "y" Властивості в даному випадку).

MFC буде генерувати DISPIDs клас CDispPoint наступним чином:

власності X    (DISPID) 0X00000001
властивість Y (DISPID) 0x00000002

Оскільки властивості не є базовим класом, HIWORD з DISPID завжди є нуль (відстань від найбільш похідних класів для CDispPoint дорівнює нулю).

MFC буде генерувати DISPIDs клас CDisp3DPoint наступним чином:

власності Z    (DISPID) 0X00000001
властивості X (DISPID) 0x00010001
властивість Y (DISPID) 0x00010002

Властивість z приділяється DISPID з нульової HIWORD так, як це визначено в класі, який викриття властивості, CDisp3DPoint. Оскільки x та y властивості, визначені в базового класу, HIWORD з DISPID є 1, так як клас, в якому визначені ці властивості знаходиться на відстані одного диференціювання з найбільш похідних класів.

Приміткаnbsp;LOWORD завжди визначається положення в карті, навіть якщо існують записів в карті з явного DISPID (див. наступний розділ інформація на _ID версії макроси DISP_PROPERTY і DISP_FU&NCTION ).

Додаткові MFC відправлення карта функції

Є цілий ряд додаткових функцій, що ClassWizard не підтримує, з цього випуску Visual c + +. ClassWizard підтримує, DISP_FUNCTION, DISP_PROPERTYі DISP_PROPERTY_EX , який визначає метод, член змінної власності та отримання/встановлення член функція власності, відповідно. Ці можливості, як правило, все, що потрібно для створення більшості сервери автоматизації.

Наступні додаткові макроси можуть бути використані при ClassWizard підтримується макроси не є адекватною: DISP_PROPERTY_NOTIFYі DISP_PROPERTY_PARAM.

DISP_PROPERTY_NOTIFY — Опис макросу

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

theClass

Ім'я класу.

pszName

Зовнішні ім'я властивості.

memberName

Ім'я змінної членів, в якому зберігається власності.

pfnAfterSet

Ім'я учасника функція для виклику під час змінення властивостей.

vtPropType

Значення, яке вказує на властивість тип.

Приміткаnbsp;  Цей макрос так само, як DISP_PROPERTY, за винятком, що він приймає додаткові аргументи. Додатковий аргумент, pfnAfterSet, повинні бути член функції, що нічого не повертає і приймає без параметрів, 'порожнеча OnProperty&Notify()'. Вона буде називатися після змінної-члена було змінено.

DISP_PROPERTY_PARAM — Опис макросу

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

theClass

Ім'я класу.

pszName

Зовнішні ім'я властивості.

memberGet

Ім'я учасника функції використовуються отримати властивість.

memberSet

Ім'я функції члена, який можна настроїти властивість.

vtPropType

Значення, яке вказує на властивість тип.

vtsParams

Рядок із місця розділені VTS_ для кожного параметра.

Примітка   Багато подібно до макросу, DISP_PROPERTY_EX , цей макрос визначає властивості, доступні з окремих отримати і набір функцій члена. Цей макрос, однак, дає змогу вказати параметр список для властивості. Це корисно для реалізації властивості, які є індексується або завдний іншим способом. Параметри будуть завжди розміщені по-перше, після чого нове значення для властивості. Наприклад:

DISP_PROPERTY_PARAM (CMyObject, "елемент", GetItem, SetItem, VT_DISPATCH, VTS_I2 VTS_I2)

буде відповідати отримати та встановити функцій-членів:

LPDISPATCH CMyObject::GetItem(short row, short col)
втрати CMyObject::SetItem (короткий рядок, короткого Коль, LPDISPATCH нове значення)

DISP_XXXX_ID — Описи макросів

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

Ім'я класу.

pszName

Зовнішні ім'я властивості.

dispid

Фіксована DISPID для властивість або метод.

pfnGet

Ім'я учасника функції використовуються отримати властивість.

pfnSet

Ім'я функції члена, який можна настроїти властивість.

memberName

Ім'я змінної-члена зіставлення на майно

vtPropType

Значення, яке вказує на властивість тип.

vtsParams

Рядок із місця розділені VTS_ для кожного параметра.

Приміткаnbsp;  Ці макроси дозволяють визначити DISPID замість того, щоб дозволити MFC автоматично призначити один. Додаткові макроси мають однакові назви, за винятком цей Ідентифікатор додається до імені макросу (наприклад DISP_PROPERTY_ID) і ID залежить від параметрів, указаних тільки після параметра psz&Name . Див AFXDISP.H більш докладну інформацію про ці макроси. _ID записи повинна міститися наприкінці відправлення карта. Вони вплинуть Автоматична генерація DISPID так само, як на не -_ID Версія макросу буде ( DISPIDs визначається позиції). Наприклад:

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 для класу CDisp3DPoint наступним чином:

власності X    (DISPID) 0X00020003
властивість Y (DISPID) 0x00000002
властивість Z (DISPID) 0x00000001

Зазначення фіксованої DISPID є корисним для підтримання зворотної сумісності до раніше існуючої інтерфейсу відправлення або для виконання певних системи визначено методи або властивості (як правило, позначається на негативних DISPID, наприклад, колекція DISPID_NEWENUM ).

Отримання IDispatch інтерфейс для на COleClientItem

Багато серверів буде підтримувати автоматизації в рамках їх документ об'єкти, разом з функції сервера OLE. Щоб отримати доступ до цього автоматизації інтерфейсу, це необхідно для безпосередньо доступу до змінної-члена COleClientItem::m_lpObject . Код буде отримати IDispatch інтерфейс для об'єкта, отриманих від COleClientItem. Ви можете включити код у вашій програмі, якщо ви знайдете цю функцію необхідно

LPDISPATCH CMyClientItem::GetIDispatch()
{
 nbsp;  ASSERT_VALID(This);
    НАДБАННЯ (m_lpObject! = NULL);

LPUNKNOWN-lpUnk = m_lpObject;

Run();    / / необхідно запустити

LPOLELINK-lpOleLink = NULL;
    Якщо (m_lpObject - > QueryInterface (IID_IOleLink, (LPVOID ДАЛЕКОГО *) & lpOleLink) = = NOERROR)
    {
        НАДБАННЯ (lpOleLink! = NULL);
        lpUnk = NULL;
        Якщо (lpOleLink - > GetBoundSource(&lpUnk)! = NOERROR)
        {
            TRACE0 ("попередження: посилання не підключено! \n");
            lpOleLink - > Release();
            повернути значення NULL;
        }
        НАДБАННЯ (lpUnk! = NULL);
    }

LPDISPATCH-lpDispatch = NULL;
    Якщо (lpUnk - > QueryInterface (IID_IDispatch і lpDispatch)! = NOERROR)
    {
        TRACE0 ("попередження: не підтримує IDispatch! \n");
        повернути значення NULL;
    }

НАДБАННЯ (lpDispatch! = NULL);
    повернення lpDispatch;
}

Відправлення інтерфейс повернувся з цієї функції потім може бути використаний безпосередньо або додається до COleDispatchDriver типу безпечного доступу. Якщо ви використовуєте його безпосередньо, переконайтеся, що ви називаєте його член реліз коли через вказівник (деструктор COleDispatchDriver робить це за замовчуванням).

Технічні примітки за номером |nbsp; Технічні примітки за категоріями

Index