www.pudn.com > TVToolbar_demo > TVToolbar.cpp


// TVToolbar.cpp : Implementation of DLL Exports. 
 
///////////////////////////////////////////////////////////////////////////// 
// 
/************************************************************** 
**        __                                          __ 
**     __/_/__________________________________________\_\__ 
**  __|_                                                  |__ 
** (___O)       William SerGio & Co., Inc.               (O___) 
**(_____O)	    www.codearchive.com/~sergio			    (O_____) 
**(_____O)		Author:	Bill SerGio				        (O_____) 
** (__O)		                    					 (O__) 
**    |___________________________________________________| 
****************************************************************/ 
/* 
 * (C) Copyright 1997-1999 by William SerGio, All Rights Reserved Worldwide. 
 * 20547 Old Cutler Road, PMB #222, Miami, FL 33189 
 * www.codearchive.com/~sergio   sergio@codearchive.com  (305)233-7654 
 * NO PART of this code may be used for any comercial purposes whatsoever. 
 * Patents Pending regarding design and user interface concepts embodied herein. 
 * 
 * Redistribution and use in source and binary forms, with or without modification, 
 * are permitted under this non-exclusive license for NON-COMMERCIAL USE ONLY 
 * provided that the following conditions are met: 
 * 1. Redistributions of source code must retain the above copyright 
 *    notice, this list of conditions and the following disclaimer. 
 * 2. Redistributions in binary form must reproduce the above copyright 
 *    notice, this list of conditions and the following disclaimer in the 
 *    documentation and/or other materials provided with the distribution. 
 * 3. Licensee does not utilize the software in a manner which is disparaging 
 *    to the Author and/or any products or companies of the Author. 
 * 4. This code/software may NOT be used for any commercial purpose whatsoever 
 *    or by any government, federal agency, or, any employee or agent of any  
 *    government or federal agency. This software is not designed or intended for  
 *    use in on-line control of aircraft, air traffic, aircraft navigation or  
 *    aircraft communications; or in design, construction, operation or maintenance  
 *    of any nuclear facility. Licensee represents and warrants that it will not use 
 *    or redistribute the Software for such purposes. 
 * 
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR FOR EDUCATIONAL PURPOSES ONLY, 
 * 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS, 
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION), 
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
 * SUCH DAMAGE. 
 * 
 * NOTICE: 
 * Contact author regarding commercial licensing of this code. 
 * The marks: TV Toolbar(tm), TVToolbar(tm), 3D TV Toolbar(tm), 3D TVToolbar(tm), 
 * SlickSkins(tm), VideoSkins(tm), LiquidVideo(tm), Email Anywhere(tm), SpeedE(tm), 
 * Windows SuperCharger(tm), Internet SuperCharger(tm), 1st Place(tm), SpeedD(tm),  
 * Speed Demon(tm), LiquidDesktop(tm), VideoAnywhere(tm) are copyrights and trademarks  
 * of William SerGio & Co., Inc. and may NOT be used in any way whatsoever. 
 * 
 */ 
 
// Note: Proxy/Stub Information 
//      To build a separate proxy/stub DLL,  
//      run nmake -f TVToolbarps.mk in the project directory. 
 
#include "stdafx.h" 
#include "resource.h" 
#include  
#include "TVToolbar.h" 
 
#include "TVToolbar_i.c" 
 
#include  
#pragma  comment( lib , "user32") 
   
//////////////////////////////////////////////////////////////////////// 
#include  
#include  
#include  
#include "ClsFact.h" 
//////////////////////////////////////////////////////////////////////// 
 
//////////////////////////////////////////////////////////////////////// 
// Required for registry stuff 
#include  
#pragma  comment( lib , "advapi32") 
//////////////////////////////////////////////////////////////////////// 
 
 
// 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  
#include  
#include "Guid.h" 
//#pragma data_seg() 
//////////////////////////////////////////////////////// 
 
BOOL RegisterServer(CLSID, LPTSTR); 
BOOL RegisterComCat(CLSID, CATID); 
BOOL UnRegisterServer(CLSID); 
BOOL UnRegisterComCat(CLSID, CATID); 
BOOL RegisterToolBand(CLSID); 
 
