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

对话框与窗口

开发平台:

Visual C++

  1. // XTTipOfTheDay.cpp : implementation of the CXTTipOfTheDay class.
  2. //
  3. // This file is a part of the XTREME CONTROLS 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"  // Visual Studio 2005 helper functions
  22. #include "Common/XTPResourceManager.h"
  23. #include "Common/XTPDrawHelpers.h"
  24. #include "Common/XTPColorManager.h"
  25. #include "Resource.h"
  26. #include "XTDefines.h"
  27. #include "XTGlobal.h"
  28. #include "XTTipOfTheDay.h"
  29. #include "XTRegistryManager.h"
  30. #include <winreg.h>
  31. #include <sysstat.h>
  32. #include <systypes.h>
  33. #ifdef _DEBUG
  34. #define new DEBUG_NEW
  35. #undef THIS_FILE
  36. static char THIS_FILE[] = __FILE__;
  37. #endif
  38. #define MAX_BUFLEN 1000
  39. static const TCHAR szSection[] = _T("Tip");
  40. static const TCHAR szIntFilePos[] = _T("FilePos");
  41. static const TCHAR szTimeStamp[] = _T("TimeStampLong");
  42. static const TCHAR szIntStartup[] = _T("StartUp");
  43. /////////////////////////////////////////////////////////////////////////////
  44. // CXTTipOfTheDay dialog
  45. /////////////////////////////////////////////////////////////////////////////
  46. CXTTipOfTheDay::CXTTipOfTheDay(LPCTSTR lpszTipFile/*= NULL*/, CWnd* pParent/*= NULL*/)
  47. {
  48. InitModalIndirect(XTPResourceManager()->LoadDialogTemplate(IDD), pParent);
  49. //{{AFX_DATA_INIT(CXTTipOfTheDay)
  50. m_bStartup = TRUE;
  51. //}}AFX_DATA_INIT
  52. SetTipsFilePath(lpszTipFile);
  53. VERIFY(XTPResourceManager()->LoadString(&m_strTipTitle, XT_IDS_DIDYOUKNOW));
  54. m_strTipText = _T("");
  55. m_pFontTitle = NULL;
  56. m_pFontTip = NULL;
  57. m_bClassicStyle = FALSE;
  58. {
  59. CXTPResourceManager::CManageState state;
  60. m_ilLightBulb.SetIcon(XT_IDI_LIGHTBULB, 1);
  61. }
  62. // We need to find out what the startup and file position parameters are
  63. // If startup does not exist, we assume that the Tips on startup is checked TRUE.
  64. CXTRegistryManager regManager;
  65. m_bStartup = !regManager.GetProfileInt(szSection, szIntStartup, 0);
  66. UINT iFilePos = regManager.GetProfileInt(szSection, szIntFilePos, 0);
  67. // Now try to open the tips file
  68. m_pStream = FOPEN_S((TCHAR*)(LPCTSTR)m_strTipFile, _T("r"));
  69. if (m_pStream == NULL)
  70. {
  71. VERIFY(XTPResourceManager()->LoadString(&m_strTipText, XT_IDS_FILE_ABSENT));
  72. return;
  73. }
  74. // If the timestamp in the INI file is different from the timestamp of
  75. // the tips file, then we know that the tips file has been modified
  76. // Reset the file position to 0 and write the latest timestamp to the
  77. // ini file
  78. struct _stat buf;
  79. _fstat(_fileno(m_pStream), &buf);
  80. int nCurrentTime = (int)(buf.st_ctime);
  81. int nStoredTime = (int)regManager.GetProfileInt(
  82. szSection, szTimeStamp, NULL);
  83. if (nCurrentTime != nStoredTime)
  84. {
  85. iFilePos = 0;
  86. regManager.WriteProfileInt(szSection, szTimeStamp, nCurrentTime);
  87. }
  88. if (fseek(m_pStream, iFilePos, SEEK_SET) != 0)
  89. {
  90. XTPResourceManager()->ShowMessageBox(XT_IDS_FILE_CORRUPT);
  91. }
  92. else
  93. {
  94. GetNextTipString(m_strTipText);
  95. }
  96. }
  97. CXTTipOfTheDay::~CXTTipOfTheDay()
  98. {
  99. // This destructor is executed whether the user had pressed the escape key
  100. // or clicked on the close button. If the user had pressed the escape key,
  101. // it is still required to update the filepos in the ini file with the
  102. // latest position so that we don't repeat the tips!
  103. // But make sure the tips file existed in the first place....
  104. if (m_pStream != NULL)
  105. {
  106. CXTRegistryManager regManager;
  107. regManager.WriteProfileInt(szSection, szIntFilePos, ftell(m_pStream));
  108. fclose(m_pStream);
  109. }
  110. if (m_fontTitle.GetSafeHandle())
  111. m_fontTitle.DeleteObject();
  112. if (m_fontTip.GetSafeHandle())
  113. m_fontTip.DeleteObject();
  114. }
  115. void CXTTipOfTheDay::DoDataExchange(CDataExchange* pDX)
  116. {
  117. CDialog::DoDataExchange(pDX);
  118. //{{AFX_DATA_MAP(CXTTipOfTheDay)
  119. DDX_Control(pDX, IDOK, m_ok);
  120. DDX_Control(pDX, XT_IDC_CHK_DAYTIP_SHOW, m_showTips);
  121. DDX_Control(pDX, XT_IDC_BTN_DAYTIP_NEXT, m_btnNextTip);
  122. DDX_Control(pDX, XT_IDC_BTN_DAYTIP_BORDER, m_staticBorder);
  123. DDX_Check(pDX, XT_IDC_CHK_DAYTIP_SHOW, m_bStartup);
  124. //}}AFX_DATA_MAP
  125. }
  126. IMPLEMENT_DYNAMIC(CXTTipOfTheDay, CDialog)
  127. BEGIN_MESSAGE_MAP(CXTTipOfTheDay, CDialog)
  128. //{{AFX_MSG_MAP(CXTTipOfTheDay)
  129. ON_WM_PAINT()
  130. ON_BN_CLICKED(XT_IDC_BTN_DAYTIP_NEXT, OnDaytipNext)
  131. //}}AFX_MSG_MAP
  132. END_MESSAGE_MAP()
  133. void CXTTipOfTheDay::OnPaint()
  134. {
  135. CPaintDC dc(this); // device context for painting
  136. dc.SetBkMode(TRANSPARENT);
  137. if (m_bClassicStyle)
  138. {
  139. CRect rcBorder(m_rcBorder);
  140. rcBorder.DeflateRect(10, 10, 10, 0);
  141. dc.FillSolidRect(rcBorder.left + 50, rcBorder.top, rcBorder.Width() - 50, rcBorder.Height(), GetXtremeColor(COLOR_WINDOW));
  142. dc.FillSolidRect(rcBorder.left, rcBorder.top, 50, rcBorder.Height(), RGB(128, 128, 128));
  143. dc.Draw3dRect(rcBorder, GetXtremeColor(COLOR_3DSHADOW), GetXtremeColor(COLOR_3DHIGHLIGHT));
  144. // Draw the light bulb bitmap to the screen.
  145. CXTPImageManagerIcon* pIcon = m_ilLightBulb.GetImage(1, 32);
  146. if (pIcon) pIcon->Draw(&dc, CPoint(rcBorder.left + 8, rcBorder.top + 8));
  147. // Draw the title text.
  148. CXTPFontDC font(&dc, m_pFontTitle);
  149. dc.SetTextColor(GetXtremeColor(COLOR_WINDOWTEXT));
  150. dc.TextOut(52 + 10 + 5, 14 + 5, m_strTipTitle);
  151. // Draw the tip of the day text.
  152. font.SetFont(m_pFontTip);
  153. dc.DrawText(m_strTipText, m_rcTipText, DT_END_ELLIPSIS | DT_WORDBREAK);
  154. }
  155. else
  156. {
  157. dc.FillSolidRect(m_rcBorder, GetXtremeColor(COLOR_WINDOW));
  158. dc.FillSolidRect(m_rcBorder.left, m_rcBorder.bottom, m_rcBorder.Width(), 1, GetXtremeColor(COLOR_3DSHADOW));
  159. // Draw the light bulb bitmap to the screen.
  160. CXTPImageManagerIcon* pIcon = m_ilLightBulb.GetImage(1, 32);
  161. if (pIcon) pIcon->Draw(&dc, CPoint(8, 8));
  162. // Draw the title text.
  163. CXTPFontDC font(&dc, m_pFontTitle);
  164. dc.SetTextColor(RGB(0x00, 0x33, 0x99));
  165. dc.TextOut(52, 14, m_strTipTitle);
  166. // Draw the tip of the day text.
  167. font.SetFont(m_pFontTip);
  168. dc.SetTextColor(GetXtremeColor(COLOR_WINDOWTEXT));
  169. dc.DrawText(m_strTipText, m_rcTipText, DT_END_ELLIPSIS | DT_WORDBREAK);
  170. }
  171. // Do not call CDialog::OnPaint() for painting messages
  172. }
  173. BOOL CXTTipOfTheDay::OnInitDialog()
  174. {
  175. CDialog::OnInitDialog();
  176. // Set font title if it has not been already set.
  177. if (m_pFontTitle == NULL && m_pFontTip == NULL)
  178. {
  179. CWindowDC dc(NULL);
  180. NONCLIENTMETRICS ncm;
  181. ncm.cbSize = sizeof(NONCLIENTMETRICS);
  182. ::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, &ncm, 0);
  183. if (_tcscmp(ncm.lfMenuFont.lfFaceName, _T("Segoe UI")) == 0)
  184. ncm.lfMenuFont.lfQuality = 5;
  185. ncm.lfMenuFont.lfWeight = FW_NORMAL;
  186. ncm.lfMenuFont.lfItalic = 0;
  187. m_fontTip.CreateFontIndirect(&ncm.lfMenuFont);
  188. ncm.lfMenuFont.lfHeight = ::MulDiv(-12, ::GetDeviceCaps(dc.m_hDC, LOGPIXELSY), 72);
  189. if (_tcscmp(ncm.lfMenuFont.lfFaceName, _T("Segoe UI")) != 0)
  190. ncm.lfMenuFont.lfWeight = FW_BOLD;
  191. m_fontTitle.CreateFontIndirect(&ncm.lfMenuFont);
  192. m_pFontTip = &m_fontTip;
  193. m_pFontTitle = &m_fontTitle;
  194. }
  195. // If Tips file does not exist then disable NextTip
  196. m_btnNextTip.EnableWindow(m_pStream != NULL);
  197. // Get the border size, this will be the base for our
  198. // painting routines.
  199. CRect rcBorder;
  200. m_staticBorder.GetWindowRect(&rcBorder);
  201. ScreenToClient(&rcBorder);
  202. m_rcBorder = CXTPClientRect(this);
  203. m_rcBorder.bottom = rcBorder.bottom - 1;
  204. if (!m_bClassicStyle)
  205. m_rcTipText.SetRect(52, 44, m_rcBorder.right - 6, m_rcBorder.bottom - 6);
  206. else
  207. m_rcTipText.SetRect(52 + 10 + 5, 44 + 5, m_rcBorder.right - 6 - 10, m_rcBorder.bottom - 6);
  208. m_ok.SetFont(&XTAuxData().font);
  209. m_showTips.SetFont(&XTAuxData().font);
  210. m_btnNextTip.SetFont(&XTAuxData().font);
  211. return TRUE;
  212. }
  213. void CXTTipOfTheDay::SetDefaultFonts(CFont* pFontTitle, CFont* pFontTip)
  214. {
  215. m_pFontTitle = pFontTitle;
  216. m_pFontTip = pFontTip;
  217. }
  218. void CXTTipOfTheDay::GetNextTipString(CString& strNext)
  219. {
  220. LPTSTR lpsz = strNext.GetBuffer(MAX_BUFLEN);
  221. // This routine identifies the next string that needs to be
  222. // read from the tips file
  223. BOOL bStop = FALSE;
  224. while (!bStop)
  225. {
  226. if (_fgetts(lpsz, MAX_BUFLEN, m_pStream) == NULL)
  227. {
  228. // We have either reached EOF or encountered some problem
  229. // In both cases reset the pointer to the beginning of the file
  230. // This behavior is same as VC++ Tips file
  231. if (fseek(m_pStream, 0, SEEK_SET) != 0)
  232. XTPResourceManager()->ShowMessageBox(XT_IDS_FILE_CORRUPT);
  233. }
  234. else
  235. {
  236. if (*lpsz != ' ' && *lpsz != 't' &&
  237. *lpsz != 'n' && *lpsz != ';')
  238. {
  239. // There should be no space at the beginning of the tip
  240. // This behavior is same as VC++ Tips file
  241. // Comment lines are ignored and they start with a semicolon
  242. bStop = TRUE;
  243. }
  244. }
  245. }
  246. strNext.ReleaseBuffer();
  247. }
  248. void CXTTipOfTheDay::OnOK()
  249. {
  250. // Update the startup information stored in the INI file
  251. UpdateData();
  252. CXTRegistryManager regManager;
  253. regManager.WriteProfileInt(szSection, szIntStartup, !m_bStartup);
  254. CDialog::OnOK();
  255. }
  256. void CXTTipOfTheDay::OnDaytipNext()
  257. {
  258. UpdateData();
  259. GetNextTipString(m_strTipText);
  260. InvalidateRect(m_rcTipText);
  261. UpdateData(FALSE);
  262. }
  263. void CXTTipOfTheDay::SetTipsFilePath(LPCTSTR lpszTipFile)
  264. {
  265. CFileFind file;
  266. if (lpszTipFile && file.FindFile(lpszTipFile))
  267. {
  268. m_strTipFile = lpszTipFile;
  269. }
  270. else
  271. {
  272. m_strTipFile = _T("tips.txt");
  273. }
  274. }