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.

342 lines
8.1 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 <afxwin.h>
  21. #include <resapi.h>
  22. #include "DDxDDv.h"
  23. #include "AdmCommonRes.h"
  24. #ifdef _DEBUG
  25. #define new DEBUG_NEW
  26. #undef THIS_FILE
  27. static char THIS_FILE[] = __FILE__;
  28. #endif
  29. /////////////////////////////////////////////////////////////////////////////
  30. // Static Function Prototypes
  31. /////////////////////////////////////////////////////////////////////////////
  32. void CleanupLabel(LPTSTR psz);
  33. /////////////////////////////////////////////////////////////////////////////
  34. //++
  35. //
  36. // DDX_Number
  37. //
  38. // Routine Description:
  39. // Do data exchange between the dialog and the class.
  40. //
  41. // Arguments:
  42. // pDX [IN OUT] Data exchange object
  43. // nIDC [IN] Control ID.
  44. // dwValue [IN OUT] Value to set or get.
  45. // dwMin [IN] Minimum value.
  46. // dwMax [IN] Maximum value.
  47. // bSigned [IN] TRUE = value is signed, FALSE = value is unsigned
  48. //
  49. // Return Value:
  50. // None.
  51. //
  52. //--
  53. /////////////////////////////////////////////////////////////////////////////
  54. void AFXAPI DDX_Number(
  55. IN OUT CDataExchange * pDX,
  56. IN int nIDC,
  57. IN OUT DWORD & rdwValue,
  58. IN DWORD dwMin,
  59. IN DWORD dwMax,
  60. IN BOOL bSigned
  61. )
  62. {
  63. HWND hwndCtrl;
  64. DWORD dwValue;
  65. ASSERT(pDX != NULL);
  66. #ifdef _DEBUG
  67. if (bSigned)
  68. {
  69. ASSERT((LONG) dwMin < (LONG) dwMax);
  70. }
  71. else
  72. {
  73. ASSERT(dwMin < dwMax);
  74. }
  75. #endif // _DEBUG
  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. if (pDX->m_bSaveAndValidate)
  181. {
  182. if (rstrValue.GetLength() == 0)
  183. {
  184. HWND hwndLabel;
  185. TCHAR szLabel[1024];
  186. CString strPrompt;
  187. // Get the label window handle
  188. hwndLabel = pDX->PrepareEditCtrl(nIDCLabel);
  189. // Get the text of the label.
  190. GetWindowText(hwndLabel, szLabel, sizeof(szLabel) / sizeof(TCHAR));
  191. // Remove ampersands (&) and colons (:).
  192. CleanupLabel(szLabel);
  193. // Format and display a message.
  194. strPrompt.FormatMessage(ADMC_IDS_REQUIRED_FIELD_EMPTY, szLabel);
  195. AfxMessageBox(strPrompt, MB_ICONEXCLAMATION);
  196. // Do this so that the control receives focus.
  197. (void) pDX->PrepareEditCtrl(nIDC);
  198. // Fail the call.
  199. strPrompt.Empty(); // exception prep
  200. pDX->Fail();
  201. } // if: field not specified
  202. } // if: saving data
  203. } //*** DDV_RequiredText()
  204. /////////////////////////////////////////////////////////////////////////////
  205. //++
  206. //
  207. // DDV_Path
  208. //
  209. // Routine Description:
  210. // Validate that the path string contains valid characters.
  211. //
  212. // Arguments:
  213. // pDX [IN OUT] Data exchange object
  214. // nIDC [IN] Control ID.
  215. // nIDCLabel [IN] Label control ID.
  216. // rstrValue [IN] Path to validate.
  217. //
  218. // Return Value:
  219. // None.
  220. //
  221. //--
  222. /////////////////////////////////////////////////////////////////////////////
  223. void AFXAPI DDV_Path(
  224. IN OUT CDataExchange * pDX,
  225. IN int nIDC,
  226. IN int nIDCLabel,
  227. IN const CString & rstrValue
  228. )
  229. {
  230. ASSERT(pDX != NULL);
  231. if (pDX->m_bSaveAndValidate)
  232. {
  233. if (!ResUtilIsPathValid(rstrValue))
  234. {
  235. HWND hwndLabel;
  236. TCHAR szLabel[1024];
  237. CString strPrompt;
  238. // Get the label window handle
  239. hwndLabel = pDX->PrepareEditCtrl(nIDCLabel);
  240. // Get the text of the label.
  241. GetWindowText(hwndLabel, szLabel, sizeof(szLabel) / sizeof(TCHAR));
  242. // Remove ampersands (&) and colons (:).
  243. CleanupLabel(szLabel);
  244. // Format and display a message.
  245. strPrompt.FormatMessage(ADMC_IDS_PATH_IS_INVALID, szLabel);
  246. AfxMessageBox(strPrompt, MB_ICONEXCLAMATION);
  247. // Do this so that the control receives focus.
  248. (void) pDX->PrepareEditCtrl(nIDC);
  249. // Fail the call.
  250. strPrompt.Empty(); // exception prep
  251. pDX->Fail();
  252. } // if: path is invalid
  253. } // if: saving data
  254. } //*** DDV_Path()
  255. /////////////////////////////////////////////////////////////////////////////
  256. //++
  257. //
  258. // CleanupLabel
  259. //
  260. // Routine Description:
  261. // Prepare a label read from a dialog to be used as a string in a
  262. // message by removing ampersands (&) and colons (:).
  263. //
  264. // Arguments:
  265. // pszLabel [IN OUT] Label to be cleaned up.
  266. //
  267. // Return Value:
  268. // None.
  269. //
  270. //--
  271. /////////////////////////////////////////////////////////////////////////////
  272. void CleanupLabel(LPTSTR pszLabel)
  273. {
  274. LPTSTR pIn, pOut;
  275. LANGID langid;
  276. WORD primarylangid;
  277. BOOL bFELanguage;
  278. // Get the language ID.
  279. langid = GetUserDefaultLangID();
  280. primarylangid = (WORD) PRIMARYLANGID(langid);
  281. bFELanguage = ((primarylangid == LANG_JAPANESE)
  282. || (primarylangid == LANG_CHINESE)
  283. || (primarylangid == LANG_KOREAN));
  284. //
  285. // copy the name sans '&' and ':' chars
  286. //
  287. pIn = pOut = pszLabel;
  288. do
  289. {
  290. //
  291. // strip FE accelerators with parentheses. e.g. "foo(&F)" -> "foo"
  292. //
  293. if ( bFELanguage
  294. && (pIn[0] == _T('('))
  295. && (pIn[1] == _T('&'))
  296. && (pIn[2] != _T('\0'))
  297. && (pIn[3] == _T(')')))
  298. {
  299. pIn += 3;
  300. }
  301. else if ((*pIn != _T('&')) && (*pIn != _T(':')))
  302. *pOut++ = *pIn;
  303. } while (*pIn++ != _T('\0')) ;
  304. } //*** CleanupLabel()