HINSTANCE  g_hInst; 
LONG       g_cDllRefCount; 
 
typedef struct 
{ 
   HKEY   hRootKey; 
   LPTSTR szSubKey;  // TCHAR szSubKey[MAX_PATH]; 
   LPTSTR lpszValueName; 
   LPTSTR szData;    // TCHAR szData[MAX_PATH]; 
 
} DOREGSTRUCT, *LPDOREGSTRUCT; 
 
CComModule _Module; 
 
BEGIN_OBJECT_MAP(ObjectMap) 
END_OBJECT_MAP() 
 
class CTVToolbarApp : public CWinApp 
{ 
public: 
 
// Overrides 
	// ClassWizard generated virtual function overrides 
	//{{AFX_VIRTUAL(CTVToolbarApp) 
	public: 
    virtual BOOL InitInstance(); 
    virtual int ExitInstance(); 
	//}}AFX_VIRTUAL 
 
	//{{AFX_MSG(CTVToolbarApp) 
		// NOTE - the ClassWizard will add and remove member functions here. 
		//    DO NOT EDIT what you see in these blocks of generated code ! 
	//}}AFX_MSG 
	DECLARE_MESSAGE_MAP() 
}; 
 
BEGIN_MESSAGE_MAP(CTVToolbarApp, CWinApp) 
	//{{AFX_MSG_MAP(CTVToolbarApp) 
		// NOTE - the ClassWizard will add and remove mapping macros here. 
		//    DO NOT EDIT what you see in these blocks of generated code! 
	//}}AFX_MSG_MAP 
END_MESSAGE_MAP() 
 
CTVToolbarApp theApp; 
 
BOOL CTVToolbarApp::InitInstance() 
{ 
	// ATL initialization 
    _Module.Init(ObjectMap, m_hInstance, &LIBID_TVTOOLBARLib); 
    //return CWinApp::InitInstance(); 
	DisableThreadLibraryCalls(m_hInstance); 
 
	// Check who's loading us, or playing with our dingy? 
	// If it's BERTHA the ugly Explorer tell her to "fuck off" and exit... 
	// You can allow explorer shell to load you if we want some kind 
	// of explorer search file utility shit... for the desktop... 
	// 
	TCHAR pszLoader[MAX_PATH]; 
	GetModuleFileName(NULL, pszLoader, MAX_PATH); 
	_tcslwr(pszLoader); 
	if (_tcsstr(pszLoader, _T("explorer.exe")))  
	{ 
		return FALSE; 
	} 
	g_hInst = m_hInstance; 
    return CWinApp::InitInstance();;    // ok 
 
} 
 
int CTVToolbarApp::ExitInstance() 
{ 
    _Module.Term(); 
    return CWinApp::ExitInstance(); 
} 
 
 
STDAPI DllCanUnloadNow(void) 
{ 
    AFX_MANAGE_STATE(AfxGetStaticModuleState()); 
	//return (g_cDllRefCount ? S_FALSE : S_OK); 
    return (AfxDllCanUnloadNow()==S_OK && _Module.GetLockCount()==0) ? S_OK : S_FALSE; 
} 
 
 
/* 
 * Returns class factory to create an object of requested type 
 */ 
STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv) 
{ 
   *ppv = NULL; 
 
   // If we don't support this classid, return proper error code 
   if (!IsEqualCLSID(rclsid, CLSID_WBToolBar)) 
      return CLASS_E_CLASSNOTAVAILABLE; 
    
   // Create CClassFactory object and check it for validity 
   CClassFactory* pClassFactory = new CClassFactory(rclsid); 
   if (NULL == pClassFactory) 
      return E_OUTOFMEMORY; 
    
   // QI for requested interface 
   HRESULT hr = pClassFactory->QueryInterface(riid, ppv); 
 
   // Call Release to decement reference count. When you create object 
   // set it to one and QueryInterface incremented it - since its being  
   // used externally (not by us), we only want ref count to be 1 
   // An example of "Hard" vs. "Soft" Reference Counting! 
   // 
   pClassFactory->Release(); 
 
   //return _Module.GetClassObject(rclsid, riid, ppv); 
   return hr; 
} 
 
