Source code of Windows XP (NT5)
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.

289 lines
6.9 KiB

  1. /////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (C) 1998-2000 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. // Maintained By:
  13. // Galen Barbee (GalenB) Mmmm DD, 1998
  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. // Routine 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((LONG) dwMin < (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 && (((LONG) dwValue < (LONG) dwMin) || ((LONG) dwValue > (LONG) dwMax)))
  103. || (!bSigned && ((dwValue < dwMin) || (dwValue > dwMax)))
  104. )
  105. {
  106. TCHAR szMin[32];
  107. TCHAR szMax[32];
  108. CString strPrompt;
  109. if (bSigned)
  110. {
  111. wsprintf(szMin, _T("%d%"), dwMin);
  112. wsprintf(szMax, _T("%d%"), dwMax);
  113. } // if: signed number
  114. else
  115. {
  116. wsprintf(szMin, _T("%u%"), dwMin);
  117. wsprintf(szMax, _T("%u%"), dwMax);
  118. } // else: unsigned number
  119. AfxFormatString2(strPrompt, AFX_IDP_PARSE_INT_RANGE, szMin, szMax);
  120. AfxMessageBox(strPrompt, MB_ICONEXCLAMATION, AFX_IDP_PARSE_INT_RANGE);
  121. strPrompt.Empty(); // exception prep
  122. pDX->Fail();
  123. } // if: invalid string
  124. else
  125. rdwValue = dwValue;
  126. } // if: saving data
  127. else
  128. {
  129. CString strMinValue;
  130. CString strMaxValue;
  131. UINT cchMax;
  132. // Set the maximum number of characters that can be entered.
  133. if (bSigned)
  134. {
  135. strMinValue.Format(_T("%d"), dwMin);
  136. strMaxValue.Format(_T("%d"), dwMax);
  137. } // if: signed value
  138. else
  139. {
  140. strMinValue.Format(_T("%u"), dwMin);
  141. strMaxValue.Format(_T("%u"), dwMax);
  142. } // else: unsigned value
  143. cchMax = max(strMinValue.GetLength(), strMaxValue.GetLength());
  144. SendMessage(hwndCtrl, EM_LIMITTEXT, cchMax, 0);
  145. // Set the value into the control.
  146. if (bSigned)
  147. {
  148. LONG lValue = (LONG) rdwValue;
  149. DDX_Text(pDX, nIDC, lValue);
  150. } // if: signed value
  151. else
  152. DDX_Text(pDX, nIDC, rdwValue);
  153. } // else: setting data onto the dialog
  154. } //*** DDX_Number()
  155. /////////////////////////////////////////////////////////////////////////////
  156. //++
  157. //
  158. // DDV_RequiredText
  159. //
  160. // Routine Description:
  161. // Validate that the dialog string is present.
  162. //
  163. // Arguments:
  164. // pDX [IN OUT] Data exchange object
  165. // nIDC [IN] Control ID.
  166. // nIDCLabel [IN] Label control ID.
  167. // rstrValue [IN] Value to set or get.
  168. //
  169. // Return Value:
  170. // None.
  171. //
  172. //--
  173. /////////////////////////////////////////////////////////////////////////////
  174. void AFXAPI DDV_RequiredText(
  175. IN OUT CDataExchange * pDX,
  176. IN int nIDC,
  177. IN int nIDCLabel,
  178. IN const CString & rstrValue
  179. )
  180. {
  181. ASSERT(pDX != NULL);
  182. AFX_MANAGE_STATE(AfxGetStaticModuleState());
  183. if (pDX->m_bSaveAndValidate)
  184. {
  185. if (rstrValue.GetLength() == 0)
  186. {
  187. HWND hwndLabel;
  188. TCHAR szLabel[1024];
  189. CString strPrompt;
  190. // Get the label window handle
  191. hwndLabel = pDX->PrepareEditCtrl(nIDCLabel);
  192. // Get the text of the label.
  193. GetWindowText(hwndLabel, szLabel, sizeof(szLabel) / sizeof(TCHAR));
  194. // Remove ampersands (&) and colons (:).
  195. CleanupLabel(szLabel);
  196. // Format and display a message.
  197. strPrompt.FormatMessage(IDS_REQUIRED_FIELD_EMPTY, szLabel);
  198. AfxMessageBox(strPrompt, MB_ICONEXCLAMATION);
  199. // Do this so that the control receives focus.
  200. (void) pDX->PrepareEditCtrl(nIDC);
  201. // Fail the call.
  202. strPrompt.Empty(); // exception prep
  203. pDX->Fail();
  204. } // if: field not specified
  205. } // if: saving data
  206. } //*** DDV_RequiredText()
  207. /////////////////////////////////////////////////////////////////////////////
  208. //++
  209. //
  210. // CleanupLabel
  211. //
  212. // Routine Description:
  213. // Prepare a label read from a dialog to be used as a string in a
  214. // message by removing ampersands (&) and colons (:).
  215. //
  216. // Arguments:
  217. // pszLabel [IN OUT] Label to be cleaned up.
  218. //
  219. // Return Value:
  220. // None.
  221. //
  222. //--
  223. /////////////////////////////////////////////////////////////////////////////
  224. static void CleanupLabel(LPTSTR pszLabel)
  225. {
  226. LPTSTR pIn, pOut;
  227. LANGID langid;
  228. WORD primarylangid;
  229. BOOL bFELanguage;
  230. // Get the language ID.
  231. langid = GetUserDefaultLangID();
  232. primarylangid = (WORD) PRIMARYLANGID(langid);
  233. bFELanguage = ((primarylangid == LANG_JAPANESE)
  234. || (primarylangid == LANG_CHINESE)
  235. || (primarylangid == LANG_KOREAN));
  236. //
  237. // copy the name sans '&' and ':' chars
  238. //
  239. pIn = pOut = pszLabel;
  240. do
  241. {
  242. //
  243. // strip FE accelerators with parentheses. e.g. "foo(&F)" -> "foo"
  244. //
  245. if ( bFELanguage
  246. && (pIn[0] == _T('('))
  247. && (pIn[1] == _T('&'))
  248. && (pIn[2] != _T('\0'))
  249. && (pIn[3] == _T(')')))
  250. {
  251. pIn += 3;
  252. }
  253. else if ((*pIn != _T('&')) && (*pIn != _T(':')))
  254. *pOut++ = *pIn;
  255. } while (*pIn++ != _T('\0')) ;
  256. } //*** CleanupLabel()