//+--------------------------------------------------------------------------- // // Microsoft Windows // Copyright (C) Microsoft Corporation 1996-2001. // // File: ANumber.cpp // // Contents: Implementation of CAttrNumber // //---------------------------------------------------------------------------- #include "stdafx.h" #include "wsecmgr.h" #include "snapmgr.h" #include "util.h" #include "ANumber.h" #include "DDWarn.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif /*-------------------------------------------------------------------------------------- The constant values below are used to retrieve the string ID of the description for a range of values. struct { int iMin - >= The value must be greater than or equal to this value. int iMax - <= The value must be less than or equale to this value. WORD uResource - The resource id of the item. WORD uMask - Flag that describes which memebers are valid. The Resource ID must always be valid. If a flag is not set for the coorisponding item, then the point is not checked against the value. RDIF_MIN - The [iMin] member is valid. RDIF_MAX - [iMax] member is valid. RDIF_END - This is the end of the array. The last item in all declarations must set this flag. --------------------------------------------------------------------------------------*/ // // Minimum password description for number attribute. // RANGEDESCRIPTION g_rdMinPassword[] = { { 0, 0, IDS_CHANGE_IMMEDIATELY, RDIF_MIN | RDIF_MAX }, { 1, 0, IDS_PASSWORD_CHANGE, RDIF_MIN | RDIF_END } }; // // Maximum password description for number attribute. // RANGEDESCRIPTION g_rdMaxPassword[] = { { 1, 999, IDS_PASSWORD_EXPIRE, RDIF_MIN | RDIF_MAX }, { 0, 0, IDS_PASSWORD_FOREVER, RDIF_MIN | RDIF_END}, }; // // Password len descriptions. // RANGEDESCRIPTION g_rdPasswordLen[] = { {0, 0, IDS_PERMIT_BLANK, RDIF_MIN | RDIF_MAX }, {1, 0, IDS_PASSWORD_LEN, RDIF_MIN | RDIF_END } }; // // Password histroy description. // RANGEDESCRIPTION g_rdPasswordHistory[] = { {0, 0, IDS_NO_HISTORY, RDIF_MIN | RDIF_MAX }, {1, 0, IDS_PASSWORD_REMEMBER, RDIF_MIN | RDIF_END } }; // // Password lockout descriptions // RANGEDESCRIPTION g_rdLockoutAccount[] = { {0, 0, IDS_NO_LOCKOUT, RDIF_MIN | RDIF_MAX }, {1, 0, IDS_LOCKOUT_AFTER, RDIF_MIN | RDIF_END } }; // // Lockout duration description. // RANGEDESCRIPTION g_rdLockoutFor[] = { {1, 0, IDS_DURATION, RDIF_MIN }, {0, 0, IDS_LOCKOUT_FOREVER, RDIF_MAX | RDIF_END} }; RANGEDESCRIPTION g_rdAutoDisconnect[] = { { 1, 0, IDS_RNH_AUTODISCONNECT_STATIC, RDIF_MIN }, { 0, 0, IDS_RNH_AUTODISCONNECT_SPECIAL, RDIF_MAX | RDIF_END} }; RANGEDESCRIPTION g_rdPasswordWarnings[] = { { 0, 0, IDS_RNH_PASSWORD_WARNINGS_SPECIAL, RDIF_MIN | RDIF_MAX}, { 1, 0, IDS_RNH_PASSWORD_WARNINGS_STATIC, RDIF_MIN | RDIF_END} }; RANGEDESCRIPTION g_rdCachedLogons[] = { { 0, 0, IDS_RNH_CACHED_LOGONS_SPECIAL, RDIF_MIN | RDIF_MAX}, { 1, 0, IDS_RNH_CACHED_LOGONS_STATIC, RDIF_MIN | RDIF_END} }; /*-------------------------------------------------------------------------------------- Method: GetRangeDescription Synopsis: This function was specifically created for SCE. Call this function if the Item ID to, and current range value to retrieve the corrisponding string. Arguments: [uType] - [in] ID of the point you want the description for. [i] - [in] The point you want the description for. [pstrRet] - [out] The return value. Returns: ERROR_SUCCESS - The operation was successfull. ERROR_INVALID_DATA - The id may not be supported or [pstrRet] is NULL. Other Win32 errors if resource loading was not successful. --------------------------------------------------------------------------------------*/ DWORD GetRangeDescription( IN UINT uType, IN int i, OUT CString *pstrRet ) { switch(uType){ case IDS_LOCK_DURATION: uType = GetRangeDescription(g_rdLockoutFor, i); break; case IDS_MAX_PAS_AGE: uType = GetRangeDescription(g_rdMaxPassword, i); break; case IDS_LOCK_COUNT: uType = GetRangeDescription(g_rdLockoutAccount, i); break; case IDS_MIN_PAS_AGE: uType = GetRangeDescription(g_rdMinPassword, i); break; case IDS_MIN_PAS_LEN: uType = GetRangeDescription(g_rdPasswordLen, i); break; case IDS_PAS_UNIQUENESS: uType = GetRangeDescription(g_rdPasswordHistory, i); break; case IDS_LOCK_RESET_COUNT: uType = 0; break; default: uType = 0; } if(uType && pstrRet){ // // Try to load the resource string. // __try { if( pstrRet->LoadString(uType) ){ return ERROR_SUCCESS; } } __except(EXCEPTION_CONTINUE_EXECUTION) { return (DWORD)E_POINTER; } return GetLastError(); } return ERROR_INVALID_DATA; } /*-------------------------------------------------------------------------------------- Method: GetRangeDescription Synopsis: This function works directly with the RANGEDESCRIPTION structure. Tests to see which string resource ID to return. This is determined by testing [i] with the [iMin] and [iMax] value of a RANGEDESCRIPTION structure. RDIF_MIN or/and RDIF_MAX must be set in the [uMask] member for this function to perform any comparisons Arguments: [pDesc] - [in] An array of RANGEDESCRIPTIONS, the last member of this array must set RDIF_END flag in the [uMask] member. [i] - [in] The point to test. Returns: A String resource ID if successfull. Otherwise 0. --------------------------------------------------------------------------------------*/ UINT GetRangeDescription( RANGEDESCRIPTION *pDesc, int i ) { RANGEDESCRIPTION *pCur = pDesc; if(!pDesc){ return 0; } // // The uMask member of the description tells us wich members // of the structure is valid. // while( 1 ){ if( (pCur->uMask & RDIF_MIN) ) { // // Test the minimum. // if(i >= pCur->iMin){ if(pCur->uMask & RDIF_MAX){ // // Test the maximum. // if( i <= pCur->iMax) { return pCur->uResource; } } else { return pCur->uResource; } } } else if(pCur->uMask & RDIF_MAX) { // // Test only the maximum. // if(i <= pCur->iMax){ return pCur->uResource; } } if(pCur->uMask & RDIF_END){ // // This is the last element of the array, so end the loop. // break; } pCur++; } return 0; } ///////////////////////////////////////////////////////////////////////////// // CAttrNumber dialog CAttrNumber::CAttrNumber(UINT nTemplateID) : CAttribute(nTemplateID ? nTemplateID : IDD), m_cMinutes(0), m_nLow(0), m_nHigh(999), m_nSave(0), m_pRDescription(NULL) { //{{AFX_DATA_INIT(CAttrNumber) m_strUnits = _T(""); m_strSetting = _T(""); m_strBase = _T(""); m_strTemplateTitle = _T(""); m_strLastInspectTitle = _T(""); //}}AFX_DATA_INIT m_pHelpIDs = (DWORD_PTR)a168HelpIDs; m_uTemplateResID = IDD; } void CAttrNumber::DoDataExchange(CDataExchange* pDX) { CAttribute::DoDataExchange(pDX); //{{AFX_DATA_MAP(CAttrNumber) DDX_Control(pDX, IDC_SPIN, m_SpinValue); DDX_Text(pDX, IDC_UNITS, m_strUnits); DDX_Text(pDX, IDC_CURRENT, m_strSetting); DDX_Text(pDX, IDC_NEW, m_strBase); DDX_Text(pDX, IDC_TEMPLATE_TITLE, m_strTemplateTitle); DDX_Text(pDX, IDC_LI_TITLE, m_strLastInspectTitle); DDX_Text(pDX, IDC_RANGEERROR,m_strError); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CAttrNumber, CAttribute) //{{AFX_MSG_MAP(CAttrNumber) ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN, OnDeltaposSpin) ON_EN_KILLFOCUS(IDC_NEW, OnKillFocusNew) ON_BN_CLICKED(IDC_CONFIGURE, OnConfigure) ON_EN_UPDATE(IDC_NEW, OnUpdateNew) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CAttrNumber message handlers void CAttrNumber::OnDeltaposSpin( NMHDR* pNMHDR, LRESULT* pResult ) { NM_UPDOWN FAR *pnmud = (NM_UPDOWN FAR *)pNMHDR; if ( pnmud ) { // // get current value // long lVal = CurrentEditValue(); if (SCE_FOREVER_VALUE == lVal) { if (pnmud->iDelta > 0) { if (m_cMinutes & DW_VALUE_OFF) { lVal = SCE_KERBEROS_OFF_VALUE; } else { lVal = m_nHigh; } } else { lVal = m_nLow; } } else if (SCE_KERBEROS_OFF_VALUE == lVal) { if (pnmud->iDelta < 0) { if (m_cMinutes & DW_VALUE_FOREVER) { lVal = SCE_FOREVER_VALUE; } else { lVal = m_nLow; } } else { lVal = m_nHigh; } } else { lVal -= (LONG)(m_iAccRate*pnmud->iDelta); if ( lVal > m_nHigh ) { // if it is overflow, go back to low if ( m_cMinutes & DW_VALUE_OFF ) { lVal = SCE_KERBEROS_OFF_VALUE; } else if (m_cMinutes & DW_VALUE_FOREVER) { lVal = SCE_FOREVER_VALUE; } else { lVal = m_nLow; } } else if ( (lVal < m_nLow) && ((lVal != SCE_KERBEROS_OFF_VALUE) || !(m_cMinutes & DW_VALUE_OFF)) && ((lVal != SCE_FOREVER_VALUE) || !(m_cMinutes & DW_VALUE_FOREVER))) { // if it is underflow, go back to high if ( (m_cMinutes & DW_VALUE_FOREVER) && (lVal != SCE_FOREVER_VALUE)) { lVal = SCE_FOREVER_VALUE; } else if ((m_cMinutes & DW_VALUE_OFF) && (lVal != SCE_KERBEROS_OFF_VALUE)) { lVal = SCE_KERBEROS_OFF_VALUE; } else { lVal = m_nHigh; } } if ( 0 == lVal && (m_cMinutes & DW_VALUE_NOZERO) ) { // zero is not allowed if ( m_nLow > 0 ) { lVal = m_nLow; } else { lVal = 1; } } } SetValueToEdit(lVal); } *pResult = 0; } void CAttrNumber::OnKillFocusNew() { LONG lVal = CurrentEditValue(); SetValueToEdit(lVal); } void CAttrNumber::SetValueToEdit(LONG lVal) { CString strNew; if ( m_iStaticId ) m_strTemplateTitle.LoadString(m_iStaticId); else m_strTemplateTitle = _T(""); if ( 0 == lVal ) { strNew.Format(TEXT("%d"),lVal); if ( m_cMinutes & DW_VALUE_NEVER && m_iNeverId > 0 ) { // change to never m_strTemplateTitle.LoadString(m_iNeverId); } } else if ( SCE_FOREVER_VALUE == lVal ) { strNew.LoadString(IDS_FOREVER); if ( m_iNeverId ) m_strTemplateTitle.LoadString(m_iNeverId); } else if (SCE_KERBEROS_OFF_VALUE == lVal) { strNew.LoadString(IDS_OFF); if ( m_iNeverId ) { m_strTemplateTitle.LoadString(m_iNeverId); } } else { strNew.Format(TEXT("%d"),lVal); } m_nSave = lVal; SetDlgItemText(IDC_NEW,strNew); SetDlgItemText(IDC_TEMPLATE_TITLE,m_strTemplateTitle); SetModified(TRUE); } LONG CAttrNumber::CurrentEditValue() { UINT uiVal = 0; LONG lVal = 0; BOOL bTrans = FALSE; uiVal = GetDlgItemInt(IDC_NEW,&bTrans,FALSE); lVal = uiVal; if (!bTrans ) { // if ( 0 == lVal && !bTrans ) { // errored, overflow, or nonnumeric CString str; if(m_cMinutes & DW_VALUE_FOREVER){ str.LoadString(IDS_FOREVER); if(str == m_strBase){ return SCE_FOREVER_VALUE; } } lVal = _ttol((LPCTSTR)m_strBase); if ( lVal == 0 ) { // // nonnumeric // lVal = (LONG) m_nSave; return lVal; } } if ( m_iAccRate > 1 && lVal > 0 ) { // // for log max size, make it multiples of m_iAccRate // int nCount = lVal % m_iAccRate; if ( nCount > 0 ) { lVal = ((LONG)(lVal/m_iAccRate))*m_iAccRate; } } if ( lVal > m_nHigh ) { // if it is overflow, go back to low if ( m_cMinutes & DW_VALUE_FOREVER ) { lVal = SCE_FOREVER_VALUE; } else if (m_cMinutes & DW_VALUE_OFF) { lVal = SCE_KERBEROS_OFF_VALUE; } else { // Leave alone and let the OnKillActive catch it } } if ( (lVal < m_nLow) && (lVal != SCE_KERBEROS_OFF_VALUE) && (lVal != SCE_FOREVER_VALUE) ) { // if it is underflow, go back to high if (m_cMinutes & DW_VALUE_OFF) { lVal = SCE_KERBEROS_OFF_VALUE; } else if ( m_cMinutes & DW_VALUE_FOREVER) { lVal = SCE_FOREVER_VALUE; } else { // Leave alone and let the OnKillActive catch it } } if ( 0 == lVal && (m_cMinutes & DW_VALUE_NOZERO) ) { // zero is not allowed if ( m_nLow > 0 ) { lVal = m_nLow; } else { lVal = 1; } } return lVal; } void CAttrNumber::OnConfigure() { CWnd *cwnd; CAttribute::OnConfigure(); // // Enable disable OK button depending on the state of the other controls. // cwnd = GetDlgItem(IDOK); if(cwnd){ if(!m_bConfigure){ cwnd->EnableWindow(TRUE); } else { OnUpdateNew(); } } } BOOL CAttrNumber::OnInitDialog() { CAttribute::OnInitDialog(); UpdateData(TRUE); /* if (m_bMinutes) { m_SpinValue.SetRange(-1,UD_MAXVAL-1); } else { m_SpinValue.SetRange(0,UD_MAXVAL); } */ AddUserControl(IDC_NEW); AddUserControl(IDC_SPIN); OnConfigure(); return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE } BOOL CAttrNumber::OnApply() { if ( !m_bReadOnly ) { BOOL bUpdateAll = FALSE; DWORD dw = 0; CString strForever,strOff; int status = 0; UpdateData(TRUE); if (!m_bConfigure) dw = SCE_NO_VALUE; else dw = CurrentEditValue(); bUpdateAll = FALSE; CEditTemplate *pet = m_pSnapin->GetTemplate(GT_COMPUTER_TEMPLATE,AREA_SECURITY_POLICY); // // Check the numbers dependencies if a dependency fails then the dialog // will return ERROR_MORE_DATA and we can display more information for the user // to see. // if(DDWarn.CheckDependencies( dw ) == ERROR_MORE_DATA ) { // // If the user presses cancel then we won't let them set this item's information // until they have set the configurion for the other items. // CThemeContextActivator activator; if( DDWarn.DoModal() != IDOK) return FALSE; // // The user pressed Auto set so we can set the other items. They are automatically set // to the correct values. // for(int i = 0; i < DDWarn.GetFailedCount(); i++) { PDEPENDENCYFAILED pItem = DDWarn.GetFailedInfo(i); if(pItem && pItem->pResult ) { pItem->pResult->SetBase( pItem->dwSuggested ); status = m_pSnapin->SetAnalysisInfo( pItem->pResult->GetID(), pItem->dwSuggested, pItem->pResult); pItem->pResult->SetStatus( status ); pItem->pResult->Update(m_pSnapin, FALSE); } } } // // Update the items security profile. // and redraw. // m_pData->SetBase((LONG_PTR)ULongToPtr(dw)); status = m_pSnapin->SetAnalysisInfo(m_pData->GetID(),(LONG_PTR)ULongToPtr(dw), m_pData); m_pData->SetStatus(status); m_pData->Update(m_pSnapin, FALSE); } return CAttribute::OnApply(); } void CAttrNumber::Initialize(CResult * pResult) { LONG_PTR dw=0; CAttribute::Initialize(pResult); DDWarn.InitializeDependencies(m_pSnapin,pResult); m_strUnits = pResult->GetUnits(); m_cMinutes = DW_VALUE_NOZERO; m_nLow = 0; m_nHigh = 999; m_nSave = 0; m_iNeverId = 0; m_iAccRate = 1; m_iStaticId = 0; CEditTemplate *pTemplate = pResult->GetBaseProfile(); switch (pResult->GetID()) { // below no zero value case IDS_LOCK_DURATION: m_cMinutes = DW_VALUE_FOREVER | DW_VALUE_NOZERO; m_nHigh = 99999; m_iStaticId = IDS_DURATION; m_iNeverId = IDS_LOCKOUT_FOREVER; m_pRDescription = g_rdLockoutAccount; break; case IDS_MAX_PAS_AGE: m_cMinutes = DW_VALUE_FOREVER | DW_VALUE_NOZERO; m_iStaticId = IDS_PASSWORD_EXPIRE; m_iNeverId = IDS_PASSWORD_FOREVER; break; // below zero value means differently case IDS_LOCK_COUNT: m_cMinutes = DW_VALUE_NEVER; m_iNeverId = IDS_NO_LOCKOUT; m_iStaticId = IDS_LOCKOUT_AFTER; break; case IDS_MIN_PAS_AGE: m_cMinutes = DW_VALUE_NEVER; m_iNeverId = IDS_CHANGE_IMMEDIATELY; m_iStaticId = IDS_PASSWORD_CHANGE; m_nHigh = 998; m_pRDescription = g_rdMinPassword; break; case IDS_MIN_PAS_LEN: m_cMinutes = DW_VALUE_NEVER; m_nHigh = 14; m_iNeverId = IDS_PERMIT_BLANK; m_iStaticId = IDS_PASSWORD_LEN; m_pRDescription = g_rdPasswordLen; break; case IDS_PAS_UNIQUENESS: m_cMinutes = DW_VALUE_NEVER; m_nHigh = 24; m_iNeverId = IDS_NO_HISTORY; m_iStaticId = IDS_PASSWORD_REMEMBER; break; // below there is no zero values case IDS_LOCK_RESET_COUNT: m_nLow = 1; m_nHigh = 99999; m_iStaticId = IDS_LOCK_RESET_COUNT; break; case IDS_SYS_LOG_MAX: case IDS_SEC_LOG_MAX: case IDS_APP_LOG_MAX: m_nLow = 64; m_nHigh = 4194240; m_iAccRate = 64; // no static text break; case IDS_SYS_LOG_DAYS: case IDS_SEC_LOG_DAYS: case IDS_APP_LOG_DAYS: m_nHigh = 365; m_nLow = 1; m_iStaticId = IDS_OVERWRITE_EVENT; break; case IDS_KERBEROS_MAX_AGE: m_cMinutes = DW_VALUE_FOREVER | DW_VALUE_NOZERO; m_nHigh = 99999; m_iStaticId = IDS_TICKET_EXPIRE; m_iNeverId = IDS_TICKET_FOREVER; break; case IDS_KERBEROS_RENEWAL: m_cMinutes = DW_VALUE_FOREVER | DW_VALUE_NOZERO; // | DW_VALUE_OFF; m_nHigh = 99999; m_iStaticId = IDS_TICKET_RENEWAL_EXPIRE; m_iNeverId = IDS_TICKET_RENEWAL_FOREVER; break; case IDS_KERBEROS_MAX_SERVICE: m_nLow = 10; m_cMinutes = DW_VALUE_FOREVER | DW_VALUE_NOZERO; m_iStaticId = IDS_TICKET_EXPIRE; m_iNeverId = IDS_TICKET_FOREVER; m_nHigh = 99999; break; case IDS_KERBEROS_MAX_CLOCK: m_cMinutes = DW_VALUE_FOREVER; m_nHigh = 99999; m_iStaticId = IDS_MAX_TOLERANCE; m_iNeverId = IDS_NO_MAX_TOLERANCE; break; } if ((m_cMinutes & DW_VALUE_NOZERO) && (0 == m_nLow)) { m_nLow = 1; } m_strTemplateTitle = _T(""); m_strLastInspectTitle = _T(""); m_strBase.Empty(); m_strSetting.Empty(); dw = pResult->GetBase(); if ((LONG_PTR)ULongToPtr(SCE_NO_VALUE) == dw) { m_bConfigure = FALSE; } else { m_bConfigure = TRUE; SetInitialValue(PtrToUlong((PVOID)dw)); } pResult->GetDisplayName( NULL, m_strSetting, 2 ); dw = pResult->GetSetting(); if ((LONG_PTR)ULongToPtr(SCE_NO_VALUE) != dw) { if ((LONG_PTR)ULongToPtr(SCE_FOREVER_VALUE) == dw) { if ( (m_cMinutes & DW_VALUE_FOREVER) && m_iNeverId > 0 ) { m_strLastInspectTitle.LoadString(m_iNeverId); } } else { if ( 0 == dw && (m_cMinutes & DW_VALUE_NEVER) && m_iNeverId > 0 ) { // zero means different values m_strLastInspectTitle.LoadString(m_iNeverId); } else if ( m_iStaticId > 0 ) { m_strLastInspectTitle.LoadString(m_iStaticId); } } } } void CAttrNumber::SetInitialValue(DWORD_PTR dw) { // // Don't overwrite an already set value. // if (!m_strBase.IsEmpty()) { return; } if (SCE_FOREVER_VALUE == dw) { m_strBase.LoadString(IDS_FOREVER); if ( (m_cMinutes & DW_VALUE_FOREVER) && m_iNeverId > 0 ) { m_strTemplateTitle.LoadString(m_iNeverId); } m_nSave = SCE_FOREVER_VALUE; } else if (SCE_KERBEROS_OFF_VALUE == dw) { m_strBase.LoadString(IDS_OFF); if ( (m_cMinutes & DW_VALUE_OFF) && m_iNeverId > 0 ) { m_strTemplateTitle.LoadString(m_iNeverId); } m_nSave = SCE_KERBEROS_OFF_VALUE; } else { m_nSave = dw; if ( 0 == dw && (m_cMinutes & DW_VALUE_NEVER) && m_iNeverId > 0 ) { // zero means different values m_strTemplateTitle.LoadString(m_iNeverId); } else if ( m_iStaticId > 0 ) { m_strTemplateTitle.LoadString(m_iStaticId); } m_strBase.Format(TEXT("%d"),dw); } } void CAttrNumber::OnUpdateNew() { DWORD dwRes = 0; UpdateData(TRUE); CString sNum; CEdit *pEdit = (CEdit *)GetDlgItem(IDC_NEW); CWnd *pOK = GetDlgItem(IDOK); DWORD dwValue = _ttoi(m_strBase); // // Don't do anything if the string is equal to predefined strings. // sNum.LoadString(IDS_FOREVER); if (m_strBase.IsEmpty()) { if (pOK) { pOK->EnableWindow(FALSE); } } else if (m_strBase == sNum) { if (pOK) { pOK->EnableWindow(TRUE); } } else { if ((long)dwValue < m_nLow) { // // Disable the OK button. // if ( pOK ) { pOK->EnableWindow(FALSE); } if (pEdit) { // // We will only force a select if edit text length >= // minimum text length // sNum.Format(TEXT("%d"), m_nLow); dwValue = m_nLow; if (sNum.GetLength() < m_strBase.GetLength()) { pEdit->SetSel(0, -1); } } } else if ( (long)dwValue > m_nHigh ) { if (pOK) { pOK->EnableWindow(TRUE); } if (pEdit) { if (m_cMinutes & DW_VALUE_FOREVER) { sNum.LoadString(IDS_FOREVER); dwValue = 0; } else { sNum.Format(TEXT("%d"), m_nHigh); dwValue = m_nHigh; } m_strBase = sNum; UpdateData(FALSE); pEdit->SetSel(0, -1); } } else { // // Enable the OK button. // if (pOK) { pOK->EnableWindow(TRUE); } } } // // Load the description for this string. // if ((dwValue <= 0) && (m_iNeverId != 0)) { m_strTemplateTitle.LoadString(m_iNeverId); } else { m_strTemplateTitle.LoadString(m_iStaticId); } GetDlgItem(IDC_TEMPLATE_TITLE)->SetWindowText(m_strTemplateTitle); SetModified(TRUE); //Raid #404145 } BOOL CAttrNumber::OnKillActive() { UINT uiVal = 0; LONG lVal = 0; BOOL bTrans = FALSE; CString strRange; int lMin = m_nLow; UpdateData(TRUE); if (m_cMinutes & DW_VALUE_NOZERO && !(m_cMinutes & DW_VALUE_FOREVER) && lMin == 0) { lMin = 1; } CString strFormat; strFormat.LoadString(IDS_RANGE); strRange.Format(strFormat,lMin,m_nHigh); uiVal = GetDlgItemInt(IDC_NEW,&bTrans,TRUE); lVal = uiVal; if ( !bTrans ) { CString str; if (m_cMinutes & DW_VALUE_FOREVER) { str.LoadString(IDS_FOREVER); if (str == m_strBase) { return TRUE;; } } lVal = _ttol((LPCTSTR)m_strBase); if ( lVal == 0 ) { // nonnumeric lVal = (LONG) m_nSave; m_strError = strRange; UpdateData(FALSE); return FALSE; } } if ( m_iAccRate > 1 && lVal > 0 ) { // for log max size, make it multiples of m_iAccRate int nCount = lVal % m_iAccRate; if ( nCount > 0 ) { lVal = ((LONG)(lVal/m_iAccRate))*m_iAccRate; } } if ( lVal > m_nHigh ) { m_strError = strRange; UpdateData(FALSE); return FALSE; } if ( (lVal < m_nLow) && (lVal != SCE_KERBEROS_OFF_VALUE) && (lVal != SCE_FOREVER_VALUE) ) { // if it is underflow, go back to high if (m_cMinutes & DW_VALUE_OFF) { lVal = SCE_KERBEROS_OFF_VALUE; } else if ( m_cMinutes & DW_VALUE_FOREVER) { lVal = SCE_FOREVER_VALUE; } else { // Leave alone and let the OnKillActive catch it } } if ( (lVal < m_nLow) && (lVal != SCE_KERBEROS_OFF_VALUE) && (lVal != SCE_FOREVER_VALUE) ) { // if it is underflow, go back to high m_strError = strRange; UpdateData(FALSE); return FALSE; } if ( 0 == lVal && (m_cMinutes & DW_VALUE_NOZERO) ) { // zero is not allowed m_strError = strRange; UpdateData(FALSE); return FALSE; } return CAttribute::OnKillActive(); }