BANDOBJS.CPP
/************************************************************************** 
   THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF 
   ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO 
   THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A 
   PARTICULAR PURPOSE. 
 
   Copyright 1997 Microsoft Corporation.  All Rights Reserved. 
**************************************************************************/ 
 
/************************************************************************** 
 
   File:          BandObjs.cpp 
    
   Description:   Contains DLLMain and standard OLE COM object creation stuff. 
 
**************************************************************************/ 
 
/************************************************************************** 
   #include statements 
**************************************************************************/ 
 
#include <ole2.h> 
#include <comcat.h> 
#include <olectl.h> 
#include "ClsFact.h" 
 
/************************************************************************** 
   GUID stuff 
**************************************************************************/ 
 
//this part is only done once 
//if you need to use the GUID in another file, just include Guid.h 
#pragma data_seg(".text") 
#define INITGUID 
#include <initguid.h> 
#include <shlguid.h> 
#include "Guid.h" 
#pragma data_seg() 
 
/************************************************************************** 
   private function prototypes 
**************************************************************************/ 
 
extern "C" BOOL WINAPI DllMain(HINSTANCE, DWORD, LPVOID); 
BOOL RegisterServer(CLSID, LPTSTR); 
BOOL RegisterComCat(CLSID, CATID); 
 
/************************************************************************** 
   global variables 
**************************************************************************/ 
 
HINSTANCE   g_hInst; 
UINT        g_DllRefCount; 
 
/************************************************************************** 
 
   DllMain 
 
**************************************************************************/ 
 
extern "C" BOOL WINAPI DllMain(  HINSTANCE hInstance,  
                                 DWORD dwReason,  
                                 LPVOID lpReserved) 
{ 
switch(dwReason) 
   { 
   case DLL_PROCESS_ATTACH: 
      g_hInst = hInstance; 
      break; 
 
   case DLL_PROCESS_DETACH: 
      break; 
   } 
    
return TRUE; 
}                                  
 
/************************************************************************** 
 
   DllCanUnloadNow 
 
**************************************************************************/ 
 
STDAPI DllCanUnloadNow(void) 
{ 
return (g_DllRefCount ? S_FALSE : S_OK); 
} 
 
/************************************************************************** 
 
   DllGetClassObject 
 
**************************************************************************/ 
 
STDAPI DllGetClassObject(  REFCLSID rclsid,  
                           REFIID riid,  
                           LPVOID *ppReturn) 
{ 
*ppReturn = NULL; 
 
//if we don't support this classid, return the proper error code 
if(   !IsEqualCLSID(rclsid, CLSID_SampleDeskBand) && 
      !IsEqualCLSID(rclsid, CLSID_SampleExplorerBar) && 
      !IsEqualCLSID(rclsid, CLSID_SampleCommBand)) 
   return CLASS_E_CLASSNOTAVAILABLE; 
    
//create a CClassFactory object and check it for validity 
CClassFactory *pClassFactory = new CClassFactory(rclsid); 
if(NULL == pClassFactory) 
   return E_OUTOFMEMORY; 
    
//get the QueryInterface return for our return value 
HRESULT hResult = pClassFactory->QueryInterface(riid, ppReturn); 
 
//call Release to decement the ref count - creating the object set it to one  
//and QueryInterface incremented it - since its being used externally (not by  
//us), we only want the ref count to be 1 
pClassFactory->Release(); 
 
//return the result from QueryInterface 
return hResult; 
} 
 
/************************************************************************** 
 
   DllRegisterServer 
 
**************************************************************************/ 
 
STDAPI DllRegisterServer(void) 
{ 
//Register the desk band object. 
if(!RegisterServer(CLSID_SampleDeskBand, TEXT("Sample &Desk Band"))) 
   return SELFREG_E_CLASS; 
 
//Register the component categories for the desk band object. 
if(!RegisterComCat(CLSID_SampleDeskBand, CATID_DeskBand)) 
   return SELFREG_E_CLASS; 
 
//Register the explorer bar object. 
if(!RegisterServer(CLSID_SampleExplorerBar, TEXT("Sample &Explorer Bar"))) 
   return SELFREG_E_CLASS; 
 
//Register the component categories for the explorer bar object. 
if(!RegisterComCat(CLSID_SampleExplorerBar, CATID_InfoBand)) 
   return SELFREG_E_CLASS; 
 
//Register the comm band object. 
if(!RegisterServer(CLSID_SampleCommBand, TEXT("Sample &Comm Band"))) 
   return SELFREG_E_CLASS; 
 
//Register the component categories for the comm band object. 
if(!RegisterComCat(CLSID_SampleCommBand, CATID_CommBand)) 
   return SELFREG_E_CLASS; 
 
return S_OK; 
} 
 
