home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / winui / shell / fileview / fileview.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1996-06-12  |  7.8 KB  |  285 lines

  1. //THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF 
  2. //ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO 
  3. //THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 
  4. // PARTICULAR PURPOSE.
  5. //
  6. // Copyright  1994-1996  Microsoft Corporation.  All Rights Reserved.
  7. //
  8. //    PROGRAM: FILEVIEW.CPP    
  9. //
  10. //    PURPOSE:   File Viewer Component Object to work with Windows 95 Explorer.
  11. // This file contains functions not specific to the nature of
  12. // the data to view but contains the non-file-specific DLL
  13. // and component object structure.  This can be used for a
  14. // custom viewer by making modifications marked with //MODIFY
  15. // comments.
  16. //
  17. //    PLATFORMS:    Windows 95
  18. //
  19. //    SPECIAL INSTRUCTIONS: N/A
  20. //
  21.  
  22. //Define INITGUIDS once in entire module build
  23. #define INITGUIDS
  24. #include "fileview.h"
  25.  
  26. #include <initguid.h>
  27. #include <shlguid.h>
  28. #include "fvtext.h"     //FileViewer specifics
  29.  
  30. //Count number of objects and number of locks.
  31. ULONG       g_cObj=0;
  32. ULONG       g_cLock=0;
  33.  
  34. //Save this from LibMain
  35. HINSTANCE   g_hInst;
  36.  
  37.  
  38. //
  39. //   FUNCTION:     LibMain
  40. //
  41. //   PURPOSE:   Entry point for a Win32 DLL
  42. //
  43. extern "C" BOOL WINAPI DllMain(HINSTANCE hInstance, ULONG ulReason
  44.     , PVOID pvReserved)
  45.     {
  46.     if (DLL_PROCESS_DETACH==ulReason)
  47.         {
  48.         return TRUE;
  49.         }
  50.     else
  51.         {
  52.         if (DLL_PROCESS_ATTACH!=ulReason)
  53.             return TRUE;
  54.         }
  55.  
  56.     g_hInst=hInstance;
  57.     return TRUE;
  58.     }
  59. //
  60. //   FUNCTION:     DllGetClassObject
  61. //
  62. //   PURPOSE:  Provides an IClassFactory for a given CLSID that this DLL is
  63. //  registered to support.  This DLL is placed under the CLSID
  64. //  in the registration database as the InProcServer.  
  65. //
  66. //   PARAMETERS: 
  67. //       clsID           REFCLSID that identifies the class factory
  68. //                  desired.  Since this parameter is passed this
  69. //                  DLL can handle any number of objects simply
  70. //                 by returning different class factories here
  71. //                  for different CLSIDs.
  72. //
  73. //  riid            REFIID specifying the interface the caller wants
  74. //                  on the class object, usually IID_ClassFactory.
  75. //
  76. //  ppv             PPVOID in which to return the interface pointer.
  77. //
  78. //   RETURN VALUE:
  79. //        HRESULT         NOERROR on success, otherwise an error code.
  80. //
  81. HRESULT PASCAL DllGetClassObject(REFCLSID rclsid, REFIID riid
  82.     , PPVOID ppv)
  83.     {
  84.     // Warning:: The shell may not have initialized OLE so
  85.     // do it here to be sure...
  86.     OleInitialize(NULL);
  87.  
  88.     //MODIFY:  Change CLSID_FileViewerText to your own CLSID
  89.     if (!IsEqualCLSID(rclsid, CLSID_FileViewerText))
  90.         return ResultFromScode(E_FAIL);
  91.  
  92.     //Check that we can provide the interface
  93.     if (!IsEqualIID(riid, IID_IUnknown)
  94.         && !IsEqualIID(riid, IID_IClassFactory))
  95.         return ResultFromScode(E_NOINTERFACE);
  96.  
  97.     //Return our IClassFactory for our viewer objects
  98.     *ppv=(LPVOID)new CFVClassFactory();
  99.  
  100.     if (NULL==*ppv)
  101.         return ResultFromScode(E_OUTOFMEMORY);
  102.  
  103.     //AddRef the object through any interface we return
  104.     ((LPUNKNOWN)*ppv)->AddRef();
  105.  
  106.     return NOERROR;
  107.     }
  108. //
  109. //   FUNCTION: DllCanUnloadNow    
  110. //
  111. //   PURPOSE:  Answers if the DLL can be freed, that is, if there are no
  112. //    references to anything this DLL provides.  
  113. //
  114. //   RETURN VALUE:
  115. //       BOOL            TRUE if nothing is using us, FALSE otherwise.
  116. //
  117. STDAPI DllCanUnloadNow(void)
  118.     {
  119.     SCODE   sc;
  120.  
  121.     //Our answer is whether there are any object or locks
  122.     sc=(0L==g_cObj && 0L==g_cLock) ? S_OK : S_FALSE;
  123.     return ResultFromScode(sc);
  124.     }
  125. //
  126. //   FUNCTION:     ObjectDestroyed
  127. //
  128. //   PURPOSE:  Function for the FileViewer object to call when it gets
  129. //  destroyed. Since we're in a DLL we only track the number of
  130. //  objects here, letting DllCanUnloadNow take care of the rest. 
  131. //
  132. void PASCAL ObjectDestroyed(void)
  133.     {
  134.     g_cObj--;
  135.     return;
  136.     }
  137. //
  138. //   FUNCTION: CFVClassFactory::CFVClassFactory    
  139. //
  140. //   PURPOSE:  Constructor
  141. //
  142. CFVClassFactory::CFVClassFactory(void)
  143.     {
  144.     m_cRef=0L;
  145.     return;
  146.     }
  147.  
  148. //
  149. //   FUNCTION: CFVClassFactory::~CFVClassFactory    
  150. //
  151. //   PURPOSE:   Destructor
  152. //
  153. CFVClassFactory::~CFVClassFactory(void)
  154.     {
  155.     return;
  156.     }
  157.  
  158. //
  159. //   FUNCTION:     CFVClassFactory::QueryInterface
  160. //
  161. STDMETHODIMP CFVClassFactory::QueryInterface(REFIID riid
  162.     , PPVOID ppv)
  163.     {
  164.     *ppv=NULL;
  165.  
  166.     //Any interface on this object is the object pointer.
  167.     if (IsEqualIID(riid, IID_IUnknown)
  168.         || IsEqualIID(riid, IID_IClassFactory))
  169.         *ppv=(LPVOID)this;
  170.  
  171.      // If we actually assign an interface to ppv we need to AddRef
  172.      // it since we're returning a new pointer.
  173.     if (NULL!=*ppv)
  174.         {
  175.         ((LPUNKNOWN)*ppv)->AddRef();
  176.         return NOERROR;
  177.         }
  178.  
  179.     return ResultFromScode(E_NOINTERFACE);
  180.     }
  181. //
  182. //   FUNCTION:     CFVClassFactory::AddRef
  183. //
  184. STDMETHODIMP_(ULONG) CFVClassFactory::AddRef(void)
  185.     {
  186.     return ++m_cRef;
  187.     }
  188.  
  189. //
  190. //   FUNCTION:     CFVClassFactory::Release
  191. //
  192. STDMETHODIMP_(ULONG) CFVClassFactory::Release(void)
  193.     {
  194.     ULONG           cRefT;
  195.  
  196.     cRefT=--m_cRef;
  197.  
  198.     if (0L==m_cRef)
  199.         delete this;
  200.  
  201.     return cRefT;
  202.     }
  203.  
  204. //
  205. //   FUNCTION:     CFVClassFactory::CreateInstance
  206. //
  207. //   PURPOSE:    Instantiates a CFileViewer object that will provide the
  208. //  IPersistFile and IFileViewer interfaces for use with the Windows 95 Explorer.
  209. //
  210. //   PARAMETERS: 
  211. //  pUnkOuter       LPUNKNOWN to the controlling IUnknown if we are being used in an aggregation.
  212. //  riid            REFIID identifying the interface the caller desires to have for the new object.
  213. //  ppvObj          PPVOID in which to store the desired interface pointer for the new object.
  214. //
  215. //   RETURN VALUE:
  216. //   HRESULT         NOERROR if successful, otherwise E_NOINTERFACE
  217. //                  if we cannot support the requested interface.
  218. //
  219. STDMETHODIMP CFVClassFactory::CreateInstance(LPUNKNOWN pUnkOuter
  220.     , REFIID riid, PPVOID ppvObj)
  221.     {
  222.     PCFileViewer        pObj;
  223.     HRESULT             hr;
  224.  
  225.     *ppvObj=NULL;
  226.     hr=ResultFromScode(E_OUTOFMEMORY);
  227.  
  228.     //Verify that a controlling unknown asks for IUnknown
  229.     if (NULL!=pUnkOuter && !IsEqualIID(riid, IID_IUnknown))
  230.         return ResultFromScode(E_NOINTERFACE);
  231.  
  232.      // MODIFY:  If you use a different object than CFileViewer
  233.     // be sure to change the name and parameters here.  I do
  234.     // recommend that you continue to follow this model, however,
  235.     // and just modify CFileViewer as necessary.
  236.     //Create the object passing function to notify on destruction.
  237.     pObj=new CFileViewer(pUnkOuter, g_hInst, ObjectDestroyed);
  238.  
  239.     if (NULL==pObj)
  240.         return hr;
  241.  
  242.     //MODIFY:  Add other parameters to Init as necessary.
  243.     hr=pObj->Init();
  244.  
  245.     if (SUCCEEDED(hr))
  246.         {
  247.         //Return the requested interface
  248.         hr=pObj->QueryInterface(riid, ppvObj);
  249.  
  250.         if (SUCCEEDED(hr))
  251.             {
  252.             //Everything worked:  count the object
  253.             g_cObj++;
  254.             return NOERROR;
  255.             }
  256.         }
  257.  
  258.     //Kill the object if anything failed after creation.
  259.     delete pObj;
  260.  
  261.     return hr;
  262.     }
  263. //
  264. //   FUNCTION: CFVClassFactory::LockServer    
  265. //
  266. //   PURPOSE:  Increments or decrements the lock count of the DLL.  If the
  267. //  lock count goes to zero and there are no objects, the DLL
  268. //  is allowed to unload.  See DllCanUnloadNow.
  269. //
  270. //   PARAMETERS: 
  271. //    fLock           BOOL specifying whether to increment or decrement the lock count.
  272. //
  273. //   RETURN VALUE:
  274. //     HRESULT         NOERROR always
  275. //
  276. STDMETHODIMP CFVClassFactory::LockServer(BOOL fLock)
  277.     {
  278.     if (fLock)
  279.         g_cLock++;
  280.     else
  281.         g_cLock--;
  282.  
  283.     return NOERROR;
  284.     }
  285.