/* 
 * DllRegisterServer - Adds entries to the system registry 
 */ 
STDAPI DllRegisterServer(void) 
{ 
	// registers object, typelib and all interfaces in typelib 
 
	//Register tool band object. 
	if(!RegisterToolBand(CLSID_WBToolBar)) 
	   return SELFREG_E_CLASS; 
 
	//Register tool band object. 
	if(!RegisterServer(CLSID_WBToolBar, TEXT("&TVToolbar"))) 
	   return SELFREG_E_CLASS; 
 
 
	// Register Component Categories for explorer bar object. 
	//if (!RegisterComCat(CLSID_WBToolBar, CATID_InfoBand)) 
	//  return SELFREG_E_CLASS; 
 
	// Register Component Categories for explorer bar object. 
	if (!RegisterComCat(CLSID_WBToolBar, CATID_CommBand)) 
	  return SELFREG_E_CLASS; 
 
	/* 
	Remove cache of deskbands on Windows 2000.  
	This will cause new deskband to be displayed  
	in toolbar menu next time the user brings it  
	up. See KB article Q214842 for more info. 
	HKEY_CLASSES_ROOT\Component Categories\ 
	{00021492-0000-0000-C000-000000000046}\Enum  
	*/ 
	TCHAR    szSubKey[MAX_PATH]; 
	TCHAR    szCATID[MAX_PATH]; 
	LPWSTR   pwszCATID; 
 
	StringFromCLSID(CATID_CommBand, &pwszCATID); 
	if(pwszCATID) 
	   { 
	#ifdef UNICODE 
	   lstrcpy(szCATID, pwszCATID); 
	#else 
	   WideCharToMultiByte( CP_ACP, 
							0, 
							pwszCATID, 
							-1, 
							szCATID, 
							ARRAYSIZE(szCATID), 
							NULL, 
							NULL); 
	#endif 
 
	//Free string 
	CoTaskMemFree(pwszCATID); 
 
	wsprintf(szSubKey, TEXT("Component Categories\\%s\\Enum"), szCATID); 
	//wsprintf(szSubKey, TEXT("Component Categories\\{00021492-0000-0000-C000-000000000046}\\Enum"), szCATID); 
 
	::RegDeleteKey(HKEY_CLASSES_ROOT, szSubKey); 
	} 
	//return S_OK; 
	return _Module.RegisterServer(TRUE); 
} 
 
/* 
 * DllUnregisterServer - Removes entries from the system registry 
 */ 
STDAPI DllUnregisterServer(void) 
{ 
	// Register the Component Categories for the explorer bar object. 
	if (!UnRegisterComCat(CLSID_WBToolBar, CATID_CommBand)) 
		return SELFREG_E_CLASS; 
 
	// Register the Component Categories for the explorer bar object. 
	//if (!UnRegisterComCat(CLSID_WBToolBar, CATID_InfoBand)) 
	//  return SELFREG_E_CLASS; 
 
	// Register the explorer bar object. 
	if (!UnRegisterServer(CLSID_WBToolBar)) 
		return SELFREG_E_CLASS; 
 
	//return S_OK; 
	return _Module.UnregisterServer(TRUE); 
} 
 
 
 
