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.

467 lines
8.6 KiB

  1. /*++
  2. Copyright (c) 1994-1998 Microsoft Corporation
  3. Module Name :
  4. ddxv.cpp
  5. Abstract:
  6. DDX/DDV Routines
  7. Author:
  8. Ronald Meijer (ronaldm)
  9. Project:
  10. Internet Services Manager
  11. Revision History:
  12. --*/
  13. //
  14. // Include Files
  15. //
  16. #include "stdafx.h"
  17. #include "comprop.h"
  18. #ifdef _DEBUG
  19. #undef THIS_FILE
  20. static char BASED_CODE THIS_FILE[] = __FILE__;
  21. #endif
  22. //
  23. // Prototype for external function
  24. //
  25. void AFXAPI AfxSetWindowText(HWND hWndCtrl, LPCTSTR lpszNew);
  26. //
  27. // Numeric strings cannot be longer than 32 digits
  28. //
  29. #define NUMERIC_BUFF_SIZE (32)
  30. //
  31. // Dummy password used for display purposes
  32. //
  33. LPCTSTR g_lpszDummyPassword = _T("**********");
  34. void
  35. AFXAPI DDV_MinChars(
  36. IN CDataExchange * pDX,
  37. IN CString const & value,
  38. IN int nChars
  39. )
  40. /*++
  41. Routine Description:
  42. Validate CString using a minimum string length
  43. Arguments:
  44. CDataExchange * pDX : Data exchange structure
  45. CString const & value : String to be validated
  46. int nChars : Minimum length of string
  47. Return Value:
  48. None
  49. --*/
  50. {
  51. if (pDX->m_bSaveAndValidate && value.GetLength() < nChars)
  52. {
  53. TCHAR szT[NUMERIC_BUFF_SIZE + 1];
  54. wsprintf(szT, _T("%d"), nChars);
  55. CString prompt;
  56. ::AfxFormatString1(prompt, IDS_DDX_MINIMUM, szT);
  57. ::AfxMessageBox(prompt, MB_ICONEXCLAMATION, IDS_DDX_MINIMUM);
  58. //
  59. // exception prep
  60. //
  61. prompt.Empty();
  62. pDX->Fail();
  63. }
  64. }
  65. void
  66. AFXAPI DDV_MinMaxChars(
  67. IN CDataExchange * pDX,
  68. IN CString const & value,
  69. IN int nMinChars,
  70. IN int nMaxChars
  71. )
  72. /*++
  73. Routine Description:
  74. Validate CString using a minimum and maximum string length.
  75. Arguments:
  76. CDataExchange * pDX : Data exchange structure
  77. CString const & value : String to be validated
  78. int nMinChars : Minimum length of string
  79. int nMaxChars : Maximum length of string
  80. Return Value:
  81. None
  82. --*/
  83. {
  84. if (pDX->m_bSaveAndValidate)
  85. {
  86. UINT nID;
  87. TCHAR szT[NUMERIC_BUFF_SIZE + 1];
  88. if (value.GetLength() < nMinChars)
  89. {
  90. nID = IDS_DDX_MINIMUM;
  91. ::wsprintf(szT, _T("%d"), nMinChars);
  92. }
  93. else if (value.GetLength() > nMaxChars)
  94. {
  95. nID = AFX_IDP_PARSE_STRING_SIZE;
  96. ::wsprintf(szT, _T("%d"), nMaxChars);
  97. }
  98. else
  99. {
  100. //
  101. // Passes both our tests, it's ok.
  102. //
  103. return;
  104. }
  105. CString prompt;
  106. ::AfxFormatString1(prompt, nID, szT);
  107. ::AfxMessageBox(prompt, MB_ICONEXCLAMATION, nID);
  108. //
  109. // exception prep
  110. //
  111. prompt.Empty();
  112. pDX->Fail();
  113. }
  114. else if (pDX->m_hWndLastControl != NULL && pDX->m_bEditLastControl)
  115. {
  116. //
  117. // limit the control max-chars automatically
  118. //
  119. ::SendMessage(pDX->m_hWndLastControl, EM_LIMITTEXT, nMaxChars, 0);
  120. }
  121. }
  122. void
  123. AFXAPI DDX_Spin(
  124. IN CDataExchange * pDX,
  125. IN int nIDC,
  126. IN OUT int & value
  127. )
  128. /*++
  129. Routine Description:
  130. Save/store data from spinbutton control
  131. Arguments:
  132. CDataExchange * pDX : Data exchange structure
  133. int nIDC : Control ID of the spinbutton control
  134. int & value : Value to be saved or stored
  135. Return Value:
  136. None
  137. --*/
  138. {
  139. HWND hWndCtrl = pDX->PrepareCtrl(nIDC);
  140. if (pDX->m_bSaveAndValidate)
  141. {
  142. value = (int)LOWORD(::SendMessage(hWndCtrl, UDM_GETPOS, 0, 0L));
  143. }
  144. else
  145. {
  146. ::SendMessage(hWndCtrl, UDM_SETPOS, 0, MAKELPARAM(value, 0));
  147. }
  148. }
  149. void
  150. AFXAPI DDV_MinMaxSpin(
  151. IN CDataExchange * pDX,
  152. IN HWND hWndControl,
  153. IN int minVal,
  154. IN int maxVal
  155. )
  156. /*++
  157. Routine Description:
  158. Enforce minimum/maximum spin button range
  159. Arguments:
  160. CDataExchange * pDX : Data exchange structure
  161. HWND hWndControl : Control window handle
  162. int minVal : Minimum value
  163. int maxVal : Maximum value
  164. Return Value:
  165. None
  166. Note:
  167. Unlike most data validation routines, this one
  168. MUST be used prior to an accompanying DDX_Spin()
  169. function. This is because spinbox controls have a
  170. native limit of 0-100. Also, this function requires
  171. a window handle to the child control. The
  172. CONTROL_HWND macro can be used for this.
  173. --*/
  174. {
  175. ASSERT(minVal <= maxVal);
  176. if (!pDX->m_bSaveAndValidate && hWndControl != NULL)
  177. {
  178. //
  179. // limit the control range automatically
  180. //
  181. ::SendMessage(hWndControl, UDM_SETRANGE, 0, MAKELPARAM(maxVal, minVal));
  182. }
  183. }
  184. void
  185. AFXAPI DDX_Password(
  186. IN CDataExchange * pDX,
  187. IN int nIDC,
  188. IN OUT CString & value,
  189. IN LPCTSTR lpszDummy
  190. )
  191. /*++
  192. Routine Description:
  193. DDX_Text for passwords. Always display a dummy string
  194. instead of the real password, and ask for confirmation
  195. if the password has changed
  196. Arguments:
  197. CDataExchange * pDX : Data exchange structure
  198. int nIDC : Control ID
  199. CString & value : value
  200. LPCTSTR lpszDummy : Dummy password string to be displayed
  201. Return Value:
  202. None
  203. --*/
  204. {
  205. HWND hWndCtrl = pDX->PrepareEditCtrl(nIDC);
  206. if (pDX->m_bSaveAndValidate)
  207. {
  208. if (!::SendMessage(hWndCtrl, EM_GETMODIFY, 0, 0))
  209. {
  210. TRACEEOLID("No changes -- skipping");
  211. return;
  212. }
  213. CString strNew;
  214. int nLen = ::GetWindowTextLength(hWndCtrl);
  215. ::GetWindowText(hWndCtrl, strNew.GetBufferSetLength(nLen), nLen + 1);
  216. strNew.ReleaseBuffer();
  217. /*
  218. if (strNew == value)
  219. {
  220. TRACEEOLID("Password already matches -- skipping");
  221. return;
  222. }
  223. */
  224. //
  225. // Password has changed -- ask for confirmation
  226. //
  227. CConfirmDlg dlg;
  228. if (dlg.DoModal() == IDOK)
  229. {
  230. if (strNew.Compare(dlg.GetPassword()) == 0)
  231. {
  232. //
  233. // Password ok, pass it on
  234. //
  235. value = strNew;
  236. return;
  237. }
  238. else
  239. {
  240. //
  241. // No match, bad password
  242. //
  243. ::AfxMessageBox(IDS_PASSWORD_NO_MATCH);
  244. }
  245. }
  246. //
  247. // throw exception
  248. //
  249. pDX->Fail();
  250. }
  251. else
  252. {
  253. //
  254. // Put the dummy password string in the edit control
  255. //
  256. if (!value.IsEmpty())
  257. {
  258. ::AfxSetWindowText(hWndCtrl, lpszDummy);
  259. }
  260. }
  261. }
  262. void
  263. AFXAPI DDX_Text(
  264. IN CDataExchange * pDX,
  265. IN int nIDC,
  266. IN OUT CILong & value
  267. )
  268. /*++
  269. Routine Description:
  270. DDX_Text for CILong class. CILong takes care of all the dirty
  271. work for output and input.
  272. Arguments:
  273. CDataExchange * pDX : Data exchange structure
  274. int nIDC : Control ID code
  275. CILong & value : value
  276. Return Value:
  277. None
  278. --*/
  279. {
  280. HWND hWndCtrl = pDX->PrepareEditCtrl(nIDC);
  281. pDX->m_bEditLastControl = TRUE;
  282. TCHAR szT[NUMERIC_BUFF_SIZE + 1];
  283. if (pDX->m_bSaveAndValidate)
  284. {
  285. LONG l;
  286. ::GetWindowText(hWndCtrl, szT, NUMERIC_BUFF_SIZE);
  287. if (CINumber::ConvertStringToLong(szT, l))
  288. {
  289. value = l;
  290. }
  291. else
  292. {
  293. HINSTANCE hOld = AfxGetResourceHandle();
  294. AfxSetResourceHandle(GetModuleHandle(COMPROP_DLL_NAME));
  295. ::AfxMessageBox(IDS_INVALID_NUMBER);
  296. AfxSetResourceHandle(hOld);
  297. //
  298. // Throw exception
  299. //
  300. pDX->Fail();
  301. }
  302. }
  303. else
  304. {
  305. ::wsprintf(szT, _T("%s"), (LPCTSTR)value);
  306. ::AfxSetWindowText(hWndCtrl, szT);
  307. }
  308. }
  309. CConfirmDlg::CConfirmDlg(
  310. IN CWnd * pParent OPTIONAL
  311. )
  312. /*++
  313. Routine Description:
  314. Constructor for the confirmation dialog -- brought up by the password ddx
  315. whenever password confirmation is necessary.
  316. Arguments:
  317. CWnd * pParent : Optional parent window
  318. Return Value:
  319. None
  320. --*/
  321. : CDialog(CConfirmDlg::IDD, pParent)
  322. {
  323. //{{AFX_DATA_INIT(CConfirmDlg)
  324. m_strPassword = _T("");
  325. //}}AFX_DATA_INIT
  326. }
  327. void
  328. CConfirmDlg::DoDataExchange(
  329. IN CDataExchange * pDX
  330. )
  331. /*++
  332. Routine Description:
  333. Initialise/Store control data
  334. Arguments:
  335. CDataExchange* pDX - DDX/DDV control structure
  336. Return Value:
  337. N/A
  338. --*/
  339. {
  340. CDialog::DoDataExchange(pDX);
  341. //{{AFX_DATA_MAP(CConfirmDlg)
  342. DDX_Text(pDX, IDC_EDIT_CONFIRM_PASSWORD, m_strPassword);
  343. //}}AFX_DATA_MAP
  344. }
  345. //
  346. // Message Handlers
  347. //
  348. BEGIN_MESSAGE_MAP(CConfirmDlg, CDialog)
  349. //{{AFX_MSG_MAP(CConfirmDlg)
  350. //}}AFX_MSG_MAP
  351. END_MESSAGE_MAP()