windows-nt/Source/XPSP1/NT/inetsrv/iis/admin/common/ddxv.cpp
2020-09-26 16:20:57 +08:00

485 lines
8.7 KiB
C++

/*++
Copyright (c) 1994-1999 Microsoft Corporation
Module Name :
ddxv.cpp
Abstract:
DDX/DDV Routines
Author:
Ronald Meijer (ronaldm)
Project:
Internet Services Manager
Revision History:
--*/
//
// Include Files
//
#include "stdafx.h"
#include "common.h"
#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif
#define new DEBUG_NEW
//
// Prototype for external function
//
void AFXAPI AfxSetWindowText(HWND hWndCtrl, LPCTSTR lpszNew);
//
// Numeric strings cannot be longer than 32 digits
//
#define NUMERIC_BUFF_SIZE (32)
//
// Dummy password used for display purposes
//
LPCTSTR g_lpszDummyPassword = _T("**********");
extern HINSTANCE hDLLInstance;
void
AFXAPI DDV_MinChars(
IN CDataExchange * pDX,
IN CString const & value,
IN int nChars
)
/*++
Routine Description:
Validate CString using a minimum string length
Arguments:
CDataExchange * pDX : Data exchange structure
CString const & value : String to be validated
int nChars : Minimum length of string
Return Value:
None
--*/
{
if (pDX->m_bSaveAndValidate && value.GetLength() < nChars)
{
TCHAR szT[NUMERIC_BUFF_SIZE + 1];
wsprintf(szT, _T("%d"), nChars);
CString prompt;
::AfxFormatString1(prompt, IDS_DDX_MINIMUM, szT);
::AfxMessageBox(prompt, MB_ICONEXCLAMATION, IDS_DDX_MINIMUM);
//
// exception prep
//
prompt.Empty();
pDX->Fail();
}
}
void
AFXAPI DDV_MinMaxChars(
IN CDataExchange * pDX,
IN CString const & value,
IN int nMinChars,
IN int nMaxChars
)
/*++
Routine Description:
Validate CString using a minimum and maximum string length.
Arguments:
CDataExchange * pDX : Data exchange structure
CString const & value : String to be validated
int nMinChars : Minimum length of string
int nMaxChars : Maximum length of string
Return Value:
None
--*/
{
if (pDX->m_bSaveAndValidate)
{
UINT nID;
TCHAR szT[NUMERIC_BUFF_SIZE + 1];
if (value.GetLength() < nMinChars)
{
nID = IDS_DDX_MINIMUM;
::wsprintf(szT, _T("%d"), nMinChars);
}
else if (value.GetLength() > nMaxChars)
{
nID = AFX_IDP_PARSE_STRING_SIZE;
::wsprintf(szT, _T("%d"), nMaxChars);
}
else
{
//
// Passes both our tests, it's ok.
//
return;
}
CString prompt;
::AfxFormatString1(prompt, nID, szT);
::AfxMessageBox(prompt, MB_ICONEXCLAMATION, nID);
//
// exception prep
//
prompt.Empty();
pDX->Fail();
}
else if (pDX->m_hWndLastControl != NULL && pDX->m_bEditLastControl)
{
//
// limit the control max-chars automatically
//
::SendMessage(pDX->m_hWndLastControl, EM_LIMITTEXT, nMaxChars, 0);
}
}
void
AFXAPI DDX_Spin(
IN CDataExchange * pDX,
IN int nIDC,
IN OUT int & value
)
/*++
Routine Description:
Save/store data from spinbutton control
Arguments:
CDataExchange * pDX : Data exchange structure
int nIDC : Control ID of the spinbutton control
int & value : Value to be saved or stored
Return Value:
None
--*/
{
HWND hWndCtrl = pDX->PrepareCtrl(nIDC);
if (pDX->m_bSaveAndValidate)
{
value = (int)LOWORD(::SendMessage(hWndCtrl, UDM_GETPOS, 0, 0L));
}
else
{
::SendMessage(hWndCtrl, UDM_SETPOS, 0, MAKELPARAM(value, 0));
}
}
void
AFXAPI DDV_MinMaxSpin(
IN CDataExchange * pDX,
IN HWND hWndControl,
IN int minVal,
IN int maxVal
)
/*++
Routine Description:
Enforce minimum/maximum spin button range
Arguments:
CDataExchange * pDX : Data exchange structure
HWND hWndControl : Control window handle
int minVal : Minimum value
int maxVal : Maximum value
Return Value:
None
Note:
Unlike most data validation routines, this one
MUST be used prior to an accompanying DDX_Spin()
function. This is because spinbox controls have a
native limit of 0-100. Also, this function requires
a window handle to the child control. The
CONTROL_HWND macro can be used for this.
--*/
{
ASSERT(minVal <= maxVal);
if (!pDX->m_bSaveAndValidate && hWndControl != NULL)
{
//
// limit the control range automatically
//
::SendMessage(hWndControl, UDM_SETRANGE, 0, MAKELPARAM(maxVal, minVal));
}
}
void
AFXAPI DDX_Password(
IN CDataExchange * pDX,
IN int nIDC,
IN OUT CString & value,
IN LPCTSTR lpszDummy
)
/*++
Routine Description:
DDX_Text for passwords. Always display a dummy string
instead of the real password, and ask for confirmation
if the password has changed
Arguments:
CDataExchange * pDX : Data exchange structure
int nIDC : Control ID
CString & value : value
LPCTSTR lpszDummy : Dummy password string to be displayed
Return Value:
None
--*/
{
HWND hWndCtrl = pDX->PrepareEditCtrl(nIDC);
if (pDX->m_bSaveAndValidate)
{
if (!::SendMessage(hWndCtrl, EM_GETMODIFY, 0, 0))
{
TRACEEOLID("No changes -- skipping");
return;
}
CString strNew;
int nLen = ::GetWindowTextLength(hWndCtrl);
::GetWindowText(hWndCtrl, strNew.GetBufferSetLength(nLen), nLen + 1);
strNew.ReleaseBuffer();
/*
if (strNew == value)
{
TRACEEOLID("Password already matches -- skipping");
return;
}
*/
//
// Password has changed -- ask for confirmation
//
HINSTANCE hOld = AfxGetResourceHandle();
AfxSetResourceHandle(hDLLInstance);
CConfirmDlg dlg;
if (dlg.DoModal() == IDOK)
{
if (strNew.Compare(dlg.GetPassword()) == 0)
{
//
// Password ok, pass it on
//
value = strNew;
return;
}
else
{
//
// No match, bad password
//
::AfxMessageBox(IDS_PASSWORD_NO_MATCH);
}
}
AfxSetResourceHandle(hOld);
//
// throw exception
//
pDX->Fail();
}
else
{
//
// Put the dummy password string in the edit control
//
if (!value.IsEmpty())
{
::AfxSetWindowText(hWndCtrl, lpszDummy);
}
}
}
void
AFXAPI DDX_Text(
IN CDataExchange * pDX,
IN int nIDC,
IN OUT CILong & value
)
/*++
Routine Description:
DDX_Text for CILong class. CILong takes care of all the dirty
work for output and input.
Arguments:
CDataExchange * pDX : Data exchange structure
int nIDC : Control ID code
CILong & value : value
Return Value:
None
--*/
{
HWND hWndCtrl = pDX->PrepareEditCtrl(nIDC);
pDX->m_bEditLastControl = TRUE;
TCHAR szT[NUMERIC_BUFF_SIZE + 1];
if (pDX->m_bSaveAndValidate)
{
LONG l;
::GetWindowText(hWndCtrl, szT, NUMERIC_BUFF_SIZE);
if (CINumber::ConvertStringToLong(szT, l))
{
value = l;
}
else
{
HINSTANCE hOld = AfxGetResourceHandle();
AfxSetResourceHandle(hDLLInstance);
::AfxMessageBox(IDS_INVALID_NUMBER);
AfxSetResourceHandle(hOld);
//
// Throw exception
//
pDX->Fail();
}
}
else
{
::wsprintf(szT, _T("%s"), (LPCTSTR)value);
::AfxSetWindowText(hWndCtrl, szT);
}
}
CConfirmDlg::CConfirmDlg(
IN CWnd * pParent OPTIONAL
)
/*++
Routine Description:
Constructor for the confirmation dialog -- brought up by the password ddx
whenever password confirmation is necessary.
Arguments:
CWnd * pParent : Optional parent window
Return Value:
None
--*/
: CDialog(CConfirmDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CConfirmDlg)
m_strPassword = _T("");
//}}AFX_DATA_INIT
}
void
CConfirmDlg::DoDataExchange(
IN CDataExchange * pDX
)
/*++
Routine Description:
Initialise/Store control data
Arguments:
CDataExchange* pDX - DDX/DDV control structure
Return Value:
N/A
--*/
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CConfirmDlg)
DDX_Text(pDX, IDC_EDIT_CONFIRM_PASSWORD, m_strPassword);
//}}AFX_DATA_MAP
}
//
// Message Handlers
//
BEGIN_MESSAGE_MAP(CConfirmDlg, CDialog)
//{{AFX_MSG_MAP(CConfirmDlg)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()