///////////////////////////////////////////////////////////////////////////// // // Copyright (c) 1996-1997 Microsoft Corporation // // Module Name: // BasePage.cpp // // Abstract: // Implementation of the CBasePropertyPage class. // // Author: // David Potter (davidp) June 28, 1996 // // Revision History: // // Notes: // ///////////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "IISClEx4.h" #include "ExtObj.h" #include "BasePage.h" #include "BasePage.inl" #include "PropList.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CBasePropertyPage property page ///////////////////////////////////////////////////////////////////////////// IMPLEMENT_DYNCREATE(CBasePropertyPage, CPropertyPage) ///////////////////////////////////////////////////////////////////////////// // Message Maps BEGIN_MESSAGE_MAP(CBasePropertyPage, CPropertyPage) //{{AFX_MSG_MAP(CBasePropertyPage) ON_WM_CREATE() ON_WM_DESTROY() ON_WM_HELPINFO() ON_WM_CONTEXTMENU() ON_MESSAGE(WM_COMMANDHELP, OnCommandHelp) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// //++ // // CBasePropertyPage::CBasePropertyPage // // Routine Description: // Default constructor. // // Arguments: // None. // // Return Value: // None. // //-- ///////////////////////////////////////////////////////////////////////////// CBasePropertyPage::CBasePropertyPage(void) { CommonConstruct(); } //*** CBasePropertyPage::CBasePropertyPage() ///////////////////////////////////////////////////////////////////////////// //++ // // CBasePropertyPage::CBasePropertyPage // // Routine Description: // Default constructor. // // Arguments: // pmap [IN] Control to help ID map. // // Return Value: // None. // //-- ///////////////////////////////////////////////////////////////////////////// CBasePropertyPage::CBasePropertyPage( IN const CMapCtrlToHelpID * pmap ) : m_dlghelp(pmap, 0) { CommonConstruct(); } //*** CBasePropertyPage::CBasePropertyPage() ///////////////////////////////////////////////////////////////////////////// //++ // // CBasePropertyPage::CBasePropertyPage // // Routine Description: // Default constructor. // // Arguments: // pmap [IN] Control to help ID map. // nIDTemplate [IN] Dialog template resource ID. // nIDCaption [IN] Caption string resource ID. // // Return Value: // None. // //-- ///////////////////////////////////////////////////////////////////////////// CBasePropertyPage::CBasePropertyPage( IN const CMapCtrlToHelpID * pmap, IN UINT nIDTemplate, IN UINT nIDCaption ) : CPropertyPage(nIDTemplate, nIDCaption) , m_dlghelp(pmap, nIDTemplate) { CommonConstruct(); } //*** CBasePropertyPage::CBasePropertyPage(UINT, UINT) ///////////////////////////////////////////////////////////////////////////// //++ // // CBasePropertyPage::CommonConstruct // // Routine Description: // Common construction. // // Arguments: // None. // // Return Value: // None. // //-- ///////////////////////////////////////////////////////////////////////////// void CBasePropertyPage::CommonConstruct(void) { //{{AFX_DATA_INIT(CBasePropertyPage) //}}AFX_DATA_INIT m_peo = NULL; m_hpage = NULL; m_bBackPressed = FALSE; m_bDoDetach = FALSE; m_iddPropertyPage = NULL; m_iddWizardPage = NULL; m_idcPPTitle = NULL; m_idsCaption = NULL; } //*** CBasePropertyPage::CommonConstruct() ///////////////////////////////////////////////////////////////////////////// //++ // // CBasePropertyPage::BInit // // Routine Description: // Initialize the page. // // Arguments: // peo [IN OUT] Pointer to the extension object. // // Return Value: // TRUE Page initialized successfully. // FALSE Page failed to initialize. // //-- ///////////////////////////////////////////////////////////////////////////// BOOL CBasePropertyPage::BInit(IN OUT CExtObject * peo) { ASSERT(peo != NULL); AFX_MANAGE_STATE(AfxGetStaticModuleState()); m_peo = peo; // Don't display a help button. m_psp.dwFlags &= ~PSP_HASHELP; // Construct the property page. if (Peo()->BWizard()) { ASSERT(IddWizardPage() != NULL); Construct(IddWizardPage(), IdsCaption()); m_dlghelp.SetHelpMask(IddWizardPage()); } // if: adding page to wizard else { ASSERT(IddPropertyPage() != NULL); Construct(IddPropertyPage(), IdsCaption()); m_dlghelp.SetHelpMask(IddPropertyPage()); } // else: adding page to property sheet // Read the properties private to this resource and parse them. { DWORD dwStatus; CClusPropList cpl; ASSERT(Peo() != NULL); ASSERT(Peo()->PrdResData() != NULL); ASSERT(Peo()->PrdResData()->m_hresource != NULL); // Read the properties. dwStatus = cpl.DwGetResourceProperties( Peo()->PrdResData()->m_hresource, CLUSCTL_RESOURCE_GET_PRIVATE_PROPERTIES ); // Parse the properties. if (dwStatus == ERROR_SUCCESS) { // Parse the properties. try { dwStatus = DwParseProperties(cpl); } // try catch (CMemoryException * pme) { dwStatus = ERROR_NOT_ENOUGH_MEMORY; pme->Delete(); } // catch: CMemoryException } // if: properties read successfully if (dwStatus != ERROR_SUCCESS) { return FALSE; } // if: error parsing getting or parsing properties } // Read the properties private to this resource and parse them return TRUE; } //*** CBasePropertyPage::BInit() ///////////////////////////////////////////////////////////////////////////// //++ // // CBasePropertyPage::DwParseProperties // // Routine Description: // Parse the properties of the resource. This is in a separate function // from BInit so that the optimizer can do a better job. // // Arguments: // rcpl [IN] Cluster property list to parse. // // Return Value: // ERROR_SUCCESS Properties were parsed successfully. // // Exceptions Thrown: // Any exceptions from CString::operator=(). // //-- ///////////////////////////////////////////////////////////////////////////// DWORD CBasePropertyPage::DwParseProperties(IN const CClusPropList & rcpl) { DWORD cProps; DWORD cprop; const CObjectProperty * pprop; CLUSPROP_BUFFER_HELPER props; CLUSPROP_PROPERTY_NAME const * pName; ASSERT(rcpl.PbProplist() != NULL); props.pb = rcpl.PbProplist(); // Loop through each property. for (cProps = *(props.pdw++) ; cProps > 0 ; cProps--) { pName = props.pName; ASSERT(pName->Syntax.dw == CLUSPROP_SYNTAX_NAME); props.pb += sizeof(*pName) + ALIGN_CLUSPROP(pName->cbLength); // Parse known properties. for (pprop = Pprops(), cprop = Cprops() ; cprop > 0 ; pprop++, cprop--) { if (lstrcmpiW(pName->sz, pprop->m_pwszName) == 0) { ASSERT(props.pSyntax->wFormat == pprop->m_propFormat); switch (pprop->m_propFormat) { case CLUSPROP_FORMAT_SZ: *pprop->m_value.pstr = props.pStringValue->sz; *pprop->m_valuePrev.pstr = props.pStringValue->sz; break; case CLUSPROP_FORMAT_DWORD: *pprop->m_value.pdw = props.pDwordValue->dw; *pprop->m_valuePrev.pdw = props.pDwordValue->dw; break; case CLUSPROP_FORMAT_BINARY: case CLUSPROP_FORMAT_MULTI_SZ: *pprop->m_value.ppb = props.pBinaryValue->rgb; *pprop->m_value.pcb = props.pBinaryValue->cbLength; *pprop->m_valuePrev.ppb = props.pBinaryValue->rgb; *pprop->m_valuePrev.pcb = props.pBinaryValue->cbLength; break; default: ASSERT(0); // don't know how to deal with this type } // switch: property format // Exit the loop since we found the parameter. break; } // if: found a match } // for: each property // If the property wasn't known, ask the derived class to parse it. if (cprop == 0) { DWORD dwStatus; dwStatus = DwParseUnknownProperty(pName->sz, props); if (dwStatus != ERROR_SUCCESS) return dwStatus; } // if: property not parsed // Advance the pointer. if ((props.pSyntax->wFormat == CLUSPROP_FORMAT_BINARY) || (props.pSyntax->wFormat == CLUSPROP_FORMAT_SZ) || (props.pSyntax->wFormat == CLUSPROP_FORMAT_MULTI_SZ)) props.pb += sizeof(*props.pBinaryValue) + ALIGN_CLUSPROP(props.pBinaryValue->cbLength) + sizeof(*props.pSyntax); // endmark else if (props.pSyntax->wFormat == CLUSPROP_FORMAT_DWORD) props.pb += sizeof(*props.pDwordValue) + sizeof(*props.pSyntax); else { ASSERT(0); // Unknown property syntax break; } // else: unknown property format } // for: each property return ERROR_SUCCESS; } //*** CBasePropertyPage::DwParseProperties() ///////////////////////////////////////////////////////////////////////////// //++ // // CBasePropertyPage::OnCreate // // Routine Description: // Handler for the WM_CREATE message. // // Arguments: // lpCreateStruct [IN OUT] Window create structure. // // Return Value: // -1 Error. // 0 Success. // //-- ///////////////////////////////////////////////////////////////////////////// int CBasePropertyPage::OnCreate(LPCREATESTRUCT lpCreateStruct) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); // Attach the window to the property page structure. // This has been done once already in the main application, since the // main application owns the property sheet. It needs to be done here // so that the window handle can be found in the DLL's handle map. if (FromHandlePermanent(m_hWnd) == NULL) // is the window handle already in the handle map { HWND hWnd = m_hWnd; m_hWnd = NULL; Attach(hWnd); m_bDoDetach = TRUE; } // if: is the window handle in the handle map return CPropertyPage::OnCreate(lpCreateStruct); } //*** CBasePropertyPage::OnCreate() ///////////////////////////////////////////////////////////////////////////// //++ // // CBasePropertyPage::OnDestroy // // Routine Description: // Handler for the WM_DESTROY message. // // Arguments: // None. // // Return Value: // None. // //-- ///////////////////////////////////////////////////////////////////////////// void CBasePropertyPage::OnDestroy(void) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); // Detach the window from the property page structure. // This will be done again by the main application, since it owns the // property sheet. It needs to be done here so that the window handle // can be removed from the DLL's handle map. if (m_bDoDetach) { if (m_hWnd != NULL) { HWND hWnd = m_hWnd; Detach(); m_hWnd = hWnd; } // if: do we have a window handle? } // if: do we need to balance the attach we did with a detach? CPropertyPage::OnDestroy(); } //*** CBasePropertyPage::OnDestroy() ///////////////////////////////////////////////////////////////////////////// //++ // // CBasePropertyPage::DoDataExchange // // Routine Description: // Do data exchange between the dialog and the class. // // Arguments: // pDX [IN OUT] Data exchange object // // Return Value: // None. // //-- ///////////////////////////////////////////////////////////////////////////// void CBasePropertyPage::DoDataExchange(CDataExchange * pDX) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); CPropertyPage::DoDataExchange(pDX); //{{AFX_DATA_MAP(CBasePropertyPage) // NOTE: the ClassWizard will add DDX and DDV calls here //}}AFX_DATA_MAP DDX_Control(pDX, IDC_PP_ICON, m_staticIcon); DDX_Control(pDX, m_idcPPTitle, m_staticTitle); if (!pDX->m_bSaveAndValidate) { // Set the title. DDX_Text(pDX, m_idcPPTitle, m_strTitle); } // if: not saving data } //*** CBasePropertyPage::DoDataExchange() ///////////////////////////////////////////////////////////////////////////// //++ // // CBasePropertyPage::OnInitDialog // // Routine Description: // Handler for the WM_INITDIALOG message. // // Arguments: // None. // // Return Value: // TRUE We need the focus to be set for us. // FALSE We already set the focus to the proper control. // //-- ///////////////////////////////////////////////////////////////////////////// BOOL CBasePropertyPage::OnInitDialog(void) { ASSERT(Peo() != NULL); AFX_MANAGE_STATE(AfxGetStaticModuleState()); // Set the title string. m_strTitle = Peo()->RrdResData().m_strName; // Call the base class method. CPropertyPage::OnInitDialog(); // Display an icon for the object. if (Peo()->Hicon() != NULL) m_staticIcon.SetIcon(Peo()->Hicon()); return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE } //*** CBasePropertyPage::OnInitDialog() ///////////////////////////////////////////////////////////////////////////// //++ // // CBasePropertyPage::OnSetActive // // Routine Description: // Handler for the PSN_SETACTIVE message. // // Arguments: // None. // // Return Value: // TRUE Page successfully initialized. // FALSE Page not initialized. // //-- ///////////////////////////////////////////////////////////////////////////// BOOL CBasePropertyPage::OnSetActive(void) { HRESULT hr; AFX_MANAGE_STATE(AfxGetStaticModuleState()); // Reread the data. hr = Peo()->HrGetObjectInfo(); if (hr != NOERROR) return FALSE; // Set the title string. m_strTitle = Peo()->RrdResData().m_strName; m_bBackPressed = FALSE; return CPropertyPage::OnSetActive(); } //*** CBasePropertyPage::OnSetActive() ///////////////////////////////////////////////////////////////////////////// //++ // // CBasePropertyPage::OnApply // // Routine Description: // Handler for the PSM_APPLY message. // // Arguments: // None. // // Return Value: // TRUE Page successfully applied. // FALSE Error applying page. // //-- ///////////////////////////////////////////////////////////////////////////// BOOL CBasePropertyPage::OnApply(void) { ASSERT(!BWizard()); AFX_MANAGE_STATE(AfxGetStaticModuleState()); // Update the data in the class from the page. UpdateData(/*bSaveAndValidate*/); if (!BApplyChanges()) return FALSE; return CPropertyPage::OnApply(); } //*** CBasePropertyPage::OnApply() ///////////////////////////////////////////////////////////////////////////// //++ // // CBasePropertyPage::OnWizardBack // // Routine Description: // Handler for the PSN_WIZBACK message. // // Arguments: // None. // // Return Value: // -1 Don't change the page. // 0 Change the page. // //-- ///////////////////////////////////////////////////////////////////////////// LRESULT CBasePropertyPage::OnWizardBack(void) { LRESULT lResult; ASSERT(BWizard()); AFX_MANAGE_STATE(AfxGetStaticModuleState()); lResult = CPropertyPage::OnWizardBack(); if (lResult != -1) m_bBackPressed = TRUE; return lResult; } //*** CBasePropertyPage::OnWizardBack() ///////////////////////////////////////////////////////////////////////////// //++ // // CBasePropertyPage::OnWizardNext // // Routine Description: // Handler for the PSN_WIZNEXT message. // // Arguments: // None. // // Return Value: // -1 Don't change the page. // 0 Change the page. // //-- ///////////////////////////////////////////////////////////////////////////// LRESULT CBasePropertyPage::OnWizardNext(void) { ASSERT(BWizard()); AFX_MANAGE_STATE(AfxGetStaticModuleState()); // Update the data in the class from the page. UpdateData(/*bSaveAndValidate*/); // Save the data in the sheet. if (!BApplyChanges()) return -1; // Create the object. return CPropertyPage::OnWizardNext(); } //*** CBasePropertyPage::OnWizardNext() ///////////////////////////////////////////////////////////////////////////// //++ // // CBasePropertyPage::OnWizardFinish // // Routine Description: // Handler for the PSN_WIZFINISH message. // // Arguments: // None. // // Return Value: // FALSE Don't change the page. // TRUE Change the page. // //-- ///////////////////////////////////////////////////////////////////////////// BOOL CBasePropertyPage::OnWizardFinish(void) { ASSERT(BWizard()); AFX_MANAGE_STATE(AfxGetStaticModuleState()); // Update the data in the class from the page. UpdateData(/*bSaveAndValidate*/); // Save the data in the sheet. if (!BApplyChanges()) return FALSE; return CPropertyPage::OnWizardFinish(); } //*** CBasePropertyPage::OnWizardFinish() ///////////////////////////////////////////////////////////////////////////// //++ // // CBasePropertyPage::OnChangeCtrl // // Routine Description: // Handler for the messages sent when a control is changed. This // method can be specified in a message map if all that needs to be // done is enable the Apply button. // // Arguments: // None. // // Return Value: // None. // //-- ///////////////////////////////////////////////////////////////////////////// void CBasePropertyPage::OnChangeCtrl(void) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); SetModified(TRUE); } //*** CBasePropertyPage::OnChangeCtrl() ///////////////////////////////////////////////////////////////////////////// //++ // // CBasePropertyPage::EnableNext // // Routine Description: // Enables or disables the NEXT or FINISH button. // // Arguments: // bEnable [IN] TRUE = enable the button, FALSE = disable the button. // // Return Value: // None. // //-- ///////////////////////////////////////////////////////////////////////////// void CBasePropertyPage::EnableNext(IN BOOL bEnable /*TRUE*/) { ASSERT(BWizard()); ASSERT(PiWizardCallback()); AFX_MANAGE_STATE(AfxGetStaticModuleState()); PiWizardCallback()->EnableNext((LONG *) Hpage(), bEnable); } //*** CBasePropertyPage::EnableNext() ///////////////////////////////////////////////////////////////////////////// //++ // // CBasePropertyPage::BApplyChanges // // Routine Description: // Apply changes made on the page. // // Arguments: // None. // // Return Value: // TRUE Page successfully applied. // FALSE Error applying page. // //-- ///////////////////////////////////////////////////////////////////////////// BOOL CBasePropertyPage::BApplyChanges(void) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); DWORD dwStatus = ERROR_SUCCESS; CClusPropList cpl(BWizard() /*bAlwaysAddProp*/); // Save data. { // Build the property list. try { BuildPropList(cpl); } // try catch (CMemoryException * pme) { pme->Delete(); dwStatus = ERROR_NOT_ENOUGH_MEMORY; } // catch: CMemoryException // Set the data. if (dwStatus == ERROR_SUCCESS) dwStatus = DwSetPrivateProps(cpl); // Handle errors. if (dwStatus != ERROR_SUCCESS) { CString strError; CString strMsg; AFX_MANAGE_STATE(AfxGetStaticModuleState()); FormatError(strError, dwStatus); if (dwStatus == ERROR_RESOURCE_PROPERTIES_STORED) { AfxMessageBox(strError, MB_OK | MB_ICONEXCLAMATION); dwStatus = ERROR_SUCCESS; } // if: properties were stored else { strMsg.FormatMessage(IDS_APPLY_PARAM_CHANGES_ERROR, strError); AfxMessageBox(strMsg, MB_OK | MB_ICONEXCLAMATION); return FALSE; } // else: error setting properties. } // if: error setting properties if (dwStatus == ERROR_SUCCESS) { // Save new values as previous values. try { DWORD cprop; const CObjectProperty * pprop; for (pprop = Pprops(), cprop = Cprops() ; cprop > 0 ; pprop++, cprop--) { switch (pprop->m_propFormat) { case CLUSPROP_FORMAT_SZ: ASSERT(pprop->m_value.pstr != NULL); ASSERT(pprop->m_valuePrev.pstr != NULL); *pprop->m_valuePrev.pstr = *pprop->m_value.pstr; break; case CLUSPROP_FORMAT_DWORD: ASSERT(pprop->m_value.pdw != NULL); ASSERT(pprop->m_valuePrev.pdw != NULL); *pprop->m_valuePrev.pdw = *pprop->m_value.pdw; break; case CLUSPROP_FORMAT_BINARY: case CLUSPROP_FORMAT_MULTI_SZ: ASSERT(pprop->m_value.ppb != NULL); ASSERT(*pprop->m_value.ppb != NULL); ASSERT(pprop->m_value.pcb != NULL); ASSERT(pprop->m_valuePrev.ppb != NULL); ASSERT(*pprop->m_valuePrev.ppb != NULL); ASSERT(pprop->m_valuePrev.pcb != NULL); delete [] *pprop->m_valuePrev.ppb; *pprop->m_valuePrev.ppb = new BYTE[*pprop->m_value.pcb]; CopyMemory(*pprop->m_valuePrev.ppb, *pprop->m_value.ppb, *pprop->m_value.pcb); *pprop->m_valuePrev.pcb = *pprop->m_value.pcb; break; default: ASSERT(0); // don't know how to deal with this type } // switch: property format } // for: each property } // try catch (CMemoryException * pme) { pme->ReportError(); pme->Delete(); } // catch: CMemoryException } // if: properties set successfully } // Save data return TRUE; } //*** CBasePropertyPage::BApplyChanges() ///////////////////////////////////////////////////////////////////////////// //++ // // CBasePropertyPage::BuildPropList // // Routine Description: // Build the property list. // // Arguments: // rcpl [IN OUT] Cluster property list. // // Return Value: // None. // // Exceptions Thrown: // Any exceptions thrown by CClusPropList::AddProp(). // //-- ///////////////////////////////////////////////////////////////////////////// void CBasePropertyPage::BuildPropList( IN OUT CClusPropList & rcpl ) { DWORD cprop; const CObjectProperty * pprop; for (pprop = Pprops(), cprop = Cprops() ; cprop > 0 ; pprop++, cprop--) { switch (pprop->m_propFormat) { case CLUSPROP_FORMAT_SZ: rcpl.AddProp( pprop->m_pwszName, *pprop->m_value.pstr, *pprop->m_valuePrev.pstr ); break; case CLUSPROP_FORMAT_DWORD: rcpl.AddProp( pprop->m_pwszName, *pprop->m_value.pdw, *pprop->m_valuePrev.pdw ); break; case CLUSPROP_FORMAT_BINARY: case CLUSPROP_FORMAT_MULTI_SZ: rcpl.AddProp( pprop->m_pwszName, *pprop->m_value.ppb, *pprop->m_value.pcb, *pprop->m_valuePrev.ppb, *pprop->m_valuePrev.pcb ); break; default: ASSERT(0); // don't know how to deal with this type return; } // switch: property format } // for: each property } //*** CBasePropertyPage::BuildPropList() ///////////////////////////////////////////////////////////////////////////// //++ // // CBasePropertyPage::DwSetPrivateProps // // Routine Description: // Set the private properties for this object. // // Arguments: // rcpl [IN] Property list to set on the object. // // Return Value: // ERROR_SUCCESS The operation was completed successfully. // !0 Failure. // //-- ///////////////////////////////////////////////////////////////////////////// DWORD CBasePropertyPage::DwSetPrivateProps( IN const CClusPropList & rcpl ) { DWORD dwStatus; DWORD cbProps; ASSERT(Peo() != NULL); ASSERT(Peo()->PrdResData()); ASSERT(Peo()->PrdResData()->m_hresource); if ((rcpl.PbProplist() != NULL) && (rcpl.CbProplist() > 0)) { // Set private properties. dwStatus = ClusterResourceControl( Peo()->PrdResData()->m_hresource, NULL, // hNode CLUSCTL_RESOURCE_SET_PRIVATE_PROPERTIES, rcpl.PbProplist(), rcpl.CbProplist(), NULL, // lpOutBuffer 0, // nOutBufferSize &cbProps ); } // if: there is data to set else dwStatus = ERROR_SUCCESS; return dwStatus; } //*** CBasePropertyPage::DwSetPrivateProps() ///////////////////////////////////////////////////////////////////////////// //++ // // CBasePropertyPage::DwReadValue // // Routine Description: // Read a REG_SZ value for this item. // // Arguments: // pszValueName [IN] Name of the value to read. // rstrValue [OUT] String in which to return the value. // hkey [IN] Handle to the registry key to read from. // // Return Value: // dwStatus ERROR_SUCCESS = success, !0 = failure // //-- ///////////////////////////////////////////////////////////////////////////// DWORD CBasePropertyPage::DwReadValue( IN LPCTSTR pszValueName, OUT CString & rstrValue, IN HKEY hkey ) { DWORD dwStatus; LPWSTR pwszValue = NULL; DWORD dwValueLen; DWORD dwValueType; ASSERT(pszValueName != NULL); ASSERT(hkey != NULL); rstrValue.Empty(); try { // Get the size of the value. dwValueLen = 0; dwStatus = ::ClusterRegQueryValue( hkey, pszValueName, &dwValueType, NULL, &dwValueLen ); if ((dwStatus == ERROR_SUCCESS) || (dwStatus == ERROR_MORE_DATA)) { ASSERT(dwValueType == REG_SZ); // Allocate enough space for the data. pwszValue = rstrValue.GetBuffer(dwValueLen / sizeof(WCHAR)); ASSERT(pwszValue != NULL); dwValueLen += 1 * sizeof(WCHAR); // Don't forget the final null-terminator. // Read the value. dwStatus = ::ClusterRegQueryValue( hkey, pszValueName, &dwValueType, (LPBYTE) pwszValue, &dwValueLen ); if (dwStatus == ERROR_SUCCESS) { ASSERT(dwValueType == REG_SZ); } // if: value read successfully rstrValue.ReleaseBuffer(); } // if: got the size successfully } // try catch (CMemoryException * pme) { pme->Delete(); dwStatus = ERROR_NOT_ENOUGH_MEMORY; } // catch: CMemoryException return dwStatus; } //*** CBasePropertyPage::DwReadValue(LPCTSTR, CString&) ///////////////////////////////////////////////////////////////////////////// //++ // // CBasePropertyPage::DwReadValue // // Routine Description: // Read a REG_DWORD value for this item. // // Arguments: // pszValueName [IN] Name of the value to read. // pdwValue [OUT] DWORD in which to return the value. // hkey [IN] Handle to the registry key to read from. // // Return Value: // dwStatus ERROR_SUCCESS = success, !0 = failure // //-- ///////////////////////////////////////////////////////////////////////////// DWORD CBasePropertyPage::DwReadValue( IN LPCTSTR pszValueName, OUT DWORD * pdwValue, IN HKEY hkey ) { DWORD dwStatus; DWORD dwValue; DWORD dwValueLen; DWORD dwValueType; ASSERT(pszValueName != NULL); ASSERT(pdwValue != NULL); ASSERT(hkey != NULL); *pdwValue = 0; // Read the value. dwValueLen = sizeof(dwValue); dwStatus = ::ClusterRegQueryValue( hkey, pszValueName, &dwValueType, (LPBYTE) &dwValue, &dwValueLen ); if (dwStatus == ERROR_SUCCESS) { ASSERT(dwValueType == REG_DWORD); ASSERT(dwValueLen == sizeof(dwValue)); *pdwValue = dwValue; } // if: value read successfully return dwStatus; } //*** CBasePropertyPage::DwReadValue(LPCTSTR, DWORD*) ///////////////////////////////////////////////////////////////////////////// //++ // // CBasePropertyPage::DwReadValue // // Routine Description: // Read a REG_BINARY value for this item. // // Arguments: // pszValueName [IN] Name of the value to read. // ppbValue [OUT] Pointer in which to return the data. Caller // is responsible for deallocating the data. // hkey [IN] Handle to the registry key to read from. // // Return Value: // dwStatus ERROR_SUCCESS = success, !0 = failure // //-- ///////////////////////////////////////////////////////////////////////////// DWORD CBasePropertyPage::DwReadValue( IN LPCTSTR pszValueName, OUT LPBYTE * ppbValue, IN HKEY hkey ) { DWORD dwStatus; DWORD dwValueLen; DWORD dwValueType; ASSERT(pszValueName != NULL); ASSERT(ppbValue != NULL); ASSERT(hkey != NULL); *ppbValue = NULL; // Get the length of the value. dwValueLen = 0; dwStatus = ::ClusterRegQueryValue( hkey, pszValueName, &dwValueType, NULL, &dwValueLen ); if (dwStatus != ERROR_MORE_DATA) return dwStatus; ASSERT(dwValueType == REG_BINARY); // Allocate a buffer, try { *ppbValue = new BYTE[dwValueLen]; } // try catch (CMemoryException *) { dwStatus = ERROR_NOT_ENOUGH_MEMORY; return dwStatus; } // catch: CMemoryException // Read the value. dwStatus = ::ClusterRegQueryValue( hkey, pszValueName, &dwValueType, *ppbValue, &dwValueLen ); if (dwStatus != ERROR_SUCCESS) { delete [] *ppbValue; *ppbValue = NULL; } // if: value read successfully return dwStatus; } //*** CBasePropertyPage::DwReadValue(LPCTSTR, LPBYTE) ///////////////////////////////////////////////////////////////////////////// //++ // // CBasePropertyPage::DwWriteValue // // Routine Description: // Write a REG_SZ value for this item if it hasn't changed. // // Arguments: // pszValueName [IN] Name of the value to write. // rstrValue [IN] Value data. // rstrPrevValue [IN OUT] Previous value. // hkey [IN] Handle to the registry key to write to. // // Return Value: // dwStatus // //-- ///////////////////////////////////////////////////////////////////////////// DWORD CBasePropertyPage::DwWriteValue( IN LPCTSTR pszValueName, IN const CString & rstrValue, IN OUT CString & rstrPrevValue, IN HKEY hkey ) { DWORD dwStatus; ASSERT(pszValueName != NULL); ASSERT(hkey != NULL); // Write the value if it hasn't changed. if (rstrValue != rstrPrevValue) { dwStatus = ::ClusterRegSetValue( hkey, pszValueName, REG_SZ, (CONST BYTE *) (LPCTSTR) rstrValue, (rstrValue.GetLength() + 1) * sizeof(TCHAR) ); if (dwStatus == ERROR_SUCCESS) rstrPrevValue = rstrValue; } // if: value changed else dwStatus = ERROR_SUCCESS; return dwStatus; } //*** CBasePropertyPage::DwWriteValue(LPCTSTR, CString&) ///////////////////////////////////////////////////////////////////////////// //++ // // CBasePropertyPage::DwWriteValue // // Routine Description: // Write a REG_DWORD value for this item if it hasn't changed. // // Arguments: // pszValueName [IN] Name of the value to write. // dwValue [IN] Value data. // pdwPrevValue [IN OUT] Previous value. // hkey [IN] Handle to the registry key to write to. // // Return Value: // dwStatus // //-- ///////////////////////////////////////////////////////////////////////////// DWORD CBasePropertyPage::DwWriteValue( IN LPCTSTR pszValueName, IN DWORD dwValue, IN OUT DWORD * pdwPrevValue, IN HKEY hkey ) { DWORD dwStatus; ASSERT(pszValueName != NULL); ASSERT(pdwPrevValue != NULL); ASSERT(hkey != NULL); // Write the value if it hasn't changed. if (dwValue != *pdwPrevValue) { dwStatus = ::ClusterRegSetValue( hkey, pszValueName, REG_DWORD, (CONST BYTE *) &dwValue, sizeof(dwValue) ); if (dwStatus == ERROR_SUCCESS) *pdwPrevValue = dwValue; } // if: value changed else dwStatus = ERROR_SUCCESS; return dwStatus; } //*** CBasePropertyPage::DwWriteValue(LPCTSTR, DWORD) ///////////////////////////////////////////////////////////////////////////// //++ // // CBasePropertyPage::DwWriteValue // // Routine Description: // Write a REG_BINARY value for this item if it hasn't changed. // // Arguments: // pszValueName [IN] Name of the value to write. // pbValue [IN] Value data. // cbValue [IN] Size of value data. // ppbPrevValue [IN OUT] Previous value. // cbPrevValue [IN] Size of the previous data. // hkey [IN] Handle to the registry key to write to. // // Return Value: // dwStatus // //-- ///////////////////////////////////////////////////////////////////////////// DWORD CBasePropertyPage::DwWriteValue( IN LPCTSTR pszValueName, IN const LPBYTE pbValue, IN DWORD cbValue, IN OUT LPBYTE * ppbPrevValue, IN DWORD cbPrevValue, IN HKEY hkey ) { DWORD dwStatus; LPBYTE pbPrevValue = NULL; ASSERT(pszValueName != NULL); ASSERT(pbValue != NULL); ASSERT(ppbPrevValue != NULL); ASSERT(cbValue > 0); ASSERT(hkey != NULL); // See if the data has changed. if (cbValue == cbPrevValue) { if (memcmp(pbValue, *ppbPrevValue, cbValue) == 0) return ERROR_SUCCESS; } // if: lengths are the same // Allocate a new buffer for the previous data pointer. try { pbPrevValue = new BYTE[cbValue]; } catch (CMemoryException *) { return ERROR_NOT_ENOUGH_MEMORY; } // catch: CMemoryException ::CopyMemory(pbPrevValue, pbValue, cbValue); // Write the value if it hasn't changed. dwStatus = ::ClusterRegSetValue( hkey, pszValueName, REG_BINARY, pbValue, cbValue ); if (dwStatus == ERROR_SUCCESS) { delete [] *ppbPrevValue; *ppbPrevValue = pbPrevValue; } // if: set was successful else delete [] pbPrevValue; return dwStatus; } //*** CBasePropertyPage::DwWriteValue(LPCTSTR, const LPBYTE) ///////////////////////////////////////////////////////////////////////////// //++ // // CBasePropertyPage::OnContextMenu // // Routine Description: // Handler for the WM_CONTEXTMENU message. // // Arguments: // pWnd Window in which user clicked the right mouse button. // point Position of the cursor, in screen coordinates. // // Return Value: // TRUE Help processed. // FALSE Help not processed. // //-- ///////////////////////////////////////////////////////////////////////////// void CBasePropertyPage::OnContextMenu(CWnd * pWnd, CPoint point) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); m_dlghelp.OnContextMenu(pWnd, point); } //*** CBasePropertyPage::OnContextMenu() ///////////////////////////////////////////////////////////////////////////// //++ // // CBasePropertyPage::OnHelpInfo // // Routine Description: // Handler for the WM_HELPINFO message. // // Arguments: // pHelpInfo Structure containing info about displaying help. // // Return Value: // TRUE Help processed. // FALSE Help not processed. // //-- ///////////////////////////////////////////////////////////////////////////// BOOL CBasePropertyPage::OnHelpInfo(HELPINFO * pHelpInfo) { BOOL bProcessed; AFX_MANAGE_STATE(AfxGetStaticModuleState()); bProcessed = m_dlghelp.OnHelpInfo(pHelpInfo); if (!bProcessed) bProcessed = CDialog::OnHelpInfo(pHelpInfo); return bProcessed; } //*** CBasePropertyPage::OnHelpInfo() ///////////////////////////////////////////////////////////////////////////// //++ // // CBasePropertyPage::OnCommandHelp // // Routine Description: // Handler for the WM_COMMANDHELP message. // // Arguments: // wParam [IN] WPARAM. // lParam [IN] LPARAM. // // Return Value: // TRUE Help processed. // FALSE Help not processed. // //-- ///////////////////////////////////////////////////////////////////////////// LRESULT CBasePropertyPage::OnCommandHelp(WPARAM wParam, LPARAM lParam) { BOOL bProcessed; AFX_MANAGE_STATE(AfxGetStaticModuleState()); bProcessed = (BOOL)m_dlghelp.OnCommandHelp(wParam, lParam); if (!bProcessed) bProcessed = (BOOL)CDialog::OnCommandHelp(wParam, lParam); return bProcessed; } //*** CBasePropertyPage::OnCommandHelp()