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.

964 lines
23 KiB

  1. /*++
  2. Copyright (c) 1994-2001 Microsoft Corporation
  3. Module Name :
  4. ddxv.cpp
  5. Abstract:
  6. DDX/DDV Routines
  7. Author:
  8. Ronald Meijer (ronaldm)
  9. Sergei Antonov (sergeia)
  10. Project:
  11. Internet Services Manager
  12. Revision History:
  13. --*/
  14. #include "stdafx.h"
  15. #include "common.h"
  16. #include "balloon.h"
  17. #include "shlobjp.h"
  18. #include "strpass.h"
  19. #include "util.h"
  20. #ifdef _DEBUG
  21. #undef THIS_FILE
  22. static char BASED_CODE THIS_FILE[] = __FILE__;
  23. #endif
  24. #define new DEBUG_NEW
  25. //
  26. // Prototype for external function
  27. //
  28. void AFXAPI AfxSetWindowText(HWND hWndCtrl, LPCTSTR lpszNew);
  29. //
  30. // Numeric strings cannot be longer than 32 digits
  31. //
  32. #define NUMERIC_BUFF_SIZE (32)
  33. //
  34. // Dummy password used for display purposes
  35. //
  36. LPCTSTR g_lpszDummyPassword = _T("**********");
  37. static TCHAR g_InvalidCharsPath[] = _T("|<>/*?\"\t\r\n");
  38. static TCHAR g_InvalidCharsPathAllowSpecialPath[] = _T("|<>/*\"\t\r\n");
  39. static TCHAR g_InvalidCharsDomainName[] = _T(" ~`!@#$%^&*()_+={}[]|/\\?*:;\"\'<>,");
  40. extern HINSTANCE hDLLInstance;
  41. #define MACRO_MAXCHARSBALLOON()\
  42. if (pDX->m_bSaveAndValidate)\
  43. {\
  44. UINT nID;\
  45. TCHAR szT[NUMERIC_BUFF_SIZE + 1];\
  46. if (value.GetLength() > nChars)\
  47. {\
  48. nID = AFX_IDP_PARSE_STRING_SIZE;\
  49. ::wsprintf(szT, _T("%d"), nChars);\
  50. CString prompt;\
  51. ::AfxFormatString1(prompt, nID, szT);\
  52. DDV_ShowBalloonAndFail(pDX, prompt);\
  53. }\
  54. }\
  55. else if (pDX->m_hWndLastControl != NULL && pDX->m_bEditLastControl)\
  56. {\
  57. ::SendMessage(pDX->m_hWndLastControl, EM_LIMITTEXT, nChars, 0);\
  58. }\
  59. #define MACRO_MINMAXCHARS()\
  60. if (pDX->m_bSaveAndValidate)\
  61. {\
  62. UINT nID;\
  63. TCHAR szT[NUMERIC_BUFF_SIZE + 1];\
  64. if (value.GetLength() < nMinChars)\
  65. {\
  66. nID = IDS_DDX_MINIMUM;\
  67. ::wsprintf(szT, _T("%d"), nMinChars);\
  68. }\
  69. else if (value.GetLength() > nMaxChars)\
  70. {\
  71. nID = AFX_IDP_PARSE_STRING_SIZE;\
  72. ::wsprintf(szT, _T("%d"), nMaxChars);\
  73. }\
  74. else\
  75. {\
  76. return;\
  77. }\
  78. CString prompt;\
  79. ::AfxFormatString1(prompt, nID, szT);\
  80. DDV_ShowBalloonAndFail(pDX, prompt);\
  81. }\
  82. else if (pDX->m_hWndLastControl != NULL && pDX->m_bEditLastControl)\
  83. {\
  84. ::SendMessage(pDX->m_hWndLastControl, EM_LIMITTEXT, nMaxChars, 0);\
  85. }\
  86. #define MACRO_MINCHARS()\
  87. if (pDX->m_bSaveAndValidate && value.GetLength() < nChars)\
  88. {\
  89. TCHAR szT[NUMERIC_BUFF_SIZE + 1];\
  90. wsprintf(szT, _T("%d"), nChars);\
  91. CString prompt;\
  92. ::AfxFormatString1(prompt, IDS_DDX_MINIMUM, szT);\
  93. DDV_ShowBalloonAndFail(pDX, prompt);\
  94. }\
  95. #define MACRO_PASSWORD()\
  96. HWND hWndCtrl = pDX->PrepareEditCtrl(nIDC);\
  97. if (pDX->m_bSaveAndValidate)\
  98. {\
  99. if (::IsWindowEnabled(hWndCtrl))\
  100. {\
  101. if (!::SendMessage(hWndCtrl, EM_GETMODIFY, 0, 0))\
  102. {\
  103. TRACEEOLID("No changes -- skipping");\
  104. return;\
  105. }\
  106. CString strNew;\
  107. int nLen = ::GetWindowTextLength(hWndCtrl);\
  108. ::GetWindowText(hWndCtrl, strNew.GetBufferSetLength(nLen), nLen + 1);\
  109. strNew.ReleaseBuffer();\
  110. CConfirmDlg dlg(pDX->m_pDlgWnd);\
  111. dlg.SetReference(strNew);\
  112. if (dlg.DoModal() == IDOK)\
  113. {\
  114. value = strNew;\
  115. ::SendMessage(hWndCtrl, EM_SETMODIFY, 0, 0);\
  116. return;\
  117. }\
  118. pDX->Fail();\
  119. }\
  120. }\
  121. else\
  122. {\
  123. if (!value.IsEmpty())\
  124. {\
  125. ::AfxSetWindowText(hWndCtrl, lpszDummy);\
  126. }\
  127. }\
  128. BOOL
  129. PathIsValid(LPCTSTR path, BOOL bAllowSpecialPath)
  130. {
  131. if (path == NULL || *path == 0)
  132. return FALSE;
  133. if (bAllowSpecialPath)
  134. {
  135. return 0 == StrSpn(path, g_InvalidCharsPathAllowSpecialPath);
  136. }
  137. else
  138. {
  139. return 0 == StrSpn(path, g_InvalidCharsPath);
  140. }
  141. }
  142. HRESULT AFXAPI
  143. LimitInputPath(HWND hWnd, BOOL bAllowSpecialPath)
  144. {
  145. LIMITINPUT li = {0};
  146. li.cbSize = sizeof(li);
  147. li.dwMask = LIM_FLAGS | LIM_FILTER | LIM_MESSAGE | LIM_HINST;
  148. li.dwFlags = LIF_EXCLUDEFILTER | LIF_HIDETIPONVALID | LIF_PASTESKIP;
  149. li.hinst = hDLLInstance;
  150. if (bAllowSpecialPath)
  151. {
  152. li.pszMessage = MAKEINTRESOURCE(IDS_PATH_INPUT_INVALID_ALLOW_DEVICE_PATH);
  153. li.pszFilter = g_InvalidCharsPathAllowSpecialPath;
  154. }
  155. else
  156. {
  157. li.pszMessage = MAKEINTRESOURCE(IDS_PATH_INPUT_INVALID);
  158. li.pszFilter = g_InvalidCharsPath;
  159. }
  160. return SHLimitInputEditWithFlags(hWnd, &li);
  161. }
  162. HRESULT AFXAPI
  163. LimitInputDomainName(HWND hWnd)
  164. {
  165. LIMITINPUT li = {0};
  166. li.cbSize = sizeof(li);
  167. li.dwMask = LIM_FLAGS | LIM_FILTER | LIM_MESSAGE | LIM_HINST;
  168. li.dwFlags = LIF_EXCLUDEFILTER | LIF_HIDETIPONVALID | LIF_PASTESKIP;
  169. li.hinst = hDLLInstance;
  170. li.pszMessage = MAKEINTRESOURCE(IDS_ERR_INVALID_HOSTHEADER_CHARS);
  171. li.pszFilter = g_InvalidCharsDomainName;
  172. return SHLimitInputEditWithFlags(hWnd, &li);
  173. }
  174. void AFXAPI
  175. DDV_MinChars(CDataExchange * pDX, CString const & value, int nChars)
  176. /*++
  177. Routine Description:
  178. Validate CString using a minimum string length
  179. Arguments:
  180. CDataExchange * pDX : Data exchange structure
  181. CString const & value : String to be validated
  182. int nChars : Minimum length of string
  183. --*/
  184. {
  185. MACRO_MINCHARS()
  186. }
  187. void AFXAPI
  188. DDV_MaxCharsBalloon(CDataExchange * pDX, CString const & value, int nChars)
  189. {
  190. MACRO_MAXCHARSBALLOON()
  191. }
  192. void AFXAPI
  193. DDV_MinMaxChars(CDataExchange * pDX, CString const & value, int nMinChars, int nMaxChars)
  194. /*++
  195. Routine Description:
  196. Validate CString using a minimum and maximum string length.
  197. Arguments:
  198. CDataExchange * pDX : Data exchange structure
  199. CString const & value : String to be validated
  200. int nMinChars : Minimum length of string
  201. int nMaxChars : Maximum length of string
  202. --*/
  203. {
  204. MACRO_MINMAXCHARS()
  205. }
  206. void
  207. AFXAPI DDX_Spin(
  208. IN CDataExchange * pDX,
  209. IN int nIDC,
  210. IN OUT int & value
  211. )
  212. /*++
  213. Routine Description:
  214. Save/store data from spinbutton control
  215. Arguments:
  216. CDataExchange * pDX : Data exchange structure
  217. int nIDC : Control ID of the spinbutton control
  218. int & value : Value to be saved or stored
  219. Return Value:
  220. None
  221. --*/
  222. {
  223. HWND hWndCtrl = pDX->PrepareCtrl(nIDC);
  224. if (pDX->m_bSaveAndValidate)
  225. {
  226. if (::IsWindowEnabled(hWndCtrl))
  227. {
  228. value = (int)LOWORD(::SendMessage(hWndCtrl, UDM_GETPOS, 0, 0L));
  229. }
  230. }
  231. else
  232. {
  233. ::SendMessage(hWndCtrl, UDM_SETPOS, 0, MAKELPARAM(value, 0));
  234. }
  235. }
  236. void
  237. AFXAPI DDV_MinMaxSpin(
  238. IN CDataExchange * pDX,
  239. IN HWND hWndControl,
  240. IN int minVal,
  241. IN int maxVal
  242. )
  243. /*++
  244. Routine Description:
  245. Enforce minimum/maximum spin button range
  246. Arguments:
  247. CDataExchange * pDX : Data exchange structure
  248. HWND hWndControl : Control window handle
  249. int minVal : Minimum value
  250. int maxVal : Maximum value
  251. Return Value:
  252. None
  253. Note:
  254. Unlike most data validation routines, this one
  255. MUST be used prior to an accompanying DDX_Spin()
  256. function. This is because spinbox controls have a
  257. native limit of 0-100. Also, this function requires
  258. a window handle to the child control. The
  259. CONTROL_HWND macro can be used for this.
  260. --*/
  261. {
  262. ASSERT(minVal <= maxVal);
  263. if (!pDX->m_bSaveAndValidate && hWndControl != NULL)
  264. {
  265. //
  266. // limit the control range automatically
  267. //
  268. ::SendMessage(hWndControl, UDM_SETRANGE, 0, MAKELPARAM(maxVal, minVal));
  269. }
  270. }
  271. void AFXAPI
  272. OldEditShowBalloon(HWND hwnd, CString txt)
  273. {
  274. EDITBALLOONTIP ebt = {0};
  275. ebt.cbStruct = sizeof(ebt);
  276. ebt.pszText = txt;
  277. SetFocus(hwnd);
  278. Edit_ShowBalloonTip(hwnd, &ebt);
  279. }
  280. void AFXAPI EditHideBalloon(void)
  281. {
  282. Edit_HideBalloonTipHandler();
  283. }
  284. void AFXAPI EditShowBalloon(HWND hwnd, CString txt)
  285. {
  286. Edit_ShowBalloonTipHandler(hwnd, (LPCTSTR) txt);
  287. }
  288. void AFXAPI
  289. EditShowBalloon(HWND hwnd, UINT ids)
  290. {
  291. if (ids != 0)
  292. {
  293. CString txt;
  294. if (txt.LoadString(ids))
  295. {
  296. EditShowBalloon(hwnd, txt);
  297. }
  298. }
  299. }
  300. void AFXAPI
  301. DDV_ShowBalloonAndFail(CDataExchange * pDX, UINT ids)
  302. {
  303. if (ids != 0)
  304. {
  305. EditShowBalloon(pDX->m_hWndLastControl, ids);
  306. pDX->Fail();
  307. }
  308. }
  309. void AFXAPI
  310. DDV_ShowBalloonAndFail(CDataExchange * pDX, CString txt)
  311. {
  312. if (!txt.IsEmpty())
  313. {
  314. EditShowBalloon(pDX->m_hWndLastControl, txt);
  315. pDX->Fail();
  316. }
  317. }
  318. void
  319. AFXAPI DDV_FolderPath(
  320. CDataExchange * pDX,
  321. CString& value,
  322. BOOL local
  323. )
  324. {
  325. if (pDX->m_bSaveAndValidate)
  326. {
  327. CString expanded, csPathMunged;
  328. ExpandEnvironmentStrings(value, expanded.GetBuffer(MAX_PATH), MAX_PATH);
  329. expanded.ReleaseBuffer();
  330. expanded.TrimRight();
  331. expanded.TrimLeft();
  332. csPathMunged = expanded;
  333. #ifdef SUPPORT_SLASH_SLASH_QUESTIONMARK_SLASH_TYPE_PATHS
  334. GetSpecialPathRealPath(0,expanded,csPathMunged);
  335. #endif
  336. int ids = 0;
  337. do
  338. {
  339. if (!PathIsValid(csPathMunged,FALSE))
  340. {
  341. ids = IDS_ERR_INVALID_PATH;
  342. break;
  343. }
  344. DWORD dwAllowed = CHKPATH_ALLOW_DEVICE_PATH;
  345. dwAllowed |= CHKPATH_ALLOW_UNC_PATH; // allow UNC type dir paths
  346. // don't allow these type of paths commented out below:
  347. //dwAllowed |= CHKPATH_ALLOW_RELATIVE_PATH;
  348. //dwAllowed |= CHKPATH_ALLOW_UNC_SERVERNAME_ONLY;
  349. //dwAllowed |= CHKPATH_ALLOW_UNC_SERVERSHARE_ONLY;
  350. DWORD dwCharSet = CHKPATH_CHARSET_GENERAL;
  351. FILERESULT dwValidRet = MyValidatePath(csPathMunged,local,CHKPATH_WANT_DIR,dwAllowed,dwCharSet);
  352. if (FAILED(dwValidRet))
  353. {
  354. ids = IDS_ERR_BAD_PATH;
  355. if (dwValidRet == CHKPATH_FAIL_NOT_ALLOWED_DIR_NOT_EXIST)
  356. {
  357. ids = IDS_ERR_PATH_NOT_FOUND;
  358. }
  359. break;
  360. }
  361. }
  362. while (FALSE);
  363. DDV_ShowBalloonAndFail(pDX, ids);
  364. }
  365. }
  366. void
  367. AFXAPI DDV_FilePath(
  368. CDataExchange * pDX,
  369. CString& value,
  370. BOOL local
  371. )
  372. {
  373. CString expanded, csPathMunged;
  374. ExpandEnvironmentStrings(value, expanded.GetBuffer(MAX_PATH), MAX_PATH);
  375. expanded.ReleaseBuffer();
  376. csPathMunged = expanded;
  377. #ifdef SUPPORT_SLASH_SLASH_QUESTIONMARK_SLASH_TYPE_PATHS
  378. GetSpecialPathRealPath(0,expanded,csPathMunged);
  379. #endif
  380. int ids = 0;
  381. do
  382. {
  383. if (!PathIsValid(csPathMunged,FALSE))
  384. {
  385. ids = IDS_ERR_INVALID_PATH;
  386. break;
  387. }
  388. if (!IsDevicePath(csPathMunged))
  389. {
  390. if (PathIsUNCServerShare(csPathMunged) || PathIsUNCServer(csPathMunged))
  391. {
  392. ids = IDS_ERR_BAD_PATH;
  393. break;
  394. }
  395. if (PathIsRelative(csPathMunged))
  396. {
  397. ids = IDS_ERR_BAD_PATH;
  398. break;
  399. }
  400. if (local)
  401. {
  402. if (PathIsDirectory(csPathMunged))
  403. {
  404. ids = IDS_ERR_FILE_NOT_FOUND;
  405. break;
  406. }
  407. if (!PathFileExists(csPathMunged))
  408. {
  409. ids = IDS_ERR_FILE_NOT_FOUND;
  410. break;
  411. }
  412. }
  413. }
  414. }
  415. while (FALSE);
  416. DDV_ShowBalloonAndFail(pDX, ids);
  417. }
  418. void
  419. AFXAPI DDV_UNCFolderPath(
  420. CDataExchange * pDX,
  421. CString& value,
  422. BOOL local
  423. )
  424. {
  425. int ids = 0;
  426. CString csPathMunged;
  427. csPathMunged = value;
  428. #ifdef SUPPORT_SLASH_SLASH_QUESTIONMARK_SLASH_TYPE_PATHS
  429. GetSpecialPathRealPath(0,value,csPathMunged);
  430. #endif
  431. do
  432. {
  433. if (!PathIsValid(csPathMunged,FALSE))
  434. {
  435. ids = IDS_ERR_INVALID_PATH;
  436. break;
  437. }
  438. // PathIsUNCServer doesn't catch "\\". We are expecting share here.
  439. if (!PathIsUNC(csPathMunged) || lstrlen(csPathMunged) == 2)
  440. {
  441. ids = IDS_BAD_UNC_PATH;
  442. break;
  443. }
  444. // Additional validation checks not covered above
  445. DWORD dwAllowed = CHKPATH_ALLOW_UNC_PATH;
  446. // We do accept server shares, but it has to have a fullpath
  447. // with a filename at the end
  448. dwAllowed |= CHKPATH_ALLOW_UNC_SERVERSHARE_ONLY;
  449. // don't allow these type of paths commented out below:
  450. //dwAllowed |= CHKPATH_ALLOW_DEVICE_PATH;
  451. //dwAllowed |= CHKPATH_ALLOW_RELATIVE_PATH;
  452. //dwAllowed |= CHKPATH_ALLOW_UNC_SERVERNAME_ONLY;
  453. DWORD dwCharSet = CHKPATH_CHARSET_GENERAL;
  454. FILERESULT dwValidRet = MyValidatePath(csPathMunged,local,CHKPATH_WANT_DIR,dwAllowed,dwCharSet);
  455. if (FAILED(dwValidRet))
  456. {
  457. ids = IDS_BAD_UNC_PATH;
  458. break;
  459. }
  460. if (local)
  461. {
  462. /*
  463. if (!DoesUNCShareExist(csPathMunged))
  464. {
  465. ids = IDS_ERR_FILE_NOT_FOUND;
  466. break;
  467. }
  468. */
  469. }
  470. }
  471. while (FALSE);
  472. DDV_ShowBalloonAndFail(pDX, ids);
  473. }
  474. void
  475. AFXAPI DDV_Url(
  476. CDataExchange * pDX,
  477. CString& value
  478. )
  479. {
  480. int ids = 0;
  481. if (IsRelURLPath(value))
  482. {
  483. return;
  484. }
  485. if ( IsWildcardedRedirectPath(value)
  486. || IsURLName(value)
  487. )
  488. {
  489. TCHAR host[MAX_PATH];
  490. DWORD cch = MAX_PATH;
  491. UrlGetPart(value, host, &cch, URL_PART_HOSTNAME, 0);
  492. if (cch > 0)
  493. {
  494. return;
  495. }
  496. }
  497. // none of the above, so it must be a bad path
  498. ids = IDS_BAD_URL_PATH;
  499. DDV_ShowBalloonAndFail(pDX, ids);
  500. }
  501. void AFXAPI
  502. DDX_Text_SecuredString(CDataExchange * pDX, int nIDC, CStrPassword & value)
  503. {
  504. HWND hWndCtrl = pDX->PrepareEditCtrl(nIDC);
  505. if (pDX->m_bSaveAndValidate)
  506. {
  507. if (::IsWindowEnabled(hWndCtrl))
  508. {
  509. // get the value from the UI if we need to
  510. if (!::SendMessage(hWndCtrl, EM_GETMODIFY, 0, 0))
  511. {
  512. TRACEEOLID("No changes -- skipping");
  513. return;
  514. }
  515. CString strNew;
  516. int nLen = ::GetWindowTextLength(hWndCtrl);
  517. ::GetWindowText(hWndCtrl, strNew.GetBufferSetLength(nLen), nLen + 1);
  518. strNew.ReleaseBuffer();
  519. value = (LPCTSTR) strNew;
  520. }
  521. }
  522. else
  523. {
  524. //
  525. // set the value in the UI if we need to
  526. //
  527. if (!value.IsEmpty())
  528. {
  529. TCHAR * pszPassword = NULL;
  530. pszPassword = value.GetClearTextPassword();
  531. if (pszPassword)
  532. {
  533. ::AfxSetWindowText(hWndCtrl, pszPassword);
  534. value.DestroyClearTextPassword(pszPassword);
  535. }
  536. }
  537. }
  538. }
  539. void AFXAPI
  540. DDV_MaxChars_SecuredString(CDataExchange* pDX, CStrPassword const& value, int nChars)
  541. {
  542. MACRO_MAXCHARSBALLOON()
  543. }
  544. void AFXAPI
  545. DDV_MaxCharsBalloon_SecuredString(CDataExchange * pDX, CStrPassword const & value, int nChars)
  546. {
  547. MACRO_MAXCHARSBALLOON()
  548. }
  549. void AFXAPI
  550. DDV_MinMaxChars_SecuredString(CDataExchange * pDX, CStrPassword const & value, int nMinChars, int nMaxChars)
  551. {
  552. MACRO_MINMAXCHARS()
  553. }
  554. void AFXAPI
  555. DDV_MinChars_SecuredString(CDataExchange * pDX, CStrPassword const & value, int nChars)
  556. {
  557. MACRO_MINCHARS()
  558. }
  559. void AFXAPI
  560. DDX_Password_SecuredString(
  561. IN CDataExchange * pDX,
  562. IN int nIDC,
  563. IN OUT CStrPassword & value,
  564. IN LPCTSTR lpszDummy
  565. )
  566. {
  567. MACRO_PASSWORD()
  568. }
  569. void AFXAPI
  570. DDX_Password(
  571. IN CDataExchange * pDX,
  572. IN int nIDC,
  573. IN OUT CString & value,
  574. IN LPCTSTR lpszDummy
  575. )
  576. /*++
  577. Routine Description:
  578. DDX_Text for passwords. Always display a dummy string
  579. instead of the real password, and ask for confirmation
  580. if the password has changed
  581. Arguments:
  582. CDataExchange * pDX : Data exchange structure
  583. int nIDC : Control ID
  584. CString & value : value
  585. LPCTSTR lpszDummy : Dummy password string to be displayed
  586. Return Value:
  587. None
  588. --*/
  589. {
  590. MACRO_PASSWORD()
  591. }
  592. void AFXAPI
  593. DDV_MinMaxBalloon(CDataExchange* pDX,int nIDC, DWORD minVal, DWORD maxVal)
  594. {
  595. HWND hWndCtrl = pDX->PrepareEditCtrl(nIDC);
  596. if (pDX->m_bSaveAndValidate && ::IsWindowEnabled(hWndCtrl))
  597. {
  598. TCHAR szT[64];
  599. BOOL bShowFailure = TRUE;
  600. ULONGLONG nBigSpace = 0;
  601. ASSERT(minVal <= maxVal);
  602. ASSERT( hWndCtrl != NULL );
  603. // Get the text
  604. ::GetWindowText(hWndCtrl, szT, sizeof(szT)/sizeof(TCHAR));
  605. // convert the text into a big number
  606. if (_stscanf(szT, _T("%I64u"), &nBigSpace) == 1)
  607. {
  608. // check the range...
  609. if (nBigSpace < minVal || nBigSpace > maxVal)
  610. {
  611. // failed
  612. }
  613. else
  614. {
  615. bShowFailure = FALSE;
  616. }
  617. }
  618. if (bShowFailure)
  619. {
  620. TCHAR szMin[32];
  621. TCHAR szMax[32];
  622. wsprintf(szMin, _T("%ld"), minVal);
  623. wsprintf(szMax, _T("%ld"), maxVal);
  624. CString prompt;
  625. AfxFormatString2(prompt, AFX_IDP_PARSE_INT_RANGE, szMin, szMax);
  626. ASSERT(pDX->m_hWndLastControl != NULL && pDX->m_bEditLastControl);
  627. EditShowBalloon(pDX->m_hWndLastControl, prompt);
  628. pDX->Fail();
  629. }
  630. }
  631. return;
  632. }
  633. static void
  634. DDX_TextWithFormatBalloon(CDataExchange* pDX, int nIDC, LPCTSTR lpszFormat, UINT nIDPrompt, DWORD dwSizeOf, ...)
  635. // only supports windows output formats - no floating point
  636. {
  637. va_list pData;
  638. va_start(pData, dwSizeOf);
  639. HWND hWndCtrl = pDX->PrepareEditCtrl(nIDC);
  640. ASSERT( hWndCtrl != NULL );
  641. TCHAR szT[64];
  642. if (pDX->m_bSaveAndValidate)
  643. {
  644. if (::IsWindowEnabled(hWndCtrl))
  645. {
  646. void* pResult;
  647. pResult = va_arg( pData, void* );
  648. // the following works for %d, %u, %ld, %lu
  649. ::GetWindowText(hWndCtrl, szT, sizeof(szT)/sizeof(TCHAR));
  650. // remove begining and trailing spaces
  651. // remove beginning 0's
  652. // check if there are too many characters to even fit in the numeric space provided
  653. //int iTextLen = ::GetWindowTextLength(hWndCtrl);
  654. // Will this string length even fit into the space they want us to put it into?
  655. ULONGLONG nBigSpace = 0;
  656. if (_stscanf(szT, _T("%I64u"), &nBigSpace) == 1)
  657. {
  658. // the string was assigned to the ia64
  659. // check if it's larger than what was passed in.
  660. if (dwSizeOf == sizeof(DWORD))
  661. {
  662. // 4 bytes
  663. if (nBigSpace > 0xffffffff)
  664. {
  665. DDV_ShowBalloonAndFail(pDX, IDS_ERR_NUM_TOO_LARGE);
  666. }
  667. }
  668. else if (dwSizeOf == sizeof(short))
  669. {
  670. // 2 bytes
  671. if (nBigSpace > 0xffff)
  672. {
  673. DDV_ShowBalloonAndFail(pDX, IDS_ERR_NUM_TOO_LARGE);
  674. }
  675. }
  676. else if (dwSizeOf == sizeof(char))
  677. {
  678. // 1 byte
  679. if (nBigSpace > 0xff)
  680. {
  681. DDV_ShowBalloonAndFail(pDX, IDS_ERR_NUM_TOO_LARGE);
  682. }
  683. }
  684. }
  685. if (_stscanf(szT, lpszFormat, pResult) != 1)
  686. {
  687. DDV_ShowBalloonAndFail(pDX, nIDPrompt);
  688. }
  689. }
  690. }
  691. else
  692. {
  693. _vstprintf(szT, lpszFormat, pData);
  694. // does not support floating point numbers - see dlgfloat.cpp
  695. AfxSetWindowText(hWndCtrl, szT);
  696. }
  697. va_end(pData);
  698. }
  699. void AFXAPI
  700. DDX_TextBalloon(CDataExchange* pDX, int nIDC, BYTE& value)
  701. {
  702. int n = (int)value;
  703. HWND hWndCtrl = pDX->PrepareEditCtrl(nIDC);
  704. if (pDX->m_bSaveAndValidate)
  705. {
  706. if (::IsWindowEnabled(hWndCtrl))
  707. {
  708. DDX_TextWithFormatBalloon(pDX, nIDC, _T("%u"), AFX_IDP_PARSE_BYTE, sizeof(BYTE), &n);
  709. if (n > 255)
  710. {
  711. DDV_ShowBalloonAndFail(pDX, AFX_IDP_PARSE_BYTE);
  712. }
  713. value = (BYTE)n;
  714. }
  715. }
  716. else
  717. DDX_TextWithFormatBalloon(pDX, nIDC, _T("%u"), AFX_IDP_PARSE_BYTE, sizeof(BYTE), n);
  718. }
  719. void AFXAPI
  720. DDX_TextBalloon(CDataExchange* pDX, int nIDC, short& value)
  721. {
  722. if (pDX->m_bSaveAndValidate)
  723. DDX_TextWithFormatBalloon(pDX, nIDC, _T("%hd"), AFX_IDP_PARSE_INT, sizeof(short), &value);
  724. else
  725. DDX_TextWithFormatBalloon(pDX, nIDC, _T("%hd"), AFX_IDP_PARSE_INT, sizeof(short), value);
  726. }
  727. void AFXAPI
  728. DDX_TextBalloon(CDataExchange* pDX, int nIDC, int& value)
  729. {
  730. if (pDX->m_bSaveAndValidate)
  731. DDX_TextWithFormatBalloon(pDX, nIDC, _T("%d"), AFX_IDP_PARSE_INT, sizeof(int), &value);
  732. else
  733. DDX_TextWithFormatBalloon(pDX, nIDC, _T("%d"), AFX_IDP_PARSE_INT, sizeof(int), value);
  734. }
  735. void AFXAPI
  736. DDX_TextBalloon(CDataExchange* pDX, int nIDC, UINT& value)
  737. {
  738. if (pDX->m_bSaveAndValidate)
  739. DDX_TextWithFormatBalloon(pDX, nIDC, _T("%u"), AFX_IDP_PARSE_UINT, sizeof(UINT), &value);
  740. else
  741. DDX_TextWithFormatBalloon(pDX, nIDC, _T("%u"), AFX_IDP_PARSE_UINT, sizeof(UINT), value);
  742. }
  743. void AFXAPI
  744. DDX_TextBalloon(CDataExchange* pDX, int nIDC, long& value)
  745. {
  746. if (pDX->m_bSaveAndValidate)
  747. DDX_TextWithFormatBalloon(pDX, nIDC, _T("%ld"), AFX_IDP_PARSE_INT, sizeof(long), &value);
  748. else
  749. DDX_TextWithFormatBalloon(pDX, nIDC, _T("%ld"), AFX_IDP_PARSE_INT, sizeof(long), value);
  750. }
  751. void AFXAPI
  752. DDX_TextBalloon(CDataExchange* pDX, int nIDC, DWORD& value)
  753. {
  754. if (pDX->m_bSaveAndValidate)
  755. DDX_TextWithFormatBalloon(pDX, nIDC, _T("%lu"), AFX_IDP_PARSE_UINT, sizeof(DWORD), &value);
  756. else
  757. DDX_TextWithFormatBalloon(pDX, nIDC, _T("%lu"), AFX_IDP_PARSE_UINT, sizeof(DWORD), value);
  758. }
  759. void AFXAPI
  760. DDX_TextBalloon(CDataExchange* pDX, int nIDC, LONGLONG& value)
  761. {
  762. if (pDX->m_bSaveAndValidate)
  763. DDX_TextWithFormatBalloon(pDX, nIDC, _T("%I64d"), AFX_IDP_PARSE_INT, sizeof(LONGLONG), &value);
  764. else
  765. DDX_TextWithFormatBalloon(pDX, nIDC, _T("%I64d"), AFX_IDP_PARSE_INT, sizeof(LONGLONG), value);
  766. }
  767. void AFXAPI
  768. DDX_TextBalloon(CDataExchange* pDX, int nIDC, ULONGLONG& value)
  769. {
  770. if (pDX->m_bSaveAndValidate)
  771. DDX_TextWithFormatBalloon(pDX, nIDC, _T("%I64u"), AFX_IDP_PARSE_UINT, sizeof(ULONGLONG), &value);
  772. else
  773. DDX_TextWithFormatBalloon(pDX, nIDC, _T("%I64u"), AFX_IDP_PARSE_UINT, sizeof(ULONGLONG), value);
  774. }
  775. void AFXAPI
  776. DDX_Text(CDataExchange * pDX, int nIDC, CILong & value)
  777. {
  778. HWND hWndCtrl = pDX->PrepareEditCtrl(nIDC);
  779. pDX->m_bEditLastControl = TRUE;
  780. TCHAR szT[NUMERIC_BUFF_SIZE + 1];
  781. if (pDX->m_bSaveAndValidate && ::IsWindowEnabled(hWndCtrl))
  782. {
  783. LONG l;
  784. ::GetWindowText(hWndCtrl, szT, NUMERIC_BUFF_SIZE);
  785. if (CINumber::ConvertStringToLong(szT, l))
  786. {
  787. value = l;
  788. }
  789. else
  790. {
  791. // HINSTANCE hOld = AfxGetResourceHandle();
  792. // AfxSetResourceHandle(hDLLInstance);
  793. // ASSERT(pDX->m_hWndLastControl != NULL && pDX->m_bEditLastControl);
  794. DDV_ShowBalloonAndFail(pDX, IDS_INVALID_NUMBER);
  795. //
  796. // AfxSetResourceHandle(hOld);
  797. //
  798. // pDX->Fail();
  799. }
  800. }
  801. else
  802. {
  803. ::wsprintf(szT, _T("%s"), (LPCTSTR)value);
  804. ::AfxSetWindowText(hWndCtrl, szT);
  805. }
  806. }
  807. CConfirmDlg::CConfirmDlg(CWnd * pParent)
  808. : CDialog(CConfirmDlg::IDD, pParent)
  809. {
  810. //{{AFX_DATA_INIT(CConfirmDlg)
  811. m_strPassword = _T("");
  812. //}}AFX_DATA_INIT
  813. }
  814. void
  815. CConfirmDlg::DoDataExchange(CDataExchange * pDX)
  816. {
  817. CDialog::DoDataExchange(pDX);
  818. //{{AFX_DATA_MAP(CConfirmDlg)
  819. DDX_Text(pDX, IDC_EDIT_CONFIRM_PASSWORD, m_strPassword);
  820. //}}AFX_DATA_MAP
  821. if (pDX->m_bSaveAndValidate)
  822. {
  823. if (m_ref.Compare(m_strPassword) != 0)
  824. {
  825. DDV_ShowBalloonAndFail(pDX, IDS_PASSWORD_NO_MATCH);
  826. }
  827. }
  828. }
  829. //
  830. // Message Handlers
  831. //
  832. BEGIN_MESSAGE_MAP(CConfirmDlg, CDialog)
  833. //{{AFX_MSG_MAP(CConfirmDlg)
  834. //}}AFX_MSG_MAP
  835. END_MESSAGE_MAP()