Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

301 lines
9.0 KiB

  1. /////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 2002 Microsoft Corporation
  4. //
  5. // Module Name:
  6. // DDxDDv.cpp
  7. //
  8. // Description:
  9. // Implementation of custom dialog data exchange/dialog data validation
  10. // routines.
  11. //
  12. // Author:
  13. // <name> (<e-mail name>) Mmmm DD, 2002
  14. //
  15. // Revision History:
  16. //
  17. // Notes:
  18. // The IDS_REQUIRED_FIELD_EMPTY string resource must be defined in
  19. // the resource file.
  20. //
  21. /////////////////////////////////////////////////////////////////////////////
  22. #include "stdafx.h"
  23. #include "DDxDDv.h"
  24. #include "resource.h"
  25. #ifdef _DEBUG
  26. #define new DEBUG_NEW
  27. #undef THIS_FILE
  28. static char THIS_FILE[] = __FILE__;
  29. #endif
  30. /////////////////////////////////////////////////////////////////////////////
  31. // Static Function Prototypes
  32. /////////////////////////////////////////////////////////////////////////////
  33. static void CleanupLabel( LPTSTR psz );
  34. /////////////////////////////////////////////////////////////////////////////
  35. //++
  36. //
  37. // DDX_Number
  38. //
  39. // Description:
  40. // Do data exchange between the dialog and the class.
  41. //
  42. // Arguments:
  43. // pDX [IN OUT] Data exchange object
  44. // nIDC [IN] Control ID.
  45. // dwValue [IN OUT] Value to set or get.
  46. // dwMin [IN] Minimum value.
  47. // dwMax [IN] Maximum value.
  48. // bSigned [IN] TRUE = value is signed, FALSE = value is unsigned
  49. //
  50. // Return Value:
  51. // None.
  52. //
  53. //--
  54. /////////////////////////////////////////////////////////////////////////////
  55. void AFXAPI DDX_Number(
  56. IN OUT CDataExchange * pDX,
  57. IN int nIDC,
  58. IN OUT DWORD & rdwValue,
  59. IN DWORD dwMin,
  60. IN DWORD dwMax,
  61. IN BOOL bSigned
  62. )
  63. {
  64. HWND hwndCtrl;
  65. DWORD dwValue;
  66. ASSERT( pDX != NULL );
  67. #ifdef _DEBUG
  68. if ( bSigned )
  69. {
  70. ASSERT( static_cast< LONG >( dwMin ) < static_cast< LONG >( dwMax ) );
  71. }
  72. else
  73. {
  74. ASSERT( dwMin < dwMax );
  75. }
  76. #endif // _DEBUG
  77. AFX_MANAGE_STATE( AfxGetStaticModuleState() );
  78. // Get the control window handle.
  79. hwndCtrl = pDX->PrepareEditCtrl( nIDC );
  80. if ( pDX->m_bSaveAndValidate )
  81. {
  82. BOOL bTranslated;
  83. // Get the number from the control.
  84. dwValue = GetDlgItemInt( pDX->m_pDlgWnd->m_hWnd, nIDC, &bTranslated, bSigned );
  85. // If the retrival failed, it is a signed number, and the minimum
  86. // value is the smallest negative value possible, check the string itself.
  87. if ( ! bTranslated && bSigned && (dwMin == 0x80000000) )
  88. {
  89. UINT cch;
  90. TCHAR szNumber[ 20 ];
  91. // See if it is the smallest negative number.
  92. cch = GetDlgItemText( pDX->m_pDlgWnd->m_hWnd, nIDC, szNumber, sizeof( szNumber ) / sizeof( TCHAR ) );
  93. if ( (cch != 0) && (lstrcmp( szNumber, _T("-2147483648") ) == 0) )
  94. {
  95. dwValue = 0x80000000;
  96. bTranslated = TRUE;
  97. } // if: text retrieved successfully and is highest negative number
  98. } // if: error translating number and getting signed number
  99. // If the retrieval failed or the specified number is
  100. // out of range, display an error.
  101. if ( ! bTranslated
  102. || (bSigned
  103. && ( (static_cast< LONG >( dwValue ) < static_cast< LONG >( dwMin ))
  104. || (static_cast< LONG >( dwValue ) > static_cast< LONG >( dwMax ))
  105. )
  106. )
  107. || (! bSigned
  108. && ( (dwValue < dwMin)
  109. || (dwValue > dwMax)
  110. )
  111. )
  112. )
  113. {
  114. TCHAR szMin[ 32 ];
  115. TCHAR szMax[ 32 ];
  116. CString strPrompt;
  117. if ( bSigned )
  118. {
  119. wsprintf( szMin, _T("%d%"), dwMin );
  120. wsprintf( szMax, _T("%d%"), dwMax );
  121. } // if: signed number
  122. else
  123. {
  124. wsprintf( szMin, _T("%u%"), dwMin );
  125. wsprintf( szMax, _T("%u%"), dwMax );
  126. } // else: unsigned number
  127. AfxFormatString2( strPrompt, AFX_IDP_PARSE_INT_RANGE, szMin, szMax );
  128. AfxMessageBox( strPrompt, MB_ICONEXCLAMATION, AFX_IDP_PARSE_INT_RANGE );
  129. strPrompt.Empty(); // exception prep
  130. pDX->Fail();
  131. } // if: invalid string
  132. else
  133. {
  134. rdwValue = dwValue;
  135. } // if: number is in range
  136. } // if: saving data
  137. else
  138. {
  139. CString strMinValue;
  140. CString strMaxValue;
  141. UINT cchMax;
  142. // Set the maximum number of characters that can be entered.
  143. if ( bSigned )
  144. {
  145. strMinValue.Format( _T("%d"), dwMin );
  146. strMaxValue.Format( _T("%d"), dwMax );
  147. } // if: signed value
  148. else
  149. {
  150. strMinValue.Format( _T("%u"), dwMin );
  151. strMaxValue.Format( _T("%u"), dwMax );
  152. } // else: unsigned value
  153. cchMax = max( strMinValue.GetLength(), strMaxValue.GetLength() );
  154. SendMessage( hwndCtrl, EM_LIMITTEXT, cchMax, 0 );
  155. // Set the value into the control.
  156. if ( bSigned )
  157. {
  158. LONG lValue = static_cast< LONG >( rdwValue );
  159. DDX_Text( pDX, nIDC, lValue );
  160. } // if: signed value
  161. else
  162. DDX_Text( pDX, nIDC, rdwValue );
  163. } // else: setting data onto the dialog
  164. } //*** DDX_Number()
  165. /////////////////////////////////////////////////////////////////////////////
  166. //++
  167. //
  168. // DDV_RequiredText
  169. //
  170. // Description:
  171. // Validate that the dialog string is present.
  172. //
  173. // Arguments:
  174. // pDX [IN OUT] Data exchange object
  175. // nIDC [IN] Control ID.
  176. // nIDCLabel [IN] Label control ID.
  177. // rstrValue [IN] Value to set or get.
  178. //
  179. // Return Value:
  180. // None.
  181. //
  182. //--
  183. /////////////////////////////////////////////////////////////////////////////
  184. void AFXAPI DDV_RequiredText(
  185. IN OUT CDataExchange * pDX,
  186. IN int nIDC,
  187. IN int nIDCLabel,
  188. IN const CString & rstrValue
  189. )
  190. {
  191. ASSERT( pDX != NULL );
  192. AFX_MANAGE_STATE( AfxGetStaticModuleState() );
  193. if ( pDX->m_bSaveAndValidate )
  194. {
  195. if ( rstrValue.GetLength() == 0 )
  196. {
  197. HWND hwndLabel;
  198. TCHAR szLabel[ 1024 ];
  199. CString strPrompt;
  200. // Get the label window handle
  201. hwndLabel = pDX->PrepareEditCtrl( nIDCLabel );
  202. // Get the text of the label.
  203. GetWindowText( hwndLabel, szLabel, sizeof( szLabel ) / sizeof( TCHAR ) );
  204. // Remove ampersands (&) and colons (:).
  205. CleanupLabel( szLabel );
  206. // Format and display a message.
  207. strPrompt.FormatMessage( IDS_REQUIRED_FIELD_EMPTY, szLabel );
  208. AfxMessageBox( strPrompt, MB_ICONEXCLAMATION );
  209. // Do this so that the control receives focus.
  210. (void) pDX->PrepareEditCtrl( nIDC );
  211. // Fail the call.
  212. strPrompt.Empty(); // exception prep
  213. pDX->Fail();
  214. } // if: field not specified
  215. } // if: saving data
  216. } //*** DDV_RequiredText()
  217. /////////////////////////////////////////////////////////////////////////////
  218. //++
  219. //
  220. // CleanupLabel
  221. //
  222. // Description:
  223. // Prepare a label read from a dialog to be used as a string in a
  224. // message by removing ampersands (&) and colons (:).
  225. //
  226. // Arguments:
  227. // pszLabel [IN OUT] Label to be cleaned up.
  228. //
  229. // Return Value:
  230. // None.
  231. //
  232. //--
  233. /////////////////////////////////////////////////////////////////////////////
  234. static void CleanupLabel( LPTSTR pszLabel )
  235. {
  236. LPTSTR pIn, pOut;
  237. LANGID langid;
  238. WORD primarylangid;
  239. BOOL bFELanguage;
  240. // Get the language ID.
  241. langid = GetUserDefaultLangID();
  242. primarylangid = static_cast< WORD >( PRIMARYLANGID( langid ) );
  243. bFELanguage = ((primarylangid == LANG_JAPANESE)
  244. || (primarylangid == LANG_CHINESE)
  245. || (primarylangid == LANG_KOREAN) );
  246. //
  247. // Copy the name sans '&' and ':' chars
  248. //
  249. pIn = pOut = pszLabel;
  250. do
  251. {
  252. //
  253. // Strip FE accelerators with parentheses. e.g. "foo(&F)" -> "foo"
  254. //
  255. if ( bFELanguage
  256. && (pIn[ 0 ] == _T('('))
  257. && (pIn[ 1 ] == _T('&'))
  258. && (pIn[ 2 ] != _T('\0'))
  259. && (pIn[ 3 ] == _T(')')) )
  260. {
  261. pIn += 3;
  262. } // if: Far East language with accelerator
  263. else if ( (*pIn != _T('&')) && (*pIn != _T(':')) )
  264. {
  265. *pOut++ = *pIn;
  266. } // else if: accelerator found
  267. } while ( *pIn++ != _T('\0') );
  268. } //*** CleanupLabel()