home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / com / activedocument / doserver / oledoc.cpp < prev    next >
C/C++ Source or Header  |  1997-09-12  |  19KB  |  686 lines

  1. /**************************************************************************
  2.    THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
  3.    ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
  4.    THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  5.    PARTICULAR PURPOSE.
  6.  
  7.    Copyright 1997 Microsoft Corporation.  All Rights Reserved.
  8. **************************************************************************/
  9.  
  10. /**************************************************************************
  11.  
  12.    File:          OleDoc.cpp
  13.    
  14.    Description:   COleDocument implementation.
  15.  
  16. **************************************************************************/
  17.  
  18. /**************************************************************************
  19.    #include statements
  20. **************************************************************************/
  21.  
  22. #include "OleDoc.h"
  23. #include "comcat.h"
  24.  
  25. /**************************************************************************
  26.    global variables
  27. **************************************************************************/
  28.  
  29. extern DWORD   g_DllRefCount;
  30.  
  31. /**************************************************************************
  32.  
  33.    COleDocument::COleDocument()
  34.  
  35. **************************************************************************/
  36.  
  37. COleDocument::COleDocument()
  38. {
  39. OutputDebugString(TEXT("COleDocument's constructor\n"));
  40.  
  41. m_ObjRefCount = 0;
  42.  
  43. m_fDirty = FALSE;
  44. m_fNoScribbleMode = FALSE;
  45. m_pOleAdviseHolder = NULL;
  46. m_pOleClientSite = NULL;
  47. m_dwRegister = 0;
  48. m_pOleDocView = NULL;
  49. m_Color = DEFAULT_COLOR;
  50. m_fCreated = FALSE;
  51.  
  52. m_pOleObject = new COleObject(this);
  53.  
  54. m_pDataObject = new CDataObject(this);
  55.  
  56. m_pOleInPlaceObject = new COleInPlaceObject(this);
  57.  
  58. m_pOleInPlaceActiveObject = new COleInPlaceActiveObject(this);
  59.  
  60. m_pPersistStorage = new CPersistStorage(this);
  61.  
  62. m_pPersistFile = new CPersistFile(this, m_pPersistStorage);
  63.  
  64. m_pOleDocView = new COleDocumentView(this);
  65.  
  66. g_DllRefCount++;
  67. }
  68.  
  69. /**************************************************************************
  70.  
  71.    COleDocument::~COleDocument()
  72.  
  73. **************************************************************************/
  74.  
  75. COleDocument::~COleDocument()
  76. {
  77. OutputDebugString(TEXT("COleDocument's destructor\n"));
  78.  
  79. if(m_pOleAdviseHolder)
  80.    m_pOleAdviseHolder->Release();
  81.  
  82. if(m_pOleClientSite)
  83.    m_pOleClientSite->Release();
  84.  
  85. delete m_pOleDocView;
  86.  
  87. delete m_pPersistFile;
  88.  
  89. delete m_pPersistStorage;
  90.  
  91. delete m_pOleInPlaceActiveObject;
  92.  
  93. delete m_pOleInPlaceObject;
  94.  
  95. delete m_pDataObject;
  96.  
  97. delete m_pOleObject;
  98.  
  99. g_DllRefCount--;
  100.  
  101. PostQuitMessage(0);
  102. }
  103.  
  104. ///////////////////////////////////////////////////////////////////////////
  105. //
  106. // IUnknown Implementation
  107. //
  108.  
  109. /**************************************************************************
  110.  
  111.    COleDocument::QueryInterface
  112.  
  113. **************************************************************************/
  114.  
  115. STDMETHODIMP COleDocument::QueryInterface(REFIID riid, LPVOID *ppReturn)
  116. {
  117. OutputDebugString(TEXT("COleDocument::QueryInterface - "));
  118.  
  119. HRESULT  hr = E_NOINTERFACE;
  120. *ppReturn = NULL;
  121.  
  122. if(riid == IID_IUnknown)
  123.    {
  124.    *ppReturn = this;
  125.    OutputDebugString(TEXT("IUnknown requested - "));
  126.    }
  127. else if (riid == IID_IOleDocument)
  128.    {
  129.    *ppReturn = this;
  130.    OutputDebugString(TEXT("IOleDocument requested - "));
  131.    }
  132. else if (riid == IID_IOleDocumentView)
  133.    {
  134.    *ppReturn = m_pOleDocView;
  135.    OutputDebugString(TEXT("IOleDocumentView requested - "));
  136.    }
  137. else if (riid == IID_IOleObject)
  138.    {
  139.    *ppReturn = m_pOleObject;
  140.    OutputDebugString(TEXT("IOleObject requested - "));
  141.    }
  142. else if (riid == IID_IDataObject)
  143.    {
  144.    *ppReturn = m_pDataObject;
  145.    OutputDebugString(TEXT("IDataObject requested - "));
  146.    }
  147. else if (riid == IID_IOleInPlaceObject)
  148.    {
  149.    *ppReturn = m_pOleInPlaceObject;
  150.    OutputDebugString(TEXT("IOleInPlaceObject requested - "));
  151.    }
  152. else if (riid == IID_IOleInPlaceActiveObject)
  153.    {
  154.    *ppReturn = m_pOleInPlaceActiveObject;
  155.    OutputDebugString(TEXT("IOleInPlaceActiveObject requested - "));
  156.    }
  157. else if((riid == IID_IPersistStorage) || (riid == IID_IPersist))
  158.    {
  159.    *ppReturn = m_pPersistStorage;
  160.    OutputDebugString(TEXT("IPersistStorage requested - "));
  161.    }
  162. else if(riid == IID_IPersistFile)
  163.    {
  164.    *ppReturn = m_pPersistFile;
  165.    OutputDebugString(TEXT("IPersistFile requested - "));
  166.    }
  167.  
  168. if (*ppReturn)
  169.    {
  170.    OutputDebugString(TEXT("Interface Found\n"));
  171.    ((LPUNKNOWN)*ppReturn)->AddRef();
  172.    hr = S_OK;
  173.    }
  174. else
  175.    {
  176.    OutputDebugString(TEXT("No Interface - "));
  177.  
  178.    LPWSTR   pwsz;
  179.    TCHAR    szString[MAX_PATH] = TEXT("");
  180.    
  181.    StringFromIID(riid, &pwsz);
  182.  
  183.    if(pwsz)
  184.       {
  185. #ifdef UNICODE
  186.       lstrcpy(szString, pwsz);
  187. #else
  188.       WideCharToMultiByte( CP_ACP,
  189.                            0,
  190.                            pwsz,
  191.                            -1,
  192.                            szString,
  193.                            ARRAYSIZE(szString),
  194.                            NULL,
  195.                            NULL);
  196. #endif
  197.       OutputDebugString(szString);
  198.       OutputDebugString(TEXT("\n"));
  199.  
  200.       //free the string
  201.       LPMALLOC pMalloc;
  202.       CoGetMalloc(1, &pMalloc);
  203.       pMalloc->Free(pwsz);
  204.       pMalloc->Release();
  205.       }
  206.    }
  207.  
  208. return hr;
  209. }                                             
  210.  
  211. /**************************************************************************
  212.  
  213.    COleDocument::AddRef
  214.  
  215. **************************************************************************/
  216.  
  217. STDMETHODIMP_(DWORD) COleDocument::AddRef()
  218. {
  219. //OutputDebugString("COleDocument::AddRef\n");
  220. TCHAR szText[MAX_PATH];
  221. wsprintf(szText, TEXT("COleDocument::AddRef - ref count will be %d\n"), m_ObjRefCount + 1);
  222. OutputDebugString(szText);
  223.  
  224. return ++m_ObjRefCount;
  225. }
  226.  
  227.  
  228. /**************************************************************************
  229.  
  230.    COleDocument::Release
  231.  
  232. **************************************************************************/
  233.  
  234. STDMETHODIMP_(DWORD) COleDocument::Release()
  235. {
  236. //OutputDebugString("COleDocument::Release\n");
  237. TCHAR szText[MAX_PATH];
  238. wsprintf(szText, TEXT("COleDocument::Release - ref count will be %d\n"), m_ObjRefCount - 1);
  239. OutputDebugString(szText);
  240.  
  241. if(0 == --m_ObjRefCount)
  242.    {
  243.    delete this;
  244.    return 0;
  245.    }
  246.    
  247. return m_ObjRefCount;
  248. }
  249.  
  250. /**************************************************************************
  251.  
  252.    COleDocument::CreateView()
  253.    
  254. **************************************************************************/
  255.  
  256. STDMETHODIMP COleDocument::CreateView( IOleInPlaceSite *pInPlaceSite, 
  257.                                        IStream *pStream, 
  258.                                        DWORD dwReserved, 
  259.                                        IOleDocumentView **ppOleDocumentView)
  260. {
  261. OutputDebugString(TEXT("COleDocument::CreateView\n"));
  262.  
  263. HRESULT  hr = E_FAIL;
  264.  
  265. //NULL the view pointer
  266. *ppOleDocumentView = NULL;
  267.  
  268. //we only support one view, so fail if the view already exists
  269. if(!m_fCreated)
  270.    {
  271.    //AddRef since we are giving away the pointer
  272.    m_pOleDocView->AddRef();
  273.  
  274.    // if we were given a site, set this as the site for the view we just created
  275.    if(pInPlaceSite) 
  276.       {
  277.       m_pOleDocView->SetInPlaceSite(pInPlaceSite);
  278.       }
  279.  
  280.    // if given a stream to initialize from, initialize our view state
  281.    if(pStream) 
  282.       {
  283.       m_pOleDocView->ApplyViewState(pStream);
  284.       }
  285.  
  286.    *ppOleDocumentView = m_pOleDocView;
  287.  
  288.    m_fCreated = TRUE;
  289.    
  290.    hr = S_OK;
  291.    }
  292.    
  293. return hr;
  294. }
  295.  
  296. /**************************************************************************
  297.  
  298.    COleDocument::GetDocMiscStatus()
  299.    
  300. **************************************************************************/
  301.  
  302. STDMETHODIMP COleDocument::GetDocMiscStatus(DWORD *pdwStatus)
  303. {
  304. OutputDebugString(TEXT("COleDocument::GetDocMiscStatus\n"));
  305.  
  306. if(!pdwStatus)
  307.    return E_INVALIDARG;
  308.  
  309. *pdwStatus = 0;
  310.  
  311. return S_OK;
  312. }
  313.  
  314. /**************************************************************************
  315.  
  316.    COleDocument::EnumViews()
  317.    
  318. **************************************************************************/
  319.  
  320. STDMETHODIMP COleDocument::EnumViews(  IEnumOleDocumentViews **ppEnum, 
  321.                                        IOleDocumentView **ppView)
  322. {
  323. OutputDebugString(TEXT("COleDocument::EnumViews\n"));
  324.  
  325. *ppEnum = NULL;
  326. *ppView = NULL;
  327.  
  328. return E_NOTIMPL;
  329. }
  330.  
  331. /**************************************************************************
  332.  
  333.    COleDocument::GetWindow()
  334.    
  335. **************************************************************************/
  336.  
  337. STDMETHODIMP COleDocument::GetWindow(HWND *phwnd)
  338. {
  339. OutputDebugString(TEXT("COleDocument::GetWindow\n"));
  340.  
  341. if(!phwnd)
  342.    return E_INVALIDARG;
  343.  
  344. *phwnd = NULL;
  345.  
  346. if(m_pOleDocView)
  347.    *phwnd = m_pOleDocView->m_hwndView;
  348.  
  349. return S_OK;
  350. }
  351.  
  352. /**************************************************************************
  353.  
  354.    COleDocument::UIDeactivate()
  355.    
  356. **************************************************************************/
  357.  
  358. STDMETHODIMP COleDocument::DeactivateUI()
  359. {
  360. OutputDebugString(TEXT("COleInPlaceObject::DeactivateUI\n"));
  361.  
  362. if(m_pOleDocView)
  363.    return m_pOleDocView->DeactivateUI();
  364.  
  365. return E_FAIL;
  366. }
  367.  
  368. /**************************************************************************
  369.  
  370.    COleDocumentView::DeactivateInPlace()
  371.    
  372. **************************************************************************/
  373.  
  374. STDMETHODIMP COleDocument::DeactivateInPlace()
  375. {
  376. OutputDebugString(TEXT("COleDocument::DeactivateInPlace\n"));
  377.  
  378. if(m_pOleDocView)
  379.    return m_pOleDocView->DeactivateInPlace();
  380.  
  381. return E_FAIL;
  382. }
  383.  
  384. /**************************************************************************
  385.  
  386.    COleDocument::RegisterServer
  387.  
  388. **************************************************************************/
  389.  
  390. typedef struct{
  391.    HKEY  hRootKey;
  392.    TCHAR szSubKey[MAX_PATH];
  393.    TCHAR szValue[MAX_PATH];
  394. }DOREGSTRUCT, *LPDOREGSTRUCT;
  395.  
  396. BOOL COleDocument::RegisterServer(void)
  397. {
  398. OutputDebugString("COleDocument::RegisterServer\n");
  399.  
  400. int      i;
  401. HKEY     hKey;
  402. LRESULT  lResult;
  403. DWORD    dwDisp;
  404. TCHAR    szSubKey[MAX_PATH];
  405. TCHAR    szCLSID[MAX_PATH];
  406. TCHAR    szApp[MAX_PATH];
  407. LPWSTR   pwsz;
  408. CLSID    clsid;
  409.  
  410. //get this app's CLSID in string form
  411. m_pPersistStorage->GetClassID(&clsid);
  412. StringFromIID(clsid, &pwsz);
  413.  
  414. if(pwsz)
  415.    {
  416. #ifdef UNICODE
  417.    lstrcpy(szCLSID, pwsz);
  418. #else
  419.    WideCharToMultiByte( CP_ACP,
  420.                         0,
  421.                         pwsz,
  422.                         -1,
  423.                         szCLSID,
  424.                         ARRAYSIZE(szCLSID),
  425.                         NULL,
  426.                         NULL);
  427. #endif
  428.  
  429.    //free the string
  430.    LPMALLOC pMalloc;
  431.    CoGetMalloc(1, &pMalloc);
  432.    pMalloc->Free(pwsz);
  433.    pMalloc->Release();
  434.    }
  435.  
  436. //get this app's path and file name
  437. GetModuleFileName(NULL, szApp, ARRAYSIZE(szApp));
  438.  
  439. //register the file extension entries
  440. {
  441. DOREGSTRUCT FileEntries[] = { HKEY_CLASSES_ROOT,   TEXT("%s"),                         PROG_ID,
  442.                               0,                   TEXT(""),                           TEXT("")};
  443.  
  444. for(i = 0; FileEntries[i].hRootKey; i++)
  445.    {
  446.    //create the sub key string - for this case, insert the file extension
  447.    wsprintf(szSubKey, FileEntries[i].szSubKey, FILE_EXT);
  448.  
  449.    lResult = RegCreateKeyEx(  FileEntries[i].hRootKey,
  450.                               szSubKey,
  451.                               0,
  452.                               NULL,
  453.                               REG_OPTION_NON_VOLATILE,
  454.                               KEY_WRITE,
  455.                               NULL,
  456.                               &hKey,
  457.                               &dwDisp);
  458.    
  459.    if(NOERROR == lResult)
  460.       {
  461.       lResult = RegSetValueEx(   hKey,
  462.                                  NULL,
  463.                                  0,
  464.                                  REG_SZ,
  465.                                  (LPBYTE)FileEntries[i].szValue,
  466.                                  lstrlen(FileEntries[i].szValue) + 1);
  467.       
  468.       RegCloseKey(hKey);
  469.       }
  470.    else
  471.       return FALSE;
  472.    }
  473. }
  474.  
  475. {
  476. DOREGSTRUCT ProgEntries[] = { HKEY_CLASSES_ROOT,   TEXT("%s"),                         DOC_NAME,
  477.                               HKEY_CLASSES_ROOT,   TEXT("%s\\CLSID"),                  TEXT("%s"),
  478.                               HKEY_CLASSES_ROOT,   TEXT("%s\\DocObject"),               TEXT(""),
  479.                               0,                   TEXT(""),                           TEXT("")};
  480.  
  481. //register the ProgID entries
  482. for(i = 0; ProgEntries[i].hRootKey; i++)
  483.    {
  484.    //create the sub key string - for this case, insert the ProgID
  485.    wsprintf(szSubKey, ProgEntries[i].szSubKey, PROG_ID);
  486.  
  487.    lResult = RegCreateKeyEx(  ProgEntries[i].hRootKey,
  488.                               szSubKey,
  489.                               0,
  490.                               NULL,
  491.                               REG_OPTION_NON_VOLATILE,
  492.                               KEY_WRITE,
  493.                               NULL,
  494.                               &hKey,
  495.                               &dwDisp);
  496.    
  497.    if(NOERROR == lResult)
  498.       {
  499.       TCHAR szValue[MAX_PATH];
  500.  
  501.       //if necessary, create the value string
  502.       wsprintf(szValue, ProgEntries[i].szValue, szCLSID);
  503.    
  504.       lResult = RegSetValueEx(   hKey,
  505.                                  NULL,
  506.                                  0,
  507.                                  REG_SZ,
  508.                                  (LPBYTE)szValue,
  509.                                  lstrlen(szValue) + 1);
  510.       
  511.       RegCloseKey(hKey);
  512.       }
  513.    else
  514.       return FALSE;
  515.    }
  516. }
  517.  
  518. {
  519. DOREGSTRUCT ClsidEntries[] = {HKEY_CLASSES_ROOT,   TEXT("CLSID\\%s"),                  DOC_NAME,
  520.                               HKEY_CLASSES_ROOT,   TEXT("CLSID\\%s\\LocalServer32"),   TEXT("%s"),
  521.                               HKEY_CLASSES_ROOT,   TEXT("CLSID\\%s\\InprocHandler32"), TEXT("ole32.dll"),
  522.                               HKEY_CLASSES_ROOT,   TEXT("CLSID\\%s\\DefaultIcon"),     TEXT("%s,0"),
  523.                               HKEY_CLASSES_ROOT,   TEXT("CLSID\\%s\\DocObject"),       TEXT("0"),
  524.                               HKEY_CLASSES_ROOT,   TEXT("CLSID\\%s\\ProgID"),           PROG_ID,
  525.                               0,                   TEXT(""),                           TEXT("")};
  526.  
  527. //register the CLSID entries
  528. for(i = 0; ClsidEntries[i].hRootKey; i++)
  529.    {
  530.    //create the sub key string - for this case, insert the file extension
  531.    wsprintf(szSubKey, ClsidEntries[i].szSubKey, szCLSID);
  532.  
  533.    lResult = RegCreateKeyEx(  ClsidEntries[i].hRootKey,
  534.                               szSubKey,
  535.                               0,
  536.                               NULL,
  537.                               REG_OPTION_NON_VOLATILE,
  538.                               KEY_WRITE,
  539.                               NULL,
  540.                               &hKey,
  541.                               &dwDisp);
  542.    
  543.    if(NOERROR == lResult)
  544.       {
  545.       TCHAR szValue[MAX_PATH];
  546.  
  547.       //if necessary, create the value string
  548.       wsprintf(szValue, ClsidEntries[i].szValue, szApp);
  549.    
  550.       lResult = RegSetValueEx(   hKey,
  551.                                  NULL,
  552.                                  0,
  553.                                  REG_SZ,
  554.                                  (LPBYTE)szValue,
  555.                                  lstrlen(szValue) + 1);
  556.       
  557.       RegCloseKey(hKey);
  558.       }
  559.    else
  560.       return FALSE;
  561.    }
  562. }
  563.  
  564. //register the component as insertable and a document object
  565. ICatRegister   *pcr;
  566. HRESULT        hr = S_OK ;
  567.     
  568. CoInitialize(NULL);
  569.  
  570. hr = CoCreateInstance(  CLSID_StdComponentCategoriesMgr, 
  571.                         NULL, 
  572.                         CLSCTX_INPROC_SERVER, 
  573.                         IID_ICatRegister, 
  574.                         (LPVOID*)&pcr);
  575.  
  576. if(SUCCEEDED(hr))
  577.    {
  578.    CATID rgcatid[2];
  579.    
  580.    rgcatid[0] = CATID_Insertable;
  581.    rgcatid[1] = CATID_DocObject;
  582.  
  583.    hr = pcr->RegisterClassImplCategories(clsid, 2, rgcatid);
  584.  
  585.    pcr->Release();
  586.    }
  587.         
  588. CoUninitialize();
  589.  
  590. return SUCCEEDED(hr);
  591. }
  592.  
  593. /**************************************************************************
  594.  
  595.    COleDocument::CreateFile(HWND)
  596.  
  597. **************************************************************************/
  598.  
  599. BOOL COleDocument::CreateFile(HWND hwndParent)
  600. {
  601. OutputDebugString("COleDocument::CreateFile(HWND)\n");
  602.  
  603. OPENFILENAME   ofn;
  604. TCHAR          szFilter[MAX_PATH];
  605. TCHAR          szFile[MAX_PATH] = TEXT("");
  606. LPTSTR         pTemp;
  607.  
  608. //build the filter string
  609. pTemp = szFilter;
  610. lstrcpy(pTemp, DOC_NAME);
  611. pTemp += lstrlen(pTemp) + 1;
  612. lstrcpy(pTemp, TEXT("*"));
  613. lstrcat(pTemp, FILE_EXT);
  614. pTemp += lstrlen(pTemp) + 1;
  615. *pTemp = 0;
  616.  
  617. ZeroMemory(&ofn, sizeof(ofn));
  618. ofn.lStructSize         = sizeof(ofn);
  619. ofn.hwndOwner           = hwndParent;
  620. ofn.hInstance           = g_hInst;
  621. ofn.lpstrFilter         = szFilter;
  622. ofn.lpstrCustomFilter   = NULL;
  623. ofn.nMaxCustFilter      = 0;
  624. ofn.nFilterIndex        = 1;
  625. ofn.lpstrFile           = szFile;
  626. ofn.nMaxFile            = ARRAYSIZE(szFile);
  627. ofn.lpstrFileTitle      = NULL;
  628. ofn.nMaxFileTitle       = 0;
  629. ofn.lpstrInitialDir     = NULL;
  630. ofn.lpstrTitle          = NULL;
  631. ofn.lpTemplateName      = MAKEINTRESOURCE(IDD_COLOR_DIALOG);
  632. ofn.lpfnHook            = (LPOFNHOOKPROC)ColorHookProc;
  633. ofn.lCustData           = (DWORD)this;
  634. ofn.Flags               = OFN_EXPLORER |
  635.                            OFN_OVERWRITEPROMPT |
  636.                            OFN_HIDEREADONLY |
  637.                            OFN_ENABLEHOOK | 
  638.                            OFN_ENABLETEMPLATE |
  639.                            0;
  640.  
  641. if(GetSaveFileName(&ofn))
  642.    {
  643.    //if the extension isn't attached, attach it
  644.    pTemp = szFile + lstrlen(szFile) - 4;
  645.    if(lstrcmpi(pTemp, FILE_EXT))
  646.       {
  647.       lstrcat(szFile, FILE_EXT);
  648.       }
  649.  
  650.    return CreateFile(szFile);
  651.    }
  652.  
  653. return FALSE;
  654. }
  655.  
  656.  
  657. /**************************************************************************
  658.  
  659.    COleDocument::CreateFile(LPTSTR)
  660.  
  661. **************************************************************************/
  662.  
  663. BOOL COleDocument::CreateFile(LPTSTR pszFile)
  664. {
  665. OutputDebugString("COleDocument::CreateFile(LPTSTR)\n");
  666.  
  667. WCHAR szwFile[MAX_PATH];
  668.  
  669. #ifdef UNICODE
  670. lstrcpy(szwFile, pszFile);
  671. #else
  672. MultiByteToWideChar( CP_ACP, 
  673.                      MB_PRECOMPOSED, 
  674.                      pszFile, 
  675.                      -1, 
  676.                      szwFile,
  677.                      ARRAYSIZE(szwFile));
  678. #endif
  679.  
  680. m_pPersistFile->Save(szwFile, FALSE);
  681.  
  682. return TRUE;
  683. }
  684.  
  685.  
  686.