/****************************************************************************** Source File: Tip of the Day.CPP This implements the Tip of the Day dialog. It was originally generated by Component Gallery, but I expect to be changing it shortly. Copyright (c) 1997 by Microsoft Corporation. All Rights Reserved. A Pretty Penny Enterprises Production Change History: 03-02-1997 Bob_Kjelgaard@Prodigy.Net Created it ******************************************************************************/ #include "StdAfx.H" #include "Resource.H" // CG: This file added by 'Tip of the Day' component. #include #include #include #include "tips.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CTipOfTheDay dialog #define MAX_BUFLEN 1000 static const TCHAR szSection[] = _T("Tip"); static const TCHAR szIntFilePos[] = _T("FilePos"); static const TCHAR szTimeStamp[] = _T("TimeStamp"); static const TCHAR szIntStartup[] = _T("StartUp"); CTipOfTheDay::CTipOfTheDay(CWnd* pParent /*=NULL*/) : CDialog(IDD_TIP, pParent) { //{{AFX_DATA_INIT(CTipOfTheDay) m_bStartup = TRUE; //}}AFX_DATA_INIT // We need to find out what the startup and file position parameters are // If startup does not exist, we assume that the Tips on startup is checked TRUE. CWinApp* pApp = AfxGetApp(); m_bStartup = !pApp->GetProfileInt(szSection, szIntStartup, 0); UINT iFilePos = pApp->GetProfileInt(szSection, szIntFilePos, 0); //raid 104081 :: tips.txt file is in the same directory with help file CString csTipFile = pApp->m_pszHelpFilePath; csTipFile = csTipFile.Left(csTipFile.ReverseFind(_T('\\'))); csTipFile = csTipFile + _T("\\tips.txt"); // Now try to open the tips file m_pStream = fopen(csTipFile, "r"); if (m_pStream == NULL) { m_strTip.LoadString(CG_IDS_FILE_ABSENT); return; } // If the timestamp in the INI file is different from the timestamp of // the tips file, then we know that the tips file has been modified // Reset the file position to 0 and write the latest timestamp to the // ini file struct _stat buf; _fstat(_fileno(m_pStream), &buf); CString strCurrentTime = ctime(&buf.st_ctime); strCurrentTime.TrimRight(); CString strStoredTime = pApp->GetProfileString(szSection, szTimeStamp, NULL); if (strCurrentTime != strStoredTime) { iFilePos = 0; pApp->WriteProfileString(szSection, szTimeStamp, strCurrentTime); } if (fseek(m_pStream, iFilePos, SEEK_SET) != 0) { AfxMessageBox(CG_IDP_FILE_CORRUPT); } else { GetNextTipString(m_strTip); } } CTipOfTheDay::~CTipOfTheDay() { // This destructor is executed whether the user had pressed the escape key // or clicked on the close button. If the user had pressed the escape key, // it is still required to update the filepos in the ini file with the // latest position so that we don't repeat the tips! // But make sure the tips file existed in the first place.... if (m_pStream != NULL) { CWinApp* pApp = AfxGetApp(); pApp->WriteProfileInt(szSection, szIntFilePos, ftell(m_pStream)); fclose(m_pStream); } } void CTipOfTheDay::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CTipOfTheDay) DDX_Check(pDX, IDC_STARTUP, m_bStartup); DDX_Text(pDX, IDC_TIPSTRING, m_strTip); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CTipOfTheDay, CDialog) //{{AFX_MSG_MAP(CTipOfTheDay) ON_BN_CLICKED(IDC_NEXTTIP, OnNextTip) ON_WM_CTLCOLOR() ON_WM_PAINT() //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CTipOfTheDay message handlers void CTipOfTheDay::OnNextTip() { GetNextTipString(m_strTip); UpdateData(FALSE); } void CTipOfTheDay::GetNextTipString(CString& strNext) { LPTSTR lpsz = strNext.GetBuffer(MAX_BUFLEN); // This routine identifies the next string that needs to be // read from the tips file BOOL bStop = FALSE; while (!bStop) { if (_fgetts(lpsz, MAX_BUFLEN, m_pStream) == NULL) { // We have either reached EOF or enocuntered some problem // In both cases reset the pointer to the beginning of the file // This behavior is same as VC++ Tips file if (fseek(m_pStream, 0, SEEK_SET) != 0) AfxMessageBox(CG_IDP_FILE_CORRUPT); } else { // raid 200630 if (*lpsz != ' ' && *lpsz != '\t' && *lpsz != '\n' && *lpsz != ';' && *lpsz != '*') { // There should be no space at the beginning of the tip // This behavior is same as VC++ Tips file // Comment lines are ignored and they start with a semicolon bStop = TRUE; } } } strNext.ReleaseBuffer(); } HBRUSH CTipOfTheDay::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) { if (pWnd->GetDlgCtrlID() == IDC_TIPSTRING) return (HBRUSH)GetStockObject(WHITE_BRUSH); return CDialog::OnCtlColor(pDC, pWnd, nCtlColor); } void CTipOfTheDay::OnOK() { CDialog::OnOK(); // Update the startup information stored in the INI file CWinApp* pApp = AfxGetApp(); pApp->WriteProfileInt(szSection, szIntStartup, !m_bStartup); } BOOL CTipOfTheDay::OnInitDialog() { CDialog::OnInitDialog(); // If Tips file does not exist then disable NextTip if (m_pStream == NULL) GetDlgItem(IDC_NEXTTIP)->EnableWindow(FALSE); return TRUE; // return TRUE unless you set the focus to a control } void CTipOfTheDay::OnPaint() { CPaintDC dc(this); // device context for painting // Get paint area for the big static control CWnd* pStatic = GetDlgItem(IDC_BULB); CRect rect; pStatic->GetWindowRect(&rect); ScreenToClient(&rect); // Paint the background white. CBrush brush; brush.CreateStockObject(WHITE_BRUSH); dc.FillRect(rect, &brush); // Load bitmap and get dimensions of the bitmap CBitmap bmp; bmp.LoadBitmap(IDB_LIGHTBULB); BITMAP bmpInfo; bmp.GetBitmap(&bmpInfo); // Draw bitmap in top corner and validate only top portion of window CDC dcTmp; dcTmp.CreateCompatibleDC(&dc); dcTmp.SelectObject(&bmp); rect.bottom = bmpInfo.bmHeight + rect.top; dc.BitBlt(rect.left, rect.top, rect.Width(), rect.Height(), &dcTmp, 0, 0, SRCCOPY); // Draw out "Did you know..." message next to the bitmap CString strMessage; strMessage.LoadString(CG_IDS_DIDYOUKNOW); rect.left += bmpInfo.bmWidth; dc.DrawText(strMessage, rect, DT_VCENTER | DT_SINGLELINE); // Do not call CDialog::OnPaint() for painting messages }