/////////////////////////////////////////////////////////////////////////////// // // Copyright 1999 American Power Conversion, All Rights Reserved // // Name: upsapplet.cpp // // Author: Noel Fegan // // Description // =========== // // Revision History // ================ // 04 May 1999 - nfegan@apcc.com : Added this comment block. // 04 May 1999 - nfegan@apcc.com : Preparing for code inspection // #include "upstab.h" #include #include #include #include "upsapplet.h" #pragma hdrstop extern "C" HINSTANCE g_theInstance = 0; UINT g_cRefThisDll = 0; // Reference count for this DLL // {DE5637D2-E12D-11d2-8844-00600844D03F} DEFINE_GUID(CLSID_ShellExtension, 0xde5637d2, 0xe12d, 0x11d2, 0x88, 0x44, 0x0, 0x60, 0x8, 0x44, 0xd0, 0x3f); // // DllMain is the DLL's entry point. // // Input parameters: // hInstance = Instance handle // dwReason = Code specifying the reason DllMain was called // lpReserved = Reserved (do not use) // // Returns: // TRUE if successful, FALSE if not // /////////////////////////////////////////////////////////////////////////////// extern "C" int APIENTRY DllMain (HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved) { // // If dwReason is DLL_PROCESS_ATTACH, save the instance handle so it // can be used again later. // if (dwReason == DLL_PROCESS_ATTACH) { g_theInstance = hInstance; DisableThreadLibraryCalls(g_theInstance); } return TRUE; } ///////////////////////////////////////////////////////////////////////////// // In-process server functions // // DllGetClassObject is called by the shell to create a class factory object. // // Input parameters: // rclsid = Reference to class ID specifier // riid = Reference to interface ID specifier // ppv = Pointer to location to receive interface pointer // // Returns: // HRESULT code signifying success or failure // STDAPI DllGetClassObject (REFCLSID rclsid, REFIID riid, LPVOID *ppv) { *ppv = NULL; // // Make sure the class ID is CLSID_ShellExtension. Otherwise, the class // factory doesn't support the object type specified by rclsid. // if (!IsEqualCLSID (rclsid, CLSID_ShellExtension)) { //Error return ResultFromScode (CLASS_E_CLASSNOTAVAILABLE); } // // Instantiate a class factory object. // CClassFactory *pClassFactory = new CClassFactory (); if (pClassFactory == NULL) { //Error return ResultFromScode (E_OUTOFMEMORY); } // // Get the interface pointer from QueryInterface and copy it to *ppv. // HRESULT hr = pClassFactory->QueryInterface (riid, ppv); pClassFactory->Release (); return hr; } // // DllCanUnloadNow is called by the shell to find out if the DLL can be // unloaded. The answer is yes if (and only if) the module reference count // stored in g_cRefThisDll is 0. // // Input parameters: // None // // Returns: // HRESULT code equal to S_OK if the DLL can be unloaded, S_FALSE if not // STDAPI DllCanUnloadNow (void) { return ResultFromScode ((g_cRefThisDll == 0) ? S_OK : S_FALSE); } ///////////////////////////////////////////////////////////////////////////// // CClassFactory member functions CClassFactory::CClassFactory () { m_cRef = 1; g_cRefThisDll++; } CClassFactory::~CClassFactory () { g_cRefThisDll--; } STDMETHODIMP CClassFactory::QueryInterface (REFIID riid, LPVOID FAR *ppv) { if (IsEqualIID (riid, IID_IUnknown)) { *ppv = (LPUNKNOWN) (LPCLASSFACTORY) this; m_cRef++; return NOERROR; } else if (IsEqualIID (riid, IID_IClassFactory)) { *ppv = (LPCLASSFACTORY) this; m_cRef++; return NOERROR; } else { *ppv = NULL; return ResultFromScode (E_NOINTERFACE); } } STDMETHODIMP_(ULONG) CClassFactory::AddRef () { return ++m_cRef; } STDMETHODIMP_(ULONG) CClassFactory::Release () { if (--m_cRef == 0) delete this; return m_cRef; } // // CreateInstance is called by the shell to create a shell extension object. // // Input parameters: // pUnkOuter = Pointer to controlling unknown // riid = Reference to interface ID specifier // ppvObj = Pointer to location to receive interface pointer // // Returns: // HRESULT code signifying success or failure // STDMETHODIMP CClassFactory::CreateInstance (LPUNKNOWN pUnkOuter, REFIID riid, LPVOID FAR *ppvObj) { *ppvObj = NULL; // // Return an error code if pUnkOuter is not NULL, because we don't // support aggregation. // if (pUnkOuter != NULL) return ResultFromScode (CLASS_E_NOAGGREGATION); // // Instantiate a shell extension object. // CShellExtension *pShellExtension = new CShellExtension (); if (pShellExtension == NULL) return ResultFromScode (E_OUTOFMEMORY); // Get the interface pointer from QueryInterface and copy it to *ppvObj. // HRESULT hr = pShellExtension->QueryInterface (riid, ppvObj); pShellExtension->Release (); return hr; } // // LockServer increments or decrements the DLL's lock count. // STDMETHODIMP CClassFactory::LockServer (BOOL fLock) { return ResultFromScode (E_NOTIMPL); } ///////////////////////////////////////////////////////////////////////////// // CShellExtension member functions CShellExtension::CShellExtension () { m_cRef = 1; g_cRefThisDll++; } CShellExtension::~CShellExtension () { g_cRefThisDll--; } STDMETHODIMP CShellExtension::QueryInterface (REFIID riid, LPVOID FAR *ppv) { if (IsEqualIID (riid, IID_IUnknown)) { *ppv = (LPUNKNOWN) (LPSHELLPROPSHEETEXT) this; m_cRef++; return NOERROR; } else if (IsEqualIID (riid, IID_IShellPropSheetExt)) { *ppv = (LPSHELLPROPSHEETEXT) this; m_cRef++; return NOERROR; } else if (IsEqualIID (riid, IID_IShellExtInit)) { *ppv = (LPSHELLEXTINIT) this; m_cRef++; return NOERROR; } else { *ppv = NULL; return ResultFromScode (E_NOINTERFACE); } } STDMETHODIMP_(ULONG) CShellExtension::AddRef () { return ++m_cRef; } STDMETHODIMP_(ULONG) CShellExtension::Release () { if (--m_cRef == 0) { delete this; } return(m_cRef); } // // AddPages is called by the shell to give property sheet shell extensions // the opportunity to add pages to a property sheet before it is displayed. // // Input parameters: // lpfnAddPage = Pointer to function called to add a page // lParam = lParam parameter to be passed to lpfnAddPage // // Returns: // HRESULT code signifying success or failure // STDMETHODIMP CShellExtension::AddPages (LPFNADDPROPSHEETPAGE lpfnAddPage, LPARAM lParam) { PROPSHEETPAGE psp; HPROPSHEETPAGE hUPSPage = NULL; HMODULE hModule = GetUPSModuleHandle(); ZeroMemory(&psp, sizeof(psp)); psp.dwSize = sizeof(psp); psp.dwFlags = PSP_USEREFPARENT; psp.hInstance = hModule; psp.pszTemplate = TEXT("IDD_UPS_EXT"); psp.pfnDlgProc = UPSMainPageProc; psp.pcRefParent = &g_cRefThisDll; hUPSPage = CreatePropertySheetPage (&psp); // // Add the pages to the property sheet. // if (hUPSPage != NULL) { if (!lpfnAddPage(hUPSPage, lParam)) { DestroyPropertySheetPage(hUPSPage); } } return(NOERROR); } // // ReplacePage is called by the shell to give control panel extensions the // opportunity to replace control panel property sheet pages. It is never // called for conventional property sheet extensions, so we simply return // a failure code if called. // // Input parameters: // uPageID = Page to replace // lpfnReplaceWith = Pointer to function called to replace a page // lParam = lParam parameter to be passed to lpfnReplaceWith // // Returns: // HRESULT code signifying success or failure // STDMETHODIMP CShellExtension::ReplacePage (UINT uPageID, LPFNADDPROPSHEETPAGE lpfnReplaceWith, LPARAM lParam) { return ResultFromScode (E_FAIL); } // // Initialize is called by the shell to initialize a shell extension. // // Input parameters: // pidlFolder = Pointer to ID list identifying parent folder // lpdobj = Pointer to IDataObject interface for selected object(s) // hKeyProgId = Registry key handle // // Returns: // HRESULT code signifying success or failure // STDMETHODIMP CShellExtension::Initialize (LPCITEMIDLIST pidlFolder, LPDATAOBJECT lpdobj, HKEY hKeyProgID) { return ResultFromScode (NO_ERROR); }