| // Copyright (c) 2009 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 <atlbase.h> |
| #include <docobj.h> |
| |
| #include "base/logging.h" |
| |
| ////////////////////////////////////////////////////////////////////////////// |
| // IOleDocumentImpl |
| template <class T> |
| class ATL_NO_VTABLE IOleDocumentImpl : public IOleDocument { |
| public: |
| STDMETHOD(CreateView)(IOleInPlaceSite* in_place_site, |
| IStream* stream, |
| DWORD reserved , |
| IOleDocumentView** new_view) { |
| DLOG(INFO) << __FUNCTION__; |
| if (new_view == NULL) |
| return E_POINTER; |
| T* t = static_cast<T*>(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<void**>(&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) { |
| DLOG(INFO) << __FUNCTION__; |
| if (NULL == status) { |
| return E_POINTER; |
| } |
| *status = DOCMISC_NOFILESUPPORT; |
| return S_OK; |
| } |
| |
| STDMETHOD(EnumViews)(IEnumOleDocumentViews** enum_views, |
| IOleDocumentView** view) { |
| DLOG(INFO) << __FUNCTION__; |
| if (view == NULL) |
| return E_POINTER; |
| T* t = static_cast<T*>(this); |
| // We only support one view |
| return t->_InternalQueryInterface(IID_IOleDocumentView, |
| reinterpret_cast<void**>(view)); |
| } |
| }; |
| |
| ////////////////////////////////////////////////////////////////////////////// |
| // IOleDocumentViewImpl |
| |
| template <class T> |
| class ATL_NO_VTABLE IOleDocumentViewImpl : public IOleDocumentView { |
| public: |
| STDMETHOD(SetInPlaceSite)(IOleInPlaceSite* in_place_site) { |
| DLOG(INFO) << __FUNCTION__; |
| T* t = static_cast<T*>(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<void **>(&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<IOleInPlaceSiteWindowless*>(in_place_site); |
| } |
| } |
| return S_OK; |
| } |
| |
| STDMETHOD(GetInPlaceSite)(IOleInPlaceSite** in_place_site) { |
| DLOG(INFO) << __FUNCTION__; |
| if (in_place_site == NULL) { |
| return E_POINTER; |
| } |
| T* t = static_cast<T*>(this); |
| return t->m_spInPlaceSite->QueryInterface( |
| IID_IOleInPlaceSite, |
| reinterpret_cast<LPVOID *>(in_place_site)); |
| } |
| |
| STDMETHOD(GetDocument)(IUnknown** document) { |
| DLOG(INFO) << __FUNCTION__; |
| if (document == NULL) { |
| return E_POINTER; |
| } |
| T* t = static_cast<T*>(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; |
| DLOG(INFO) << __FUNCTION__ << " " << view_rect->left << "," << |
| view_rect->top << "," << view_rect->right << "," << view_rect->bottom; |
| T* t = static_cast<T*>(this); |
| t->SetObjectRects(view_rect, view_rect); |
| is_resizing = false; |
| return S_OK; |
| } |
| |
| STDMETHOD(GetRect)(LPRECT view_rect) { |
| DLOG(INFO) << __FUNCTION__; |
| if (view_rect == NULL) { |
| return E_POINTER; |
| } |
| T* t = static_cast<T*>(this); |
| *view_rect = t->m_rcPos; |
| return S_OK; |
| } |
| |
| STDMETHOD(SetRectComplex)(LPRECT view_rect, |
| LPRECT hscroll_rect, |
| LPRECT vscroll_rect, |
| LPRECT size_box_rect) { |
| DLOG(INFO) << __FUNCTION__ << " not implemented"; |
| return E_NOTIMPL; |
| } |
| |
| STDMETHOD(Show)(BOOL show) { |
| DLOG(INFO) << __FUNCTION__; |
| T* t = static_cast<T*>(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) { |
| DLOG(INFO) << __FUNCTION__; |
| T* t = static_cast<T*>(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 { |
| t->InPlaceMenuDestroy(); |
| // t->DestroyToolbar(); |
| hr = t->UIDeactivate(); |
| } |
| return hr; |
| } |
| |
| STDMETHOD(Open)() { |
| DLOG(INFO) << __FUNCTION__ << " not implemented"; |
| return E_NOTIMPL; |
| } |
| |
| STDMETHOD(CloseView)(DWORD reserved) { |
| DLOG(INFO) << __FUNCTION__; |
| T* t = static_cast<T*>(this); |
| t->Show(FALSE); |
| t->SetInPlaceSite(NULL); |
| return S_OK; |
| } |
| |
| STDMETHOD(SaveViewState)(LPSTREAM stream) { |
| DLOG(INFO) << __FUNCTION__ << " not implemented"; |
| return E_NOTIMPL; |
| } |
| |
| STDMETHOD(ApplyViewState)(LPSTREAM stream) { |
| DLOG(INFO) << __FUNCTION__ << " not implemented"; |
| return E_NOTIMPL; |
| } |
| |
| STDMETHOD(Clone)(IOleInPlaceSite* new_in_place_site, |
| IOleDocumentView** new_view) { |
| DLOG(INFO) << __FUNCTION__ << " not implemented"; |
| return E_NOTIMPL; |
| } |
| |
| HRESULT ActiveXDocActivate(LONG verb) { |
| return E_NOTIMPL; |
| } |
| }; |
| |
| #endif // CHROME_FRAME_OLE_DOCUMENT_IMPL_H_ |