www.pudn.com > ctxmenu_src.rar > ShellExt.cpp


// CCL.cpp : Defines the initialization routines for the DLL. 
// 
 
#include "stdafx.h" 
#include "resource.h" 
#include "priv.h" 
#include "ShellExt.h" 
#include "CtxMenu.h" 
 
#include  
#include  
 
#include "ShUtils.h" 
 
/* 
 
	What follows is our implementation of the IClassFactory interface. 
	This code is basically unmodified from the SHELLEX example. 
 
*/ 
 
 
 
/*************************************************************** 
	Function: 
	CShellExtClassFactory::CShellExtClassFactory() 
 
	Purpose: 
	constructor 
 
	Param			Type			Use 
	-----			----			--- 
 
	Returns 
	------- 
 
***************************************************************/ 
CShellExtClassFactory::CShellExtClassFactory() 
{ 
    ODS("CShellExtClassFactory::CShellExtClassFactory()\r\n"); 
 
    m_cRef = 0L; 
 
    g_cRefThisDll++;	 
} 
 
/*************************************************************** 
	Function: 
	CShellExtClassFactory::~CShellExtClassFactory()	 
 
	Purpose: 
	destructor 
 
	Param			Type			Use 
	-----			----			--- 
 
	Returns 
	------- 
 
***************************************************************/																 
CShellExtClassFactory::~CShellExtClassFactory()				 
{ 
    g_cRefThisDll--; 
} 
 
/*************************************************************** 
	Function: 
	STDMETHODIMP CShellExtClassFactory::QueryInterface(REFIID riid, 
                                                   LPVOID FAR *ppv) 
 
	Purpose: 
	Return a ptr to an interface 
 
	Param			Type			Use 
	-----			----			--- 
	riid			REFIID			interface to get 
	ppv				LPVOID *		ptr to rec our interface 
 
	Returns 
	------- 
	NOERROR on successz 
 
***************************************************************/ 
STDMETHODIMP CShellExtClassFactory::QueryInterface(REFIID riid, 
                                                   LPVOID FAR *ppv) 
{ 
    ODS("CShellExtClassFactory::QueryInterface()\r\n"); 
 
    *ppv = NULL; 
 
    // Any interface on this object is the object pointer 
 
    if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IClassFactory)) 
    { 
        *ppv = (LPCLASSFACTORY)this; 
 
        AddRef(); 
 
        return NOERROR; 
    } 
 
    return E_NOINTERFACE; 
}	 
 
/*************************************************************** 
	Function: 
	STDMETHODIMP_(ULONG) CShellExtClassFactory::AddRef() 
 
	Purpose: 
	Increase our object's reference count 
 
	Param			Type			Use 
	-----			----			--- 
 
	Returns 
	------- 
	# of references 
 
***************************************************************/ 
STDMETHODIMP_(ULONG) CShellExtClassFactory::AddRef() 
{ 
    return ++m_cRef; 
} 
 
/*************************************************************** 
	Function: 
	STDMETHODIMP_(ULONG) CShellExtClassFactory::Release() 
 
	Purpose: 
	Decrease our object's reference count 
 
	Param			Type			Use 
	-----			----			--- 
 
	Returns 
	------- 
	# of references 
 
***************************************************************/ 
 
STDMETHODIMP_(ULONG) CShellExtClassFactory::Release() 
{ 
    if (--m_cRef) 
        return m_cRef; 
 
    delete this; 
 
    return 0L; 
} 
 
/*************************************************************** 
	Function: 
	STDMETHODIMP CShellExtClassFactory::CreateInstance(LPUNKNOWN pUnkOuter, 
                                                      REFIID riid, 
                                                      LPVOID *ppvObj) 
 
	Purpose: 
	Create an instace of a particular interface 
 
	Param			Type			Use 
	-----			----			--- 
	pUnkOuter		LPUNKNOWN		outer IUnknown 
	riid			REFIID			interface ID 
	ppvObj			LPVOID *		ptr to rec our interface 
	Returns 
	------- 
	NOERROR on success 
 
***************************************************************/ 
STDMETHODIMP CShellExtClassFactory::CreateInstance(LPUNKNOWN pUnkOuter, 
                                                      REFIID riid, 
                                                      LPVOID *ppvObj) 
{ 
   AFX_MANAGE_STATE(AfxGetStaticModuleState( )); 
 
   ODS("CShellExtClassFactory::CreateInstance()\r\n"); 
 
   *ppvObj = NULL; 
 
   // Shell extensions typically don't support aggregation (inheritance) 
 
   if (pUnkOuter) 
      return CLASS_E_NOAGGREGATION; 
 
   // Create the main shell extension object.  The shell will then call 
   // QueryInterface with IID_IShellExtInit--this is how shell extensions are 
   // initialized. 
 
   LPCSHELLEXT pShellExt; 
   try  
   { 
      pShellExt = new CShellExt();  //Create the CShellExt object 
   } catch (CMemoryException *e) { 
      e->Delete(); 
      pShellExt=NULL; 
   } 
 
 
   if (NULL == pShellExt) 
      return E_OUTOFMEMORY; 
 
   return pShellExt->QueryInterface(riid, ppvObj); 
} 
 
/*************************************************************** 
	Function: 
	STDMETHODIMP CShellExtClassFactory::LockServer(BOOL fLock) 
 
	Purpose: 
	Pretend we did something 
 
	Param			Type			Use 
	-----			----			--- 
 
	Returns 
	------- 
	NOERROR, always 
 
***************************************************************/ 
STDMETHODIMP CShellExtClassFactory::LockServer(BOOL fLock) 
{ 
    return NOERROR; 
} 
 
 
/* 
	What follows is our implementation of several interfaces : 
			IContextMenu 
			IShellExtInit  
			IExtractIcon  
			IPersistFile  
			IShellPropSheetExt 
			ICopyHook 
 
	These represent the services we can provide for Explorer. 
	Not all of these need to be implemented. 
 
	This code is unmodified from SHELLEX 
*/ 
// *********************** CShellExt ************************* 
 
