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.

286 lines
6.8 KiB

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