#ifndef INCLUDE_SNPDATA_H #define INCLUDE_SNPDATA_H #include "snapdata.h" // interface definition for IWirelessSnapInDataObject // forward declaration for spolitem stuff class CSecPolItem; typedef CComObject* LPCSECPOLITEM; /////////////////////////////////////////////////////////////////////////////// // Macros to be used for adding toolbars to CSnapObject derived objects. // See CSnapObject class definition for example. #define BEGIN_SNAPINTOOLBARID_MAP(theClass) \ public: \ STDMETHOD_(CSnapInToolbarInfo*, GetToolbarInfo)(void) \ { \ if (NULL == m_aToolbarInfo) \ { \ CSnapInToolbarInfo m_tbInfo_##theClass[] = \ { #define SNAPINTOOLBARID_ENTRY(id) \ { NULL, NULL, NULL, id, 0, NULL }, #define END_SNAPINTOOLBARID_MAP(theClass) \ { NULL, NULL, NULL, 0, 0, NULL } \ }; \ int nElemCount = sizeof(m_tbInfo_##theClass)/sizeof(CSnapInToolbarInfo); \ if (nElemCount > 1) \ { \ m_aToolbarInfo = new CSnapInToolbarInfo[nElemCount]; \ if (NULL != m_aToolbarInfo) \ { \ CopyMemory( m_aToolbarInfo, m_tbInfo_##theClass, sizeof( CSnapInToolbarInfo ) * nElemCount ); \ } \ } \ else { \ ASSERT( 1 == nElemCount ); /* the NULL entry marking end-of-array */ \ ASSERT( 0 == m_tbInfo_##theClass[0].m_idToolbar ); \ } \ } \ return m_aToolbarInfo; \ } /////////////////////////////////////////////////////////////////////////////// // struct CSnapInToolbarInfo - Used to add a toolbar to MMC for a result/scope item. struct CSnapInToolbarInfo { public: TCHAR** m_pStrToolTip; // array of tooltip strings TCHAR** m_pStrButtonText; // NOT USED (array of button text strings) UINT* m_pnButtonID; // array of button IDs UINT m_idToolbar; // id of toolbar UINT m_nButtonCount; // # of buttons on toolbar IToolbar* m_pToolbar; // Interface ptr ~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; } }; /////////////////////////////////////////////////////////////////////////////// struct CSnapInToolBarData { WORD wVersion; WORD wWidth; WORD wHeight; WORD wItemCount; //WORD aItems[wItemCount] WORD* items() { return (WORD*)(this+1); } }; #define RT_TOOLBAR MAKEINTRESOURCE(241) /////////////////////////////////////////////////////////////////////////////// // class CWirelessSnapInDataObjectImpl - Implementation of private COM interface template class CWirelessSnapInDataObjectImpl : public IWirelessSnapInDataObject { public: CWirelessSnapInDataObjectImpl() : m_DataObjType( CCT_UNINITIALIZED ), m_aToolbarInfo( NULL ), m_bEnablePropertyChangeHook( FALSE ) { OPT_TRACE(_T("CWirelessSnapInDataObjectImpl::CWirelessSnapInDataObjectImpl this-%p\n"), this); } virtual ~CWirelessSnapInDataObjectImpl() { OPT_TRACE(_T("CWirelessSnapInDataObjectImpl::~CWirelessSnapInDataObjectImpl this-%p\n"), this); // Clean up array of toolbar info if (NULL != m_aToolbarInfo) { delete [] m_aToolbarInfo; m_aToolbarInfo = NULL; } } /////////////////////////////////////////////////////////////////////////// // Interface to handle IExtendContextMenu STDMETHOD(AddMenuItems)( LPCONTEXTMENUCALLBACK piCallback, long *pInsertionAllowed ) { OPT_TRACE(_T("CWirelessSnapInDataObjectImpl::AddMenuItems NOT implemented, this-%p\n"), this); return E_NOTIMPL; } STDMETHOD(Command)( long lCommandID, IConsoleNameSpace *pNameSpace ) { OPT_TRACE(_T("CWirelessSnapInDataObjectImpl::Command NOT implemented, this-%p\n"), this); return E_NOTIMPL; } /////////////////////////////////////////////////////////////////////////// // IExtendContextMenu helpers // Non-interface members intended to be overridden by instantiated class. STDMETHOD(AdjustVerbState)(LPCONSOLEVERB pConsoleVerb) { OPT_TRACE(_T("CWirelessSnapInDataObjectImpl::AdjustVerbState this-%p\n"), this); HRESULT hr = pConsoleVerb->SetVerbState(MMC_VERB_REFRESH, ENABLED, FALSE); ASSERT (hr == S_OK); hr = pConsoleVerb->SetVerbState(MMC_VERB_REFRESH, HIDDEN, TRUE); ASSERT (hr == S_OK); return hr; } /////////////////////////////////////////////////////////////////////////// // Interface to handle IExtendPropertySheet STDMETHOD(CreatePropertyPages)( LPPROPERTYSHEETCALLBACK lpProvider, LONG_PTR handle ) { OPT_TRACE(_T("CWirelessSnapInDataObjectImpl::CreatePropertyPages this-%p\n"), this); return S_OK; // no prop pages added by default } STDMETHOD(QueryPagesFor)( void ) { OPT_TRACE(_T("CWirelessSnapInDataObjectImpl::QueryPagesFor NOT implemented this-%p\n"), this); return E_NOTIMPL; } /////////////////////////////////////////////////////////////////////////// // Interface to handle IExtendControlbar STDMETHOD(ControlbarNotify)( IControlbar *pControlbar, IExtendControlbar *pExtendControlbar, MMC_NOTIFY_TYPE event, LPARAM arg, LPARAM param ) { OPT_TRACE(_T("CWirelessSnapInDataObjectImpl::ControlbarNotify this-%p\n"), this); AFX_MANAGE_STATE(AfxGetStaticModuleState()); T* pThis = (T*)this; HRESULT hr; // Load object's toolbar (if any) and associated baggage. pThis->SetControlbar(pControlbar, pExtendControlbar); if(MMCN_SELECT == event) { BOOL bScope = (BOOL) LOWORD(arg); BOOL bSelect = (BOOL) HIWORD (arg); // A scope item has been selected CSnapInToolbarInfo* pInfo = pThis->GetToolbarInfo(); if (pInfo == NULL) return S_OK; // Attach toolbar to console, and set button states with UpdateToolbarButton() for(; pInfo->m_idToolbar; pInfo++) { // When a result item has been deselected, remove its toolbar. // Otherwise add the object's toolbar. Note: the scope item's // toolbar is always displayed as long as we're in its "scope", // thats why we Detach() for a result item only. if (!bScope && !bSelect) { hr = pControlbar->Detach(pInfo->m_pToolbar); ASSERT (hr == S_OK); } else { hr = pControlbar->Attach(TOOLBAR, pInfo->m_pToolbar); ASSERT (hr == S_OK); } for (UINT i = 0; i < pInfo->m_nButtonCount; i++) { if (pInfo->m_pnButtonID[i]) { // set the button state properly for each valid state pInfo->m_pToolbar->SetButtonState( pInfo->m_pnButtonID[i], ENABLED, UpdateToolbarButton( pInfo->m_pnButtonID[i], bSelect, ENABLED )); pInfo->m_pToolbar->SetButtonState( pInfo->m_pnButtonID[i], CHECKED, UpdateToolbarButton( pInfo->m_pnButtonID[i], bSelect, CHECKED )); pInfo->m_pToolbar->SetButtonState( pInfo->m_pnButtonID[i], HIDDEN, UpdateToolbarButton( pInfo->m_pnButtonID[i], bSelect, HIDDEN )); pInfo->m_pToolbar->SetButtonState( pInfo->m_pnButtonID[i], INDETERMINATE, UpdateToolbarButton( pInfo->m_pnButtonID[i], bSelect, INDETERMINATE )); pInfo->m_pToolbar->SetButtonState( pInfo->m_pnButtonID[i], BUTTONPRESSED, UpdateToolbarButton( pInfo->m_pnButtonID[i], bSelect, BUTTONPRESSED )); } } } return S_OK; } // This is supposed to be the only other event IExtendControlbar receives. ASSERT( MMCN_BTN_CLICK == event ); return pThis->Command( (UINT)param, NULL ); } STDMETHOD(SetControlbar)( IControlbar *pControlbar, IExtendControlbar *pExtendControlbar ) { OPT_TRACE(_T("CWirelessSnapInDataObjectImpl::SetControlbar this-%p\n"), this); AFX_MANAGE_STATE(AfxGetStaticModuleState()); T* pThis = (T*)this; CSnapInToolbarInfo* pInfo = pThis->GetToolbarInfo(); if (pInfo == NULL) return S_OK; for( ; pInfo->m_idToolbar; pInfo++) { if (pInfo->m_pToolbar) continue; HBITMAP hBitmap = LoadBitmap( AfxGetInstanceHandle(), MAKEINTRESOURCE(pInfo->m_idToolbar) ); if (hBitmap == NULL) return S_OK; HRSRC hRsrc = ::FindResource( AfxGetInstanceHandle(), MAKEINTRESOURCE(pInfo->m_idToolbar), RT_TOOLBAR ); if (hRsrc == NULL) return S_OK; HGLOBAL hGlobal = LoadResource( AfxGetInstanceHandle(), hRsrc ); if (hGlobal == NULL) return S_OK; CSnapInToolBarData* pData = (CSnapInToolBarData*)LockResource( hGlobal ); if (pData == NULL) return S_OK; ASSERT( 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( AfxGetInstanceHandle(), 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(""); pThis->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(&pInfo->m_pToolbar) ); if (hr != S_OK) continue; // pData->wHeight is 15, but AddBitmap insists on 16, hard code it. hr = pInfo->m_pToolbar->AddBitmap( pData->wItemCount, hBitmap, pData->wWidth, 16, RGB(192, 192, 192) ); if (hr != S_OK) { pInfo->m_pToolbar->Release(); pInfo->m_pToolbar = NULL; continue; } hr = pInfo->m_pToolbar->AddButtons( pData->wItemCount, pButtons ); if (hr != S_OK) { pInfo->m_pToolbar->Release(); pInfo->m_pToolbar = NULL; } delete [] pButtons; } return S_OK; } /////////////////////////////////////////////////////////////////////////// // IExtendControlbar helpers // Non-interface members intended to be overridden by instantiated class. STDMETHOD_(void, SetToolbarButtonInfo)( UINT id, // button ID BYTE *fsState, // return button state here BYTE *fsType ) // return button type here { *fsState = TBSTATE_ENABLED; *fsType = TBSTYLE_BUTTON; } STDMETHOD_(BOOL, UpdateToolbarButton)( UINT id, // button ID BOOL bSnapObjSelected, // ==TRUE when result/scope item is selected BYTE fsState ) // enable/disable this button state by returning TRUE/FALSE { return FALSE; } BEGIN_SNAPINTOOLBARID_MAP(CWirelessSnapInDataObjectImpl) // Add a line like the following one for each toolbar to be displayed // for the derived class. Since there is no toolbar by default we'll // leave the macro out completely. //SNAPINTOOLBARID_ENTRY(your_toolbar_resource_id_goes_here, NULL) END_SNAPINTOOLBARID_MAP(CWirelessSnapInDataObjectImpl) /////////////////////////////////////////////////////////////////////////// // Interface to handle IComponent and IComponentData STDMETHOD(Notify)( MMC_NOTIFY_TYPE event, LPARAM arg, LPARAM param, BOOL bComponentData, IConsole *pConsole, IHeaderCtrl *pHeader ) { OPT_TRACE(_T("CWirelessSnapInDataObjectImpl::Notify NOT implemented this-%p\n"), this); return E_NOTIMPL; } /////////////////////////////////////////////////////////////////////////// // IComponent and IComponentData Notify() helpers // Non-interface members intended to be overridden by instantiated class. STDMETHOD(OnDelete)( LPARAM arg, LPARAM param ) { return S_OK; } STDMETHOD(OnRename)( LPARAM arg, LPARAM param ) { return S_OK; } STDMETHOD(OnPropertyChange)( LPARAM lParam, LPCONSOLE pConsole ) { T* pThis = (T*)this; // we changed, so update the views // NOTE: after we do this we are essentially invalid, so make sure we don't // touch any members etc on the way back out return pConsole->UpdateAllViews( pThis, 0, 0 ); // we don't have a failure case } STDMETHOD(EnumerateResults)(LPRESULTDATA pResult, int nSortColumn, DWORD dwSortOrder ) { ASSERT (0); // set the sort parameters pResult->Sort( nSortColumn, dwSortOrder, 0 ); return S_OK; //hr; } /////////////////////////////////////////////////////////////////////////// // Interface to handle IComponent STDMETHOD(GetResultDisplayInfo)( RESULTDATAITEM *pResultDataItem ) { OPT_TRACE(_T("CWirelessSnapInDataObjectImpl::GetResultDisplayInfo NOT implmented, this-%p\n"), this); return E_NOTIMPL; } /////////////////////////////////////////////////////////////////////////// // Interface to handle IComponentData STDMETHOD(GetScopeDisplayInfo)( SCOPEDATAITEM *pScopeDataItem ) { OPT_TRACE(_T("CWirelessSnapInDataObjectImpl::GetScopeDisplayInfo NOT implemented, this-%p\n"), this); return E_NOTIMPL; } /////////////////////////////////////////////////////////////////////////// // Non-interface functions intended to be overridden by instantiated class STDMETHOD(DoPropertyChangeHook)( void ) { return S_OK; } /////////////////////////////////////////////////////////////////////////// // Other IIWirelessSnapInData interface functions STDMETHOD(GetScopeData)( SCOPEDATAITEM **ppScopeDataItem ) { OPT_TRACE(_T("CWirelessSnapInDataObjectImpl::GetScopeData NOT implemented, this-%p\n"), this); return E_NOTIMPL; } STDMETHOD(GetResultData)( RESULTDATAITEM **ppResultDataItem ) { OPT_TRACE(_T("CWirelessSnapInDataObjectImpl::GetResultData NOT implemented, this-%p\n"), this); return E_NOTIMPL; } STDMETHOD(GetGuidForCompare)( GUID *pGuid ) { OPT_TRACE(_T("CWirelessSnapInDataObjectImpl::GetGuidForCompare NOT implemented, this-%p\n"), this); return E_NOTIMPL; } STDMETHOD(GetDataObjectType)( DATA_OBJECT_TYPES *ptype ) { ASSERT( NULL != ptype ); if (NULL == ptype) return E_INVALIDARG; *ptype = m_DataObjType; return S_OK; } STDMETHOD(SetDataObjectType)( DATA_OBJECT_TYPES type ) { m_DataObjType = type; return S_OK; } STDMETHOD(EnablePropertyChangeHook)( BOOL bEnable ) { m_bEnablePropertyChangeHook = bEnable; return S_OK; } BOOL IsPropertyChangeHookEnabled() { return m_bEnablePropertyChangeHook; } protected: DATA_OBJECT_TYPES m_DataObjType; CSnapInToolbarInfo *m_aToolbarInfo; // IExtendControlbar impl CString m_strName; // Policy's name, stored on rename, used in GetResultDisplayInfo? BOOL m_bEnablePropertyChangeHook; // if TRUE, call DoPropertyChangeHook on MMCN_PROPERTY_CHANGE }; #endif //#ifndef INCLUDE_SNPDATA_H