🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: borland.public.cppbuilder.nativeapi
Article #9123

Re: Windows Shell Extension

#9123
From: Ramon F Herrera
Date: Tue, 03 Aug 2004 18:37
419 lines
9681 bytes

//
// Cmpnt.cpp - server implementation
//
#include <iostream.h>
#include <objbase.h>

#include <shlobj.h>     // IColumnProvider

#include "Iface.h"      // Interface declarations
#include "Registry.h"   // Registry helper functions

// Trace function
void trace(const char* msg) { cout << msg << endl ;}

///////////////////////////////////////////////////////////
//
// Global variables
//
static HMODULE g_hModule = NULL ;   // DLL module handle
static long g_cComponents = 0 ;     // Count of active components
static long g_cServerLocks = 0 ;    // Count of locks

// Friendly name of component
const char g_szFriendlyName[] = "Inside COM, Chapter 7 Example" ;

// Version-independent ProgID
const char g_szVerIndProgID[] = "InsideCOM.Chap07" ;

// ProgID
const char g_szProgID[] = "InsideCOM.Chap07.1" ;


///////////////////////////////////////////////////////////
//
// Components
//

CLSID CLSID_ChenOnly;


class CChenOnly : public IUnknown,
                   public IPersist,
                   public IColumnProvider
{
     public:
     /* IUnknown */
     STDMETHODIMP QueryInterface(REFIID riid, LPVOID *ppvOut);
     STDMETHODIMP_(ULONG) AddRef();
     STDMETHODIMP_(ULONG) Release();

     /* IPersist */
     STDMETHODIMP GetClassID(CLSID *pclsid);

     /* IColumnProvider */
     STDMETHODIMP Initialize(LPCSHCOLUMNINIT);
     STDMETHODIMP GetColumnInfo(DWORD dwIndex, LPSHCOLUMNINFO psci);
     STDMETHODIMP GetItemData(LPCSHCOLUMNID pscid, LPCSHCOLUMNDATA pscd, 
VARIANT *pvarData);

     // Constructor
     CChenOnly();

     // Destructor
     ~CChenOnly();

     private:
     // Reference count
     long m_cRef;
};



//
// IUnknown
//
HRESULT __stdcall CChenOnly::QueryInterface(const IID& iid, void** ppv)
{
         if (iid == IID_IUnknown)
         {
		*ppv = reinterpret_cast<IUnknown*>(this) ;
         }
         else if (iid == IID_IX)
         {
                 *ppv = static_cast<IPersist*>(this) ;
                 trace("Component:\t\tReturn pointer to IPersist.") ;
         }
         else if (iid == IID_IY)
         {
                 *ppv = static_cast<IColumnProvider*>(this) ;
                 trace("Component:\t\tReturn pointer to IColumnProvider.") ;
         }
         else
         {
                 *ppv = NULL ;
                 return E_NOINTERFACE ;
         }
         reinterpret_cast<IUnknown*>(*ppv)->AddRef() ;
         return S_OK ;
}



//
// IUnknown
//
ULONG __stdcall CChenOnly::AddRef()
{
         return InterlockedIncrement(&m_cRef) ;
}



//
// IUnknown
//
ULONG __stdcall CChenOnly::Release()
{
         if (InterlockedDecrement(&m_cRef) == 0)
         {
                 delete this ;
                 return 0 ;
         }
         return m_cRef ;
}


/* IPersist */
STDMETHODIMP CChenOnly::GetClassID(CLSID *pclsid)
{
     *pclsid = CLSID_ChenOnly;
     return S_OK;
}



/* IColumnProvider */
STDMETHODIMP CChenOnly::Initialize(LPCSHCOLUMNINIT)
{
     return S_OK;
}



