ATLSNAP.H
#ifndef __ATL_SNAPIN_H__ 
#define __ATL_SNAPIN_H__ 
 
#include <mmc.h> 
#include <commctrl.h> 
 
#ifdef _DEBUG 
void __cdecl operator delete(void* p); 
void* __cdecl operator new(size_t nSize, LPCSTR lpszFileName, int nLine); 
#undef new 
#define new new(__FILE__, __LINE__) 
 
#endif 
 
#ifdef __cplusplus 
extern "C"{ 
#endif  
 
void __RPC_FAR * __RPC_USER MIDL_user_allocate(size_t); 
void __RPC_USER MIDL_user_free( void __RPC_FAR * );  
 
#ifndef __ISnapInDataInterface_INTERFACE_DEFINED__ 
#define __ISnapInDataInterface_INTERFACE_DEFINED__ 
 
EXTERN_C const IID IID_ISnapInDataInterface; 
 
#if defined(__cplusplus) && !defined(CINTERFACE) 
     
    interface DECLSPEC_UUID("1FABD781-ECDA-11D0-AACE-00AA00C00189") 
    ISnapInDataInterface : public IUnknown 
    { 
    public: 
        virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE Notify(  
            MMC_NOTIFY_TYPE event, 
            long arg, 
            long param, 
            BOOL bComponentData, 
            IConsole __RPC_FAR *pConsole, 
            IHeaderCtrl __RPC_FAR *pHeader, 
            IToolbar __RPC_FAR *pToolbar) = 0; 
         
        virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetDispInfo(  
            SCOPEDATAITEM __RPC_FAR *pScopeDataItem) = 0; 
         
        virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetResultViewType(  
            LPOLESTR __RPC_FAR *ppVIewType, 
            long __RPC_FAR *pViewOptions) = 0; 
         
        virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetDisplayInfo(  
            RESULTDATAITEM __RPC_FAR *pResultDataItem) = 0; 
         
        virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE AddMenuItems(  
            LPCONTEXTMENUCALLBACK piCallback, 
            long __RPC_FAR *pInsertionAllowed) = 0; 
         
        virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE Command(  
            long lCommandID) = 0; 
         
        virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE CreatePropertyPages(  
            LPPROPERTYSHEETCALLBACK lpProvider, 
            long handle, 
IUnknown* pUnk) = 0; 
         
        virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE QueryPagesFor( void) = 0; 
         
        virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetControlbar(  
            IControlbar __RPC_FAR *pControlbar, 
            IExtendControlbar __RPC_FAR *pExtendControlbar) = 0; 
         
        virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE ControlbarNotify(  
            IControlbar __RPC_FAR *pControlbar, 
            IExtendControlbar __RPC_FAR *pExtendControlbar, 
            MMC_NOTIFY_TYPE event, 
            long arg, 
            long param) = 0; 
         
        virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetScopeData(  
            SCOPEDATAITEM __RPC_FAR *__RPC_FAR *pScopeDataItem) = 0; 
         
        virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetResultData(  
            RESULTDATAITEM __RPC_FAR *__RPC_FAR *pResultDataItem) = 0; 
         
    }; 
     
#else /* C style interface */ 
 
    typedef struct ISnapInDataInterfaceVtbl 
    { 
        BEGIN_INTERFACE 
         
        HRESULT ( STDMETHODCALLTYPE __RPC_FAR *QueryInterface )(  
            ISnapInDataInterface __RPC_FAR * This, 
            /* [in] */ REFIID riid, 
            /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject); 
         
        ULONG ( STDMETHODCALLTYPE __RPC_FAR *AddRef )(  
            ISnapInDataInterface __RPC_FAR * This); 
         
        ULONG ( STDMETHODCALLTYPE __RPC_FAR *Release )(  
            ISnapInDataInterface __RPC_FAR * This); 
         
        /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Notify )(  
            ISnapInDataInterface __RPC_FAR * This, 
            MMC_NOTIFY_TYPE event, 
            long arg, 
            long param, 
            BOOL bComponentData, 
            IConsole __RPC_FAR *pConsole, 
            IHeaderCtrl __RPC_FAR *pHeader, 
            IToolbar __RPC_FAR *pToolbar); 
         
        /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetDispInfo )(  
            ISnapInDataInterface __RPC_FAR * This, 
            SCOPEDATAITEM __RPC_FAR *pScopeDataItem); 
         
        /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetResultViewType )(  
            ISnapInDataInterface __RPC_FAR * This, 
            LPOLESTR __RPC_FAR *ppVIewType, 
            long __RPC_FAR *pViewOptions); 
         
        /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetDisplayInfo )(  
            ISnapInDataInterface __RPC_FAR * This, 
            RESULTDATAITEM __RPC_FAR *pResultDataItem); 
         
        /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *AddMenuItems )(  
            ISnapInDataInterface __RPC_FAR * This, 
            LPCONTEXTMENUCALLBACK piCallback, 
            long __RPC_FAR *pInsertionAllowed); 
         
        /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *Command )(  
            ISnapInDataInterface __RPC_FAR * This, 
            long lCommandID); 
         
        /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *CreatePropertyPages )(  
            ISnapInDataInterface __RPC_FAR * This, 
            LPPROPERTYSHEETCALLBACK lpProvider, 
            long handle, 
IUnknown* pUnk); 
         
        /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *QueryPagesFor )(  
            ISnapInDataInterface __RPC_FAR * This); 
         
        /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *SetControlbar )(  
            ISnapInDataInterface __RPC_FAR * This, 
            IControlbar __RPC_FAR *pControlbar, 
            IExtendControlbar __RPC_FAR *pExtendControlbar); 
         
        /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *ControlbarNotify )(  
            ISnapInDataInterface __RPC_FAR * This, 
            IControlbar __RPC_FAR *pControlbar, 
            IExtendControlbar __RPC_FAR *pExtendControlbar, 
            MMC_NOTIFY_TYPE event, 
            long arg, 
            long param); 
         
        /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetScopeData )(  
            ISnapInDataInterface __RPC_FAR * This, 
            SCOPEDATAITEM __RPC_FAR *__RPC_FAR *pScopeDataItem); 
         
        /* [helpstring] */ HRESULT ( STDMETHODCALLTYPE __RPC_FAR *GetResultData )(  
            ISnapInDataInterface __RPC_FAR * This, 
            RESULTDATAITEM __RPC_FAR *__RPC_FAR *pResultDataItem); 
         
        END_INTERFACE 
    } ISnapInDataInterfaceVtbl; 
 
    interface ISnapInDataInterface 
    { 
        CONST_VTBL struct ISnapInDataInterfaceVtbl __RPC_FAR *lpVtbl; 
    }; 
 
     
 
#ifdef COBJMACROS 
 
 
#define ISnapInDataInterface_QueryInterface(This,riid,ppvObject)\ 
    (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) 
 
#define ISnapInDataInterface_AddRef(This)\ 
    (This)->lpVtbl -> AddRef(This) 
 
#define ISnapInDataInterface_Release(This)\ 
    (This)->lpVtbl -> Release(This) 
 
 
#define ISnapInDataInterface_Notify(This,event,arg,param,bComponentData,pConsole,pHeader,pToolbar)\ 
    (This)->lpVtbl -> Notify(This,event,arg,param,bComponentData,pConsole,pHeader,pToolbar) 
 
#define ISnapInDataInterface_GetDispInfo(This,pScopeDataItem)\ 
    (This)->lpVtbl -> GetDispInfo(This,pScopeDataItem) 
 
#define ISnapInDataInterface_GetResultViewType(This,ppVIewType,pViewOptions)\ 
    (This)->lpVtbl -> GetResultViewType(This,ppVIewType,pViewOptions) 
 
#define ISnapInDataInterface_GetDisplayInfo(This,pResultDataItem)\ 
    (This)->lpVtbl -> GetDisplayInfo(This,pResultDataItem) 
 
#define ISnapInDataInterface_AddMenuItems(This,piCallback,pInsertionAllowed)\ 
    (This)->lpVtbl -> AddMenuItems(This,piCallback,pInsertionAllowed) 
 
#define ISnapInDataInterface_Command(This,lCommandID)\ 
    (This)->lpVtbl -> Command(This,lCommandID) 
 
#define ISnapInDataInterface_CreatePropertyPages(This,lpProvider,handle, pUnk)\ 
    (This)->lpVtbl -> CreatePropertyPages(This,lpProvider,handle, pUnk) 
 
#define ISnapInDataInterface_QueryPagesFor(This)\ 
    (This)->lpVtbl -> QueryPagesFor(This) 
 
#define ISnapInDataInterface_SetControlbar(This,pControlbar,pExtendControlbar)\ 
    (This)->lpVtbl -> SetControlbar(This,pControlbar,pExtendControlbar) 
 
