DateEdit.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521
  1. #include "stdafx.h"
  2. #include "DateEdit.h"
  3. #include "LYFZIPManage.h"
  4. #ifdef _DEBUG
  5. #define new DEBUG_NEW
  6. #undef THIS_FILE
  7. static char THIS_FILE[] = __FILE__;
  8. #endif
  9. /////////////////////////////////////////////////////////////////////////////
  10. // COleDateTime read /write
  11. /*
  12. COleDateTime ReadCOleDateTime(LPCSTR lpszData)
  13. {
  14. COleDateTime DateTime;
  15. DateTime.ParseDateTime(lpszData);
  16. return DateTime;
  17. }
  18. void FormatCOleDateTime(CString& strData, COleDateTime DateTime, int len)
  19. {
  20. strData = "";
  21. if (DateTime.m_dt == 0) return;
  22. if (len == 8)
  23. strData = DateTime.Format("%d/%m/%y");
  24. else if(len == 5) // added these two
  25. strData = DateTime.Format("%H:%M");
  26. else
  27. strData = DateTime.Format("%d/%m/%Y");
  28. }
  29. /////////////////////////////////////////////////////////////////////////////
  30. // DDX for mask control
  31. void AFXAPI DDX_OleDate(CDataExchange* pDX, int nIDC, CDateEdit& rControl, COleDateTime& Date)
  32. {
  33. DDX_Control(pDX, nIDC, (CWnd&)rControl);
  34. if (!pDX->m_bSaveAndValidate)
  35. rControl.SetDate(Date);
  36. else
  37. Date = rControl.GetDate();
  38. }
  39. */
  40. /////////////////////////////////////////////////////////////////////////////
  41. // CDateEdit
  42. IMPLEMENT_DYNAMIC(CDateEdit,CEdit)
  43. BEGIN_MESSAGE_MAP(CDateEdit, CEdit)
  44. //{{AFX_MSG_MAP(CDateEdit)
  45. ON_WM_CHAR()
  46. ON_WM_KEYDOWN()
  47. ON_CONTROL_REFLECT(EN_SETFOCUS, OnEnSetfocus)
  48. //}}AFX_MSG_MAP
  49. // ON_MESSAGE(WM_CUT, OnCut)
  50. // ON_MESSAGE(WM_PASTE, OnPaste)
  51. // ON_MESSAGE(WM_CLEAR, OnClear)
  52. END_MESSAGE_MAP()
  53. CDateEdit::CDateEdit()
  54. {
  55. Reset();
  56. SetClassType("DateEdit");
  57. }
  58. CDateEdit::~CDateEdit()
  59. {
  60. }
  61. /////////////////////////////////////////////////////////////////////////////
  62. // CDateEdit message handlers
  63. void CDateEdit::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
  64. {
  65. CString str;
  66. try
  67. {
  68. GetWindowText(str);
  69. }
  70. catch(...)
  71. {
  72. }
  73. for (int i = 0; i<str.GetLength() && i<m_str.GetLength();i++)
  74. m_str.SetAt(i, str.GetAt(i));
  75. if(!m_bMaskKeyInProgress)
  76. if(!CheckChar(nChar)) return;
  77. if(m_bUseMask) //要使用掩码
  78. {
  79. if(isprint(nChar)) //是可打印字符
  80. {
  81. int startPos,endPos;
  82. GetSel(startPos,endPos);
  83. SetSel(startPos,endPos+1);
  84. Clear();
  85. }
  86. /* else if(nChar==VK_BACK)
  87. {
  88. int startPos,endPos;
  89. GetSel(startPos,endPos);
  90. if((startPos==endPos) && (startPos>=1) && (startPos<=m_str.GetLength()))
  91. {
  92. char c;
  93. if(m_strMaskLiteral != _T(""))
  94. c=m_strMaskLiteral[startPos-1];
  95. TRACE("m_strMaskLiteral=[%s](%s)\n",m_strMaskLiteral,m_str);
  96. //回退光标
  97. SendMessage(WM_KEYDOWN,VK_LEFT,0);
  98. if(m_strMaskLiteral != _T(""))
  99. {
  100. //恢复在该位置预设的字符
  101. SendChar(c);
  102. //再次退回
  103. SendMessage(WM_KEYDOWN,VK_LEFT,0);
  104. }
  105. }
  106. else //越界或者存在选择区域
  107. MessageBeep((UINT)-1);
  108. return;
  109. }*/
  110. }
  111. CEdit::OnChar(nChar, nRepCnt, nFlags);
  112. if(!m_bMaskKeyInProgress && m_bUseMask && m_strLiteral != _T(""))
  113. {
  114. int startPos,endPos;
  115. GetSel(startPos,endPos);
  116. //确保字符串的长度小于m_strLiteral的长度
  117. if(endPos<m_strLiteral.GetLength())
  118. {
  119. UINT c=m_strLiteral.GetAt(endPos);
  120. if(c!='_')
  121. SendChar(c);
  122. }
  123. }
  124. }
  125. void CDateEdit::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
  126. {
  127. /* if(m_bUseMask)
  128. {
  129. switch(nChar)//忽略删除和插入键
  130. {
  131. case VK_DELETE:
  132. case VK_INSERT: return;
  133. }
  134. }*/
  135. CEdit::OnKeyDown(nChar, nRepCnt, nFlags);
  136. }
  137. BOOL CDateEdit::CheckChar(UINT nChar)
  138. {
  139. UINT c;
  140. int nTime = 0;
  141. CString sText;
  142. //如果不使用掩码,则返回
  143. if(!m_bUseMask) return TRUE;
  144. //如果是控制字符,则返回
  145. if(!isprint(nChar)) return TRUE;
  146. //如果存在选择区域,则取消选择
  147. int startPos,endPos;
  148. GetSel(startPos,endPos);
  149. SetSel(-1,0);
  150. //重新选中原选择区域的第一个字符
  151. SetSel(startPos,startPos);
  152. GetSel(startPos,endPos);
  153. //确保字符串的长度不超过掩码的长度
  154. if(endPos>=m_strMask.GetLength())
  155. {
  156. MessageBeep((UINT)-1);
  157. return FALSE;
  158. }
  159. //检查在当前位置是否应存在文字
  160. c='_';
  161. if(m_strLiteral != _T("") &&
  162. m_strLiteral.GetLength()>endPos)
  163. c=m_strLiteral.GetAt(endPos);
  164. if(c!='_')
  165. {//发送默认值
  166. SendChar(c);
  167. GetSel(startPos,endPos);
  168. }
  169. //检查字符的有效性
  170. if(m_strValid.Find(nChar)!=-1) return TRUE;
  171. //检查当前位置的掩码
  172. c=m_strMask.GetAt(endPos);
  173. BOOL doit=TRUE;
  174. sText = m_str;
  175. sText.SetAt(endPos, nChar);
  176. if (nChar == VK_SPACE) return true; //空格
  177. switch(c)
  178. {
  179. case '0': //只能是数字
  180. {
  181. BOOL doit=TRUE;
  182. if(isdigit(nChar))
  183. {
  184. if(m_isDate || m_isDateTime) //是否按照日期格式输入
  185. {
  186. // sText.SetAt(endPos, nChar);
  187. if (!IsValid(COleDateTime(COleVariant(sText))))
  188. {
  189. if(endPos < 8)
  190. {//月、日设置为默认
  191. sText.SetAt(4, '-');
  192. sText.SetAt(5, '0');
  193. sText.SetAt(6, '1');
  194. sText.SetAt(7, '-');
  195. sText.SetAt(8, '0');
  196. sText.SetAt(9, '1');
  197. SetWindowText(sText);
  198. SetSel(endPos+1,endPos+1);
  199. }
  200. if(endPos >= 8)
  201. {//日设置为少30
  202. if (sText.GetAt(8) > '3')
  203. sText.SetAt(8, '0');
  204. sText.SetAt(9, '1');
  205. SetWindowText(sText);
  206. SetSel(endPos+1,endPos+1);
  207. }
  208. doit=FALSE;
  209. }
  210. /* if(endPos==8)
  211. {
  212. if(nChar>'3') //每月只能有三十几天
  213. doit=FALSE;
  214. }
  215. if(endPos==9)
  216. {
  217. if(m_str.GetAt(5)=='0' &&
  218. m_str.GetAt(6)=='2' &&
  219. m_str.GetAt(8)=='2')
  220. {
  221. if(nChar>'8')//2月不超过29天
  222. doit=FALSE;
  223. }
  224. else if(m_str.GetAt(5)=='0' &&
  225. m_str.GetAt(6)=='2' &&
  226. m_str.GetAt(8)>'2')
  227. {//2月不起30
  228. doit=FALSE;
  229. }
  230. else if(m_str.GetAt(8)=='3')
  231. {
  232. if(nChar>'1')//每月不超过31天
  233. doit=FALSE;
  234. }
  235. }
  236. if(endPos==5)
  237. {
  238. if(nChar>'1') //一年只能有12个月
  239. doit=FALSE;
  240. }
  241. if(endPos==6)
  242. {
  243. if(m_str.GetAt(5)=='1')
  244. {
  245. if(nChar>'2') //一年只能有12个月
  246. doit=FALSE;
  247. }
  248. }
  249. */
  250. }//结束日期检查
  251. if (m_isDateTime) nTime = 11;
  252. if (m_isTime || m_isDateTime) //按时间格式检查
  253. {
  254. //转换时间为HH0MM
  255. // for(int i = nTime; i < nTime+5; i++)
  256. // {
  257. // if (sText.GetAt(i) == TCHAR(' ') ||
  258. // sText.GetAt(i) == TCHAR(':'))
  259. // sText.SetAt(i, TCHAR('0'));
  260. // }
  261. if (!IsValid(COleDateTime(COleVariant(sText))))
  262. // if (atoi((LPCSTR)sText.Mid(nTime)) > 24000)
  263. {
  264. if(endPos == nTime &&
  265. nChar < '3')
  266. {
  267. sText.SetAt(nTime+1, '0');
  268. sText.SetAt(nTime+2, ':');
  269. sText.SetAt(nTime+3, '0');
  270. sText.SetAt(nTime+4, '0');
  271. SetWindowText(sText);
  272. SetSel(endPos+1,endPos+1);
  273. }
  274. if(endPos == nTime + 1 &&
  275. nChar < '4')
  276. {
  277. sText.SetAt(nTime+2, ':');
  278. sText.SetAt(nTime+3, '0');
  279. sText.SetAt(nTime+4, '0');
  280. SetWindowText(sText);
  281. SetSel(endPos+1,endPos+1);
  282. }
  283. doit=FALSE;
  284. }
  285. }//结束 时间检查
  286. return doit;
  287. }
  288. break;
  289. }
  290. }
  291. MessageBeep((UINT)-1);
  292. return FALSE;
  293. }
  294. void CDateEdit::SetMask(LPCSTR lpMask, LPCSTR lpLiteral, LPCSTR lpValid)
  295. {
  296. m_bUseMask=FALSE;
  297. TCHAR szMask[] = {'0', '9', '#', 'A', 'a', '?'};
  298. if(lpMask==NULL) return;
  299. m_strMask=lpMask;
  300. if(m_strMask == _T("")) return;
  301. if(lpLiteral!=NULL)
  302. {
  303. m_strLiteral=lpLiteral;
  304. if(m_strLiteral.GetLength()!=m_strMask.GetLength())
  305. m_strLiteral.Empty();
  306. }
  307. else
  308. {//自动生成
  309. //m_strLiteral.Empty();
  310. m_strLiteral = m_strMask;
  311. for(int i = 0; i < 6; i++)
  312. {
  313. int j = 0;
  314. j = m_strLiteral.Find(szMask[i], j);
  315. while(j>=0)
  316. {
  317. m_strLiteral.SetAt(j, TCHAR('_'));
  318. j = m_strLiteral.Find(szMask[i], j);
  319. }//end while
  320. }//end for
  321. }
  322. if(lpValid!=NULL)
  323. m_strValid=lpValid;
  324. else
  325. m_strValid.Empty();
  326. m_bUseMask=TRUE;
  327. //分配存储空间
  328. m_str = CString(TCHAR(' '), m_strMask.GetLength());
  329. }
  330. BOOL CDateEdit::IsValid(const COleDateTime& date)const
  331. {
  332. return (date.GetStatus() == COleDateTime::valid);
  333. }
  334. LONG CDateEdit::OnCut(UINT, LONG)
  335. {//禁止CUT
  336. /* int nStart, nEnd;
  337. GetSel(nStart, nEnd);
  338. if (nStart < nEnd)
  339. {
  340. SendMessage(WM_COPY); // copy the selection and...
  341. SendMessage(WM_KEYDOWN, VK_DELETE); // delete it
  342. }
  343. */
  344. return 0;
  345. }
  346. // Clears the current selection.
  347. LONG CDateEdit::OnClear(UINT wParam, LONG lParam)
  348. {//禁止CLEAR
  349. /* int nStart, nEnd;
  350. GetSel(nStart, nEnd);
  351. if (nStart < nEnd)
  352. SendMessage(WM_KEYDOWN, VK_DELETE); // delete the selection
  353. */
  354. return 0;
  355. }
  356. // Pastes the text from the clipboard onto the current selection.
  357. LONG CDateEdit::OnPaste(UINT, LONG)
  358. {//禁止PASTE
  359. /* int nStart, nEnd;
  360. GetSel(nStart, nEnd);
  361. CEdit::Default();
  362. CString strText = GetValidText();
  363. if (strText != GetText())
  364. {
  365. SetWindowText(strText);
  366. SetSel(nStart, nEnd);
  367. }
  368. */
  369. return 0;
  370. }
  371. // Insures that text set via SetWindowText is valid.
  372. void CDateEdit::SetClassType(LPCSTR pName, LPCSTR pMask)
  373. {
  374. try
  375. {
  376. CString sName = pName;
  377. sName.MakeUpper();
  378. Reset();
  379. if(sName == _T("DATEEDIT")) //日期
  380. {
  381. m_bUseMask = TRUE;
  382. m_isDate = TRUE; //added this
  383. m_strMask = _T("0000-00-00"); //掩码
  384. m_strLiteral = _T("____-__-__"); //掩码有效设置 有效_ 其它-
  385. m_str = _T(" "); //数据保存空间
  386. //SetWindowText(_T(" - - "));
  387. }
  388. else if(sName == _T("TIMEEDIT")) //时间
  389. {
  390. m_bUseMask = TRUE;
  391. m_isTime = true;
  392. m_strMask = _T("00:00");
  393. m_strLiteral = _T("__:__");
  394. m_str = _T(" ");
  395. SetWindowText(_T(" : "));
  396. }
  397. else if(sName == _T("DATETIMEEDIT")) //日期+时间
  398. {
  399. m_bUseMask = TRUE;
  400. m_isDateTime = true;
  401. m_strMask = _T("0000-00-00 00:00");
  402. m_strLiteral = _T("____-__-__ __:__");
  403. m_str = _T(" ");
  404. SetWindowText(_T(" - - : "));
  405. }
  406. }
  407. catch(...)
  408. {
  409. }
  410. }
  411. void CDateEdit::Reset()
  412. {
  413. m_bUseMask=FALSE;
  414. m_strMask=_T("");
  415. m_strLiteral=_T("");
  416. m_strValid=_T("");
  417. // m_strHours=_T("24");
  418. // m_strMins=_T("60");
  419. m_bMaskKeyInProgress=FALSE;
  420. m_strMaskLiteral=_T("");
  421. m_str = _T("");
  422. m_isDate = FALSE;//是否是日期格式
  423. m_isTime = FALSE;//是否是时间格式
  424. m_isDateTime = FALSE;//是否是日期时间格式
  425. m_isNumber = FALSE;
  426. }
  427. void CDateEdit::SendChar(UINT nChar)
  428. {
  429. m_bMaskKeyInProgress=TRUE;
  430. #ifdef WIN32
  431. AfxCallWndProc(this,m_hWnd,WM_CHAR,nChar,1);
  432. #else
  433. SendMessage(WM_CHAR,nChar,1);
  434. #endif
  435. m_bMaskKeyInProgress=FALSE;
  436. }
  437. void CDateEdit::SetDefault()
  438. {
  439. try
  440. {
  441. if (m_isDate)
  442. SetWindowText(_T(" - - "));
  443. else if (m_isTime)
  444. SetWindowText(_T(" : "));
  445. else if (m_isDateTime)
  446. SetWindowText(_T(" - - : "));
  447. }
  448. catch(...)
  449. {
  450. }
  451. }
  452. void CDateEdit::SetNow()
  453. {
  454. try
  455. {
  456. COleDateTime tNow = COleDateTime::GetCurrentTime();
  457. if (m_isDate)
  458. SetWindowText(tNow.Format("%Y-%m-%d"));
  459. else if (m_isTime)
  460. SetWindowText(tNow.Format("%H:%M"));
  461. else if (m_isDateTime)
  462. SetWindowText(tNow.Format("%Y-%m-%d %H:%M"));
  463. }
  464. catch(...)
  465. {
  466. }
  467. }
  468. void CDateEdit::OnEnSetfocus()
  469. {
  470. try
  471. {
  472. CString str;
  473. GetWindowText(str);
  474. str.TrimLeft ();
  475. str.TrimRight ();
  476. if(str.IsEmpty ())
  477. SetWindowText(CTime::GetCurrentTime ().Format ("%Y-%m-%d"));
  478. }
  479. catch(...)
  480. {
  481. }
  482. }