XTPCalendarTimeZoneHelper.cpp
上传用户:szled88
上传日期:2015-04-09
资源大小:43957k
文件大小:13k
源码类别:

对话框与窗口

开发平台:

Visual C++

  1. // XTPCalendarTimeZoneHelper.cpp: implementation of Time Zone Helper classes.
  2. //
  3. // This file is a part of the XTREME CALENDAR MFC class library.
  4. // (c)1998-2008 Codejock Software, All Rights Reserved.
  5. //
  6. // THIS SOURCE FILE IS THE PROPERTY OF CODEJOCK SOFTWARE AND IS NOT TO BE
  7. // RE-DISTRIBUTED BY ANY MEANS WHATSOEVER WITHOUT THE EXPRESSED WRITTEN
  8. // CONSENT OF CODEJOCK SOFTWARE.
  9. //
  10. // THIS SOURCE CODE CAN ONLY BE USED UNDER THE TERMS AND CONDITIONS OUTLINED
  11. // IN THE XTREME TOOLKIT PRO LICENSE AGREEMENT. CODEJOCK SOFTWARE GRANTS TO
  12. // YOU (ONE SOFTWARE DEVELOPER) THE LIMITED RIGHT TO USE THIS SOFTWARE ON A
  13. // SINGLE COMPUTER.
  14. //
  15. // CONTACT INFORMATION:
  16. // support@codejock.com
  17. // http://www.codejock.com
  18. //
  19. /////////////////////////////////////////////////////////////////////////////
  20. #include "stdafx.h"
  21. #include "Common/XTPVC80Helpers.h"
  22. #include "Common/XTPSystemHelpers.h"
  23. #include "XTPCalendarTimeZoneHelper.h"
  24. #include "XTPCalendarDefines.h"
  25. #ifdef _DEBUG
  26. #undef THIS_FILE
  27. static char THIS_FILE[] = __FILE__;
  28. #define new DEBUG_NEW
  29. #endif
  30. //================================================================
  31. IMPLEMENT_DYNAMIC(CXTPCalendarTimeZone, CCmdTarget)
  32. IMPLEMENT_DYNAMIC(CXTPCalendarTimeZones, CCmdTarget)
  33. CXTPCalendarTimeZone::CXTPCalendarTimeZone(const TIME_ZONE_INFORMATION* pTZInfo)
  34. {
  35. if (pTZInfo)
  36. {
  37. *((TIME_ZONE_INFORMATION*)this) = *pTZInfo;
  38. }
  39. else
  40. {
  41. ::ZeroMemory((void*)((TIME_ZONE_INFORMATION*)this), sizeof(TIME_ZONE_INFORMATION));
  42. }
  43. m_dwIndex = 0;
  44. }
  45. CXTPCalendarTimeZone::CXTPCalendarTimeZone(const CXTPCalendarTimeZone* pTZInfoEx)
  46. {
  47. *this = *pTZInfoEx;
  48. }
  49. CXTPCalendarTimeZone::~CXTPCalendarTimeZone()
  50. {
  51. }
  52. const CXTPCalendarTimeZone&
  53. CXTPCalendarTimeZone::operator=(const CXTPCalendarTimeZone& rTZInfo)
  54. {
  55. *((TIME_ZONE_INFORMATION*)this) = *((TIME_ZONE_INFORMATION*)&rTZInfo);
  56. m_strDisplayString = rTZInfo.GetDisplayString();
  57. m_dwIndex = rTZInfo.GetIndex();
  58. return *this;
  59. }
  60. CString CXTPCalendarTimeZone::GetDisplayString() const
  61. {
  62. return m_strDisplayString;
  63. }
  64. DWORD CXTPCalendarTimeZone::GetIndex() const
  65. {
  66. return m_dwIndex;
  67. }
  68. BOOL CXTPCalendarTimeZone::IsEqual(const TIME_ZONE_INFORMATION* pTZI2) const
  69. {
  70. if (!pTZI2)
  71. {
  72. ASSERT(FALSE);
  73. return FALSE;
  74. }
  75. const int cnChSize_name = _countof(StandardName);
  76. if (_wcsnicmp(StandardName, pTZI2->StandardName, cnChSize_name) == 0)
  77. {
  78. return TRUE;
  79. }
  80. return FALSE;
  81. }
  82. CXTPCalendarTimeZonePtr CXTPCalendarTimeZone::GetTimeZoneInfo(
  83. const TIME_ZONE_INFORMATION* pTZIdata)
  84. {
  85. if (!pTZIdata)
  86. {
  87. ASSERT(FALSE);
  88. return NULL;
  89. }
  90. CXTPCalendarTimeZones arXTP_TZI;
  91. if (!arXTP_TZI.InitFromRegistry())
  92. {
  93. return NULL;
  94. }
  95. CXTPCalendarTimeZone* pTZI2Info = arXTP_TZI.Find(pTZIdata);
  96. if (pTZI2Info)
  97. {
  98. CXTPCalendarTimeZone* pTZI2;
  99. pTZI2 = new CXTPCalendarTimeZone(pTZI2Info);
  100. //to update "biases" and names values
  101. if (pTZI2)
  102. {
  103. *((TIME_ZONE_INFORMATION*)pTZI2) = *pTZIdata;
  104. }
  105. CXTPCalendarTimeZonePtr ptrTZI2(pTZI2, FALSE);
  106. return ptrTZI2;
  107. }
  108. return NULL;
  109. }
  110. /////////////////////////////////////////////////////////////////////////////
  111. //class CXTPCalendarTimeZones : public CCmdTarget
  112. CXTPCalendarTimeZones::CXTPCalendarTimeZones()
  113. {
  114. }
  115. CXTPCalendarTimeZones::~CXTPCalendarTimeZones()
  116. {
  117. }
  118. BOOL CXTPCalendarTimeZones::GetRegBSTR(HKEY hKey, LPCWSTR pcszValueNameW,
  119.    BSTR& rbstrValue)
  120. {
  121. if (rbstrValue)
  122. {
  123. ::SysFreeString(rbstrValue);
  124. rbstrValue = NULL;
  125. }
  126. //------------------------------------------------------------
  127. if (CXTPCalendarUtils::IsWin9x())
  128. {
  129. CString strValueName(pcszValueNameW);
  130. CString strValue;
  131. if (GetRegStr(hKey, strValueName, strValue))
  132. {
  133. rbstrValue = strValue.AllocSysString();
  134. }
  135. return rbstrValue != NULL;
  136. }
  137. //------------------------------------------------------------
  138. const DWORD cdwDataSize = 4 * 1024;
  139. BYTE arData[cdwDataSize];
  140. ::ZeroMemory(arData, sizeof(arData));
  141. DWORD dwType = 0, dwDataSize = sizeof(arData)-2;
  142. LONG lRes = ::RegQueryValueExW(hKey, pcszValueNameW, NULL, &dwType,
  143. arData, &dwDataSize);
  144. if (lRes != ERROR_SUCCESS)
  145. {
  146. return FALSE;
  147. }
  148. if (dwType == REG_SZ || dwType == REG_EXPAND_SZ || dwType == REG_MULTI_SZ)
  149. {
  150. ASSERT(dwType != REG_MULTI_SZ); // WARMING!
  151. rbstrValue = ::SysAllocString((LPCWSTR)arData);
  152. return rbstrValue != NULL;
  153. }
  154. return FALSE;
  155. }
  156. BOOL CXTPCalendarTimeZones::GetRegStr(HKEY hKey, LPCTSTR pcszValueName, CString& rstrValue)
  157. {
  158. rstrValue.Empty();
  159. const DWORD cdwDataSize = 4 * 1024;
  160. BYTE arData[cdwDataSize];
  161. ::ZeroMemory(arData, sizeof(arData));
  162. DWORD dwType = 0, dwDataSize = sizeof(arData)-2;
  163. LONG lRes = ::RegQueryValueEx(hKey, pcszValueName, NULL, &dwType,
  164. arData, &dwDataSize);
  165. if (lRes != ERROR_SUCCESS)
  166. {
  167. return FALSE;
  168. }
  169. if (dwType == REG_SZ || dwType == REG_EXPAND_SZ || dwType == REG_MULTI_SZ)
  170. {
  171. ASSERT(dwType != REG_MULTI_SZ); // WARMING!
  172. rstrValue = (LPCTSTR)arData;
  173. return TRUE;
  174. }
  175. return FALSE;
  176. }
  177. BOOL CXTPCalendarTimeZones::GetRegDWORD(HKEY hKey, LPCTSTR pcszValueName, DWORD& rdwValue)
  178. {
  179. rdwValue = 0;
  180. const DWORD cdwDataSize = 16;
  181. BYTE arData[cdwDataSize];
  182. ::ZeroMemory(arData, sizeof(arData));
  183. DWORD dwType = 0, dwDataSize = sizeof(arData);
  184. LONG lRes = ::RegQueryValueEx(hKey, pcszValueName, NULL, &dwType,
  185. arData, &dwDataSize);
  186. if (lRes != ERROR_SUCCESS)
  187. {
  188. return FALSE;
  189. }
  190. if (dwType == REG_DWORD || dwType == REG_DWORD_BIG_ENDIAN || dwType == REG_BINARY)
  191. {
  192. rdwValue = *((DWORD*)arData);
  193. return TRUE;
  194. }
  195. return FALSE;
  196. }
  197. BOOL CXTPCalendarTimeZones::GetRegTZI(HKEY hKey, LPCTSTR pcszValueName,
  198. CXTPCalendarTimeZones::REGISTRY_TIMEZONE_INFORMATION& rRegTZI)
  199. {
  200. ::ZeroMemory(&rRegTZI, sizeof(rRegTZI));
  201. const DWORD cdwDataSize = sizeof(rRegTZI)*2;
  202. BYTE arData[cdwDataSize];
  203. ::ZeroMemory(arData, sizeof(arData));
  204. DWORD dwType = 0, dwDataSize = sizeof(arData);
  205. LONG lRes = ::RegQueryValueEx(hKey, pcszValueName, NULL, &dwType,
  206. arData, &dwDataSize);
  207. if (lRes != ERROR_SUCCESS)
  208. {
  209. return FALSE;
  210. }
  211. if (dwType == REG_BINARY && dwDataSize == sizeof(rRegTZI))
  212. {
  213. rRegTZI = *((REGISTRY_TIMEZONE_INFORMATION*)arData);
  214. return TRUE;
  215. }
  216. ASSERT(FALSE);
  217. return FALSE;
  218. }
  219. BOOL CXTPCalendarTimeZones::InitFromRegistry()
  220. {
  221. m_arTZInfo.RemoveAll();
  222. CString strTZIRootKey = XTP_CALENDAR_TIMEZONESKEY_NT;
  223. HKEY hkTZIRoot = NULL;
  224. BOOL bUseIndex = !XTPSystemVersion()->IsWinXPOrGreater();
  225. // Try NT information first
  226. LONG lRes = ::RegOpenKeyEx(HKEY_LOCAL_MACHINE, strTZIRootKey, 0, KEY_READ, &hkTZIRoot);
  227. if (lRes != ERROR_SUCCESS)
  228. {
  229. // try Win9x information
  230. strTZIRootKey = XTP_CALENDAR_TIMEZONESKEY_9X;
  231. bUseIndex = FALSE;
  232. lRes = ::RegOpenKeyEx(HKEY_LOCAL_MACHINE, strTZIRootKey, 0, KEY_READ, &hkTZIRoot);
  233. if (lRes != ERROR_SUCCESS)
  234. {
  235. TRACE(_T("Cannot open Time Zones information registry key. err = %d n"), lRes);
  236. return FALSE;
  237. }
  238. }
  239. const DWORD cdwKeyBufSize = 1024;
  240. TCHAR szTZIKey[cdwKeyBufSize + 1];
  241. BSTR bstrStandardName = NULL;
  242. BSTR bstrDaylightName = NULL;
  243. lRes = ERROR_SUCCESS;
  244. for (DWORD dwEnumKey = 0; lRes == ERROR_SUCCESS; dwEnumKey++)
  245. {
  246. ::ZeroMemory(szTZIKey, sizeof(szTZIKey));
  247. lRes = ::RegEnumKey (hkTZIRoot, dwEnumKey, szTZIKey, cdwKeyBufSize);
  248. if (lRes != ERROR_SUCCESS)
  249. {
  250. ASSERT(lRes == ERROR_NO_MORE_ITEMS);
  251. break;
  252. }
  253. //===================================================================
  254. CString strTZIKey = strTZIRootKey + _T("\") + szTZIKey;
  255. HKEY hkTZIdata = NULL;
  256. LONG lRes2 = ::RegOpenKeyEx(HKEY_LOCAL_MACHINE, strTZIKey, 0, KEY_READ, &hkTZIdata);
  257. if (lRes2 != ERROR_SUCCESS)
  258. {
  259. TRACE(_T("Cannot open registry key 'HKEY_LOCAL_MACHINE\%s'. err = %d n"), (LPCTSTR)strTZIKey, lRes2);
  260. continue;
  261. }
  262. CString strDisplayStr, strStandardName, strDaylightName;
  263. DWORD dwIndex;
  264. REGISTRY_TIMEZONE_INFORMATION regTZI;
  265. if (!GetRegStr(hkTZIdata, XTP_CALENDAR_TZIRegValName_DisplayStr, strDisplayStr))
  266. {
  267. TRACE(_T("Cannot get value from registry: 'HKEY_LOCAL_MACHINE\%s\%s'n"), (LPCTSTR)strTZIKey, XTP_CALENDAR_TZIRegValName_DisplayStr);
  268. continue;
  269. }
  270. if (!GetRegBSTR(hkTZIdata, XTP_CALENDAR_TZIRegValName_StandardNameW, bstrStandardName))
  271. {
  272. TRACE(_T("Cannot get value from registry: 'HKEY_LOCAL_MACHINE\%s\%s'n"), (LPCTSTR)strTZIKey, XTP_CALENDAR_TZIRegValName_StandardName);
  273. continue;
  274. }
  275. if (!GetRegBSTR(hkTZIdata, XTP_CALENDAR_TZIRegValName_DaylightNameW, bstrDaylightName))
  276. {
  277. TRACE(_T("Cannot get value from registry: 'HKEY_LOCAL_MACHINE\%s\%s'n"), (LPCTSTR)strTZIKey, XTP_CALENDAR_TZIRegValName_DaylightName);
  278. continue;
  279. }
  280. if (!GetRegTZI(hkTZIdata, XTP_CALENDAR_TZIRegValName_DATA, regTZI))
  281. {
  282. TRACE(_T("Cannot get value from registry: 'HKEY_LOCAL_MACHINE\%s\%s'n"), (LPCTSTR)strTZIKey, XTP_CALENDAR_TZIRegValName_DATA);
  283. continue;
  284. }
  285. if (!GetRegDWORD(hkTZIdata, XTP_CALENDAR_TZIRegValName_Index, dwIndex))
  286. {
  287. if (bUseIndex)
  288. {
  289. TRACE(_T("Cannot get value from registry: 'HKEY_LOCAL_MACHINE\%s\%s'n"), (LPCTSTR)strTZIKey, XTP_CALENDAR_TZIRegValName_Index);
  290. }
  291. dwIndex = 0;
  292. }
  293. //=================================================
  294. CXTPCalendarTimeZone* pXTP_TZI;
  295. pXTP_TZI = new CXTPCalendarTimeZone();
  296. if (!pXTP_TZI)
  297. {
  298. AfxThrowOleException(E_OUTOFMEMORY);
  299. }
  300. pXTP_TZI->Bias = regTZI.Bias;
  301. WCSNCPY_S(pXTP_TZI->StandardName, bstrStandardName, 32);
  302. pXTP_TZI->StandardName[_countof(pXTP_TZI->StandardName)-1] = L'';
  303. pXTP_TZI->StandardDate = regTZI.StandardDate;
  304. pXTP_TZI->StandardBias = regTZI.StandardBias;
  305. WCSNCPY_S(pXTP_TZI->DaylightName, bstrDaylightName, 32);
  306. pXTP_TZI->DaylightName[_countof(pXTP_TZI->DaylightName)-1] = L'';
  307. pXTP_TZI->DaylightDate = regTZI.DaylightDate;
  308. pXTP_TZI->DaylightBias = regTZI.DaylightBias;
  309. pXTP_TZI->m_strDisplayString = strDisplayStr;
  310. pXTP_TZI->m_dwIndex = dwIndex;
  311. m_arTZInfo.Add(pXTP_TZI, FALSE);
  312. }
  313. //-----------------------------------------------
  314. if (bstrStandardName)
  315. {
  316. ::SysFreeString(bstrStandardName);
  317. }
  318. if (bstrDaylightName)
  319. {
  320. ::SysFreeString(bstrDaylightName);
  321. }
  322. //-----------------------------------------------
  323. int nCount = m_arTZInfo.GetCount();
  324. for (int i = 0; i < nCount; i++)
  325. {
  326. for (int j = i + 1; j < nCount; j++)
  327. {
  328. CXTPCalendarTimeZonePtr ptrElem1, ptrElem2;
  329. ptrElem1 = m_arTZInfo.GetAt(i, TRUE);
  330. ptrElem2 = m_arTZInfo.GetAt(j, TRUE);
  331. if (CompareTZI(ptrElem1, ptrElem2, bUseIndex) > 0)
  332. {
  333. m_arTZInfo.SetAt(i, ptrElem2.Detach());
  334. m_arTZInfo.SetAt(j, ptrElem1.Detach());
  335. }
  336. }
  337. }
  338. return TRUE;
  339. }
  340. int CXTPCalendarTimeZones::GetDigit(TCHAR ch) const
  341. {
  342. int nD = ch - _T('0');
  343. return (nD >= 0 && nD <= 9) ? nD : -1;
  344. }
  345. void CXTPCalendarTimeZones::ParseDisplayStr(LPCTSTR str, int& rnOffset, CString& rstrPlace) const
  346. {
  347. // (GMT + 02:00) Athens, ...
  348. // (GMT-02:00) place, ...
  349. //----------------------------------------------
  350. //  (GMT - 02 : 00) place, ...
  351. //0 1      2    3  4 5
  352. //----------------------------------------------
  353. rnOffset = 0;
  354. rstrPlace.Empty();
  355. int nSign = 0, nHr = 0, nMin = 0;
  356. int nState = 0;
  357. for (const TCHAR* pCh = (LPCTSTR)str; pCh && *pCh != 0; pCh = _tcsinc(pCh))
  358. {
  359. if (nState == 0 && *pCh == _T('('))
  360. {
  361. nState = 1;
  362. }
  363. else if (nState == 1)
  364. {
  365. if (*pCh == _T('+'))
  366. {
  367. nSign = 1;
  368. nState = 2;
  369. }
  370. else if (*pCh == _T('-'))
  371. {
  372. nSign = -1;
  373. nState = 2;
  374. }
  375. }
  376. else if (nState == 2)
  377. {
  378. if (GetDigit(*pCh) >= 0)
  379. {
  380. nHr *= 10;
  381. nHr += GetDigit(*pCh);
  382. }
  383. else if (*pCh == _T(':'))
  384. {
  385. nState = 3;
  386. }
  387. }
  388. else if (nState == 3)
  389. {
  390. if (GetDigit(*pCh) >= 0)
  391. {
  392. nMin *= 10;
  393. nMin += GetDigit(*pCh);
  394. }
  395. else if (*pCh == _T(')'))
  396. {
  397. nState = 4;
  398. }
  399. }
  400. else if (nState == 4)
  401. {
  402. if (*pCh != _T(' '))
  403. {
  404. rstrPlace = pCh;
  405. break;
  406. }
  407. }
  408. }
  409. //---------------------------------------
  410. rnOffset = nSign * (nHr * 60 + nMin);
  411. }
  412. int CXTPCalendarTimeZones::CompareTZI(const CXTPCalendarTimeZone* pTZI1,
  413.   const CXTPCalendarTimeZone* pTZI2,
  414.   BOOL bUseIndex) const
  415. {
  416. if (bUseIndex)
  417. {
  418. return XTPCompare(pTZI1->m_dwIndex, pTZI2->m_dwIndex);
  419. }
  420. int nOffset1, nOffset2;
  421. CString strPlace1, strPlace2;
  422. ParseDisplayStr(pTZI1->GetDisplayString(), nOffset1, strPlace1);
  423. ParseDisplayStr(pTZI2->GetDisplayString(), nOffset2, strPlace2);
  424. int nCmpRes = XTPCompare(nOffset1, nOffset2);
  425. if (nCmpRes)
  426. {
  427. return nCmpRes;
  428. }
  429. return XTPCompare(strPlace1, strPlace2);
  430. }
  431. int CXTPCalendarTimeZones::GetCount() const
  432. {
  433. return m_arTZInfo.GetCount();
  434. }
  435. CXTPCalendarTimeZone* CXTPCalendarTimeZones::GetAt(long nIndex) const
  436. {
  437. if (nIndex < 0 || nIndex >= m_arTZInfo.GetCount())
  438. {
  439. ASSERT(FALSE);
  440. return NULL;
  441. }
  442. CXTPCalendarTimeZone* pTZI = m_arTZInfo.GetAt(nIndex, FALSE);
  443. return pTZI;
  444. }
  445. CXTPCalendarTimeZone* CXTPCalendarTimeZones::Find(const TIME_ZONE_INFORMATION* pTZI2) const
  446. {
  447. if (!pTZI2)
  448. {
  449. ASSERT(FALSE);
  450. return NULL;
  451. }
  452. int nCount = GetCount();
  453. for (int i = 0; i < nCount; i++)
  454. {
  455. CXTPCalendarTimeZone* pTZI = GetAt(i);
  456. if (!pTZI)
  457. {
  458. ASSERT(FALSE);
  459. continue;
  460. }
  461. if (pTZI->IsEqual(pTZI2))
  462. {
  463. return pTZI;
  464. }
  465. }
  466. return NULL;
  467. }