/************************************************************************** 
 
   RegisterServer 
 
**************************************************************************/ 
 
typedef struct{ 
   HKEY  hRootKey; 
   LPTSTR szSubKey;//TCHAR szSubKey[MAX_PATH]; 
   LPTSTR lpszValueName; 
   LPTSTR szData;//TCHAR szData[MAX_PATH]; 
}DOREGSTRUCT, *LPDOREGSTRUCT; 
 
BOOL RegisterServer(CLSID clsid, LPTSTR lpszTitle) 
{ 
int      i; 
HKEY     hKey; 
LRESULT  lResult; 
DWORD    dwDisp; 
TCHAR    szSubKey[MAX_PATH]; 
TCHAR    szCLSID[MAX_PATH]; 
TCHAR    szModule[MAX_PATH]; 
LPWSTR   pwsz; 
 
//get the CLSID in string form 
StringFromIID(clsid, &pwsz); 
 
if(pwsz) 
   { 
#ifdef UNICODE 
   lstrcpy(szCLSID, pwsz); 
#else 
   WideCharToMultiByte( CP_ACP, 
                        0, 
                        pwsz, 
                        -1, 
                        szCLSID, 
                        ARRAYSIZE(szCLSID), 
                        NULL, 
                        NULL); 
#endif 
 
   //free the string 
   LPMALLOC pMalloc; 
   CoGetMalloc(1, &pMalloc); 
   pMalloc->Free(pwsz); 
   pMalloc->Release(); 
   } 
 
//get this app's path and file name 
GetModuleFileName(g_hInst, szModule, ARRAYSIZE(szModule)); 
 
DOREGSTRUCT ClsidEntries[] = {HKEY_CLASSES_ROOT,   TEXT("CLSID\\%s"),                  NULL,                   lpszTitle, 
                              HKEY_CLASSES_ROOT,   TEXT("CLSID\\%s\\InprocServer32"),  NULL,                   szModule, 
                              HKEY_CLASSES_ROOT,   TEXT("CLSID\\%s\\InprocServer32"),  TEXT("ThreadingModel"), TEXT("Apartment"), 
                              NULL,                NULL,                               NULL,                   NULL}; 
 
//register the CLSID entries 
for(i = 0; ClsidEntries[i].hRootKey; i++) 
   { 
   //create the sub key string - for this case, insert the file extension 
   wsprintf(szSubKey, ClsidEntries[i].szSubKey, szCLSID); 
 
   lResult = RegCreateKeyEx(  ClsidEntries[i].hRootKey, 
                              szSubKey, 
                              0, 
                              NULL, 
                              REG_OPTION_NON_VOLATILE, 
                              KEY_WRITE, 
                              NULL, 
                              &hKey, 
                              &dwDisp); 
    
   if(NOERROR == lResult) 
      { 
      TCHAR szData[MAX_PATH]; 
 
      //if necessary, create the value string 
      wsprintf(szData, ClsidEntries[i].szData, szModule); 
    
      lResult = RegSetValueEx(   hKey, 
                                 ClsidEntries[i].lpszValueName, 
                                 0, 
                                 REG_SZ, 
                                 (LPBYTE)szData, 
                                 lstrlen(szData) + 1); 
       
      RegCloseKey(hKey); 
      } 
   else 
      return FALSE; 
   } 
 
return TRUE; 
} 
 
/************************************************************************** 
 
   RegisterComCat 
 
**************************************************************************/ 
 
BOOL RegisterComCat(CLSID clsid, CATID CatID) 
{ 
ICatRegister   *pcr; 
HRESULT        hr = S_OK ; 
     
CoInitialize(NULL); 
 
hr = CoCreateInstance(  CLSID_StdComponentCategoriesMgr,  
                        NULL,  
                        CLSCTX_INPROC_SERVER,  
                        IID_ICatRegister,  
                        (LPVOID*)&pcr); 
 
if(SUCCEEDED(hr)) 
   { 
   hr = pcr->RegisterClassImplCategories(clsid, 1, &CatID); 
 
   pcr->Release(); 
   } 
         
CoUninitialize(); 
 
return SUCCEEDED(hr); 
}