Sharkky
Зарегистрирован: 10.01.2004 Сообщения: 72
|
Добавлено: Вт Авг 30 2005 09:18 Заголовок сообщения: word.document in-place activation. Нужен пример. |
|
|
Я пытаюсь создать программу на vc++ (non-MFC, non-ATL), в которой в окне моего диалога отображался бы документ ms word. С тем, чтобы в дальнейшем управлять им через IDispatch. У меня не получается активировать word.document. Мне удаётся начать in-place активацию, однако, после того, как word.document вызывает GetWindowContext в моей реализации, doVerb возвращает E_FAIL, и активация дальше не идёт.
Для того, чтобы добиться поставленной цели я созадал контейнер - класс, который имплементирует IOleClientSite, IOleInPlaceSite, IOleInPlaceFrame. В моей реализации все функции возрващают E_NOTIMPL, кроме CanInPlaceActivate, OnInPlaceActivate, GetWindow, GetWindowContext.
По ходу выполнения WinMain я пытаюсь делать следующее (возможно это не самая лучшая реализация такой программы с точки зрения проектирования, но мне сейчас не до красоты )
0. Объявляю необходимые переменные
1. Создаю окно диалога.
2. Создаю экзэмпляр своего TestContainer
3. Выполняю необходимые действия, чтобы загрузить объект Word. document и получить IOleObject на него.
4. Передаю своему конетейнеру указатель IOleObject на Word.Document.
5. Пытаюсь вызвать DoVerb для in-place актиации word.document.
WinMain:
Код: | int __stdcall WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow
)
{
//Declaring necessary variables
HRESULT hr;
DWORD err;
CComPtr<IStorage> pStorage;
CComPtr<IOleObject> pWordObject;
CComPtr<IOleClientSite> pClientSite;
//Creating dialog window
HWND hwnd = ::CreateDialog(hInstance, MAKEINTRESOURCE(IDD_DIALOG1), HWND_DESKTOP, MyDialogProc);
if(!hwnd)
{
err = GetLastError();
}
ShowWindow(hwnd, nCmdShow);
//Instantiating TestContainer
TestContainer testcon(hwnd);
testcon.QueryInterface(IID_IOleClientSite, (void**) &pClientSite);
//Getting IOleObject pointer to word.document object
::OleInitialize(NULL);
CLSID idMsWord;
hr = ::CLSIDFromProgID(L"word.document", &idMsWord);
hr = ::StgCreateStorageEx(NULL, STGM_READWRITE | STGM_SHARE_EXCLUSIVE | STGM_DIRECT | STGM_CREATE, STGFMT_DOCFILE,
0, NULL, 0, IID_IStorage, (LPVOID*) &pStorage);
hr = OleCreate(idMsWord, IID_IOleObject, OLERENDER_DRAW, NULL, pClientSite, pStorage, (void**)&pWordObject);
hr = OleLoad(pStorage, IID_IOleObject, pClientSite, (void**) &pWordObject);
hr = OleSetContainedObject(pWordObject, TRUE);
//Getting IOleObject to my contianer
testcon.SetObject(pWordObject);
//Starting in-place activation
hr = pWordObject->DoVerb(OLEIVERB_INPLACEACTIVATE, NULL, pClientSite, 0, hwnd, &rect);
MSG msg;
while(::GetMessage(&msg, hwnd, 0, 0))
{
//::PeekMessage(&msg, hwnd, 0, 0, PM_REMOVE);
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
::OleUninitialize();
return 0;
} |
Вызов doVerb заканчивается с результатом E_FAIL. Это и есть та проблема, которая заставила меня просить помоши в её решении на этом форуме.
После действия номер 4 word.document начинает вызывать методы моего TestContainer связанные с активацией. Эти методы в порядке их вызова:
Код: | virtual HRESULT STDMETHODCALLTYPE CanInPlaceActivate( void)
{return S_OK;} |
Код: | virtual HRESULT STDMETHODCALLTYPE OnInPlaceActivate( void)
{
return S_OK;
} |
Код: | virtual /* [input_sync] */ HRESULT STDMETHODCALLTYPE GetWindow(
/* [out] */ HWND *phwnd)
{
*phwnd = m_hwnd;
return S_OK;
} |
Код: | virtual HRESULT STDMETHODCALLTYPE GetWindowContext(
/* [out] */ IOleInPlaceFrame **ppFrame,
/* [out] */ IOleInPlaceUIWindow **ppDoc,
/* [out] */ LPRECT lprcPosRect,
/* [out] */ LPRECT lprcClipRect,
/* [out][in] */ LPOLEINPLACEFRAMEINFO lpFrameInfo)
{
CComPtr<IOleInPlaceObject> pInObj;
HRESULT hr = m_obj.QueryInterface(&pInObj);
pInObj->GetWindow(&m_objhwnd);
SIZEL sizel;
m_obj->GetExtent(DVASPECT_CONTENT, &sizel);
sizel.cx /= HIMETRIC_PER_PIXEL;
sizel.cy /= HIMETRIC_PER_PIXEL;
*ppFrame = this;
AddRef();
*ppDoc = this;
AddRef();
SetRect(lprcClipRect , 0, 0, sizel.cx, sizel.cy);
SetRect(lprcPosRect, 0, 0, sizel.cx, sizel.cy);
OLEINPLACEFRAMEINFO frameinfo;
frameinfo.cb = sizeof(OLEINPLACEFRAMEINFO);
frameinfo.fMDIApp = FALSE;
frameinfo.hwndFrame = m_hwnd;
ACCEL acc;
acc.cmd = LOWORD(IDD_DIALOG1);
acc.fVirt = FALT;
acc.key = 'a';
HACCEL haccel = CreateAcceleratorTable(&acc, 1);
DWORD err;
if(!haccel)
err = GetLastError();
frameinfo.haccel = haccel;
frameinfo.cAccelEntries = 1;
return S_OK;
} |
Надеюсь, что кто-нибудь дочитал до этого места И сможет мне помочь. Мне нужно, услышать что я делаю неправильно, либо получить реально работающий пример такоей программы.
Заранее спасибо |
|