#define ISnapInDataInterface_ControlbarNotify(This,pControlbar,pExtendControlbar,event,arg,param)\ 
    (This)->lpVtbl -> ControlbarNotify(This,pControlbar,pExtendControlbar,event,arg,param) 
 
#define ISnapInDataInterface_GetScopeData(This,pScopeDataItem)\ 
    (This)->lpVtbl -> GetScopeData(This,pScopeDataItem) 
 
#define ISnapInDataInterface_GetResultData(This,pResultDataItem)\ 
    (This)->lpVtbl -> GetResultData(This,pResultDataItem) 
 
#endif /* COBJMACROS */ 
 
 
#endif /* C style interface */ 
 
 
 
/* [helpstring] */ HRESULT STDMETHODCALLTYPE ISnapInDataInterface_Notify_Proxy(  
    ISnapInDataInterface __RPC_FAR * This, 
    MMC_NOTIFY_TYPE event, 
    long arg, 
    long param, 
    BOOL bComponentData, 
    IConsole __RPC_FAR *pConsole, 
    IHeaderCtrl __RPC_FAR *pHeader, 
    IToolbar __RPC_FAR *pToolbar); 
 
 
void __RPC_STUB ISnapInDataInterface_Notify_Stub( 
    IRpcStubBuffer *This, 
    IRpcChannelBuffer *_pRpcChannelBuffer, 
    PRPC_MESSAGE _pRpcMessage, 
    DWORD *_pdwStubPhase); 
 
 
/* [helpstring] */ HRESULT STDMETHODCALLTYPE ISnapInDataInterface_GetDispInfo_Proxy(  
    ISnapInDataInterface __RPC_FAR * This, 
    SCOPEDATAITEM __RPC_FAR *pScopeDataItem); 
 
 
void __RPC_STUB ISnapInDataInterface_GetDispInfo_Stub( 
    IRpcStubBuffer *This, 
    IRpcChannelBuffer *_pRpcChannelBuffer, 
    PRPC_MESSAGE _pRpcMessage, 
    DWORD *_pdwStubPhase); 
 
 
/* [helpstring] */ HRESULT STDMETHODCALLTYPE ISnapInDataInterface_GetResultViewType_Proxy(  
    ISnapInDataInterface __RPC_FAR * This, 
    LPOLESTR __RPC_FAR *ppVIewType, 
    long __RPC_FAR *pViewOptions); 
 
 
void __RPC_STUB ISnapInDataInterface_GetResultViewType_Stub( 
    IRpcStubBuffer *This, 
    IRpcChannelBuffer *_pRpcChannelBuffer, 
    PRPC_MESSAGE _pRpcMessage, 
    DWORD *_pdwStubPhase); 
 
 
/* [helpstring] */ HRESULT STDMETHODCALLTYPE ISnapInDataInterface_GetDisplayInfo_Proxy(  
    ISnapInDataInterface __RPC_FAR * This, 
    RESULTDATAITEM __RPC_FAR *pResultDataItem); 
 
 
void __RPC_STUB ISnapInDataInterface_GetDisplayInfo_Stub( 
    IRpcStubBuffer *This, 
    IRpcChannelBuffer *_pRpcChannelBuffer, 
    PRPC_MESSAGE _pRpcMessage, 
    DWORD *_pdwStubPhase); 
 
 
/* [helpstring] */ HRESULT STDMETHODCALLTYPE ISnapInDataInterface_AddMenuItems_Proxy(  
    ISnapInDataInterface __RPC_FAR * This, 
    LPCONTEXTMENUCALLBACK piCallback, 
    long __RPC_FAR *pInsertionAllowed); 
 
 
void __RPC_STUB ISnapInDataInterface_AddMenuItems_Stub( 
    IRpcStubBuffer *This, 
    IRpcChannelBuffer *_pRpcChannelBuffer, 
    PRPC_MESSAGE _pRpcMessage, 
    DWORD *_pdwStubPhase); 
 
 
/* [helpstring] */ HRESULT STDMETHODCALLTYPE ISnapInDataInterface_Command_Proxy(  
    ISnapInDataInterface __RPC_FAR * This, 
    long lCommandID); 
 
 
void __RPC_STUB ISnapInDataInterface_Command_Stub( 
    IRpcStubBuffer *This, 
    IRpcChannelBuffer *_pRpcChannelBuffer, 
    PRPC_MESSAGE _pRpcMessage, 
    DWORD *_pdwStubPhase); 
 
 
/* [helpstring] */ HRESULT STDMETHODCALLTYPE ISnapInDataInterface_CreatePropertyPages_Proxy(  
    ISnapInDataInterface __RPC_FAR * This, 
    LPPROPERTYSHEETCALLBACK lpProvider, 
    long handle, 
IUnknown* pUnk); 
 
 
void __RPC_STUB ISnapInDataInterface_CreatePropertyPages_Stub( 
    IRpcStubBuffer *This, 
    IRpcChannelBuffer *_pRpcChannelBuffer, 
    PRPC_MESSAGE _pRpcMessage, 
    DWORD *_pdwStubPhase); 
 
 
/* [helpstring] */ HRESULT STDMETHODCALLTYPE ISnapInDataInterface_QueryPagesFor_Proxy(  
    ISnapInDataInterface __RPC_FAR * This); 
 
 
void __RPC_STUB ISnapInDataInterface_QueryPagesFor_Stub( 
    IRpcStubBuffer *This, 
    IRpcChannelBuffer *_pRpcChannelBuffer, 
    PRPC_MESSAGE _pRpcMessage, 
    DWORD *_pdwStubPhase); 
 
 
/* [helpstring] */ HRESULT STDMETHODCALLTYPE ISnapInDataInterface_SetControlbar_Proxy(  
    ISnapInDataInterface __RPC_FAR * This, 
    IControlbar __RPC_FAR *pControlbar, 
    IExtendControlbar __RPC_FAR *pExtendControlbar); 
 
 
void __RPC_STUB ISnapInDataInterface_SetControlbar_Stub( 
    IRpcStubBuffer *This, 
    IRpcChannelBuffer *_pRpcChannelBuffer, 
    PRPC_MESSAGE _pRpcMessage, 
    DWORD *_pdwStubPhase); 
 
 
/* [helpstring] */ HRESULT STDMETHODCALLTYPE ISnapInDataInterface_ControlbarNotify_Proxy(  
    ISnapInDataInterface __RPC_FAR * This, 
    IControlbar __RPC_FAR *pControlbar, 
    IExtendControlbar __RPC_FAR *pExtendControlbar, 
    MMC_NOTIFY_TYPE event, 
    long arg, 
    long param); 
 
 
void __RPC_STUB ISnapInDataInterface_ControlbarNotify_Stub( 
    IRpcStubBuffer *This, 
    IRpcChannelBuffer *_pRpcChannelBuffer, 
    PRPC_MESSAGE _pRpcMessage, 
    DWORD *_pdwStubPhase); 
 
 
/* [helpstring] */ HRESULT STDMETHODCALLTYPE ISnapInDataInterface_GetScopeData_Proxy(  
    ISnapInDataInterface __RPC_FAR * This, 
    SCOPEDATAITEM __RPC_FAR *__RPC_FAR *pScopeDataItem); 
 
 
void __RPC_STUB ISnapInDataInterface_GetScopeData_Stub( 
    IRpcStubBuffer *This, 
    IRpcChannelBuffer *_pRpcChannelBuffer, 
    PRPC_MESSAGE _pRpcMessage, 
    DWORD *_pdwStubPhase); 
 
 
/* [helpstring] */ HRESULT STDMETHODCALLTYPE ISnapInDataInterface_GetResultData_Proxy(  
    ISnapInDataInterface __RPC_FAR * This, 
    RESULTDATAITEM __RPC_FAR *__RPC_FAR *pResultDataItem); 
 
 
void __RPC_STUB ISnapInDataInterface_GetResultData_Stub( 
    IRpcStubBuffer *This, 
    IRpcChannelBuffer *_pRpcChannelBuffer, 
    PRPC_MESSAGE _pRpcMessage, 
    DWORD *_pdwStubPhase); 
 
 
 
#endif /* __ISnapInDataInterface_INTERFACE_DEFINED__ */ 
 
#ifdef __cplusplus 
} 
#endif 
 
#pragma comment(lib, "mmc.lib") 
 
#ifndef CPropertyPageImpl 
#pragma comment(lib, "comctl32.lib") 
 
