2025-11-28 00:35:46 +09:00

352 lines
9.2 KiB
C++

/////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2003 <company name>
//
// Module Name:
// DDxDDv.cpp
//
// Description:
// Implementation of custom dialog data exchange/dialog data validation
// routines.
//
// Author:
// <name> (<e-mail name>) Mmmm DD, 2003
//
// Revision History:
//
// Notes:
// The IDS_REQUIRED_FIELD_EMPTY string resource must be defined in
// the resource file.
//
/////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "DDxDDv.h"
#include "resource.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
//++
//
// DDX_Number
//
// Description:
// Do data exchange between the dialog and the class.
//
// Arguments:
// pDXIn
// Data exchange object.
//
// nIDCIn
// Control ID.
//
// rdwValueInout
// Value to set or get.
//
// dwMinIn
// Minimum value.
//
// dwMaxIn
// Maximum value.
//
// fSignedIn
// TRUE = value is signed, FALSE = value is unsigned
//
// Return Value:
// None.
//
//--
/////////////////////////////////////////////////////////////////////////////
void AFXAPI
DDX_Number(
CDataExchange * pDXIn
, int nIDCIn
, DWORD & rdwValueInout
, DWORD dwMinIn
, DWORD dwMaxIn
, BOOL fSignedIn /* =FALSE */
)
{
HWND hwndCtrl = NULL;
DWORD dwValue = 0;
HRESULT hr = S_OK;
ASSERT( pDXIn != NULL );
#ifdef _DEBUG
if ( fSignedIn )
{
ASSERT( static_cast< LONG >( dwMinIn ) < static_cast< LONG >( dwMaxIn ) );
}
else
{
ASSERT( dwMinIn < dwMaxIn );
}
#endif // _DEBUG
AFX_MANAGE_STATE( AfxGetStaticModuleState() );
//
// Get the control window handle.
//
hwndCtrl = pDXIn->PrepareEditCtrl( nIDCIn );
if ( pDXIn->m_bSaveAndValidate )
{
BOOL bTranslated;
//
// Get the number from the control.
//
dwValue = GetDlgItemInt( pDXIn->m_pDlgWnd->m_hWnd, nIDCIn, &bTranslated, fSignedIn );
//
// If the retrival failed, it is a signed number, and the minimum
// value is the smallest negative value possible, check the string itself.
//
if ( ! bTranslated && fSignedIn && (dwMinIn == 0x80000000) )
{
UINT cch = 0;
TCHAR szNumber[ 20 ];
//
// See if it is the smallest negative number.
//
cch = GetDlgItemText( pDXIn->m_pDlgWnd->m_hWnd, nIDCIn, szNumber, RTL_NUMBER_OF( szNumber ) );
if ( (cch != 0) && (_tcsnicmp( szNumber, _T("-2147483648"), RTL_NUMBER_OF( szNumber ) ) == 0) )
{
dwValue = 0x80000000;
bTranslated = TRUE;
} // if: text retrieved successfully and is highest negative number
} // if: error translating number and getting signed number
//
// If the retrieval failed or the specified number is
// out of range, display an error.
//
if ( ! bTranslated
|| (fSignedIn
&& ( (static_cast< LONG >( dwValue ) < static_cast< LONG >( dwMinIn ))
|| (static_cast< LONG >( dwValue ) > static_cast< LONG >( dwMaxIn ))
)
)
|| (! fSignedIn
&& ( (dwValue < dwMinIn)
|| (dwValue > dwMaxIn)
)
)
)
{
TCHAR szMin[ 32 ];
TCHAR szMax[ 32 ];
CString strPrompt;
if ( fSignedIn )
{
hr = StringCchPrintf( szMin, RTL_NUMBER_OF( szMin ), _T("%d%"), dwMinIn );
ASSERT( SUCCEEDED( hr ) );
hr = StringCchPrintf( szMax, RTL_NUMBER_OF( szMax ), _T("%d%"), dwMaxIn );
ASSERT( SUCCEEDED( hr ) );
} // if: signed number
else
{
hr = StringCchPrintf( szMin, RTL_NUMBER_OF( szMin ), _T("%u%"), dwMinIn );
ASSERT( SUCCEEDED( hr ) );
hr = StringCchPrintf( szMax, RTL_NUMBER_OF( szMax ), _T("%u%"), dwMaxIn );
ASSERT( SUCCEEDED( hr ) );
} // else: unsigned number
AfxFormatString2( strPrompt, AFX_IDP_PARSE_INT_RANGE, szMin, szMax );
AfxMessageBox( strPrompt, MB_ICONEXCLAMATION, AFX_IDP_PARSE_INT_RANGE );
strPrompt.Empty(); // exception prep
pDXIn->Fail();
} // if: invalid string
else
{
rdwValueInout = dwValue;
} // if: number is in range
} // if: saving data
else
{
CString strMinValue;
CString strMaxValue;
UINT cchMax;
//
// Set the maximum number of characters that can be entered.
//
if ( fSignedIn )
{
strMinValue.Format( _T("%d"), dwMinIn );
strMaxValue.Format( _T("%d"), dwMaxIn );
} // if: signed value
else
{
strMinValue.Format( _T("%u"), dwMinIn );
strMaxValue.Format( _T("%u"), dwMaxIn );
} // else: unsigned value
cchMax = max( strMinValue.GetLength(), strMaxValue.GetLength() );
SendMessage( hwndCtrl, EM_LIMITTEXT, cchMax, 0 );
//
// Set the value into the control.
//
if ( fSignedIn )
{
LONG lValue = static_cast< LONG >( rdwValueInout );
DDX_Text( pDXIn, nIDCIn, lValue );
} // if: signed value
else
{
DDX_Text( pDXIn, nIDCIn, rdwValueInout );
} // else:
} // else: setting data onto the dialog
} //*** DDX_Number
/////////////////////////////////////////////////////////////////////////////
//++
//
// DDV_RequiredText
//
// Description:
// Validate that the dialog string is present.
//
// Arguments:
// pDXIn
// Data exchange object.
//
// nIDCIn
// Control ID.
//
// nIDCLabelIn
// Label control ID.
//
// rstrValueIn
// Value to set or get.
//
// Return Value:
// None.
//
//--
/////////////////////////////////////////////////////////////////////////////
void AFXAPI
DDV_RequiredText(
CDataExchange * pDXIn
, int nIDCIn
, int nIDCLabelIn
, const CString & rstrValueIn
)
{
ASSERT( pDXIn != NULL );
AFX_MANAGE_STATE( AfxGetStaticModuleState() );
if ( pDXIn->m_bSaveAndValidate )
{
if ( rstrValueIn.GetLength() == 0 )
{
HWND hwndLabel;
TCHAR szLabel[ 1024 ];
CString strPrompt;
// Get the label window handle
hwndLabel = pDXIn->PrepareEditCtrl( nIDCLabelIn );
// Get the text of the label.
GetWindowText( hwndLabel, szLabel, RTL_NUMBER_OF( szLabel ) );
// Remove ampersands (&) and colons (:).
CleanupLabel( szLabel );
// Format and display a message.
strPrompt.FormatMessage( IDS_REQUIRED_FIELD_EMPTY, szLabel );
AfxMessageBox( strPrompt, MB_ICONEXCLAMATION );
// Do this so that the control receives focus.
(void) pDXIn->PrepareEditCtrl( nIDCIn );
// Fail the call.
strPrompt.Empty(); // exception prep
pDXIn->Fail();
} // if: field not specified
} // if: saving data
} //*** DDV_RequiredText
/////////////////////////////////////////////////////////////////////////////
//++
//
// CleanupLabel
//
// Description:
// Prepare a label read from a dialog to be used as a string in a
// message by removing ampersands (&) and colons (:).
//
// Arguments:
// pwszLabelIn
// Label to be cleaned up.
//
// Return Value:
// None.
//
//--
/////////////////////////////////////////////////////////////////////////////
void
CleanupLabel( LPTSTR pwszLabelIn )
{
LPTSTR pin = NULL;
LPTSTR pout = NULL;
LANGID langid;
WORD primarylangid;
BOOL fFELanguage;
//
// Get the language ID.
//
langid = GetUserDefaultLangID();
primarylangid = static_cast< WORD >( PRIMARYLANGID( langid ) );
fFELanguage = ((primarylangid == LANG_JAPANESE)
|| (primarylangid == LANG_CHINESE)
|| (primarylangid == LANG_KOREAN) );
//
// Copy the name sans '&' and ':' chars
//
pin = pout = pwszLabelIn;
do
{
//
// Strip FE accelerators with parentheses. e.g. "foo(&F)" -> "foo"
//
if ( fFELanguage
&& (pin[ 0 ] == _T('('))
&& (pin[ 1 ] == _T('&'))
&& (pin[ 2 ] != _T('\0'))
&& (pin[ 3 ] == _T(')')) )
{
pin += 3;
} // if: Far East language with accelerator
else if ( (*pin != _T('&')) && (*pin != _T(':')) )
{
*pout++ = *pin;
} // else if: accelerator found
} while ( *pin++ != _T('\0') );
} //*** CleanupLabel