/*************************************************************** 
	Function: 
	CShellExt::CShellExt() 
 
	Purpose: 
	contructor 
 
	Param			Type			Use 
	-----			----			--- 
 
	Returns 
	------- 
 
***************************************************************/ 
CShellExt::CShellExt() 
{ 
   AFX_MANAGE_STATE(AfxGetStaticModuleState( )); 
 
   ODS("CShellExt::CShellExt()\r\n"); 
 
   m_cRef = 0L; 
   m_pDataObj = NULL; 
 
   g_cRefThisDll++;    
 
   m_menuBmp.LoadBitmap(IDB_MENU_BMP); 
 
} 
 
/*************************************************************** 
	Function: 
	CShellExt::~CShellExt() 
 
	Purpose: 
	destructor 
 
	Param			Type			Use 
	-----			----			--- 
 
	Returns 
	------- 
 
***************************************************************/ 
CShellExt::~CShellExt() 
{ 
   AFX_MANAGE_STATE(AfxGetStaticModuleState( )); 
 
   if (m_pDataObj) 
      m_pDataObj->Release(); 
 
   g_cRefThisDll--; 
 
   if (m_menuBmp.GetSafeHandle()) 
      m_menuBmp.DeleteObject(); 
} 
 
/*************************************************************** 
	Function: 
	STDMETHODIMP CShellExt::QueryInterface(REFIID riid, LPVOID FAR *ppv) 
 
	Purpose: 
	See if we support a given interface 
 
	Param			Type			Use 
	-----			----			--- 
	riid			REFIID			interface ID 
	ppv				LPVOID *		ptr to rec our interface 
 
	Returns 
	------- 
	NOERROR on success 
 
***************************************************************/ 
STDMETHODIMP CShellExt::QueryInterface(REFIID riid, LPVOID FAR *ppv) 
{ 
   *ppv = NULL; 
 
   if (IsEqualIID(riid, IID_IShellExtInit) || IsEqualIID(riid, IID_IUnknown)) 
   { 
      ODS("CShellExt::QueryInterface()==>IID_IShellExtInit\r\n"); 
 
      *ppv = (LPSHELLEXTINIT)this; 
   } 
   else if (IsEqualIID(riid, IID_IContextMenu)) 
   { 
      ODS("CShellExt::QueryInterface()==>IID_IContextMenu\r\n"); 
 
      *ppv = (LPCONTEXTMENU)this; 
   } 
 
   if (*ppv) 
   { 
      AddRef(); 
      return NOERROR; 
   } 
 
   ODS("CShellExt::QueryInterface()==>Unknown Interface!\r\n"); 
 
	return E_NOINTERFACE; 
} 
 
/*************************************************************** 
	Function: 
	STDMETHODIMP_(ULONG) CShellExt::AddRef() 
 
	Purpose: 
	increase our reference count 
 
	Param			Type			Use 
	-----			----			--- 
 
	Returns 
	------- 
	# of references 
 
***************************************************************/ 
STDMETHODIMP_(ULONG) CShellExt::AddRef() 
{ 
   ODS("CShellExt::AddRef()\r\n"); 
 
   return ++m_cRef; 
} 
 
/*************************************************************** 
	Function: 
	STDMETHODIMP_(ULONG) CShellExt::Release() 
 
	Purpose: 
	decrease our reference count, clean up 
 
	Param			Type			Use 
	-----			----			--- 
 
	Returns 
	------- 
	# of references 
 
***************************************************************/ 
STDMETHODIMP_(ULONG) CShellExt::Release() 
{ 
   AFX_MANAGE_STATE(AfxGetStaticModuleState( )); 
 
   ODS("CShellExt::Release()\r\n"); 
 
   if (--m_cRef) 
      return m_cRef; 
 
   delete this; 
 
   return 0L; 
} 
 
 
// 
//  FUNCTION: CShellExt::Initialize(LPCITEMIDLIST, LPDATAOBJECT, HKEY) 
// 
//  PURPOSE: Called by the shell when initializing a context menu or property 
//           sheet extension. 
// 
//  PARAMETERS: 
//    pIDFolder - Specifies the parent folder 
//    pDataObj  - Spefifies the set of items selected in that folder. 
//    hRegKey   - Specifies the type of the focused item in the selection. 
// 
//  RETURN VALUE: 
// 
//    NOERROR in all cases. 
// 
//  COMMENTS:   Note that at the time this function is called, we don't know  
//              (or care) what type of shell extension is being initialized.   
//              It could be a context menu or a property sheet. 
// 
 
STDMETHODIMP CShellExt::Initialize(LPCITEMIDLIST pIDFolder, 
                                   LPDATAOBJECT pDataObj, 
                                   HKEY hRegKey) 
{ 
 
   AFX_MANAGE_STATE(AfxGetStaticModuleState( )); 
 
   ODS("CShellExtFld::Initialize()\r\n"); 
 
   // this can be called more than once 
   if (m_pDataObj) 
	   m_pDataObj->Release(); 
 
   // duplicate the object pointer and registry handle 
   if (pDataObj) 
   { 
	   m_pDataObj = pDataObj; 
	   pDataObj->AddRef(); 
   }  
   else 
   { 
	   return E_FAIL; 
   } 
 
   return GetSelectedFiles(pIDFolder, m_pDataObj, m_csaPaths); 
}