template <class T> 
class ATL_NO_VTABLE CPropertyPageImpl : public CDialogImplBase 
{ 
public: 
PROPSHEETPAGE m_psp; 
 
operator PROPSHEETPAGE*() { return &m_psp; } 
 
// Construction 
CPropertyPageImpl(LPCTSTR lpszTitle = NULL) 
{ 
// initialize PROPSHEETPAGE struct 
memset(&m_psp, 0, sizeof(PROPSHEETPAGE)); 
m_psp.dwSize = sizeof(PROPSHEETPAGE); 
m_psp.dwFlags = PSP_USECALLBACK; 
m_psp.hInstance = _Module.GetResourceInstance(); 
m_psp.pszTemplate = MAKEINTRESOURCE(T::IDD); 
m_psp.pfnDlgProc = (DLGPROC)T::StartDialogProc; 
m_psp.pfnCallback = T::PropPageCallback; 
m_psp.lParam = (LPARAM)this; 
 
if(lpszTitle != NULL) 
{ 
m_psp.pszTitle = lpszTitle; 
m_psp.dwFlags |= PSP_USETITLE; 
} 
} 
 
static UINT CALLBACK PropPageCallback(HWND hWnd, UINT uMsg, LPPROPSHEETPAGE ppsp) 
{ 
if(uMsg == PSPCB_CREATE) 
{ 
_ASSERTE(hWnd == NULL); 
CDialogImplBase* pPage = (CDialogImplBase*)ppsp->lParam; 
_Module.AddCreateWndData(&pPage->m_thunk.cd, pPage); 
} 
 
return 1; 
} 
 
HPROPSHEETPAGE Create() 
{ 
return ::CreatePropertySheetPage(&m_psp); 
} 
 
BOOL EndDialog(int) 
{ 
// do nothing here, calling ::EndDialog will close the whole sheet 
_ASSERTE(FALSE); 
return FALSE; 
} 
 
// Operations 
void CancelToClose() 
{ 
_ASSERTE(::IsWindow(m_hWnd)); 
_ASSERTE(GetParent() != NULL); 
 
::SendMessage(GetParent(), PSM_CANCELTOCLOSE, 0, 0L); 
} 
void SetModified(BOOL bChanged = TRUE) 
{ 
_ASSERTE(::IsWindow(m_hWnd)); 
_ASSERTE(GetParent() != NULL); 
 
if(bChanged) 
::SendMessage(GetParent(), PSM_CHANGED, (WPARAM)m_hWnd, 0L); 
else 
::SendMessage(GetParent(), PSM_UNCHANGED, (WPARAM)m_hWnd, 0L); 
} 
LRESULT QuerySiblings(WPARAM wParam, LPARAM lParam) 
{ 
_ASSERTE(::IsWindow(m_hWnd)); 
_ASSERTE(GetParent() != NULL); 
 
return ::SendMessage(GetParent(), PSM_QUERYSIBLINGS, wParam, lParam); 
} 
 
BEGIN_MSG_MAP(CPropertyPageImpl< T >) 
MESSAGE_HANDLER(WM_NOTIFY, OnNotify) 
END_MSG_MAP() 
 
// Message handler 
LRESULT OnNotify(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) 
{ 
_ASSERTE(::IsWindow(m_hWnd)); 
NMHDR* pNMHDR = (NMHDR*)lParam; 
 
// don't handle messages not from the page/sheet itself 
if(pNMHDR->hwndFrom != m_hWnd && pNMHDR->hwndFrom != ::GetParent(m_hWnd)) 
{ 
bHandled = FALSE; 
return 1; 
} 
 
T* pT = (T*)this; 
LRESULT lResult = 0; 
// handle default 
switch(pNMHDR->code) 
{ 
case PSN_SETACTIVE: 
//? other values 
lResult = pT->OnSetActive() ? 0 : -1; 
break; 
case PSN_KILLACTIVE: 
lResult = !pT->OnKillActive(); 
break; 
case PSN_APPLY: 
lResult = pT->OnApply() ? PSNRET_NOERROR : PSNRET_INVALID_NOCHANGEPAGE; 
break; 
case PSN_RESET: 
pT->OnReset(); 
break; 
case PSN_QUERYCANCEL: 
lResult = !pT->OnQueryCancel(); 
break; 
case PSN_WIZNEXT: 
//? other values 
lResult = !pT->OnWizardNext(); 
break; 
case PSN_WIZBACK: 
lResult = !pT->OnWizardBack(); 
break; 
case PSN_WIZFINISH: 
lResult = !pT->OnWizardFinish(); 
break; 
case PSN_HELP: 
/**/lResult = pT->OnHelp(); 
break; 
default: 
bHandled = FALSE;// not handled 
} 
 
return lResult; 
} 
 
// Overridables 
BOOL OnSetActive() 
{ 
return TRUE; 
} 
BOOL OnKillActive() 
{ 
return TRUE; 
} 
BOOL OnApply() 
{ 
return TRUE; 
} 
void OnReset() 
{ 
} 
BOOL OnQueryCancel() 
{ 
return TRUE;    // ok to cancel 
} 
BOOL OnWizardBack() 
{ 
return TRUE; 
} 
BOOL OnWizardNext() 
{ 
return TRUE; 
} 
BOOL OnWizardFinish() 
{ 
return TRUE; 
} 
BOOL OnHelp() 
{ 
return TRUE; 
} 
}; 
#endif 
 
 
template <class T> 
class ATL_NO_VTABLE CSnapInDataObjectImpl : public IDataObject 
{ 
public: 
STDMETHOD(GetData)(FORMATETC *pformatetcIn, STGMEDIUM *pmedium) 
{ 
ATLTRACENOTIMPL(_T("SnapInDataObjectImpl::GetData\n")); 
} 
 
STDMETHOD(GetDataHere)(FORMATETC* pformatetc, STGMEDIUM* pmedium) 
{ 
ATLTRACE(_T("SnapInDataObjectImpl::GetDataHere\n")); 
if (pmedium == NULL) 
return E_POINTER; 
 
HRESULT hr = DV_E_TYMED; 
// Make sure the type medium is HGLOBAL 
if (pmedium->tymed == TYMED_HGLOBAL) 
{ 
// Create the stream on the hGlobal passed in 
LPSTREAM pStream; 
hr = CreateStreamOnHGlobal(pmedium->hGlobal, FALSE, &pStream); 
if (SUCCEEDED(hr)) 
{ 
T* pT = static_cast<T*>(this); 
hr = pT->FillData(pformatetc->cfFormat, pStream); 
pStream->Release(); 
} 
} 
 
return hr; 
} 
 
STDMETHOD(QueryGetData)(FORMATETC* /* pformatetc */) 
{ 
ATLTRACENOTIMPL(_T("SnapInDataObjectImpl::QueryGetData\n")); 
} 
STDMETHOD(GetCanonicalFormatEtc)(FORMATETC* /* pformatectIn */,FORMATETC* /* pformatetcOut */) 
{ 
ATLTRACENOTIMPL(_T("SnapInDataObjectImpl::GetCanonicalFormatEtc\n")); 
} 
STDMETHOD(SetData)(FORMATETC* /* pformatetc */, STGMEDIUM* /* pmedium */, BOOL /* fRelease */) 
{ 
ATLTRACENOTIMPL(_T("SnapInDataObjectImpl::SetData\n")); 
} 
STDMETHOD(EnumFormatEtc)(DWORD /* dwDirection */, IEnumFORMATETC** /* ppenumFormatEtc */) 
{ 
ATLTRACENOTIMPL(_T("SnapInDataObjectImpl::EnumFormatEtc\n")); 
} 
STDMETHOD(DAdvise)(FORMATETC *pformatetc, DWORD advf, IAdviseSink *pAdvSink, 
DWORD *pdwConnection) 
{ 
ATLTRACENOTIMPL(_T("SnapInDataObjectImpl::SetData\n")); 
} 
STDMETHOD(DUnadvise)(DWORD dwConnection) 
{ 
ATLTRACENOTIMPL(_T("SnapInDataObjectImpl::SetDatan\n")); 
} 
STDMETHOD(EnumDAdvise)(IEnumSTATDATA **ppenumAdvise) 
{ 
ATLTRACENOTIMPL(_T("SnapInDataObjectImpl::SetData\n")); 
} 
}; 
 
 
template <class T, class C> 
class ATL_NO_VTABLE IComponentDataImpl : public IComponentData  
{ 
public : 
CComQIPtr<IConsoleNameSpace, &IID_IConsoleNameSpace> m_spConsoleNameSpace; 
CComQIPtr<IConsole, &IID_IConsole> m_spConsole; 
 
