#pragma once #include "vs_haskell_dlg.h" ///////////////////////////////////////////////////////////////////////////// // CSettingsPropertyPage extern LPCWSTR g_pszCmdLine; template class ATL_NO_VTABLE CSettingsPropertyPage : public IPropertyPageImpl, public CDialogImpl, public CComObjectRoot, public CComCoClass { public: CSettingsPropertyPage() { m_dwTitleID = dwTitleID; m_dwHelpFileID = NULL; m_bActive = FALSE; m_nLastObjects = 0; m_ppUnkArray = NULL; m_pServiceProvider = NULL; } ~CSettingsPropertyPage() { ReleaseObjects(); } protected: void ReleaseObjects() { if(m_ppUnkArray == NULL) return; for (UINT i = 0; i < m_nLastObjects; i++) { if (m_ppUnkArray[i]) m_ppUnkArray[i]->Release(); } delete [] m_ppUnkArray; m_ppUnkArray = NULL; m_nLastObjects = 0; m_pServiceProvider = NULL; } public: enum {IDD = IDD_SETTINGSPAGE}; DECLARE_PROTECT_FINAL_CONSTRUCT() BEGIN_COM_MAP(CSettingsPropertyPage) COM_INTERFACE_ENTRY(IPropertyPage) END_COM_MAP() BEGIN_MSG_MAP(CSettingsPropertyPage) CHAIN_MSG_MAP(IPropertyPageImpl) END_MSG_MAP() static HRESULT WINAPI UpdateRegistry(BOOL bRegister) { CComBSTR cbstrCLSID(TpCLSID); if (!cbstrCLSID) return E_OUTOFMEMORY; CComBSTR cbstrVSTUDIO_VERSION(g_pszCmdLine); _ATL_REGMAP_ENTRY rgMap[] = { {L"CLSID", cbstrCLSID}, {L"VSTUDIO_VERSION", cbstrVSTUDIO_VERSION}, {NULL, NULL} }; return ATL::_pAtlModule->UpdateRegistryFromResource(IDR_REGISTERCLASS, bRegister, rgMap); }; public: STDMETHODIMP Activate(HWND hWndParent, LPCRECT pRect, BOOL /* bModal */) { ATLTRACE2(atlTraceControls,2,_T("IPropertyPageImpl::Activate\n")); if (pRect == NULL) { ATLTRACE2(atlTraceControls,2,_T("Error : Passed a NULL rect\n")); return E_POINTER; } m_hWnd = Create(hWndParent); if (!m_hWnd) return E_FAIL; if (!m_nObjects) return S_OK; m_size.cx = pRect->right - pRect->left; m_size.cy = pRect->bottom - pRect->top; HRESULT hr = S_OK; if (m_pGrid == NULL) { CComPtr srpIVSMDPropertyBrowser; hr = m_pServiceProvider->QueryService( SID_SVSMDPropertyBrowser, __uuidof(IVSMDPropertyBrowser), (void**)&srpIVSMDPropertyBrowser); if (FAILED(hr)) return hr; if (!srpIVSMDPropertyBrowser) return E_UNEXPECTED; hr = srpIVSMDPropertyBrowser->CreatePropertyGrid(&m_pGrid); if (FAILED(hr)) return hr; if (!m_pGrid) return E_UNEXPECTED; } m_bActive = TRUE; if (hr == S_OK) { HWND hwndGrid; RECT rectGrid; hr = m_pGrid->get_Handle(&hwndGrid); if (FAILED(hr)) return hr; if (!::GetClientRect(m_hWnd, &rectGrid)) return HRESULT_FROM_WIN32(GetLastError()); if (!::SetParent(hwndGrid, m_hWnd)) return HRESULT_FROM_WIN32(GetLastError()); if (!::SetWindowPos(hwndGrid, HWND_TOP, rectGrid.left, rectGrid.top, rectGrid.right - rectGrid.left, rectGrid.bottom - rectGrid.top, SWP_FRAMECHANGED)) return HRESULT_FROM_WIN32(GetLastError()); VARIANT vt; VariantInit(&vt); V_VT(&vt) = VT_BOOL; V_BOOL(&vt) = VARIANT_FALSE; hr = m_pGrid->SetOption(PGOPT_TOOLBAR, vt); if (FAILED(hr)) return hr; // Set the sort order of props. you could want PGSORT_CATEGORIZED instead. hr = m_pGrid->put_GridSort(PGSORT_NOSORT); if (FAILED(hr)) return hr; return UpdateObjects(); } return S_OK; } STDMETHODIMP Deactivate() { HRESULT hr; ReleaseObjects(); hr = IPropertyPageImpl::Deactivate(); m_bActive = FALSE; return hr; } STDMETHODIMP SetObjects(ULONG nObjects, IUnknown **ppUnk) { HRESULT hr; IObjectWithSite *pObject; if (!nObjects) return E_UNEXPECTED; hr = (*ppUnk)->QueryInterface(IID_IObjectWithSite, (void **) &pObject); if (FAILED(hr)) return hr; hr = pObject->GetSite(IID_IServiceProvider, (void**) &m_pServiceProvider); pObject->Release(); if (FAILED(hr)) return hr; if (!m_pServiceProvider) return E_UNEXPECTED; // call base-class implementation hr = IPropertyPageImpl::SetObjects(nObjects, ppUnk); if (FAILED(hr)) return hr; // update the objects if we have ever been activated. if (m_bActive) hr = UpdateObjects(); return hr; } STDMETHODIMP Apply() { if (!m_ppUnkArray) return E_UNEXPECTED; for (UINT i = 0; i < m_nObjects; i++) { if (m_ppUnkArray[i]) { CComQIPtr pContainer = m_ppUnkArray[i]; if (pContainer != NULL) { HRESULT hr = pContainer->Commit(); if (FAILED(hr)) return hr; } } } SetDirty(FALSE); if (m_pGrid) m_pGrid->Refresh(); return S_OK; } STDMETHODIMP Help(LPCOLESTR pszHelpDir) { return E_NOTIMPL; } STDMETHODIMP TranslateAccelerator(MSG *pMsg) { if (!pMsg) return E_UNEXPECTED; if ((pMsg->message < WM_KEYFIRST || pMsg->message > WM_KEYLAST) && (pMsg->message < WM_MOUSEFIRST || pMsg->message > WM_MOUSELAST)) return S_FALSE; return (::IsDialogMessage(m_hWnd, pMsg)) ? S_OK : S_FALSE; } protected: HRESULT UpdateObjects() { // Get Rid of the old list ReleaseObjects(); // Make a new list m_ppUnkArray = new IUnknown*[ m_nObjects ]; if (!m_ppUnkArray) return E_OUTOFMEMORY; memset(m_ppUnkArray, 0, sizeof(IUnknown*) * m_nObjects); m_nLastObjects = m_nObjects; for (UINT i = 0; i < m_nObjects; i++) { HRESULT hr = T::CreateInstance(this, m_ppUnk[i], &m_ppUnkArray[i]); if (FAILED(hr)) return hr; } if (m_pGrid) { HRESULT hr = m_pGrid->SetSelectedObjects(m_nObjects, m_ppUnkArray); if (FAILED(hr)) return hr; hr = m_pGrid->Refresh(); if (FAILED(hr)) return hr; } return S_OK; } protected: BOOL m_bActive; UINT m_nLastObjects; IUnknown ** m_ppUnkArray; // array of pointers to the PropertyPageObject CComPtr m_pGrid; IServiceProvider *m_pServiceProvider; };