/*!
  @file           vos223.cpp
  @author         RaymondR
  @brief          MSCS - Implementation of custom dialog data exchange/dialog data validation
  @see            

\if EMIT_LICENCE

    ========== licence begin  GPL
    Copyright (c) 2000-2005 SAP AG

    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
    as published by the Free Software Foundation; either version 2
    of the License, or (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
    ========== licence end



\endif
*/




/*===========================================================================*
 *  INCLUDES                                                                 *
 *===========================================================================*/

#include "gos220.h"
#include "gos223.h"
#include "gos229.h"


/*===========================================================================*
 *  DEFINES                                                                  *
 *===========================================================================*/

#ifdef _DEBUG
# define new DEBUG_NEW
# undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif


/*===========================================================================*
 *  MACROS                                                                   *
 *===========================================================================*/



/*===========================================================================*
 *  LOCAL CLASSES, STRUCTURES, TYPES, UNIONS ...                             *
 *===========================================================================*/



/*===========================================================================*
 *  GLOBAL VARIABLES                                                         *
 *===========================================================================*/



/*===========================================================================*
 *  LOCAL VARIABLES                                                          *
 *===========================================================================*/



/*===========================================================================*
 *  STATIC/INLINE FUNCTIONS (PROTOTYPES)                                     *
 *===========================================================================*/

static void CleanupLabel(LPTSTR psz);


/*===========================================================================*
 *  PUBLIC FUNCTIONS (CODE)                                                  *
 *===========================================================================*/

/////////////////////////////////////////////////////////////////////////////
//++
//
//	DDX_Number
//
//	Routine Description:
//		Do data exchange between the dialog and the class.
//
//	Arguments:
//		pDX			[IN OUT] Data exchange object 
//		nIDC		[IN] Control ID.
//		dwValue		[IN OUT] Value to set or get.
//		dwMin		[IN] Minimum value.
//		dwMax		[IN] Maximum value.
//		bSigned		[IN] TRUE = value is signed, FALSE = value is unsigned
//
//	Return Value:
//		None.
//
//--
/////////////////////////////////////////////////////////////////////////////