    STDMETHOD(Initialize)(LPUNKNOWN pUnknown) 
{ 
ATLTRACE(_T("IComponentDataImpl::Initialize\n")); 
 
if (pUnknown == NULL) 
{ 
ATLTRACE(_T("IComponentData::Initialize called with pUnknown == NULL\n")); 
return E_UNEXPECTED; 
} 
 
m_spConsoleNameSpace = pUnknown; 
if (m_spConsoleNameSpace == NULL) 
{ 
ATLTRACE(_T("QI for IConsoleNameSpace failed\n")); 
return E_UNEXPECTED; 
} 
 
m_spConsole = pUnknown; 
if (m_spConsole == NULL) 
{ 
ATLTRACE(_T("QI for IConsole failed\n")); 
return E_UNEXPECTED; 
} 
 
return S_OK; 
} 
 
STDMETHOD(CreateComponent)(LPCOMPONENT *ppComponent) 
{ 
ATLTRACE(_T("IComponentDataImpl::CreateComponent\n")); 
if (ppComponent == NULL) 
{ 
ATLTRACE(_T("IComponentData::CreateComponent called with ppComponent == NULL\n")); 
return E_UNEXPECTED; 
} 
 
*ppComponent = NULL; 
 
CComObject< C >* pComponent; 
HRESULT hr = CComObject< C >::CreateInstance(&pComponent); 
if (FAILED(hr)) 
{ 
ATLTRACE(_T("IComponentData::CreateComponent : Could not create IComponent object\n")); 
return hr; 
} 
 
return pComponent->QueryInterface(IID_IComponent, (void**)ppComponent); 
} 
 
     
    STDMETHOD(Notify)(  
        LPDATAOBJECT lpDataObject, 
        MMC_NOTIFY_TYPE event, 
        long arg, 
        long param) 
{ 
ATLTRACE(_T("IComponentDataImpl::Notify\n")); 
if (lpDataObject == NULL) 
{ 
ATLTRACE(_T("IComponentData::Notify called with lpDataObject == NULL\n")); 
return E_UNEXPECTED; 
} 
 
CComQIPtr<ISnapInDataInterface, &IID_ISnapInDataInterface> spData(lpDataObject); 
if (spData == NULL) 
{ 
ATLTRACE(_T("QI for ISnapInDataInterface failed\n")); 
return E_UNEXPECTED; 
} 
return spData->Notify(event, arg, param, TRUE, m_spConsole, NULL, NULL); 
} 
 
    STDMETHOD(Destroy)(void) 
{ 
ATLTRACE(_T("IComponentDataImpl::Destroy\n")); 
 
m_spNode.Release(); 
m_spConsole.Release(); 
m_spConsoleNameSpace.Release(); 
return S_OK; 
} 
 
    STDMETHOD(QueryDataObject)(long cookie, 
        DATA_OBJECT_TYPES type, 
        LPDATAOBJECT  *ppDataObject) 
{ 
ATLTRACE(_T("IComponentDataImpl::QueryDataObject\n")); 
_ASSERTE(m_spNode != NULL); 
 
if (ppDataObject == NULL) 
{ 
ATLTRACE(_T("IComponentData::QueryDataObject called with ppDataObject == NULL\n")); 
return E_UNEXPECTED; 
} 
 
*ppDataObject = NULL; 
 
if (cookie == NULL) 
return m_spNode->QueryInterface(IID_IDataObject, (void**)(ppDataObject)); 
 
IUnknown* pUnk = (IUnknown*) cookie; 
return pUnk->QueryInterface(IID_IDataObject, (void**)(ppDataObject)); 
} 
     
    STDMETHOD(GetDisplayInfo)(SCOPEDATAITEM *pScopeDataItem) 
{ 
ATLTRACE(_T("IComponentDataImpl::GetDisplayInfo\n")); 
 
if (pScopeDataItem == NULL) 
{ 
ATLTRACE(_T("IComponentData::GetDisplayInfo called with pScopeDataItem == NULL\n")); 
return E_UNEXPECTED; 
} 
 
IUnknown* pUnk = (IUnknown*) pScopeDataItem->lParam; 
if (pUnk == NULL) 
pUnk = m_spNode; 
 
CComQIPtr<ISnapInDataInterface, &IID_ISnapInDataInterface> spData(pUnk); 
if (spData == NULL) 
{ 
ATLTRACE(_T("QI for ISnapInDataInterface failed\n")); 
return E_UNEXPECTED; 
} 
return spData->GetDispInfo(pScopeDataItem); 
} 
     
    STDMETHOD(CompareObjects)(LPDATAOBJECT lpDataObjectA, 
        LPDATAOBJECT lpDataObjectB) 
{ 
ATLTRACENOTIMPL(_T("IComponentDataImpl::CompareObjects\n")); 
return S_FALSE; 
    } 
 
protected: 
CComPtr<IUnknown> m_spNode; 
}; 
 
template <class T> 
class ATL_NO_VTABLE IComponentImpl : public IComponent 
{ 
public: 
//Review all of these may not be required 
CComPtr<IConsole> m_spConsole; 
CComQIPtr<IHeaderCtrl, &IID_IHeaderCtrl> m_spHeaderCtrl; 
CComPtr<IImageList> m_spImageList; 
CComPtr<IConsoleVerb> m_spConsoleVerb; 
 
    STDMETHOD(Initialize)(LPCONSOLE lpConsole) 
{ 
ATLTRACE(_T("IComponentImpl::Initialize\n")); 
 
if (lpConsole == NULL) 
{ 
ATLTRACE(_T("lpConsole is NULL\n")); 
return E_UNEXPECTED; 
} 
 
m_spConsole = lpConsole; 
 
m_spHeaderCtrl = lpConsole; 
if (m_spHeaderCtrl == NULL) 
{ 
ATLTRACE(_T("QI for IHeaderCtrl failed\n")); 
return E_UNEXPECTED; 
} 
 
HRESULT hr = m_spConsole->SetHeader(m_spHeaderCtrl); 
if (FAILED(hr)) 
{ 
ATLTRACE(_T("IConsole::SetHeader failed (HRESULT = %x)\n"), hr); 
return hr; 
} 
 
hr = lpConsole->QueryResultImageList(&m_spImageList); 
if (FAILED(hr)) 
{ 
ATLTRACE(_T("IConsole::QueryResultImageList failed (HRESULT = %x)\n"), hr); 
return hr; 
} 
 
lpConsole->QueryConsoleVerb(&m_spConsoleVerb) ; 
if (FAILED(hr)) 
{ 
ATLTRACE(_T("IConsole::QueryConsoleVerb failed (HRESULT = %x)\n"), hr); 
return hr; 
} 
 
return S_OK; 
} 
     
STDMETHOD(Notify)(LPDATAOBJECT lpDataObject, 
        MMC_NOTIFY_TYPE event, 
        long arg, 
        long param) 
{ 
ATLTRACE(_T("IComponentImpl::Notify\n")); 
if (lpDataObject == NULL) 
{ 
ATLTRACE(_T("IComponent::Notify called with lpDataObject==NULL \n")); 
return E_UNEXPECTED; 
} 
 
CComQIPtr<ISnapInDataInterface, &IID_ISnapInDataInterface> spData(lpDataObject); 
if (spData == NULL) 
{ 
ATLTRACE(_T("QI for ISnapInDataInterface failed\n")); 
return E_UNEXPECTED; 
} 
return spData->Notify(event, arg, param, FALSE, m_spConsole, m_spHeaderCtrl, NULL); 
} 
     
    STDMETHOD(Destroy)(long cookie) 
{ 
ATLTRACE(_T("IComponentImpl::Destroy\n")); 
 
m_spConsoleVerb = NULL; 
m_spImageList = NULL; 
m_spHeaderCtrl.Release(); 
m_spConsole.Release(); 
 
return S_OK; 
} 
     
    STDMETHOD(QueryDataObject)(long cookie, 
        DATA_OBJECT_TYPES type, 
        LPDATAOBJECT  *ppDataObject) 
{ 
ATLTRACE(_T("IComponentImpl::QueryDataObject\n")); 
 
if (ppDataObject == NULL) 
{ 
ATLTRACE(_T("IComponent::QueryDataObject called with ppDataObject==NULL \n")); 
return E_UNEXPECTED; 
} 
 
if (cookie == NULL) 
{ 
ATLTRACE(_T("IComponent::QueryDataObject called with cookie==NULL \n")); 
return E_UNEXPECTED; 
} 
 
*ppDataObject = NULL; 
 
IUnknown* pUnk = (IUnknown *) cookie; 
return pUnk->QueryInterface(IID_IDataObject, (void**)ppDataObject); 
} 
     
    STDMETHOD(GetResultViewType)(long cookie, 
        LPOLESTR  *ppViewType, 
        long  *pViewOptions) 
{ 
ATLTRACE(_T("IComponentImpl::GetResultViewType\n")); 
 
if (cookie == NULL) 
{ 
*ppViewType = NULL; 
*pViewOptions = MMC_VIEW_OPTIONS_NONE; 
return S_OK; 
} 
 
CComQIPtr<ISnapInDataInterface, &IID_ISnapInDataInterface> spData((IUnknown*)cookie); 
return spData->GetResultViewType(ppViewType, pViewOptions); 
} 
     
