Студопедия КАТЕГОРИИ: АвтоАвтоматизацияАрхитектураАстрономияАудитБиологияБухгалтерияВоенное делоГенетикаГеографияГеологияГосударствоДомЖурналистика и СМИИзобретательствоИностранные языкиИнформатикаИскусствоИсторияКомпьютерыКулинарияКультураЛексикологияЛитератураЛогикаМаркетингМатематикаМашиностроениеМедицинаМенеджментМеталлы и СваркаМеханикаМузыкаНаселениеОбразованиеОхрана безопасности жизниОхрана ТрудаПедагогикаПолитикаПравоПриборостроениеПрограммированиеПроизводствоПромышленностьПсихологияРадиоРегилияСвязьСоциологияСпортСтандартизацияСтроительствоТехнологииТорговляТуризмФизикаФизиологияФилософияФинансыХимияХозяйствоЦеннообразованиеЧерчениеЭкологияЭконометрикаЭкономикаЭлектроникаЮриспунденкция |
Class CApplication : public COleDispatchDriver
{ public: // … LPDISPATCH get_Documents() { LPDISPATCH result; InvokeHelper(0x6, DISPATCH_PROPERTYGET, VT_DISPATCH, (void*)&result, NULL); return result; } void Quit(VARIANT * SaveChanges, VARIANT * OriginalFormat, VARIANT * RouteDocument) { static BYTE parms[] = VTS_PVARIANT VTS_PVARIANT VTS_PVARIANT ; InvokeHelper(0x451, DISPATCH_METHOD, VT_EMPTY, NULL, parms, SaveChanges, OriginalFormat, RouteDocument); }
Объявления этих методов содержатся в файле CApplication.h. Вспомогательная функция InvokeHelper(), реализация которой содержится в файле OleDisp2.cpp, подготавливает параметры для вызова функции IDispatch::Invoke(), вызывает ее и возвращает результат. Мы бы могли не добавлять в наш проект класс-оболочку CApplication, а после получения интерфейса pDisp с помощью функции QueryInterface() непосредственно вызывать метод IDispatch::Invoke(), предварительно подготовив его параметры. Но это стоило бы очень больших усилий, так как подготовка параметров является очень непростой задачей. Чтобы убедиться в этом, посмотрите на объявление метода IDispatch::Invoke(): virtual /* [local] */ HRESULT STDMETHODCALLTYPE Invoke( /* [in] */ DISPID dispIdMember, /* [in] */ REFIID riid, /* [in] */ LCID lcid, /* [in] */ WORD wFlags, /* [out][in] */ DISPPARAMS *pDispParams, /* [out] */ VARIANT *pVarResult, /* [out] */ EXCEPINFO *pExcepInfo, /* [out] */ UINT *puArgErr) = 0;
Главную трудность представляет собой параметр pDispParams, посредством которого конкретному методу с номером dispIdMember передаются входные параметры и, после его выполнения, возвращается результат. При желании можно в режиме трассировки посмотреть на код метода COleDispatchDriver::InvokeHelper(), чтобы не хотелось этого делать «вручную». С другой стороны, можно воспользоваться функцией InvokeHelper(), для того, чтобы «облегчить себе жизнь». Вот ее прототип: virtual void AFX_CDECL InvokeHelper( DISPID dwDispID, WORD wFlags, VARTYPE vtRet, void* pvRet, const BYTE* pbParamInfo, ... );
Параметры:
Замечание. Если в процессе отладки программы Вы запустите какой-либо сервер и выйдете из программы, не завершив его, то останется запущенным процесс сервера, который Вы можете не заметить, если окно сервера показано не будет. Так как такая ситуация может привести к ошибкам при последующем запуске сервера, то о ней надо помнить и при необходимости вручную завершить процесс сервера с помощью менеджера задач путем уничтожения процесса.
Функция COleDispatchDriver::InvokeHelper() на самом деле вызывает функцию COleDispatchDriver::InvokeHelperV(), которая подготавливает параметры для вызова «настоящего» метода IDispatch::Invoke() и делает его. Если обнаруживается, что сервер Word в данное время не запущен, то это можно сделать с помощью функции COleDispatchDriver::CreateDispatch(), которая инициирует создание СОМ объекта, идентифицируемого переданным ей параметром clsid, и прикрепление к нему интерфейса нашего объекта m_app. Если функция COleDispatchDriver::CreateDispatch() выполнится успешно, то процесс WinWord.exe будет запущен, но окно приложения Word отображаться не будет и приложения Word Вы не увидите ни в списке приложений менеджера задач, ни в строке панели задач (но в списке процессов менеджера задач он будет присутствовать). Можно работать с приложением Word и в таком состоянии, а если нужно сделать его видимым, то вызовите метод put_Visible(true) сервера Word, что и сделано в приведенном выше тексте программы. Завершить работу сервера Word может пользователь (если окно Word мы сделали видимым) или наша программа с помощью метода Quit(). Если первый параметр этого метода имеет значение true, то перед завершением Word будет выполнено автоматическое сохранение открытых в редакторе документов.
Так как многие методы серверов имеют тип VARIANT, который введен, в частности, для совместимости с Visual Basic, то необходимо ознакомиться с этим типом по подразделу конспекта. Вместо типа VARIANT в программе можно было использовать класс CComVariant, производный от tagVARIANT и являющийся классом-оболочкой для типа VARIANT. Так как этот класс имеет, в частности, несколько конструкторов, то его использование существенно упрощает текст программы: CComVariant SaveChanges(VARIANT_TRUE),DocumentFormat(1,VT_I4), Empty(VT_EMPTY);
Вот текст функции COleDispatchDriver::CreateDispatch(), обеспечивающей запуск сервера и получение диспетчерского интерфейса IDispatch:
BOOL COleDispatchDriver::CreateDispatch(REFCLSID clsid, COleException* pError) { ASSERT(m_lpDispatch == NULL); m_bAutoRelease = TRUE; /* good default is to auto-release create an instance of the object */ LPUNKNOWN lpUnknown = NULL; SCODE sc = CoCreateInstance(clsid, NULL, CLSCTX_ALL | CLSCTX_REMOTE_SERVER, IID_IUnknown, (LPLP)&lpUnknown); if (sc == E_INVALIDARG) { // may not support CLSCTX_REMOTE_SERVER, so try without sc = CoCreateInstance(clsid, NULL, CLSCTX_ALL & ~CLSCTX_REMOTE_SERVER, IID_IUnknown, (LPLP)&lpUnknown); } if (FAILED(sc)) goto Failed;
// make sure it is running sc = OleRun(lpUnknown); if (FAILED(sc)) goto Failed;
// query for IDispatch interface m_lpDispatch = QUERYINTERFACE(lpUnknown, IDispatch); if (m_lpDispatch == NULL) goto Failed;
lpUnknown->Release(); ASSERT(m_lpDispatch != NULL); return TRUE;
Failed: RELEASE(lpUnknown); if (pError != NULL) pError->m_sc = sc; return FALSE; }
Как найти информацию по объектам, предоставляемым серверами MS Office? Во-первых, это документация MSDN. Путь к нужному разделу справки в MSDN для MVS-2005 показан на рис. 2. В справочной системе описаны как объектные модели приложений MS Office, так и приведены примеры использования методов классов на языке VBA. Во-вторых, можно использовать такой сервис приложений MS Office, как запись макросов. Например, чтобы воспользоваться этим средством в MS Word, надо проделать такие операции: 1. Запустить на выполнение MS Word и включить запись макроса – Сервис/Макрос/Начать запись. В появившемся диалоговом окне можно изменить имя макроса и сферу его применения 2. Выполнить «вручную» те операции, которые необходимо запрограммировать. При этом возможно с помощью кнопок панели управления макроса приостановить или отменить его запись 3. После завершения всех операций остановить запись и открыть текст макроса, например, с помощью команды Сервис/Макрос/Редактор Visual Basic. Сгенерированный текст макроса можно использовать как шаблон для записи текста программы.
Рис. 2. Путь к разделу справки по программированию доступа к сервисам MSWord |
||||||||||||||||||
Последнее изменение этой страницы: 2018-04-12; просмотров: 476. stydopedya.ru не претендует на авторское право материалов, которые вылажены, но предоставляет бесплатный доступ к ним. В случае нарушения авторского права или персональных данных напишите сюда... |