/* IColumnProvider */
STDMETHODIMP CChenOnly::GetColumnInfo(DWORD dwIndex, LPSHCOLUMNINFO psci)
{
     if (dwIndex == 0) {
         psci->scid.fmtid = CLSID_ChenOnly;
         psci->scid.pid = 0;
         psci->vt = VT_I4;
         psci->fmt = LVCFMT_RIGHT;
         psci->cChars = 20;
         psci->csFlags = SHCOLSTATE_TYPE_INT | SHCOLSTATE_SECONDARYUI;
         lstrcpyW(psci->wszTitle, L"Byte Size");
         lstrcpyW(psci->wszDescription, L"Size in bytes");
         return S_OK;
     }
     else {
         return S_FALSE;
     }
}



/* IColumnProvider */
STDMETHODIMP CChenOnly::GetItemData(LPCSHCOLUMNID pscid, LPCSHCOLUMNDATA 
pscd, VARIANT *pvar)
{
     pvar = pvar++;
     if (pscid->fmtid == CLSID_ChenOnly) {
         switch (pscid->pid) {
         case 0:
             WIN32_FILE_ATTRIBUTE_DATA fad;
             if ((!(pscd->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) &&
                 GetFileAttributesExW(pscd->wszFile, 
GetFileExInfoStandard, &fad)) {
                 V_VT(pvar) = VT_I4;
                 V_I4(pvar) = fad.nFileSizeLow;
                 return S_OK;
             }
             break;
        }
     }

     return S_FALSE;
}



//
// Constructor
//
CChenOnly::CChenOnly() : m_cRef(1)
{
	InterlockedIncrement(&g_cComponents) ;
}



//
// Destructor
//
CChenOnly::~CChenOnly()
{
	InterlockedDecrement(&g_cComponents) ;
	trace("Component:\t\tDestroy self.") ;
}



///////////////////////////////////////////////////////////
//
// Class factory
//
class CFactory : public IClassFactory
{
public:
	// IUnknown
	virtual HRESULT __stdcall QueryInterface(const IID& iid, void** ppv) ;
	virtual ULONG   __stdcall AddRef() ;
	virtual ULONG   __stdcall Release() ;

	// Interface IClassFactory
	virtual HRESULT __stdcall CreateInstance(IUnknown* pUnknownOuter,
	                                         const IID& iid,
	                                         void** ppv) ;
	virtual HRESULT __stdcall LockServer(BOOL bLock) ;

	// Constructor
	CFactory() : m_cRef(1) {}

	// Destructor
	~CFactory() { trace("Class factory:\t\tDestroy self.") ;}

private:
	long m_cRef ;
} ;



//
// Class factory IUnknown implementation
//
HRESULT __stdcall CFactory::QueryInterface(const IID& iid, void** ppv)
{
	if ((iid == IID_IUnknown) || (iid == IID_IClassFactory))
	{
		*ppv = static_cast<IClassFactory*>(this) ;
	}
	else
	{
		*ppv = NULL ;
		return E_NOINTERFACE ;
	}
	reinterpret_cast<IUnknown*>(*ppv)->AddRef() ;
	return S_OK ;
}



ULONG __stdcall CFactory::AddRef()
{
	return InterlockedIncrement(&m_cRef) ;
}



ULONG __stdcall CFactory::Release()
{
	if (InterlockedDecrement(&m_cRef) == 0)
	{
		delete this ;
		return 0 ;
	}
	return m_cRef ;
}



//
// IClassFactory implementation
//
HRESULT __stdcall CFactory::CreateInstance(IUnknown* pUnknownOuter,
                                            const IID& iid,
                                            void** ppv)
{
	trace("Class factory:\t\tCreate component.") ;

	// Cannot aggregate.
	if (pUnknownOuter != NULL)
	{
		return CLASS_E_NOAGGREGATION ;
	}

	// Create component.
	CChenOnly* pChen = new CChenOnly ;
	if (pChen == NULL)
	{
		return E_OUTOFMEMORY ;
	}

	// Get the requested interface.
	HRESULT hr = pChen->QueryInterface(iid, ppv) ;

	// Release the IUnknown pointer.
	// (If QueryInterface failed, component will delete itself.)
	pChen->Release() ;
	return hr ;
}



// LockServer
HRESULT __stdcall CFactory::LockServer(BOOL bLock)
{
	if (bLock)
	{
		InterlockedIncrement(&g_cServerLocks) ;
	}
	else
	{
		InterlockedDecrement(&g_cServerLocks) ;
	}
	return S_OK ;
}


///////////////////////////////////////////////////////////
//
// Exported functions
//

//
// Can DLL unload now?
//
STDAPI __export DllCanUnloadNow()
{
	if ((g_cComponents == 0) && (g_cServerLocks == 0))
	{
		return S_OK ;
	}
	else
	{
		return S_FALSE ;
	}
}

//
// Get class factory
//
STDAPI __export DllGetClassObject(const CLSID& clsid,
                          const IID& iid,
                          void** ppv)
{
	trace("DllGetClassObject:\tCreate class factory.") ;

	// Can we create this component?
	if (clsid != CLSID_Component1)
	{
		return CLASS_E_CLASSNOTAVAILABLE ;
	}

	// Create class factory.
	CFactory* pFactory = new CFactory ;  // Reference count set to 1
	                                     // in constructor
	if (pFactory == NULL)
	{
		return E_OUTOFMEMORY ;
	}

	// Get requested interface.
	HRESULT hr = pFactory->QueryInterface(iid, ppv) ;
	pFactory->Release() ;

	return hr ;
}

//
// Server registration
//
STDAPI __export DllRegisterServer()
{
	return RegisterServer(g_hModule,
	                      CLSID_Component1,
	                      g_szFriendlyName,
	                      g_szVerIndProgID,
	                      g_szProgID) ;
}


//
// Server unregistration
//
STDAPI __export DllUnregisterServer()
{
	return UnregisterServer(CLSID_Component1,
	                        g_szVerIndProgID,
	                        g_szProgID) ;
}

///////////////////////////////////////////////////////////
//
// DLL module information
//
BOOL APIENTRY DllMain(HANDLE hModule,
                       DWORD dwReason,
                       void* lpReserved)
{

         lpReserved = lpReserved;

	if (dwReason == DLL_PROCESS_ATTACH)
	{
		g_hModule = (HMODULE) hModule ;
	}
	return TRUE ;
}
Technical Details
Message-ID: <410fdb81@newsgroups.borland.com>
Path: arc1-ca.pugleaf.net!g2news1.google.com!news2.google.com!proxad.net!213.200.89.82.MISMATCH!tiscali!newsfeed1.ip.tiscali.net!newsfeed00.sul.t-online.de!newsfeed01.sul.t-online.de!t-online.de!newsgroups.borland.com!not-for-mail
References: <410fdb19@newsgroups.borland.com>

Show Full Headers
Complete Article Headers
X-Google-Thread: 10cc67,34354709b2dc2fba
X-Google-Attributes: gid10cc67,public
X-Google-Language: ENGLISH,ASCII-7-bit
Date: Tue, 03 Aug 2004 14:37:45 -0400
From: Ramon F Herrera <ramon@jonjay.com>
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.4) Gecko/20030624 Netscape/7.1 (ax)
X-Accept-Language: en-us, en
MIME-Version: 1.0
Newsgroups: borland.public.cppbuilder.nativeapi
Subject: Re: Windows Shell Extension
References: <410fdb19@newsgroups.borland.com>
In-Reply-To: <410fdb19@newsgroups.borland.com>
Content-Type: text/plain; charset=us-ascii; format=flowed
Content-Transfer-Encoding: 7bit
NNTP-Posting-Host: 161.196.117.171
Message-ID: <410fdb81@newsgroups.borland.com>
X-Trace: newsgroups.borland.com 1091558273 161.196.117.171 (3 Aug 2004 11:37:53 -0700)
Lines: 422
Path: arc1-ca.pugleaf.net!g2news1.google.com!news2.google.com!proxad.net!213.200.89.82.MISMATCH!tiscali!newsfeed1.ip.tiscali.net!newsfeed00.sul.t-online.de!newsfeed01.sul.t-online.de!t-online.de!newsgroups.borland.com!not-for-mail