    STDMETHOD(GetDisplayInfo)(RESULTDATAITEM *pResultDataItem) 
{ 
ATLTRACE(_T("IComponentImpl::GetDisplayInfo\n")); 
if (pResultDataItem == NULL) 
{ 
ATLTRACE(_T("IComponent::GetDisplayInfo called with pResultDataItem==NULL\n")); 
return E_UNEXPECTED; 
} 
 
IUnknown* pUnk = (IUnknown*) pResultDataItem->lParam; 
if (pUnk == NULL) 
return E_UNEXPECTED; 
 
CComQIPtr<ISnapInDataInterface, &IID_ISnapInDataInterface> spData(pUnk); 
if (spData == NULL) 
{ 
ATLTRACE(_T("QI for ISnapInDataInterface failed\n")); 
return E_UNEXPECTED; 
} 
return spData->GetDisplayInfo(pResultDataItem); 
} 
     
    STDMETHOD(CompareObjects)( LPDATAOBJECT lpDataObjectA, 
        LPDATAOBJECT lpDataObjectB) 
{ 
ATLTRACENOTIMPL(_T("IComponentImpl::CompareObjects\n")); 
} 
}; 
 
template <class T, class D>         
class ATL_NO_VTABLE IResultDataCompareImpl : public IResultDataCompare 
{ 
public: 
    STDMETHOD(Compare)(long lUserParam, 
        long cookieA, 
        long cookieB, 
        int *pnResult) 
{ 
ATLTRACENOTIMPL(_T("IResultDataCompareImpl::Compare")); 
} 
}; 
 
 
template <class T>         
class ATL_NO_VTABLE IExtendContextMenuImpl : public IExtendContextMenu 
{ 
public: 
    STDMETHOD(AddMenuItems)(LPDATAOBJECT piDataObject, 
        LPCONTEXTMENUCALLBACK piCallback, 
        long *pInsertionAllowed) 
{ 
ATLTRACE(_T("IExtendContextMenuImpl::AddMenuItems\n")); 
if (piDataObject == NULL) 
{ 
ATLTRACE(_T("IExtendContextMenu::AddMenuItems called with piDataObject==NULL\n")); 
return E_UNEXPECTED; 
} 
CComQIPtr<ISnapInDataInterface, &IID_ISnapInDataInterface> spData(piDataObject); 
if (spData == NULL) 
{ 
ATLTRACE(_T("QI for ISnapInDataInterface failed\n")); 
return E_UNEXPECTED; 
} 
return spData->AddMenuItems(piCallback, pInsertionAllowed); 
} 
     
    STDMETHOD(Command)(long lCommandID, 
        LPDATAOBJECT piDataObject) 
{ 
ATLTRACE(_T("IExtendContextMenuImpl::Command\n")); 
if (piDataObject == NULL) 
{ 
ATLTRACE(_T("IExtendContextMenu::Command called with piDataObject==NULL\n")); 
return E_UNEXPECTED; 
} 
CComQIPtr<ISnapInDataInterface, &IID_ISnapInDataInterface> spData(piDataObject); 
if (spData == NULL) 
{ 
ATLTRACE(_T("QI for ISnapInDataInterface failed\n")); 
return E_UNEXPECTED; 
} 
return spData->Command(lCommandID); 
} 
}; 
 
template<class T> 
class ATL_NO_VTABLE IExtendPropertySheetImpl : public IExtendPropertySheet 
{ 
public: 
STDMETHOD(CreatePropertyPages)(LPPROPERTYSHEETCALLBACK lpProvider, 
long handle, 
        LPDATAOBJECT lpIDataObject) 
{ 
ATLTRACE(_T("IExtendPropertySheetImpl::CreatePropertyPages\n")); 
if (lpIDataObject == NULL) 
{ 
ATLTRACE(_T("IExtendPropertySheetImpl::CreatePropertyPages called with lpIDataObject==NULL\n")); 
return E_UNEXPECTED; 
} 
CComQIPtr<ISnapInDataInterface, &IID_ISnapInDataInterface> spData(lpIDataObject); 
if (spData == NULL) 
{ 
ATLTRACE(_T("QI for ISnapInDataInterface failed\n")); 
return E_UNEXPECTED; 
} 
return spData->CreatePropertyPages(lpProvider, handle, this); 
} 
     
    STDMETHOD(QueryPagesFor)(LPDATAOBJECT lpDataObject) 
{ 
ATLTRACE(_T("IExtendPropertySheetImpl::QueryPagesFor\n")); 
if (lpDataObject == NULL) 
{ 
ATLTRACE(_T("IExtendPropertySheetImpl::QueryPagesFor called with lpDataObject==NULL\n")); 
return E_UNEXPECTED; 
} 
CComQIPtr<ISnapInDataInterface, &IID_ISnapInDataInterface> spData(lpDataObject); 
if (spData == NULL) 
{ 
ATLTRACE(_T("QI for ISnapInDataInterface failed\n")); 
return E_UNEXPECTED; 
} 
return spData->QueryPagesFor(); 
} 
}; 
 
template <class T> 
class ATL_NO_VTABLE IExtendControlbarImpl : public IExtendControlbar 
{ 
CComPtr <IControlbar> m_spControlbar; 
public: 
STDMETHOD(SetControlbar)(LPCONTROLBAR pControlbar) 
{ 
ATLTRACE(_T("IExtendControlbarImpl::SetControlbar\n")); 
if (pControlbar == NULL) 
{ 
ATLTRACE(_T("IExtendControlbar::SetControlbar called with pControlbar==NULL\n")); 
return E_UNEXPECTED; 
} 
m_spControlbar = pControlbar; 
return S_OK; 
} 
     
    STDMETHOD(ControlbarNotify)(MMC_NOTIFY_TYPE event, 
        long arg, 
        long param) 
{ 
ATLTRACE(_T("IExtendControlbarImpl::ControlbarNotify\n")); 
CComQIPtr<ISnapInDataInterface, &IID_ISnapInDataInterface> spData; 
if (event == MMCN_BTN_CLICK) 
{ 
spData = ((IDataObject*) arg); 
} 
else if (event == MMCN_SELECT) 
{ 
BOOL bScope = (BOOL) LOWORD(arg); 
if (bScope) 
{ 
LPDATAOBJECT* ppDataobject = (LPDATAOBJECT*) param; 
if (ppDataobject[0]) 
{ 
spData = ppDataobject[0]; 
if (spData != NULL) 
spData->ControlbarNotify(m_spControlbar, this, event, arg, param); 
} 
 
if (ppDataobject[1]) 
{ 
spData = ppDataobject[1]; 
} 
} 
else 
spData = (IDataObject*) param; 
} 
if (spData == NULL) 
{ 
ATLTRACE(_T("QI for ISnapInDataInterface failed\n")); 
return E_UNEXPECTED; 
} 
return spData->ControlbarNotify(m_spControlbar, this, event, arg, param); 
} 
}; 
 
template <class T> 
class ATL_NO_VTABLE ISnapinAboutImpl : public ISnapinAbout 
{ 
public: 
STDMETHOD(GetSnapinDescription)(LPOLESTR *lpDescription) 
{ 
ATLTRACENOTIMPL(_T("ISnapinAboutImpl::GetSnapinDescription\n")); 
return S_OK; 
} 
     
    STDMETHOD(GetProvider)(LPOLESTR *lpName) 
{ 
ATLTRACENOTIMPL(_T("ISnapinAboutImpl::GetProvider\n")); 
return S_OK; 
} 
     
    STDMETHOD(GetSnapinVersion)(LPOLESTR *lpVersion) 
{ 
ATLTRACENOTIMPL(_T("ISnapinAboutImpl::GetSnapinVersion\n")); 
return S_OK; 
} 
     
    STDMETHOD(GetSnapinImage)(HICON *hAppIcon) 
{ 
ATLTRACENOTIMPL(_T("ISnapinAboutImpl::GetSnapinImage\n")); 
return S_OK; 
} 
     
    STDMETHOD(GetStaticFolderImage)(HBITMAP *hSmallImage, 
        HBITMAP *hSmallImageOpen, 
        HBITMAP *hLargeImage, 
        COLORREF *cMask) 
{ 
ATLTRACENOTIMPL(_T("ISnapinAboutImpl::GetStaticFolderImage\n")); 
return S_OK; 
} 
}; 
 
