|
|
//+----------------------------------------------------------------------------
//
// Windows NT Active Directory Property Page Sample
//
// The code contained in this source file is for demonstration purposes only.
// No warrantee is expressed or implied and Microsoft disclaims all liability
// for the consequenses of the use of this source code.
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1999
//
// File: host.cxx
//
// Contents: CDsPropPageHost, the class that exposes IShellExtInit and
// IShellPropSheetExt
// Also, the ClassFactory and IUnknown code.
//
// History: 8-Sep-97 Eric Brown created
//
//-----------------------------------------------------------------------------
#include "page.h"
CLIPFORMAT g_cfDsObjectNames = 0; const CLSID CLSID_SamplePage = { /* cca62184-294f-11d1-bcfe-00c04fd8d5b6 */ 0xcca62184, 0x294f, 0x11d1, {0xbc, 0xfe, 0x00, 0xc0, 0x4f, 0xd8, 0xd5, 0xb6} };
//+----------------------------------------------------------------------------
//
// Member: CDsPropPageHost::CDsPropPageHost
//
//-----------------------------------------------------------------------------
CDsPropPageHost::CDsPropPageHost() : m_pDataObj(NULL), m_uRefs(1) { }
//+----------------------------------------------------------------------------
//
// Member: CDsPropPageHost::~CDsPropPageHost
//
//-----------------------------------------------------------------------------
CDsPropPageHost::~CDsPropPageHost() { if (m_pDataObj) { m_pDataObj->Release(); } }
//+----------------------------------------------------------------------------
//
// Member: CDsPropPageHost::IShellExtInit::Initialize
//
// Returns: HRESULTS
//
//-----------------------------------------------------------------------------
STDMETHODIMP CDsPropPageHost::Initialize(LPCITEMIDLIST pIDFolder, LPDATAOBJECT pDataObj, HKEY hKeyID) { if (IsBadReadPtr(pDataObj, sizeof(LPDATAOBJECT))) { return E_INVALIDARG; }
if (m_pDataObj) { m_pDataObj->Release(); m_pDataObj = NULL; }
// Hang onto the IDataObject we are being passed.
m_pDataObj = pDataObj; if (m_pDataObj) { m_pDataObj->AddRef(); } else { return E_INVALIDARG; }
// Check to see if we have our clipboard format registered, if not then
// lets do it.
if (!g_cfDsObjectNames) { g_cfDsObjectNames = (CLIPFORMAT)RegisterClipboardFormat(CFSTR_DSOBJECTNAMES); } if (!g_cfDsObjectNames) { return E_FAIL; }
return S_OK; }
//+----------------------------------------------------------------------------
//
// Member: CDsPropPageHost::IShellExtInit::AddPages
//
// Returns: HRESULTS
//
//-----------------------------------------------------------------------------
STDMETHODIMP CDsPropPageHost::AddPages(LPFNADDPROPSHEETPAGE pAddPageProc, LPARAM lParam) { HRESULT hr = S_OK; HPROPSHEETPAGE hPage; STGMEDIUM ObjMedium = {TYMED_NULL}; FORMATETC fmte = {g_cfDsObjectNames, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL}; LPDSOBJECTNAMES pDsObjectNames; PWSTR pwzObjName; PWSTR pwzClass; CDsPropPage * PropPage;
//
// Get the path to the DS object from the data object.
// Note: This call runs on the caller's main thread. The pages' window
// procs run on a different thread, so don't reference the data object
// from a winproc unless it is first marshalled on this thread.
//
hr = m_pDataObj->GetData(&fmte, &ObjMedium); if (!SUCCEEDED(hr)) { return hr; }
pDsObjectNames = (LPDSOBJECTNAMES)ObjMedium.hGlobal;
if (pDsObjectNames->cItems < 1) { hr = E_FAIL; goto Cleanup; }
pwzObjName = (PWSTR)ByteOffset(pDsObjectNames, pDsObjectNames->aObjects[0].offsetName); pwzClass = (PWSTR)ByteOffset(pDsObjectNames, pDsObjectNames->aObjects[0].offsetClass);
//
// NOTIFY_OBJ
// Create/contact the notification object.
//
HWND hNotifyObj;
hr = ADsPropCreateNotifyObj(m_pDataObj, pwzObjName, &hNotifyObj);
if (FAILED(hr)) { goto Cleanup; }
//
// Create the page.
//
PropPage = new CDsPropPage(hNotifyObj);
hr = PropPage->Init(pwzObjName, pwzClass);
if (!SUCCEEDED(hr)) { goto Cleanup; }
hr = PropPage->CreatePage(&hPage);
if (!SUCCEEDED(hr)) { goto Cleanup; }
//
// Invoke the callback function, which will add the page to the list of
// pages that will be used to create the property sheet.
//
(*pAddPageProc)(hPage, lParam);
Cleanup: ReleaseStgMedium(&ObjMedium);
return hr; }
//+----------------------------------------------------------------------------
//
// Member: CDsPropPageHost::IShellExtInit::ReplacePage
//
// Notes: Not used.
//
//-----------------------------------------------------------------------------
STDMETHODIMP CDsPropPageHost::ReplacePage(UINT uPageID, LPFNADDPROPSHEETPAGE lpfnReplaceWith, LPARAM lParam) { return E_NOTIMPL; }
//+----------------------------------------------------------------------------
//
// Member: CDsPropPageHost::IUnknown::QueryInterface
//
// Synopsis: Returns requested interface pointer
//
//-----------------------------------------------------------------------------
STDMETHODIMP CDsPropPageHost::QueryInterface(REFIID riid, void ** ppvObject) { if (IID_IUnknown == riid) { *ppvObject = (IUnknown *)(LPSHELLEXTINIT)this; } else if (IID_IShellExtInit == riid) { *ppvObject = (LPSHELLEXTINIT)this; } else if (IID_IShellPropSheetExt == riid) { *ppvObject = (LPSHELLPROPSHEETEXT)this; } else { *ppvObject = NULL; return E_NOINTERFACE; } AddRef(); return S_OK; }
//+----------------------------------------------------------------------------
//
// Member: CDsPropPageHost::IUnknown::AddRef
//
// Synopsis: increments reference count
//
// Returns: the reference count
//
//-----------------------------------------------------------------------------
STDMETHODIMP_(ULONG) CDsPropPageHost::AddRef(void) { return InterlockedIncrement((long *)&m_uRefs); }
//+----------------------------------------------------------------------------
//
// Member: CDsPropPageHost::IUnknown::Release
//
// Synopsis: Decrements the object's reference count and frees it when
// no longer referenced.
//
// Returns: zero if the reference count is zero or non-zero otherwise
//
//-----------------------------------------------------------------------------
STDMETHODIMP_(ULONG) CDsPropPageHost::Release(void) { unsigned long uTmp; if ((uTmp = InterlockedDecrement((long *)&m_uRefs)) == 0) { delete this; } return uTmp; }
//+----------------------------------------------------------------------------
//
// CDsPropPageHostCF - class factory for the CDsPropPageHost object
//
//-----------------------------------------------------------------------------
//+----------------------------------------------------------------------------
//
// Member: CDsPropPageHostCF::Create
//
// Synopsis: creates a new class factory object
//
//-----------------------------------------------------------------------------
IClassFactory * CDsPropPageHostCF::Create(void) { return new CDsPropPageHostCF(); }
//+----------------------------------------------------------------------------
//
// Member: CDsPropPageHostCF::CDsPropPageHostCF
//
// Synopsis: ctor
//
//-----------------------------------------------------------------------------
CDsPropPageHostCF::CDsPropPageHostCF() : m_uRefs(1) { }
//+----------------------------------------------------------------------------
//
// Member: CDsPropPageHostCF::~CDsPropPageHostCF
//
// Synopsis: dtor
//
//-----------------------------------------------------------------------------
CDsPropPageHostCF::~CDsPropPageHostCF(void) { }
//+----------------------------------------------------------------------------
//
// Member: CDsPropPageHostCF::IUnknown::QueryInterface
//
// Synopsis: Returns requested interface pointer
//
//-----------------------------------------------------------------------------
STDMETHODIMP CDsPropPageHostCF::QueryInterface(REFIID riid, void ** ppvObject) { if (IID_IUnknown == riid) { *ppvObject = (IUnknown *)this; } else if (IsEqualIID(IID_IClassFactory, riid)) { *ppvObject = (IClassFactory *)this; } else { *ppvObject = NULL; return E_NOINTERFACE; } AddRef(); return S_OK; }
//+----------------------------------------------------------------------------
//
// Member: CDsPropPageHostCF::IUnknown::AddRef
//
// Synopsis: increments reference count
//
// Returns: the new reference count
//
//-----------------------------------------------------------------------------
STDMETHODIMP_(ULONG) CDsPropPageHostCF::AddRef(void) { return InterlockedIncrement((long *)&m_uRefs); }
//+----------------------------------------------------------------------------
//
// Member: CDsPropPageHostCF::IUnknown::Release
//
// Synopsis: decrement the refcount
//
// Returns: the new reference count
//
//-----------------------------------------------------------------------------
STDMETHODIMP_(ULONG) CDsPropPageHostCF::Release(void) { unsigned long uTmp; if ((uTmp = InterlockedDecrement((long *)&m_uRefs)) == 0) { delete this; } return uTmp; }
//+----------------------------------------------------------------------------
//
// Member: CDsPropPageHostCF::IClassFactory::CreateInstance
//
// Synopsis: create an incore instance of the proppage host class object
//
// Arguments: [pUnkOuter] - aggregator
// [riid] - requested interface
// [ppvObject] - receptor for itf ptr
//
// Returns: HRESULTS
//
//-----------------------------------------------------------------------------
STDMETHODIMP CDsPropPageHostCF::CreateInstance(IUnknown *pUnkOuter, REFIID riid, void **ppvObject) { HRESULT hr = S_OK; *ppvObject = NULL;
CDsPropPageHost * pPropPage = new CDsPropPageHost(); if (pPropPage == NULL) { return E_OUTOFMEMORY; }
hr = pPropPage->QueryInterface(riid, ppvObject); if (FAILED(hr)) { pPropPage->Release(); return hr; }
//
// We got a refcount of one when launched, and the above QI increments it
// to 2, so call release to take it back to 1.
//
pPropPage->Release(); return hr; }
//+----------------------------------------------------------------------------
//
// Member: CDsPropPageHostCF::IClassFactory::LockServer
//
// Synopsis: Called with fLock set to TRUE to indicate that the server
// should continue to run even if none of its objects are active
//
// Arguments: [fLock] - increment/decrement the instance count
//
// Returns: HRESULTS
//
//-----------------------------------------------------------------------------
STDMETHODIMP CDsPropPageHostCF::LockServer(BOOL fLock) { CDll::LockServer(fLock); return S_OK; }
|