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 / bandobjs / bandobjs.cpp next >
Encoding:
C/C++ Source or Header  |  1997-12-11  |  8.5 KB  |  286 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 - 1998 Microsoft Corporation.  All Rights Reserved.
  8. **************************************************************************/
  9.  
  10. /**************************************************************************
  11.  
  12.    File:          BandObjs.cpp
  13.    
  14.    Description:   Contains DLLMain and standard OLE COM object creation stuff.
  15.  
  16. **************************************************************************/
  17.  
  18. /**************************************************************************
  19.    #include statements
  20. **************************************************************************/
  21.  
  22. #include <ole2.h>
  23. #include <comcat.h>
  24. #include <olectl.h>
  25. #include "ClsFact.h"
  26.  
  27. /**************************************************************************
  28.    GUID stuff
  29. **************************************************************************/
  30.  
  31. //this part is only done once
  32. //if you need to use the GUID in another file, just include Guid.h
  33. #pragma data_seg(".text")
  34. #define INITGUID
  35. #include <initguid.h>
  36. #include <shlguid.h>
  37. #include "Guid.h"
  38. #pragma data_seg()
  39.  
  40. /**************************************************************************
  41.    private function prototypes
  42. **************************************************************************/
  43.  
  44. extern "C" BOOL WINAPI DllMain(HINSTANCE, DWORD, LPVOID);
  45. BOOL RegisterServer(CLSID, LPTSTR);
  46. BOOL RegisterComCat(CLSID, CATID);
  47.  
  48. /**************************************************************************
  49.    global variables
  50. **************************************************************************/
  51.  
  52. HINSTANCE   g_hInst;
  53. UINT        g_DllRefCount;
  54.  
  55. /**************************************************************************
  56.  
  57.    DllMain
  58.  
  59. **************************************************************************/
  60.  
  61. extern "C" BOOL WINAPI DllMain(  HINSTANCE hInstance, 
  62.                                  DWORD dwReason, 
  63.                                  LPVOID lpReserved)
  64. {
  65. switch(dwReason)
  66.    {
  67.    case DLL_PROCESS_ATTACH:
  68.       g_hInst = hInstance;
  69.       break;
  70.  
  71.    case DLL_PROCESS_DETACH:
  72.       break;
  73.    }
  74.    
  75. return TRUE;
  76. }                                 
  77.  
  78. /**************************************************************************
  79.  
  80.    DllCanUnloadNow
  81.  
  82. **************************************************************************/
  83.  
  84. STDAPI DllCanUnloadNow(void)
  85. {
  86. return (g_DllRefCount ? S_FALSE : S_OK);
  87. }
  88.  
  89. /**************************************************************************
  90.  
  91.    DllGetClassObject
  92.  
  93. **************************************************************************/
  94.  
  95. STDAPI DllGetClassObject(  REFCLSID rclsid, 
  96.                            REFIID riid, 
  97.                            LPVOID *ppReturn)
  98. {
  99. *ppReturn = NULL;
  100.  
  101. //if we don't support this classid, return the proper error code
  102. if(   !IsEqualCLSID(rclsid, CLSID_SampleDeskBand) &&
  103.       !IsEqualCLSID(rclsid, CLSID_SampleExplorerBar) &&
  104.       !IsEqualCLSID(rclsid, CLSID_SampleCommBand))
  105.    return CLASS_E_CLASSNOTAVAILABLE;
  106.    
  107. //create a CClassFactory object and check it for validity
  108. CClassFactory *pClassFactory = new CClassFactory(rclsid);
  109. if(NULL == pClassFactory)
  110.    return E_OUTOFMEMORY;
  111.    
  112. //get the QueryInterface return for our return value
  113. HRESULT hResult = pClassFactory->QueryInterface(riid, ppReturn);
  114.  
  115. //call Release to decement the ref count - creating the object set it to one 
  116. //and QueryInterface incremented it - since its being used externally (not by 
  117. //us), we only want the ref count to be 1
  118. pClassFactory->Release();
  119.  
  120. //return the result from QueryInterface
  121. return hResult;
  122. }
  123.  
  124. /**************************************************************************
  125.  
  126.    DllRegisterServer
  127.  
  128. **************************************************************************/
  129.  
  130. STDAPI DllRegisterServer(void)
  131. {
  132. //Register the desk band object.
  133. if(!RegisterServer(CLSID_SampleDeskBand, TEXT("Sample &Desk Band")))
  134.    return SELFREG_E_CLASS;
  135.  
  136. //Register the component categories for the desk band object.
  137. if(!RegisterComCat(CLSID_SampleDeskBand, CATID_DeskBand))
  138.    return SELFREG_E_CLASS;
  139.  
  140. //Register the explorer bar object.
  141. if(!RegisterServer(CLSID_SampleExplorerBar, TEXT("Sample &Explorer Bar")))
  142.    return SELFREG_E_CLASS;
  143.  
  144. //Register the component categories for the explorer bar object.
  145. if(!RegisterComCat(CLSID_SampleExplorerBar, CATID_InfoBand))
  146.    return SELFREG_E_CLASS;
  147.  
  148. //Register the comm band object.
  149. if(!RegisterServer(CLSID_SampleCommBand, TEXT("Sample &Comm Band")))
  150.    return SELFREG_E_CLASS;
  151.  
  152. //Register the component categories for the comm band object.
  153. if(!RegisterComCat(CLSID_SampleCommBand, CATID_CommBand))
  154.    return SELFREG_E_CLASS;
  155.  
  156. return S_OK;
  157. }
  158.  
  159. /**************************************************************************
  160.  
  161.    RegisterServer
  162.  
  163. **************************************************************************/
  164.  
  165. typedef struct{
  166.    HKEY  hRootKey;
  167.    LPTSTR szSubKey;//TCHAR szSubKey[MAX_PATH];
  168.    LPTSTR lpszValueName;
  169.    LPTSTR szData;//TCHAR szData[MAX_PATH];
  170. }DOREGSTRUCT, *LPDOREGSTRUCT;
  171.  
  172. BOOL RegisterServer(CLSID clsid, LPTSTR lpszTitle)
  173. {
  174. int      i;
  175. HKEY     hKey;
  176. LRESULT  lResult;
  177. DWORD    dwDisp;
  178. TCHAR    szSubKey[MAX_PATH];
  179. TCHAR    szCLSID[MAX_PATH];
  180. TCHAR    szModule[MAX_PATH];
  181. LPWSTR   pwsz;
  182.  
  183. //get the CLSID in string form
  184. StringFromIID(clsid, &pwsz);
  185.  
  186. if(pwsz)
  187.    {
  188. #ifdef UNICODE
  189.    lstrcpy(szCLSID, pwsz);
  190. #else
  191.    WideCharToMultiByte( CP_ACP,
  192.                         0,
  193.                         pwsz,
  194.                         -1,
  195.                         szCLSID,
  196.                         ARRAYSIZE(szCLSID),
  197.                         NULL,
  198.                         NULL);
  199. #endif
  200.  
  201.    //free the string
  202.    LPMALLOC pMalloc;
  203.    CoGetMalloc(1, &pMalloc);
  204.    pMalloc->Free(pwsz);
  205.    pMalloc->Release();
  206.    }
  207.  
  208. //get this app's path and file name
  209. GetModuleFileName(g_hInst, szModule, ARRAYSIZE(szModule));
  210.  
  211. DOREGSTRUCT ClsidEntries[] = {HKEY_CLASSES_ROOT,   TEXT("CLSID\\%s"),                  NULL,                   lpszTitle,
  212.                               HKEY_CLASSES_ROOT,   TEXT("CLSID\\%s\\InprocServer32"),  NULL,                   szModule,
  213.                               HKEY_CLASSES_ROOT,   TEXT("CLSID\\%s\\InprocServer32"),  TEXT("ThreadingModel"), TEXT("Apartment"),
  214.                               NULL,                NULL,                               NULL,                   NULL};
  215.  
  216. //register the CLSID entries
  217. for(i = 0; ClsidEntries[i].hRootKey; i++)
  218.    {
  219.    //create the sub key string - for this case, insert the file extension
  220.    wsprintf(szSubKey, ClsidEntries[i].szSubKey, szCLSID);
  221.  
  222.    lResult = RegCreateKeyEx(  ClsidEntries[i].hRootKey,
  223.                               szSubKey,
  224.                               0,
  225.                               NULL,
  226.                               REG_OPTION_NON_VOLATILE,
  227.                               KEY_WRITE,
  228.                               NULL,
  229.                               &hKey,
  230.                               &dwDisp);
  231.    
  232.    if(NOERROR == lResult)
  233.       {
  234.       TCHAR szData[MAX_PATH];
  235.  
  236.       //if necessary, create the value string
  237.       wsprintf(szData, ClsidEntries[i].szData, szModule);
  238.    
  239.       lResult = RegSetValueEx(   hKey,
  240.                                  ClsidEntries[i].lpszValueName,
  241.                                  0,
  242.                                  REG_SZ,
  243.                                  (LPBYTE)szData,
  244.                                  lstrlen(szData) + 1);
  245.       
  246.       RegCloseKey(hKey);
  247.       }
  248.    else
  249.       return FALSE;
  250.    }
  251.  
  252. return TRUE;
  253. }
  254.  
  255. /**************************************************************************
  256.  
  257.    RegisterComCat
  258.  
  259. **************************************************************************/
  260.  
  261. BOOL RegisterComCat(CLSID clsid, CATID CatID)
  262. {
  263. ICatRegister   *pcr;
  264. HRESULT        hr = S_OK ;
  265.     
  266. CoInitialize(NULL);
  267.  
  268. hr = CoCreateInstance(  CLSID_StdComponentCategoriesMgr, 
  269.                         NULL, 
  270.                         CLSCTX_INPROC_SERVER, 
  271.                         IID_ICatRegister, 
  272.                         (LPVOID*)&pcr);
  273.  
  274. if(SUCCEEDED(hr))
  275.    {
  276.    hr = pcr->RegisterClassImplCategories(clsid, 1, &CatID);
  277.  
  278.    pcr->Release();
  279.    }
  280.         
  281. CoUninitialize();
  282.  
  283. return SUCCEEDED(hr);
  284. }
  285.  
  286.