class CSnapInBaseData 
{ 
public: 
static const UINT m_CCF_NODETYPE; 
static const UINT m_CCF_SZNODETYPE; 
static const UINT m_CCF_DISPLAY_NAME; 
static const UINT m_CCF_SNAPIN_CLASSID; 
static const UINT m_CCF_SCOPEDATAITEM; 
static const UINT m_CCF_RESULTDATAITEM; 
CComDynamicUnkArray m_scopeonlyitems; 
CComDynamicUnkArray m_resultonlyitems; 
CComDynamicUnkArray* m_pParentList; 
OLECHAR* m_pszDisplayName; 
 
SCOPEDATAITEM m_scopeDataItem; 
RESULTDATAITEM m_resultDataItem; 
CSnapInBaseData() 
{ 
m_pszDisplayName = NULL; 
 
memset(&m_scopeDataItem, 0, sizeof(SCOPEDATAITEM)); 
 
m_scopeDataItem.mask = SDI_STR | SDI_IMAGE | SDI_OPENIMAGE | SDI_PARAM | SDI_PARENT; 
m_scopeDataItem.displayname = MMC_CALLBACK; 
m_scopeDataItem.nImage = 0; 
m_scopeDataItem.nOpenImage = 1; 
 
memset(&m_resultDataItem, 0, sizeof(RESULTDATAITEM)); 
 
m_resultDataItem.mask = RDI_STR | RDI_IMAGE | RDI_PARAM; 
m_resultDataItem.str = MMC_CALLBACK; 
m_resultDataItem.nImage = 2; 
 
m_pParentList = NULL; 
} 
 
~CSnapInBaseData() 
{ 
delete m_pszDisplayName; 
m_pszDisplayName = NULL; 
for (IUnknown** pp = m_scopeonlyitems.begin(); pp < m_scopeonlyitems.end(); pp++) 
{ 
if (*pp) 
{ 
IUnknown* pUnk = *pp; 
m_scopeonlyitems.Remove((DWORD)*pp); 
pUnk->Release(); 
} 
} 
for (pp = m_resultonlyitems.begin(); pp < m_resultonlyitems.end(); pp++) 
{ 
 
if (*pp) 
{ 
IUnknown* pUnk = *pp; 
m_resultonlyitems.Remove((DWORD)*pp); 
pUnk->Release(); 
} 
} 
} 
 
void InitParentList(CComDynamicUnkArray* pParent) 
{ 
m_pParentList = pParent; 
} 
 
}; 
 
#define SNAPINMENUID(id) \ 
public: \ 
static const UINT GetMenuID() \ 
{ \ 
static const UINT IDMENU = id; \ 
return id; \ 
} 
 
#define BEGIN_SNAPINCOMMAND_MAP(theClass) \ 
typedef theClass _theClass; \ 
HRESULT ProcessCommand(UINT nID, IDataObject* pDataObject) \ 
{  
 
#define PRIMARY_SNAPINCOMMAND_ENTRY(id, func) \ 
if (id == nID) \ 
return func(); 
 
#define PRIMARY_SNAPINCOMMAND_RANGE_ENTRY(id1, id2, func) \ 
if (id1 >= nID && nID <= id2) \ 
return func(nID); 
 
#define EXTENSION_SNAPINCOMMAND_ENTRY(id, func) \ 
if (id == nID) \ 
return func(pDataObject); 
 
#define EXTENSION_SNAPINCOMMAND_RANGE_ENTRY(id1, id2, func) \ 
if (id1 >= nID && nID <= id2) \ 
return func(nID, pDataObject); 
 
#define END_SNAPINCOMMAND_MAP() \ 
return ISnapInDataInterfaceImpl< _theClass >::ProcessCommand(nID, pDataObject); \ 
} 
 
struct CSnapInToolBarData 
{ 
WORD wVersion; 
WORD wWidth; 
WORD wHeight; 
WORD wItemCount; 
//WORD aItems[wItemCount] 
 
WORD* items() 
{ return (WORD*)(this+1); } 
}; 
 
#define RT_TOOLBAR  MAKEINTRESOURCE(241) 
 
struct CSnapInToolbarInfo 
{ 
public: 
TCHAR** m_pStrToolTip; 
TCHAR** m_pStrButtonText; 
UINT* m_pnButtonID; 
UINT m_idToolbar; 
UINT m_nButtonCount; 
IToolbar* m_pToolbar; 
 
~CSnapInToolbarInfo() 
{ 
if (m_pStrToolTip) 
{ 
for (UINT i = 0; i < m_nButtonCount; i++) 
{ 
delete m_pStrToolTip[i]; 
m_pStrToolTip[i] = NULL; 
} 
delete [] m_pStrToolTip; 
m_pStrToolTip = NULL; 
} 
 
if (m_pStrButtonText) 
{ 
for (UINT i = 0; i < m_nButtonCount; i++) 
{ 
delete m_pStrButtonText[i]; 
m_pStrButtonText[i] = NULL; 
} 
 
delete [] m_pStrButtonText; 
m_pStrButtonText = NULL; 
} 
if (m_pnButtonID) 
{ 
delete m_pnButtonID; 
m_pnButtonID = NULL; 
} 
 
m_nButtonCount = 0; 
if (m_pToolbar) 
m_pToolbar->Release(); 
m_pToolbar = NULL; 
} 
}; 
 
#define BEGIN_SNAPINTOOLBARID_MAP(theClass) \ 
public: \ 
static CSnapInToolbarInfo* GetToolbarInfo() \ 
{ \ 
static CSnapInToolbarInfo m_toolbarInfo[] = \ 
{ 
 
#define SNAPINTOOLBARID_ENTRY(id) \ 
{ NULL, NULL, NULL, id, 0, NULL}, 
 
#define END_SNAPINTOOLBARID_MAP() \ 
{ NULL, NULL, NULL, 0, 0, NULL} \ 
}; \ 
return m_toolbarInfo; \ 
} 
 