void AFXAPI DDX_Number(
	IN OUT CDataExchange *	pDX,
	IN int					nIDC,
	IN OUT DWORD &			rdwValue,
	IN DWORD				dwMin,
	IN DWORD				dwMax,
	IN BOOL					bSigned
	)
{
	HWND	hwndCtrl;
	DWORD	dwValue;

	ASSERT(pDX != NULL);
#ifdef _DEBUG
	if (bSigned)
	{
		ASSERT((LONG) dwMin < (LONG) dwMax);
	}
	else
	{
		ASSERT(dwMin < dwMax);
	}
#endif // _DEBUG

	AFX_MANAGE_STATE(AfxGetStaticModuleState());

	// Get the control window handle.
	hwndCtrl = pDX->PrepareEditCtrl(nIDC);

	if (pDX->m_bSaveAndValidate)
	{
		BOOL	bTranslated;

		// Get the number from the control.
		dwValue = GetDlgItemInt(pDX->m_pDlgWnd->m_hWnd, nIDC, &bTranslated, bSigned);

		// 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 && bSigned && (dwMin == 0x80000000))
		{
			UINT	cch;
			TCHAR	szNumber[20];

			// See if it is the smallest negative number.
			cch = GetDlgItemText(pDX->m_pDlgWnd->m_hWnd, nIDC, szNumber, sizeof(szNumber) / sizeof(TCHAR));
			if ((cch != 0) && (lstrcmp(szNumber, _T("-2147483648")) == 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
			|| (bSigned && (((LONG) dwValue < (LONG) dwMin) || ((LONG) dwValue > (LONG) dwMax)))
			|| (!bSigned && ((dwValue < dwMin) || (dwValue > dwMax)))
			)
		{
			TCHAR szMin[32];
			TCHAR szMax[32];
			CString strPrompt;

			if (bSigned)
			{
				wsprintf(szMin, _T("%d%"), dwMin);
				wsprintf(szMax, _T("%d%"), dwMax);
			}  // if:  signed number
			else
			{
				wsprintf(szMin, _T("%u%"), dwMin);
				wsprintf(szMax, _T("%u%"), dwMax);
			}  // 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
			pDX->Fail();
		}  // if:  invalid string
		else
			rdwValue = dwValue;
	}  // if:  saving data
	else
	{
		CString		strMinValue;
		CString		strMaxValue;
		UINT		cchMax;

		// Set the maximum number of characters that can be entered.
		if (bSigned)
		{
			strMinValue.Format(_T("%d"), dwMin);
			strMaxValue.Format(_T("%d"), dwMax);
		}  // if:  signed value
		else
		{
			strMinValue.Format(_T("%u"), dwMin);
			strMaxValue.Format(_T("%u"), dwMax);
		}  // else:  unsigned value
		cchMax = max(strMinValue.GetLength(), strMaxValue.GetLength());
		SendMessage(hwndCtrl, EM_LIMITTEXT, cchMax, 0);

		// Set the value into the control.
		if (bSigned)
		{
			LONG lValue = (LONG) rdwValue;
			DDX_Text(pDX, nIDC, lValue);
		}  // if:  signed value
		else
			DDX_Text(pDX, nIDC, rdwValue);
	}  // else:  setting data onto the dialog

}  //*** DDX_Number()

/////////////////////////////////////////////////////////////////////////////
//++
//
//	DDV_RequiredText
//
//	Routine Description:
//		Validate that the dialog string is present.
//
//	Arguments:
//		pDX			[IN OUT] Data exchange object 
//		nIDC		[IN] Control ID.
//		nIDCLabel	[IN] Label control ID.
//		rstrValue	[IN] Value to set or get.
//
//	Return Value:
//		None.
//
//--
/////////////////////////////////////////////////////////////////////////////

void AFXAPI DDV_RequiredText(
	IN OUT CDataExchange *	pDX,
	IN int					nIDC,
	IN int					nIDCLabel,
	IN const CString &		rstrValue
	)
{
	ASSERT(pDX != NULL);

	AFX_MANAGE_STATE(AfxGetStaticModuleState());

	if (pDX->m_bSaveAndValidate)
	{
		if (rstrValue.GetLength() == 0)
		{
			HWND		hwndLabel;
			TCHAR		szLabel[1024];
			CString		strPrompt;

			// Get the label window handle
			hwndLabel = pDX->PrepareEditCtrl(nIDCLabel);

			// Get the text of the label.
			GetWindowText(hwndLabel, szLabel, sizeof(szLabel) / sizeof(TCHAR));

			// 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) pDX->PrepareEditCtrl(nIDC);

			// Fail the call.
			strPrompt.Empty();	// exception prep
			pDX->Fail();
		}  // if:  field not specified
	}  // if:  saving data

}  //*** DDV_RequiredText()



/*===========================================================================*
 *  LOCAL/PRIVATE/PROTECTED FUNCTIONS (CODE)                                 *
 *===========================================================================*/


/////////////////////////////////////////////////////////////////////////////
//++
//
//	CleanupLabel
//
//	Routine Description:
//		Prepare a label read from a dialog to be used as a string in a
//		message by removing ampersands (&) and colons (:).
//
//	Arguments:
//		pszLabel	[IN OUT] Label to be cleaned up.
//
//	Return Value:
//		None.
//
//--
/////////////////////////////////////////////////////////////////////////////

static void CleanupLabel(LPTSTR pszLabel)
{
	LPTSTR	pIn, pOut;
	LANGID	langid;
	WORD	primarylangid;
	BOOL	bFELanguage;

	// Get the language ID.
	langid = GetUserDefaultLangID();
	primarylangid = (WORD) PRIMARYLANGID(langid);
	bFELanguage = ((primarylangid == LANG_JAPANESE)
					|| (primarylangid == LANG_CHINESE)
					|| (primarylangid == LANG_KOREAN));

	//
	// copy the name sans '&' and ':' chars
	//

	pIn = pOut = pszLabel;
	do
	{
		//
		// strip FE accelerators with parentheses. e.g. "foo(&F)" -> "foo"
		//
		if (   bFELanguage
			&& (pIn[0] == _T('('))
			&& (pIn[1] == _T('&'))
			&& (pIn[2] != _T('\0'))
			&& (pIn[3] == _T(')')))
		{
			pIn += 3;
		}
		else if ((*pIn != _T('&')) && (*pIn != _T(':')))
			*pOut++ = *pIn;
	} while (*pIn++ != _T('\0')) ;

}  //*** CleanupLabel()


/*===========================================================================*
 *  END OF CODE                                                              *
 *===========================================================================*/