// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. // TODO(slightlyoff): Add any required LICENSE block changes for MSFT code // inclusion. // ole_document_impl.h : IOleDocument implementation // // This file is a modified version of the OleDocument.h file, which is // part of the ActiveDoc MSDN sample. The modifications are largely // conversions to Google coding guidelines. Below if the original header // from the file. // This is a part of the Active Template Library. // Copyright (c) Microsoft Corporation. All rights reserved. // // This source code is only intended as a supplement to the // Active Template Library Reference and related // electronic documentation provided with the library. // See these sources for detailed information regarding the // Active Template Library product. #ifndef CHROME_FRAME_OLE_DOCUMENT_IMPL_H_ #define CHROME_FRAME_OLE_DOCUMENT_IMPL_H_ // TODO(sanjeevr): Revisit this impl file and cleanup dependencies #include #include #include "base/logging.h" ////////////////////////////////////////////////////////////////////////////// // IOleDocumentImpl template class ATL_NO_VTABLE IOleDocumentImpl : public IOleDocument { public: STDMETHOD(CreateView)(IOleInPlaceSite* in_place_site, IStream* stream, DWORD reserved , IOleDocumentView** new_view) { DVLOG(1) << __FUNCTION__; if (new_view == NULL) return E_POINTER; T* t = static_cast(this); // If we've already created a view then we can't create another as we // currently only support the ability to create one view if (t->m_spInPlaceSite) return E_FAIL; IOleDocumentView* view; t->GetUnknown()->QueryInterface(IID_IOleDocumentView, reinterpret_cast(&view)); // If we support IOleDocument we should support IOleDocumentView ATLENSURE(view != NULL); // If they've given us a site then use it if (in_place_site != NULL) view->SetInPlaceSite(in_place_site); // If they have given us an IStream pointer then use it to // initialize the view if (stream != NULL) view->ApplyViewState(stream); // Return the view *new_view = view; return S_OK; } STDMETHOD(GetDocMiscStatus)(DWORD* status) { DVLOG(1) << __FUNCTION__; if (NULL == status) return E_POINTER; *status = DOCMISC_NOFILESUPPORT; return S_OK; } STDMETHOD(EnumViews)(IEnumOleDocumentViews** enum_views, IOleDocumentView** view) { DVLOG(1) << __FUNCTION__; if (view == NULL) return E_POINTER; T* t = static_cast(this); // We only support one view return t->_InternalQueryInterface(IID_IOleDocumentView, reinterpret_cast(view)); } }; ////////////////////////////////////////////////////////////////////////////// // IOleDocumentViewImpl template class ATL_NO_VTABLE IOleDocumentViewImpl : public IOleDocumentView { public: STDMETHOD(SetInPlaceSite)(IOleInPlaceSite* in_place_site) { DVLOG(1) << __FUNCTION__; T* t = static_cast(this); if (t->m_spInPlaceSite) { // If we already have a site get rid of it UIActivate(FALSE); HRESULT hr = t->InPlaceDeactivate(); if (FAILED(hr)) return hr; DCHECK(!t->m_bInPlaceActive); } if (in_place_site != NULL) { t->m_spInPlaceSite.Release(); in_place_site->QueryInterface( IID_IOleInPlaceSiteWindowless, reinterpret_cast(&t->m_spInPlaceSite)); if (!t->m_spInPlaceSite) { // TODO(sanjeevr): This is a super-hack because m_spInPlaceSite // is an IOleInPlaceSiteWindowless pointer and we are setting // an IOleInPlaceSite pointer into it. The problem is that ATL // (CComControlBase) uses this in a schizophrenic manner based // on the m_bWndLess flag. Ouch, ouch, ouch! Find a way to clean // this up. // Disclaimer: I did not invent this hack, it exists in the MSDN // sample from where this code has been derived and it also exists // in ATL itself (look at atlctl.h line 938). t->m_spInPlaceSite = reinterpret_cast(in_place_site); } } return S_OK; } STDMETHOD(GetInPlaceSite)(IOleInPlaceSite** in_place_site) { DVLOG(1) << __FUNCTION__; if (in_place_site == NULL) return E_POINTER; T* t = static_cast(this); return t->m_spInPlaceSite->QueryInterface( IID_IOleInPlaceSite, reinterpret_cast(in_place_site)); } STDMETHOD(GetDocument)(IUnknown** document) { DVLOG(1) << __FUNCTION__; if (document == NULL) return E_POINTER; T* t = static_cast(this); *document = t->GetUnknown(); (*document)->AddRef(); return S_OK; } STDMETHOD(SetRect)(LPRECT view_rect) { static bool is_resizing = false; if (is_resizing) return S_OK; is_resizing = true; DVLOG(1) << __FUNCTION__ << " " << view_rect->left << "," << view_rect->top << "," << view_rect->right << "," << view_rect->bottom; T* t = static_cast(this); t->SetObjectRects(view_rect, view_rect); is_resizing = false; return S_OK; } STDMETHOD(GetRect)(LPRECT view_rect) { DVLOG(1) << __FUNCTION__; if (view_rect == NULL) return E_POINTER; T* t = static_cast(this); *view_rect = t->m_rcPos; return S_OK; } STDMETHOD(SetRectComplex)(LPRECT view_rect, LPRECT hscroll_rect, LPRECT vscroll_rect, LPRECT size_box_rect) { DVLOG(1) << __FUNCTION__ << " not implemented"; return E_NOTIMPL; } STDMETHOD(Show)(BOOL show) { DVLOG(1) << __FUNCTION__; T* t = static_cast(this); HRESULT hr = S_OK; if (show) { if (!t->m_bUIActive) hr = t->ActiveXDocActivate(OLEIVERB_INPLACEACTIVATE); } else { hr = t->UIActivate(FALSE); ::ShowWindow(t->m_hWnd, SW_HIDE); } return hr; } STDMETHOD(UIActivate)(BOOL ui_activate) { DVLOG(1) << __FUNCTION__; T* t = static_cast(this); HRESULT hr = S_OK; if (ui_activate) { // We must know the client site first if (t->m_spInPlaceSite == NULL) return E_UNEXPECTED; if (!t->m_bUIActive) hr = t->ActiveXDocActivate(OLEIVERB_UIACTIVATE); } else { // Menu integration is still not complete, so do not destroy // IE's menus. If we call InPlaceMenuDestroy here, menu items such // as Print etc will be disabled and we will not get calls to QueryStatus // for those commands. // t->InPlaceMenuDestroy(); // t->DestroyToolbar(); hr = t->UIDeactivate(); } return hr; } STDMETHOD(Open)() { DVLOG(1) << __FUNCTION__ << " not implemented"; return E_NOTIMPL; } STDMETHOD(CloseView)(DWORD reserved) { DVLOG(1) << __FUNCTION__; T* t = static_cast(this); t->Show(FALSE); t->SetInPlaceSite(NULL); return S_OK; } STDMETHOD(SaveViewState)(LPSTREAM stream) { DVLOG(1) << __FUNCTION__ << " not implemented"; return E_NOTIMPL; } STDMETHOD(ApplyViewState)(LPSTREAM stream) { DVLOG(1) << __FUNCTION__ << " not implemented"; return E_NOTIMPL; } STDMETHOD(Clone)(IOleInPlaceSite* new_in_place_site, IOleDocumentView** new_view) { DVLOG(1) << __FUNCTION__ << " not implemented"; return E_NOTIMPL; } HRESULT ActiveXDocActivate(LONG verb) { return E_NOTIMPL; } }; #endif // CHROME_FRAME_OLE_DOCUMENT_IMPL_H_