template <class T> 
class ISnapInDataInterfaceImpl : public ISnapInDataInterface,  
public CSnapInBaseData 
{ 
public: 
    STDMETHOD(Notify)( MMC_NOTIFY_TYPE event, 
        long arg, 
        long param, 
BOOL bComponentData, 
IConsole* pConsole, 
IHeaderCtrl* pHeader, 
IToolbar* pToolbar) 
{ 
ATLTRACE(_T("ISnapInDataInterfaceImpl::Notify")); 
if (event == MMCN_RENAME) 
{ 
T* pT = static_cast<T*>(this); 
OLECHAR* pTemp = new OLECHAR[lstrlen((OLECHAR*)param) + 1]; 
if (pTemp == NULL) 
return S_FALSE; 
lstrcpy(pTemp, (OLECHAR*)param); 
if (!pT->Rename(pTemp)) 
{ 
delete []pTemp; 
return S_FALSE; 
} 
 
delete []m_pszDisplayName; 
m_pszDisplayName = pTemp; 
return S_OK; 
} 
 
if (event == MMCN_ADD_IMAGES) 
{ 
CComPtr<IImageList> spImageList; 
spImageList = (IImageList*)arg; 
 
return S_OK; 
} 
 
if (event == MMCN_SHOW) 
{ 
int n = 0; 
CComQIPtr<IResultData, &IID_IResultData> spResultData(pConsole); 
pHeader->InsertColumn(1, _T("File"),  LVCFMT_LEFT, MMCLV_AUTO); 
return EnumerateResultChildren(spResultData); 
} 
 
if (event == MMCN_EXPAND) 
{ 
CComQIPtr<IConsoleNameSpace, &IID_IConsoleNameSpace> spConsoleNameSpace(pConsole); 
return EnumerateScopeChildren(param, spConsoleNameSpace); 
} 
 
if (event == MMCN_SELECT) 
{ 
CComPtr<IConsoleVerb> spVerb; 
pConsole->QueryConsoleVerb(&spVerb) ; 
 
spVerb->SetVerbState(MMC_VERB_PROPERTIES, ENABLED, TRUE); 
return S_OK; 
} 
 
return E_UNEXPECTED; 
} 
     
    STDMETHOD(GetDispInfo)(SCOPEDATAITEM *pScopeDataItem) 
{ 
ATLTRACE(_T("ISnapInDataInterfaceImpl::GetDispInfo")); 
if (pScopeDataItem->mask & SDI_STR) 
pScopeDataItem->displayname = m_pszDisplayName; 
if (pScopeDataItem->mask & SDI_IMAGE) 
pScopeDataItem->nImage = m_scopeDataItem.nImage; 
if (pScopeDataItem->mask & SDI_OPENIMAGE) 
pScopeDataItem->nOpenImage = m_scopeDataItem.nOpenImage; 
if (pScopeDataItem->mask & SDI_CHILDREN) 
pScopeDataItem->cChildren = m_scopeonlyitems.end() - m_scopeonlyitems.begin(); 
return S_OK; 
 
} 
     
    STDMETHOD(GetResultViewType)(LPOLESTR *ppVIewType, 
        long *pViewOptions) 
{ 
ATLTRACENOTIMPL(_T("ISnapInDataInterfaceImpl::GetResultViewType")); 
} 
     
    STDMETHOD(GetDisplayInfo)(RESULTDATAITEM *pResultDataItem) 
{ 
ATLTRACE(_T("ISnapInDataInterfaceImpl::GetDisplayInfo")); 
T* pT = static_cast<T*> (this); 
 
if (pResultDataItem->bScopeItem) 
{ 
if (pResultDataItem->mask & RDI_STR) 
{ 
pResultDataItem->str = pT->GetResultPaneInfo(pResultDataItem->nCol); 
} 
if (pResultDataItem->mask & RDI_IMAGE) 
{ 
pResultDataItem->nImage = m_scopeDataItem.nImage; 
} 
 
return S_OK; 
} 
if (pResultDataItem->mask & RDI_STR) 
{ 
pResultDataItem->str = pT->GetResultPaneInfo(pResultDataItem->nCol); 
} 
if (pResultDataItem->mask & RDI_IMAGE) 
{ 
pResultDataItem->nImage = m_resultDataItem.nImage; 
} 
return S_OK; 
} 
     
    STDMETHOD(AddMenuItems)(LPCONTEXTMENUCALLBACK piCallback, 
        long *pInsertionAllowed) 
{ 
ATLTRACE(_T("ISnapInDataInterfaceImpl::AddMenuItems")); 
long insertionID; 
T* pT = static_cast<T*> (this); 
UINT menuID = pT->GetMenuID(); 
if (menuID == 0) 
return S_OK; 
HMENU hMenu = LoadMenu(_Module.GetResourceInstance(), MAKEINTRESOURCE(menuID)); 
if (hMenu) 
{ 
for (int i = 0; 1; i++) 
{ 
HMENU hSubMenu = GetSubMenu(hMenu, i); 
if (hSubMenu == NULL) 
break; 
 
MENUITEMINFO menuItemInfo; 
memset(&menuItemInfo, 0, sizeof(menuItemInfo)); 
menuItemInfo.cbSize = sizeof(menuItemInfo); 
 
switch (i) 
{ 
case 0: 
if (! (*pInsertionAllowed & CCM_INSERTIONALLOWED_TOP) ) 
continue; 
insertionID = CCM_INSERTIONPOINTID_PRIMARY_TOP; 
break; 
 
case 1: 
if (! (*pInsertionAllowed & CCM_INSERTIONALLOWED_NEW) ) 
continue; 
insertionID = CCM_INSERTIONPOINTID_PRIMARY_NEW; 
break; 
 
case 2:; 
if (! (*pInsertionAllowed & CCM_INSERTIONALLOWED_TASK) ) 
continue; 
insertionID = CCM_INSERTIONPOINTID_PRIMARY_TASK; 
break; 
case 3:; 
if (! (*pInsertionAllowed & CCM_INSERTIONALLOWED_VIEW) ) 
continue; 
insertionID = CCM_INSERTIONPOINTID_PRIMARY_VIEW; 
break; 
default: 
{ 
insertionID = 0; 
continue; 
// Review 
// Determine what to do here. 
menuItemInfo.fMask = MIIM_TYPE ; 
menuItemInfo.fType = MFT_STRING; 
TCHAR buf[128]; 
menuItemInfo.dwTypeData = buf; 
menuItemInfo.cch = 128; 
if (!GetMenuItemInfo(hMenu, i, TRUE, &menuItemInfo)) 
continue; 
//insertionID = _ttol(buf); 
} 
break; 
} 
 
menuItemInfo.fMask = MIIM_TYPE | MIIM_STATE | MIIM_ID; 
menuItemInfo.fType = MFT_STRING; 
TCHAR buf[128]; 
menuItemInfo.dwTypeData = buf; 
 
for (int j = 0; 1; j++) 
{ 
menuItemInfo.fMask = MIIM_TYPE | MIIM_STATE | MIIM_ID; 
menuItemInfo.fType = MFT_STRING; 
menuItemInfo.cch = 128; 
TCHAR strStatusBar[257]; 
 
if (!GetMenuItemInfo(hSubMenu, j, TRUE, &menuItemInfo)) 
break; 
 
pT->UpdateMenuState(menuItemInfo.wID, buf, &menuItemInfo.fState); 
LoadString(_Module.GetResourceInstance(), menuItemInfo.wID, strStatusBar, 257); 
 
CONTEXTMENUITEM contextMenuItem; 
memset(&contextMenuItem, 0, sizeof(contextMenuItem)); 
contextMenuItem.strName = buf; 
contextMenuItem.strStatusBarText = strStatusBar; 
contextMenuItem.lCommandID = menuItemInfo.wID; 
contextMenuItem.lInsertionPointID = insertionID; 
contextMenuItem.fFlags = menuItemInfo.fState; 
 
piCallback->AddItem(&contextMenuItem); 
} 
} 
DestroyMenu(hMenu); 
} 
 
return S_OK; 
} 
     
    STDMETHOD(Command)(long lCommandID) 
{ 
ATLTRACE(_T("ISnapInDataInterfaceImpl::Command\n")); 
T* pT = static_cast<T*>(this); 
return pT->ProcessCommand(lCommandID, NULL); 
} 
     
    STDMETHOD(CreatePropertyPages)(LPPROPERTYSHEETCALLBACK lpProvider, 
        long handle, IUnknown* pUnk) 
{ 
ATLTRACENOTIMPL(_T("ISnapInDataInterfaceImpl::CreatePropertyPages")); 
} 
     
    STDMETHOD(QueryPagesFor)(void) 
{ 
ATLTRACENOTIMPL(_T("ISnapInDataInterfaceImpl::QueryPagesFor")); 
} 
 
    STDMETHOD(SetControlbar)(IControlbar *pControlbar, IExtendControlbar* pExtendControlBar) 
{ 
ATLTRACE(_T("ISnapInDataInterfaceImpl::SetControlbar\n")); 
T* pT = static_cast<T*>(this); 
 
CSnapInToolbarInfo* pInfo = pT->GetToolbarInfo(); 
if (pInfo == NULL) 
return S_OK; 
 
for( ; pInfo->m_idToolbar; pInfo++) 
{ 
if (pInfo->m_pToolbar) 
continue; 
 
HBITMAP hBitmap = LoadBitmap(_Module.GetResourceInstance(), MAKEINTRESOURCE(pInfo->m_idToolbar)); 
if (hBitmap == NULL) 
return S_OK; 
 
HRSRC hRsrc = ::FindResource(_Module.GetResourceInstance(), MAKEINTRESOURCE(pInfo->m_idToolbar), RT_TOOLBAR); 
if (hRsrc == NULL) 
return S_OK; 
 
HGLOBAL hGlobal = LoadResource(_Module.GetResourceInstance(), hRsrc); 
if (hGlobal == NULL) 
return S_OK; 
 
CSnapInToolBarData* pData = (CSnapInToolBarData*)LockResource(hGlobal); 
if (pData == NULL) 
return S_OK; 
_ASSERTE(pData->wVersion == 1); 
 
pInfo->m_nButtonCount = pData->wItemCount; 
pInfo->m_pnButtonID = new UINT[pInfo->m_nButtonCount]; 
MMCBUTTON *pButtons = new MMCBUTTON[pData->wItemCount]; 
 
pInfo->m_pStrToolTip = new TCHAR* [pData->wItemCount]; 
if (pInfo->m_pStrToolTip == NULL) 
continue; 
 
for (int i = 0, j = 0; i < pData->wItemCount; i++) 
{ 
pInfo->m_pStrToolTip[i] = NULL; 
memset(&pButtons[i], 0, sizeof(MMCBUTTON)); 
pInfo->m_pnButtonID[i] = pButtons[i].idCommand = pData->items()[i]; 
if (pButtons[i].idCommand) 
{ 
pButtons[i].nBitmap = j++; 
// get the statusbar string and allow modification of the button state 
TCHAR strStatusBar[512]; 
LoadString(_Module.GetResourceInstance(), pButtons[i].idCommand, strStatusBar, 512); 
 
pInfo->m_pStrToolTip[i] = new TCHAR[lstrlen(strStatusBar) + 1]; 
if (pInfo->m_pStrToolTip[i] == NULL) 
continue; 
lstrcpy(pInfo->m_pStrToolTip[i], strStatusBar); 
pButtons[i].lpTooltipText = pInfo->m_pStrToolTip[i]; 
pButtons[i].lpButtonText = _T(""); 
pT->SetToolbarButtonInfo(pButtons[i].idCommand, &pButtons[i].fsState, &pButtons[i].fsType); 
} 
else 
{ 
pButtons[i].lpTooltipText = _T(""); 
pButtons[i].lpButtonText = _T(""); 
pButtons[i].fsType = TBSTYLE_SEP; 
} 
} 
 
        HRESULT hr = pControlbar->Create(TOOLBAR, pExtendControlBar, reinterpret_cast<LPUNKNOWN*>(&pInfo->m_pToolbar)); 
if (FAILED(hr)) 
continue; 
 
hr = pInfo->m_pToolbar->AddBitmap(pData->wItemCount, hBitmap, pData->wWidth, pData->wHeight, RGB(192, 192, 192)); 
if (FAILED(hr)) 
{ 
pInfo->m_pToolbar->Release(); 
pInfo->m_pToolbar = NULL; 
continue; 
} 
 
hr = pInfo->m_pToolbar->AddButtons(pData->wItemCount, pButtons); 
if (FAILED(hr)) 
{ 
pInfo->m_pToolbar->Release(); 
pInfo->m_pToolbar = NULL; 
} 
 
delete [] pButtons; 
} 
return S_OK; 
} 
     
    STDMETHOD(ControlbarNotify)(IControlbar *pControlbar, 
        IExtendControlbar *pExtendControlbar, 
MMC_NOTIFY_TYPE event, 
        long arg, long param) 
{ 
ATLTRACE(_T("ISnapInDataInterfaceImpl::ControlbarNotify\n")); 
T* pT = static_cast<T*>(this); 
CComQIPtr<IDataObject, &IID_IDataObject> spData(this); 
 
SetControlbar(pControlbar, pExtendControlbar); 
 
if(event == MMCN_SELECT) 
{ 
BOOL bScope = (BOOL) LOWORD(arg); 
BOOL bSelect = (BOOL) HIWORD (arg); 
 
if (!bScope) 
{ 
CSnapInToolbarInfo* pInfo = pT->GetToolbarInfo(); 
if (pInfo == NULL) 
return S_OK; 
 
if (!bSelect) 
return S_OK; 
 
for(; pInfo->m_idToolbar; pInfo++) 
{ 
for (UINT i = 0; i < pInfo->m_nButtonCount; i++) 
{ 
if (pInfo->m_pnButtonID[i]) 
{ 
for (int j = ENABLED; j <= BUTTONPRESSED; j++) 
{ 
pInfo->m_pToolbar->SetButtonState(pInfo->m_pnButtonID[i],  
(MMC_BUTTON_STATE)j, 
pT->UpdateToolbarButton(pInfo->m_pnButtonID[i], (MMC_BUTTON_STATE)j)); 
} 
} 
} 
} 
} 
else 
{ 
LPDATAOBJECT* pData = (LPDATAOBJECT*) param; 
if (pData[0] == pData[1]) 
return S_OK; 
if (spData == pData[0]) 
{ 
CSnapInToolbarInfo* pInfo = pT->GetToolbarInfo(); 
if (pInfo == NULL) 
return S_OK; 
 
for(; pInfo->m_idToolbar; pInfo++) 
{ 
pControlbar->Detach(pInfo->m_pToolbar); 
} 
return S_OK; 
} 
 
CSnapInToolbarInfo* pInfo = pT->GetToolbarInfo(); 
if (pInfo == NULL) 
return S_OK; 
 
for(; pInfo->m_idToolbar; pInfo++) 
{ 
pControlbar->Attach(TOOLBAR, pInfo->m_pToolbar); 
for (UINT i = 0; i < pInfo->m_nButtonCount; i++) 
{ 
if (pInfo->m_pnButtonID[i]) 
{ 
for (int j = ENABLED; j <= BUTTONPRESSED; j++) 
{ 
pInfo->m_pToolbar->SetButtonState(pInfo->m_pnButtonID[i],  
(MMC_BUTTON_STATE)j, 
pT->UpdateToolbarButton(pInfo->m_pnButtonID[i], (MMC_BUTTON_STATE)j)); 
} 
} 
} 
} 
return S_OK; 
} 
} 
return pT->ProcessCommand((UINT) param, NULL); 
} 
 
STDMETHOD(GetScopeData)(SCOPEDATAITEM **pScopeDataItem) 
{ 
if (pScopeDataItem == NULL) 
return E_FAIL; 
 
*pScopeDataItem = &m_scopeDataItem; 
return S_OK; 
} 
         
    STDMETHOD(GetResultData)(RESULTDATAITEM **pResultDataItem) 
{ 
if (pResultDataItem == NULL) 
return E_FAIL; 
 
*pResultDataItem = &m_resultDataItem; 
return S_OK; 
} 
 
void UpdateMenuState(UINT id, LPTSTR pBuf, UINT *flags) 
{ 
return; 
} 
 
void SetToolbarButtonInfo(UINT id, BYTE *fsState, BYTE *fsType) 
{ 
*fsState = TBSTATE_ENABLED; 
*fsType = TBSTYLE_BUTTON; 
} 
 
BOOL UpdateToolbarButton(UINT id, BYTE fsState) 
{ 
if (fsState == ENABLED) 
return TRUE; 
return FALSE; 
} 
 
HRESULT ProcessCommand(UINT nID, IDataObject* pDataObject) 
{ 
ATLTRACE(_T("No handler for item with ID %d\n"), nID); 
return S_OK; 
} 
 
HRESULT FillData(CLIPFORMAT cf, LPSTREAM pStream) 
{ 
HRESULT hr = DV_E_CLIPFORMAT; 
ULONG uWritten; 
 
T* pT = static_cast<T*> (this); 
 
if (cf == m_CCF_NODETYPE) 
{ 
hr = pStream->Write(pT->GetNodeType(), sizeof(GUID), &uWritten); 
return hr; 
} 
 
if (cf == m_CCF_SZNODETYPE) 
{ 
hr = pStream->Write(pT->GetSZNodeType(), (lstrlen((LPCTSTR)pT->GetSZNodeType()) + 1 )* sizeof(TCHAR), &uWritten); 
return hr; 
} 
 
if (cf == m_CCF_DISPLAY_NAME) 
{ 
hr = pStream->Write(pT->GetDisplayName(), (lstrlen((LPCTSTR)pT->GetDisplayName()) + 1) * sizeof(TCHAR), &uWritten); 
return hr; 
} 
 
if (cf == m_CCF_SNAPIN_CLASSID) 
{ 
hr = pStream->Write(pT->GetSnapInCLSID(), sizeof(CLSID), &uWritten); 
return hr; 
} 
 
if (cf == m_CCF_SCOPEDATAITEM) 
{ 
hr = pStream->Write(&m_scopeDataItem, sizeof(SCOPEDATAITEM), &uWritten); 
return hr; 
} 
 
if (cf == m_CCF_RESULTDATAITEM) 
{ 
hr = pStream->Write(&m_resultDataItem, sizeof(RESULTDATAITEM), &uWritten); 
return hr; 
} 
 
return hr; 
} 
OLECHAR* GetResultPaneInfo(int nCol) 
{ 
if (nCol == 0 && m_pszDisplayName) 
return m_pszDisplayName; 
 
return L"Override GetResultPaneInfo in your derived class"; 
} 
 
void PopulateChildren() 
{ 
return; 
} 
 
void AddScopeItem(IUnknown* p) 
{ 
m_scopeonlyitems.Add(p); 
} 
 
void AddResultItem(IUnknown* p) 
{ 
m_resultonlyitems.Add(p); 
} 
 
void RemoveScopeItem(IUnknown* p) 
{ 
m_scopeonlyitems.Remove((DWORD)p); 
} 
 
void RemoveResultItem(IUnknown* p) 
{ 
m_resultonlyitems.Remove((DWORD)p); 
} 
 
HRESULT EnumerateScopeChildren(long param, IConsoleNameSpace* pNameSpace) 
{ 
T* pT = static_cast<T*>(this); 
 
pT->PopulateChildren(); 
 
for (IUnknown** pp = m_scopeonlyitems.begin(); pp < m_scopeonlyitems.end(); pp++) 
{ 
if (*pp == NULL) 
continue; 
 
CComQIPtr<ISnapInDataInterface, &IID_ISnapInDataInterface> pData(*pp); 
if (pData == NULL) 
continue; 
 
SCOPEDATAITEM* pscopeData; 
pData->GetScopeData(&pscopeData); 
 
if (pscopeData == NULL) 
continue; 
 
pscopeData->relativeID = param; 
HRESULT hr = pNameSpace->InsertItem(pscopeData); 
if (FAILED(hr)) 
return hr; 
} 
 
return S_OK; 
} 
 
HRESULT EnumerateResultChildren(IResultData* pResultData) 
{ 
T* pT = static_cast<T*>(this); 
 
pT->PopulateChildren(); 
 
for (IUnknown** pp = m_resultonlyitems.begin(); pp < m_resultonlyitems.end(); pp++) 
{ 
if (*pp == NULL) 
continue; 
 
CComQIPtr<ISnapInDataInterface, &IID_ISnapInDataInterface> pData(*pp); 
if (pData == NULL) 
continue; 
 
RESULTDATAITEM* pResultDataItem; 
pData->GetResultData(&pResultDataItem); 
 
if (pResultDataItem == NULL) 
continue; 
 
HRESULT hr = pResultData->InsertItem(pResultDataItem); 
if (FAILED(hr)) 
return hr; 
} 
 
return S_OK; 
} 
 
static CSnapInToolbarInfo* GetToolbarInfo() 
{ 
return NULL; 
} 
 
static const UINT GetMenuID()  
{ 
return 0; 
} 
 
ISnapInDataInterfaceImpl() 
{ 
} 
 
BOOL Rename(OLECHAR* pNewName) 
{ 
return TRUE; 
} 
         
}; 
 
 
#endif //__ATL_SNAPIN_H__