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.

219 lines
6.5 KiB

  1. /******************************************************************************
  2. Source File: Tip of the Day.CPP
  3. This implements the Tip of the Day dialog. It was originally generated by
  4. Component Gallery, but I expect to be changing it shortly.
  5. Copyright (c) 1997 by Microsoft Corporation. All Rights Reserved.
  6. A Pretty Penny Enterprises Production
  7. Change History:
  8. 03-02-1997 Bob_Kjelgaard@Prodigy.Net Created it
  9. ******************************************************************************/
  10. #include "StdAfx.H"
  11. #include "Resource.H"
  12. // CG: This file added by 'Tip of the Day' component.
  13. #include <WinReg.H>
  14. #include <Sys\Stat.H>
  15. #include <Sys\Types.H>
  16. #include "tips.h"
  17. #ifdef _DEBUG
  18. #define new DEBUG_NEW
  19. #undef THIS_FILE
  20. static char THIS_FILE[] = __FILE__;
  21. #endif
  22. /////////////////////////////////////////////////////////////////////////////
  23. // CTipOfTheDay dialog
  24. #define MAX_BUFLEN 1000
  25. static const TCHAR szSection[] = _T("Tip");
  26. static const TCHAR szIntFilePos[] = _T("FilePos");
  27. static const TCHAR szTimeStamp[] = _T("TimeStamp");
  28. static const TCHAR szIntStartup[] = _T("StartUp");
  29. CTipOfTheDay::CTipOfTheDay(CWnd* pParent /*=NULL*/)
  30. : CDialog(IDD_TIP, pParent) {
  31. //{{AFX_DATA_INIT(CTipOfTheDay)
  32. m_bStartup = TRUE;
  33. //}}AFX_DATA_INIT
  34. // We need to find out what the startup and file position parameters are
  35. // If startup does not exist, we assume that the Tips on startup is checked TRUE.
  36. CWinApp* pApp = AfxGetApp();
  37. m_bStartup = !pApp->GetProfileInt(szSection, szIntStartup, 0);
  38. UINT iFilePos = pApp->GetProfileInt(szSection, szIntFilePos, 0);
  39. //raid 104081 :: tips.txt file is in the same directory with help file
  40. CString csTipFile = pApp->m_pszHelpFilePath;
  41. csTipFile = csTipFile.Left(csTipFile.ReverseFind(_T('\\')));
  42. csTipFile = csTipFile + _T("\\tips.txt");
  43. // Now try to open the tips file
  44. m_pStream = fopen(csTipFile, "r");
  45. if (m_pStream == NULL)
  46. {
  47. m_strTip.LoadString(CG_IDS_FILE_ABSENT);
  48. return;
  49. }
  50. // If the timestamp in the INI file is different from the timestamp of
  51. // the tips file, then we know that the tips file has been modified
  52. // Reset the file position to 0 and write the latest timestamp to the
  53. // ini file
  54. struct _stat buf;
  55. _fstat(_fileno(m_pStream), &buf);
  56. CString strCurrentTime = ctime(&buf.st_ctime);
  57. strCurrentTime.TrimRight();
  58. CString strStoredTime =
  59. pApp->GetProfileString(szSection, szTimeStamp, NULL);
  60. if (strCurrentTime != strStoredTime)
  61. {
  62. iFilePos = 0;
  63. pApp->WriteProfileString(szSection, szTimeStamp, strCurrentTime);
  64. }
  65. if (fseek(m_pStream, iFilePos, SEEK_SET) != 0)
  66. {
  67. AfxMessageBox(CG_IDP_FILE_CORRUPT);
  68. }
  69. else
  70. {
  71. GetNextTipString(m_strTip);
  72. }
  73. }
  74. CTipOfTheDay::~CTipOfTheDay() {
  75. // This destructor is executed whether the user had pressed the escape key
  76. // or clicked on the close button. If the user had pressed the escape key,
  77. // it is still required to update the filepos in the ini file with the
  78. // latest position so that we don't repeat the tips!
  79. // But make sure the tips file existed in the first place....
  80. if (m_pStream != NULL) {
  81. CWinApp* pApp = AfxGetApp();
  82. pApp->WriteProfileInt(szSection, szIntFilePos, ftell(m_pStream));
  83. fclose(m_pStream);
  84. }
  85. }
  86. void CTipOfTheDay::DoDataExchange(CDataExchange* pDX) {
  87. CDialog::DoDataExchange(pDX);
  88. //{{AFX_DATA_MAP(CTipOfTheDay)
  89. DDX_Check(pDX, IDC_STARTUP, m_bStartup);
  90. DDX_Text(pDX, IDC_TIPSTRING, m_strTip);
  91. //}}AFX_DATA_MAP
  92. }
  93. BEGIN_MESSAGE_MAP(CTipOfTheDay, CDialog)
  94. //{{AFX_MSG_MAP(CTipOfTheDay)
  95. ON_BN_CLICKED(IDC_NEXTTIP, OnNextTip)
  96. ON_WM_CTLCOLOR()
  97. ON_WM_PAINT()
  98. //}}AFX_MSG_MAP
  99. END_MESSAGE_MAP()
  100. /////////////////////////////////////////////////////////////////////////////
  101. // CTipOfTheDay message handlers
  102. void CTipOfTheDay::OnNextTip() {
  103. GetNextTipString(m_strTip);
  104. UpdateData(FALSE);
  105. }
  106. void CTipOfTheDay::GetNextTipString(CString& strNext) {
  107. LPTSTR lpsz = strNext.GetBuffer(MAX_BUFLEN);
  108. // This routine identifies the next string that needs to be
  109. // read from the tips file
  110. BOOL bStop = FALSE;
  111. while (!bStop) {
  112. if (_fgetts(lpsz, MAX_BUFLEN, m_pStream) == NULL) {
  113. // We have either reached EOF or enocuntered some problem
  114. // In both cases reset the pointer to the beginning of the file
  115. // This behavior is same as VC++ Tips file
  116. if (fseek(m_pStream, 0, SEEK_SET) != 0)
  117. AfxMessageBox(CG_IDP_FILE_CORRUPT);
  118. }
  119. else { // raid 200630
  120. if (*lpsz != ' ' && *lpsz != '\t' &&
  121. *lpsz != '\n' && *lpsz != ';' && *lpsz != '*') {
  122. // There should be no space at the beginning of the tip
  123. // This behavior is same as VC++ Tips file
  124. // Comment lines are ignored and they start with a semicolon
  125. bStop = TRUE;
  126. }
  127. }
  128. }
  129. strNext.ReleaseBuffer();
  130. }
  131. HBRUSH CTipOfTheDay::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) {
  132. if (pWnd->GetDlgCtrlID() == IDC_TIPSTRING)
  133. return (HBRUSH)GetStockObject(WHITE_BRUSH);
  134. return CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
  135. }
  136. void CTipOfTheDay::OnOK() {
  137. CDialog::OnOK();
  138. // Update the startup information stored in the INI file
  139. CWinApp* pApp = AfxGetApp();
  140. pApp->WriteProfileInt(szSection, szIntStartup, !m_bStartup);
  141. }
  142. BOOL CTipOfTheDay::OnInitDialog() {
  143. CDialog::OnInitDialog();
  144. // If Tips file does not exist then disable NextTip
  145. if (m_pStream == NULL)
  146. GetDlgItem(IDC_NEXTTIP)->EnableWindow(FALSE);
  147. return TRUE; // return TRUE unless you set the focus to a control
  148. }
  149. void CTipOfTheDay::OnPaint() {
  150. CPaintDC dc(this); // device context for painting
  151. // Get paint area for the big static control
  152. CWnd* pStatic = GetDlgItem(IDC_BULB);
  153. CRect rect;
  154. pStatic->GetWindowRect(&rect);
  155. ScreenToClient(&rect);
  156. // Paint the background white.
  157. CBrush brush;
  158. brush.CreateStockObject(WHITE_BRUSH);
  159. dc.FillRect(rect, &brush);
  160. // Load bitmap and get dimensions of the bitmap
  161. CBitmap bmp;
  162. bmp.LoadBitmap(IDB_LIGHTBULB);
  163. BITMAP bmpInfo;
  164. bmp.GetBitmap(&bmpInfo);
  165. // Draw bitmap in top corner and validate only top portion of window
  166. CDC dcTmp;
  167. dcTmp.CreateCompatibleDC(&dc);
  168. dcTmp.SelectObject(&bmp);
  169. rect.bottom = bmpInfo.bmHeight + rect.top;
  170. dc.BitBlt(rect.left, rect.top, rect.Width(), rect.Height(),
  171. &dcTmp, 0, 0, SRCCOPY);
  172. // Draw out "Did you know..." message next to the bitmap
  173. CString strMessage;
  174. strMessage.LoadString(CG_IDS_DIDYOUKNOW);
  175. rect.left += bmpInfo.bmWidth;
  176. dc.DrawText(strMessage, rect, DT_VCENTER | DT_SINGLELINE);
  177. // Do not call CDialog::OnPaint() for painting messages
  178. }