BOOL RegisterServer(CLSID clsid, LPTSTR lpszTitle) 
{ 
   int     i; 
   HKEY    hKey; 
   LRESULT lResult; 
   DWORD   dwDisp; 
   TCHAR   szSubKey[MAX_PATH]; 
   TCHAR   szCLSID[MAX_PATH]; 
   TCHAR   szTVToolbarCLSID[MAX_PATH]; 
   TCHAR   szModule[MAX_PATH]; 
   LPWSTR  pwsz; 
 
   // Get CLSID in string form 
   StringFromIID(clsid, &pwsz); 
 
   if (pwsz) 
   { 
#ifdef UNICODE 
      lstrcpy(szTVToolbarCLSID, pwsz); 
#else 
      WideCharToMultiByte(CP_ACP, 0, pwsz, -1, szTVToolbarCLSID, 
                          ARRAYSIZE(szTVToolbarCLSID), NULL, NULL); 
#endif 
 
      // Free 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)); 
	// OR 
	//HMODULE hModule; 
	//hModule = GetModuleHandle(TEXT("TVToolbar.dll")); 
	//GetModuleFileName(hModule, 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 CLSID entries 
   for (i = 0; ClsidEntries[i].hRootKey; i++) 
   { 
      // Create sub key string for this case, insert file extension 
      wsprintf(szSubKey, ClsidEntries[i].szSubKey, szTVToolbarCLSID); 
 
      lResult = ::RegCreateKeyEx(ClsidEntries[i].hRootKey, szSubKey,  
                               0, NULL, REG_OPTION_NON_VOLATILE, 
                               KEY_WRITE, NULL, &hKey, &dwDisp); 
    
      if (ERROR_SUCCESS == lResult) 
      { 
         TCHAR szData[MAX_PATH]; 
 
         // If necessary, create value string 
         wsprintf(szData, ClsidEntries[i].szData, szModule); 
    
         lResult = ::RegSetValueEx(hKey, ClsidEntries[i].lpszValueName,  
                                 0, REG_SZ, (LPBYTE)szData, 
                                 lstrlen(szData) + 1); 
         ::RegCloseKey(hKey); 
 
         if (ERROR_SUCCESS != lResult) 
            return FALSE; 
      } 
      else 
      { 
         return FALSE; 
      } 
   } 
 
   // Create Registry key entry and values for toolbar button 
   StringFromIID(CLSID_TVToolbarButton, &pwsz); 
 
   if (!pwsz) 
      return TRUE; 
 
#ifdef UNICODE 
   lstrcpy(szCLSID, pwsz); 
#else 
   WideCharToMultiByte(CP_ACP, 0, pwsz, -1, szCLSID, 
                       ARRAYSIZE(szCLSID), NULL, NULL); 
#endif 
 
   // Free string 
   LPMALLOC pMalloc; 
 
   CoGetMalloc(1, &pMalloc); 
   pMalloc->Free(pwsz); 
   pMalloc->Release(); 
 
   wsprintf(szSubKey, _T("Software\\Microsoft\\Internet Explorer\\Extensions\\%s"), szCLSID); 
 
   lResult = ::RegCreateKeyEx(HKEY_LOCAL_MACHINE, szSubKey,  
                            0, NULL, REG_OPTION_NON_VOLATILE, 
                            KEY_WRITE, NULL, &hKey, &dwDisp); 
    
   if (ERROR_SUCCESS == lResult) 
   { 
      TCHAR szData[MAX_PATH]; 
 
      // Create value strings 
      lstrcpy(szData, _T("TVToolbar")); 
      ::RegSetValueEx(hKey, TEXT("ButtonText"),  
                    0, REG_SZ, (LPBYTE)szData, 
                    lstrlen(szData) + 1); 
 
      lstrcpy(szData, _T("Yes")); 
      ::RegSetValueEx(hKey, TEXT("Default Visible"),  
                    0, REG_SZ, (LPBYTE)szData, 
                    lstrlen(szData) + 1); 
 
      TCHAR szPath[MAX_PATH]; 
      HMODULE hModule; 
 
      hModule = GetModuleHandle(TEXT("TVToolbar.dll")); 
      GetModuleFileName(hModule, szPath, MAX_PATH); 
 
      wsprintf(szData, _T("%s,%d"), szPath, IDI_HOTICON); 
      ::RegSetValueEx(hKey, TEXT("HotIcon"),  
                    0, REG_SZ, (LPBYTE)szData, 
                    lstrlen(szData) + 1); 
 
      wsprintf(szData, _T("%s,%d"), szPath, IDI_ICON); 
      ::RegSetValueEx(hKey, TEXT("Icon"),  
                    0, REG_SZ, (LPBYTE)szData, 
                    lstrlen(szData) + 1); 
 
	  // ALWAYS USE THIS ID: E0DD6CAB-2D10-11D2-8F1A-0000F87ABD16 
      lstrcpy(szData, _T("{E0DD6CAB-2D10-11D2-8F1A-0000F87ABD16}") ); 
      ::RegSetValueEx(hKey, TEXT("CLSID"),  
                    0, REG_SZ, (LPBYTE)szData, 
                    lstrlen(szData) + 1); 
 
      wsprintf(szData, _T("%s"), szTVToolbarCLSID); 
      ::RegSetValueEx(hKey, TEXT("BandCLSID"),  
                    0, REG_SZ, (LPBYTE)szData, 
                    lstrlen(szData) + 1); 
 
      ::RegCloseKey(hKey); 
   } 
 
   return TRUE; 
} 
 
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); 
} 
 
