home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / atl / activedoc / activectl.h < prev    next >
C/C++ Source or Header  |  1998-04-03  |  12KB  |  438 lines

  1. // ActiveCtl.h : Declaration of the CActiveDoc class
  2. //
  3. // This is a part of the Active Template Library.
  4. // Copyright (C) 1996-1998 Microsoft Corporation
  5. // All rights reserved.
  6. //
  7. // This source code is only intended as a supplement to the
  8. // Active Template Library Reference and related
  9. // electronic documentation provided with the library.
  10. // See these sources for detailed information regarding the
  11. // Active Template Library product.
  12.  
  13. #include "resource.h"       // main symbols
  14. #include "OleDocument.h"
  15. #include "Menu.h"
  16. #include "ToolBar.h"
  17. #include <RichEdit.h>
  18.  
  19. /////////////////////////////////////////////////////////////////////////////
  20. // CActiveDoc
  21. class CActiveDoc :
  22.     public CComObjectRoot,
  23.     public CComCoClass<CActiveDoc, &CLSID_CActiveDoc>,
  24.     public CComControl<CActiveDoc>,
  25.     public IDispatchImpl<IActiveDoc, &IID_IActiveDoc, &LIBID_ACTIVEDOCLib>,
  26.     public IProvideClassInfo2Impl<&CLSID_CActiveDoc, NULL, &LIBID_ACTIVEDOCLib>,
  27.     public IPersistStreamInitImpl<CActiveDoc>,
  28.     public IPersistStorageImpl<CActiveDoc>,
  29.     public IQuickActivateImpl<CActiveDoc>,
  30.     public IOleControlImpl<CActiveDoc>,
  31.     public IOleObjectImpl<CActiveDoc>,
  32.     public IOleInPlaceActiveObjectImpl<CActiveDoc>,
  33.     public IViewObjectExImpl<CActiveDoc>,
  34.     public IOleInPlaceObjectWindowlessImpl<CActiveDoc>,
  35.     public IDataObjectImpl<CActiveDoc>,
  36.     public ISupportErrorInfo,
  37.     public IOleDocumentImpl<CActiveDoc>,
  38.     public IOleDocumentViewImpl<CActiveDoc>,
  39.     public CMenu<CActiveDoc>,
  40.     public CToolbar<CActiveDoc>,
  41.     public IPersistFile
  42. {
  43. public:
  44.     CActiveDoc() :
  45.       m_wndRTF(_T("RichEdit"), this, 1)
  46.     {
  47.         m_wndRTF.m_hWnd = NULL;
  48.         m_bWindowOnly = TRUE;
  49.     }
  50.  
  51. DECLARE_REGISTRY_RESOURCEID(IDR_ActiveDoc)
  52.  
  53. BEGIN_COM_MAP(CActiveDoc)
  54.     COM_INTERFACE_ENTRY(IActiveDoc)
  55.     COM_INTERFACE_ENTRY(IDispatch)
  56.     COM_INTERFACE_ENTRY_IMPL(IViewObjectEx)
  57.     COM_INTERFACE_ENTRY_IMPL_IID(IID_IViewObject2, IViewObjectEx)
  58.     COM_INTERFACE_ENTRY_IMPL_IID(IID_IViewObject, IViewObjectEx)
  59.     COM_INTERFACE_ENTRY_IMPL(IOleInPlaceObjectWindowless)
  60.     COM_INTERFACE_ENTRY_IMPL_IID(IID_IOleInPlaceObject, IOleInPlaceObjectWindowless)
  61.     COM_INTERFACE_ENTRY_IMPL_IID(IID_IOleWindow, IOleInPlaceObjectWindowless)
  62.     COM_INTERFACE_ENTRY_IMPL(IOleInPlaceActiveObject)
  63.     COM_INTERFACE_ENTRY_IMPL(IOleControl)
  64.     COM_INTERFACE_ENTRY_IMPL(IOleObject)
  65.     COM_INTERFACE_ENTRY_IMPL(IQuickActivate)
  66.     COM_INTERFACE_ENTRY_IMPL(IPersistStorage)
  67.     COM_INTERFACE_ENTRY_IMPL(IPersistStreamInit)
  68.     COM_INTERFACE_ENTRY_IMPL(IDataObject)
  69.     COM_INTERFACE_ENTRY(IOleDocument)
  70.     COM_INTERFACE_ENTRY(IOleDocumentView)
  71.     COM_INTERFACE_ENTRY(IProvideClassInfo)
  72.     COM_INTERFACE_ENTRY(IProvideClassInfo2)
  73.     COM_INTERFACE_ENTRY(ISupportErrorInfo)
  74.     COM_INTERFACE_ENTRY(IPersistFile)
  75. END_COM_MAP()
  76.  
  77. BEGIN_PROPERTY_MAP(CActiveDoc)
  78.     // PROP_ENTRY("Description", dispid, clsid)
  79. END_PROPERTY_MAP()
  80.  
  81. BEGIN_MSG_MAP(CActiveDoc)
  82.     MESSAGE_HANDLER(WM_PAINT, OnPaint)
  83.     MESSAGE_HANDLER(WM_SETFOCUS, OnSetFocus)
  84.     MESSAGE_HANDLER(WM_KILLFOCUS, OnKillFocus)
  85.     MESSAGE_HANDLER(WM_CREATE, OnCreate)
  86.     MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
  87.     MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBackgnd)
  88.     COMMAND_RANGE_HANDLER(ID_BLACK, ID_BLUE, OnColorChange)
  89.     COMMAND_ID_HANDLER(ID_HELP_ABOUT, OnHelpAbout)
  90.     NOTIFY_CODE_HANDLER(TTN_NEEDTEXT, OnToolbarNeedText)
  91.  
  92.     ALT_MSG_MAP(1)
  93. END_MSG_MAP()
  94.  
  95. BEGIN_TOOLBAR_MAP(CActiveDoc)
  96.     TOOLBAR_BUTTON(ID_BLACK)
  97.     TOOLBAR_BUTTON(ID_RED)
  98.     TOOLBAR_BUTTON(ID_GREEN)
  99.     TOOLBAR_BUTTON(ID_BLUE)
  100.     TOOLBAR_SEPARATOR()
  101.     TOOLBAR_BUTTON(ID_HELP_ABOUT)
  102. END_TOOLBAR_MAP()
  103.  
  104. // ISupportsErrorInfo
  105.     STDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid);
  106.  
  107. // IActiveDoc
  108. public:
  109.  
  110. // Override SetClientSite
  111.     HRESULT IOleObject_SetClientSite(IOleClientSite *pClientSite)
  112.     {
  113.         // If we currently have a document site pointer, release it.
  114.         m_spDocSite.Release();
  115.         m_bDocObject=FALSE;
  116.  
  117.         if (pClientSite != NULL)
  118.         {
  119.             pClientSite->QueryInterface(&m_spDocSite);
  120.             if (m_spDocSite != NULL)
  121.                 m_bDocObject = true;
  122.         }
  123.         return CComControlBase::IOleObject_SetClientSite(pClientSite);
  124.     }
  125.  
  126. // Override DoVerb
  127.     STDMETHOD(DoVerb)(LONG iVerb, LPMSG pMsg, IOleClientSite* pActiveSite, LONG lindex,
  128.                                      HWND hwndParent, LPCRECT lprcPosRect)
  129.     {
  130.         // Check if we should activate as a docobject or not
  131.         // (client supports IOleDocumentSite)
  132.         if (m_bDocObject)
  133.         {
  134.             switch (iVerb)
  135.             {
  136.             case OLEIVERB_SHOW:
  137.             case OLEIVERB_OPEN:
  138.             case OLEIVERB_UIACTIVATE:
  139.                 if (!m_bUIActive)
  140.                     return m_spDocSite->ActivateMe(NULL);
  141.             break;
  142.             }
  143.         }
  144.         return IOleObjectImpl<CActiveDoc>::DoVerb(iVerb, pMsg, pActiveSite, lindex, hwndParent, lprcPosRect);
  145.     }
  146.  
  147.     STDMETHOD(InPlaceDeactivate)(void)
  148.     {
  149.         // Release the pointers we have no need for now.
  150.         m_spDocSite.Release();
  151.         m_spInPlaceFrame.Release();
  152.  
  153.         return IOleInPlaceObjectWindowlessImpl<CActiveDoc>::InPlaceDeactivate();
  154.     }
  155.  
  156.     // Override IOleInPlaceActiveObjectImpl::OnDocWindowActivate
  157.     STDMETHOD(OnDocWindowActivate)(BOOL fActivate)
  158.     {
  159.         ATLTRACE(_T("CActiveDoc::OnDocWindowActivate\n"));
  160.         if (fActivate)
  161.         {
  162.             InPlaceMenuCreate();
  163.             SetupToolbar(NULL);
  164.         }
  165.         else
  166.         {
  167.             DestroyToolbar();
  168.             InPlaceMenuDestroy();
  169.         }
  170.         return S_OK;
  171.     }
  172.     STDMETHOD(TranslateAccelerator)(MSG *pMsg)
  173.     {
  174.         ATLTRACE(_T("CActiveDoc::TranslateAccelerator\n"));
  175.  
  176.         if (pMsg == NULL)
  177.             return E_POINTER;
  178.  
  179.         if (m_spInPlaceFrame != NULL)
  180.             return OleTranslateAccelerator(m_spInPlaceFrame, &m_frameInfo, pMsg);
  181.         else
  182.             return S_FALSE;
  183.     }
  184.     // Override IPersistStorageImpl::IsDirty
  185.     STDMETHOD(IsDirty)()
  186.     {
  187.         ATLTRACE(_T("CActiveDoc::IsDirty\n"));
  188.         if (m_wndRTF.m_hWnd != NULL)
  189.         {
  190.             return (m_wndRTF.SendMessage(EM_GETMODIFY, 0, 0)) ? S_OK : S_FALSE;
  191.         }
  192.         else
  193.             return S_FALSE;
  194.     }
  195.     // Override IPersistStreamInitImp::Save
  196.     STDMETHOD(Save)(LPSTREAM pStm, BOOL fClearDirty)
  197.     {
  198.         ATLTRACE(_T("CActiveDoc::Save\n"));
  199.         // We can only save if we have an RTF control to save data from
  200.         if (m_wndRTF.m_hWnd != NULL)
  201.         {
  202.             EDITSTREAM  es;
  203.             es.dwCookie     = (DWORD)pStm;
  204.             es.dwError      = 0;
  205.             es.pfnCallback  = RTFSave;
  206.             m_wndRTF.SendMessage(EM_STREAMOUT, SF_RTF, (LPARAM)&es);
  207.             if (fClearDirty)
  208.                 SetRTFModified(FALSE); // We're no longer dirty
  209.         }
  210.         return S_OK;
  211.     }
  212.     // Override IPersistStreamInitImp::Load
  213.     STDMETHOD(Load)(LPSTREAM pStm)
  214.     {
  215.         ATLTRACE(_T("CActiveDoc::Load\n"));
  216.         // Ensure the RTF window has been created, so that we can load data into it.
  217.         if (m_wndRTF.m_hWnd == NULL)
  218.             CreateRTFWindow();
  219.  
  220.         EDITSTREAM  es;
  221.         es.dwCookie     = (DWORD)pStm;
  222.         es.dwError      = 0;
  223.         es.pfnCallback  = RTFLoad;
  224.         m_wndRTF.SendMessage(EM_STREAMIN, SF_RTF, (LPARAM)&es);
  225.         SetRTFModified(FALSE); // We're not dirty
  226.         return S_OK;
  227.     }
  228.     static DWORD CALLBACK RTFSave(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG FAR *pcb)
  229.     {
  230.         HRESULT  hr;
  231.         LPSTREAM pStm = (LPSTREAM)dwCookie;
  232.  
  233.         hr = pStm->Write(pbBuff, cb, (ULONG*)pcb);
  234.         if (SUCCEEDED(hr))
  235.             return 0;
  236.         else
  237.             return 1; // Failed so stop calling us.
  238.     }
  239.     static DWORD CALLBACK RTFLoad(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG FAR *pcb)
  240.     {
  241.         HRESULT  hr;
  242.         LPSTREAM pStm = (LPSTREAM)dwCookie;
  243.  
  244.         hr = pStm->Read(pbBuff, cb, (ULONG*)pcb);
  245.         if (SUCCEEDED(hr))
  246.             return 0;
  247.         else
  248.             return 1; // Failed so stop calling us.
  249.     }
  250.  
  251.     HRESULT OnDraw(ATL_DRAWINFO& /* di */)
  252.     {
  253.         // Drawing handled by RTF control
  254.         return 0;
  255.     }
  256.     LRESULT OnEraseBackgnd(UINT, WPARAM, LPARAM, BOOL&)
  257.     {
  258.         return 0;
  259.     }
  260.     LRESULT OnCreate(UINT, WPARAM, LPARAM, BOOL&)
  261.     {
  262.         // If we haven't created the RTF window then we need to create it. If not, is has already
  263.         // been created by the Load procedure so we just make sure it is a parent of our window.
  264.         if (m_wndRTF.m_hWnd == NULL)
  265.             CreateRTFWindow();
  266.         else
  267.         {
  268.             m_wndRTF.ModifyStyle(WS_POPUP, WS_CHILD | WS_VISIBLE);
  269.             m_wndRTF.SetParent(m_hWnd);
  270.         }
  271.         return 0;
  272.     }
  273.     LRESULT OnDestroy(UINT, WPARAM, LPARAM, BOOL&)
  274.     {
  275.         // Destroy RTF window and unload the DLL
  276.         m_wndRTF.DestroyWindow();
  277.         FreeLibrary(m_hLibRTF);
  278.         return 0;
  279.     }
  280.     LRESULT OnSetFocus(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
  281.     {
  282.         // When the control window get's the focus, set the focus to the
  283.         // RTF control.
  284.         CComControl<CActiveDoc>::OnSetFocus(nMsg, wParam, lParam, bHandled);
  285.         m_wndRTF.SetFocus();
  286.         return 0;
  287.     }
  288.     void CreateRTFWindow()
  289.     {
  290.         DWORD dwStyle;
  291.         RECT  rc;
  292.         // If the control window has been created then we can use it's size otherwise default
  293.         // to zero.
  294.         if (m_hWnd == NULL)
  295.         {
  296.             // If the window isn't going to be a child at the moment, then don't set
  297.             // WS_CHILD and don't make it visible yet
  298.             dwStyle = WS_POPUP;
  299.             ZeroMemory(&rc, sizeof(RECT));
  300.         }
  301.         else
  302.         {
  303.             dwStyle = WS_CHILD | WS_VISIBLE;
  304.             GetWindowRect(&rc);
  305.             rc.right -= rc.left;
  306.             rc.bottom -= rc.top;
  307.             rc.top = rc.left = 0;
  308.         }
  309.         m_hLibRTF = LoadLibrary(_T("RICHED32.DLL"));
  310.         m_wndRTF.Create(m_hWnd, rc, NULL, dwStyle | ES_MULTILINE | ES_AUTOVSCROLL | WS_VSCROLL, 0);
  311.         ATLASSERT(m_wndRTF != NULL);
  312.     }
  313.     void SetRTFModified(BOOL bModified)
  314.     {
  315.         if (m_wndRTF.m_hWnd != NULL)
  316.         {
  317.             m_wndRTF.SendMessage(EM_SETMODIFY, (WPARAM)bModified, 0);
  318.         }
  319.     }
  320.     // IOleInPlaceActiveObject::ResizeBorder
  321.     STDMETHOD(ResizeBorder)(LPCRECT prcBorder, IOleInPlaceUIWindow* /* pUIWindow */, BOOL /* bFrameWindow */)
  322.     {
  323.         ATLTRACE(_T("CActiveDoc::ResizeBorder\n"));
  324.  
  325.         MoveToolbar(prcBorder);
  326.  
  327.         return S_OK;
  328.     }
  329.     STDMETHOD(SetObjectRects)(LPCRECT prcPos,LPCRECT prcClip)
  330.     {
  331.         ATLTRACE("CActiveDoc::SetObjectRects(%d, %d,  %d, %d)\n", prcPos->left, prcPos->top, prcPos->right, prcPos->bottom);
  332.  
  333.         MoveToolbar();
  334.  
  335.         // When our control window moves, move the toolbar and the RTF window.
  336.         IOleInPlaceObjectWindowlessImpl<CActiveDoc>::SetObjectRects(prcPos, prcClip);
  337.  
  338.         // Move the RTF control
  339.         if (m_wndRTF.m_hWnd != NULL)
  340.         {
  341.             m_wndRTF.SetWindowPos(NULL, 0, 0, prcPos->right - prcPos->left, prcPos->bottom - prcPos->top,
  342.                 SWP_NOZORDER | SWP_NOACTIVATE);
  343.         }
  344.         return S_OK;
  345.     }
  346.     HRESULT OnColorChange(WORD, WORD nID, HWND, BOOL&)
  347.     {
  348.         COLORREF col[4] =
  349.         {
  350.             RGB(0, 0, 0),   // Black
  351.             RGB(255, 0, 0), // Red
  352.             RGB(0, 255, 0), // Green
  353.             RGB(0, 0, 255)  // Blue
  354.         };
  355.         CHARFORMAT cf;
  356.         int nColor;
  357.         nColor = nID - ID_BLACK;
  358.         ATLASSERT(nColor >=0 && nColor <= sizeof(col)/sizeof(COLORREF));
  359.         cf.cbSize = sizeof(CHARFORMAT);
  360.         cf.dwMask = CFM_COLOR;
  361.         cf.dwEffects = 0;
  362.         cf.crTextColor = col[nColor];
  363.         m_wndRTF.SendMessage(EM_SETCHARFORMAT, SCF_SELECTION, (LPARAM)&cf);
  364.         return 0;
  365.     }
  366.  
  367.  
  368.     // IPersistFile
  369.     STDMETHODIMP GetClassID(CLSID* pClassID)
  370.     {
  371.         *pClassID = GetObjectCLSID();
  372.         return S_OK;
  373.     }
  374.  
  375.     STDMETHOD(Load)(LPCOLESTR pszFileName, DWORD dwMode)
  376.     {
  377.         USES_CONVERSION;
  378.         HRESULT hr;
  379.         CComPtr<IStorage>   spStorage;
  380.  
  381.         hr = ::StgOpenStorage(OLE2CW(pszFileName), NULL,
  382.             dwMode,
  383.             NULL, 0, &spStorage);
  384.         if (FAILED(hr))
  385.             return hr;
  386.  
  387.         // If the load fails we'll just start with an empty document
  388.         IPersistStorageImpl<CActiveDoc>::Load(spStorage);
  389.  
  390.         return S_OK;
  391.     }
  392.  
  393.     STDMETHOD(Save)(LPCOLESTR pszFileName, BOOL /* fRemember */)
  394.     {
  395.         USES_CONVERSION;
  396.         HRESULT hr;
  397.         CComPtr<IStorage>   spStorage;
  398.  
  399.         hr = ::StgOpenStorage(OLE2CW(pszFileName), NULL,
  400.             STGM_DIRECT | STGM_READWRITE | STGM_SHARE_EXCLUSIVE,
  401.             NULL, 0, &spStorage);
  402.  
  403.         return IPersistStorageImpl<CActiveDoc>::Save(spStorage, false);
  404.     }
  405.  
  406.     STDMETHOD(SaveCompleted)(LPCOLESTR /* pszFileName */) { return S_OK; }
  407.  
  408.     STDMETHOD(GetCurFile)(LPOLESTR* /* ppszFileName */) { return E_NOTIMPL; }
  409.  
  410.     class CAboutDlg : public CDialogImpl<CAboutDlg>
  411.     {
  412.     public:
  413.         enum { IDD = IDD_ABOUT };
  414.         BEGIN_MSG_MAP(CAboutDlg)
  415.             COMMAND_ID_HANDLER(IDOK, OnOK)
  416.         END_MSG_MAP()
  417.         HRESULT OnOK(WORD, WORD, HWND, BOOL&)
  418.         {
  419.             EndDialog(0);
  420.             return 0;
  421.         }
  422.     };
  423.     HRESULT OnHelpAbout(WORD, WORD, HWND, BOOL&)
  424.     {
  425.         CAboutDlg dlg;
  426.         dlg.DoModal();
  427.         return 0;
  428.     }
  429.  
  430. // Data
  431.     CContainedWindow            m_wndRTF;
  432.     HINSTANCE                   m_hLibRTF;
  433.     bool                        m_bDocObject;
  434.     CComPtr<IOleDocumentSite>   m_spDocSite;
  435.     CComPtr<IOleInPlaceFrame>   m_spInPlaceFrame;
  436.     OLEINPLACEFRAMEINFO         m_frameInfo;
  437. };
  438.