BOOL UnRegisterServer(CLSID clsid) 
{ 
   TCHAR   szSubKey[MAX_PATH]; 
   TCHAR   szCLSID[MAX_PATH]; 
   LPWSTR  pwsz; 
 
   // Get 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 string 
      LPMALLOC pMalloc; 
 
      CoGetMalloc(1, &pMalloc); 
 
      pMalloc->Free(pwsz); 
      pMalloc->Release(); 
   } 
 
   DOREGSTRUCT ClsidEntries[] = 
   { 
      HKEY_CLASSES_ROOT, TEXT("CLSID\\%s\\InprocServer32"),  
	  NULL, NULL, 
      // Remove "Implemented Categories" key, just in case  
      // UnRegisterClassImplCategories does not remove it 
      HKEY_CLASSES_ROOT, TEXT("CLSID\\%s\\Implemented Categories"), 
      NULL, NULL, 
      HKEY_CLASSES_ROOT, TEXT("CLSID\\%s"), NULL, NULL, 
      NULL, NULL, NULL, NULL 
   }; 
 
   // Delete CLSID entries 
   for (int i = 0; ClsidEntries[i].hRootKey; i++) 
 
   { 
      wsprintf(szSubKey, ClsidEntries[i].szSubKey, szCLSID); 
      ::RegDeleteKey(ClsidEntries[i].hRootKey, szSubKey); 
   } 
 
   // Delete button information 
   StringFromIID(CLSID_TVToolbarButton, &pwsz); 
 
   if (!pwsz) 
      return TRUE; 
 
#ifdef UNICODE 
   lstrcpy(szCLSID, pwsz); 
#else 
   WideCharToMultiByte(CP_ACP, 0, pwsz, -1, szCLSID, 
                       ARRAYSIZE(szCLSID), NULL, NULL); 
#endif 
 
   // Free string 
   LPMALLOC pMalloc; 
 
   CoGetMalloc(1, &pMalloc); 
   pMalloc->Free(pwsz); 
   pMalloc->Release(); 
 
   wsprintf(szSubKey, _T("Software\\Microsoft\\Internet Explorer\\Extensions\\%s"), szCLSID); 
   ::RegDeleteKey(HKEY_LOCAL_MACHINE, szSubKey); 
 
   return TRUE; 
} 
 
BOOL UnRegisterComCat(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->UnRegisterClassImplCategories(clsid, 1, &CatID); 
      pcr->Release(); 
   } 
         
   CoUninitialize(); 
 
   return SUCCEEDED(hr); 
} 
 
/* 
 * RegisterToolBand 
 */ 
BOOL RegisterToolBand(CLSID clsid) 
{ 
	HKEY     hKey; 
	LRESULT  lResult; 
	DWORD    dwDisp; 
	TCHAR    szCLSID[MAX_PATH]; 
	LPWSTR   pwsz; 
 
	//get 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 string 
	   CoTaskMemFree(pwsz); 
	   } 
 
	lResult = ::RegCreateKeyEx(  HKEY_LOCAL_MACHINE, 
							   TEXT("Software\\Microsoft\\Internet Explorer\\Toolbar"), 
							   0, 
							   NULL, 
							   REG_OPTION_NON_VOLATILE, 
							   KEY_WRITE, 
							   NULL, 
							   &hKey, 
							   &dwDisp); 
    
	if(NOERROR == lResult) 
	   { 
	   TCHAR szData[] = TEXT(""); 
 
	   lResult = ::RegSetValueEx(   hKey, 
								  szCLSID, 
								  0, 
								  REG_SZ, 
								  (LPBYTE)szData, 
								  lstrlen(szData) + 1); 
    
	   ::RegCloseKey(hKey); 
	   } 
	else 
	   return FALSE; 
 
	return TRUE; 
}