用VC制作“每日提示”对话框

用VC制作“每日提示”对话框
 

熊   亮

摘要 本文主要介绍了制作“每日提示”对话框的全过程,使得读者制作的软件也和大型软件一样,具有绚丽的提示信息,并且随心所欲的修改提示内容。
关键词 VC,对话框

一、前言
    许多应用软件在刚启动时,经常会显示一个“Tip of the day”对话框,即“每天提示”对话框。在对话框中显示与应用程序使用有关的一些小知识提示,而且每天都会显示一条新的小知识。这些“每天提示”对话框的界面基本上是统一的。
二、设计思路
    虽然我们对软件启动时的每日提示并不关注,或是感觉比较厌烦,第一时间就是想着要关闭它,但对于编程爱好者来说,美化界面也是软件设计重要的一个方面。因此,有些环节是必不可少的。比如,“每日提示”对话框的制作,可以给他们提供很多额外的软件帮助。下面介绍一下“每日提示”对话框的设计思路:用MFC AppWizard创建一单文档应用工程,如Tip;建立Tip对话框,并用ClassWizard作类的映射;制作一个每日提示菜单,加载其对话框,目的是当启动时,该提示对话框被关闭,可以通过菜单再次打开;在TipApp文件中的InitInstance()函数中加载提示对话框,此处就是程序启动时,自动显示“每日提示”对话框。
    下面着重介绍一下Tip对话框中内容的设计。
    在Tip对话框中,需要的控件如下表所示。
    表 Tip对话框控件说明表

控件名

类型

主要功能

IDB_LIGHTBULB

Bitmap

提示对话框中的提示图片

IDC_STATIC

Picture

type设置为frame,用来装其他控件

IDC_BULB

Picture

用来存放提示图片

IDC_TIPSTRING

Edit

用来显示提示信息

IDC_STARTUP

CheckBox

判断是否启动加载提示对话框

IDOK

Button

点击时显示下一条提示信息

IDCANCEL

Button

关闭对话框

    在Tip对话框中是如何控制提示信息的显示的呢?下面看一下设计流程图,如下图所示。
 


图 软件设计流程
    通过以上流程,实现了“每日提示”对话框的制作。下面介绍详细的实现过程。
三、实现过程
    启动时加载提示对话框:该程序代码应该写在加再单文档主界面以后,即m_pMainWnd->UpdateWindow()之后,代码如下:
 CCommandLineInfo cmdInfo;
 CWinApp *pInfApp = AfxGetApp();
 pInfApp->ParseCommandLine(cmdInfo);//调用系统的类来显示对话框界面
 if (cmdInfo.m_bShowSplash)
 {
  CTipDlg dlg;
  if (dlg.m_bStartup)
   dlg.DoModal();
 }
    Tip对话框的设计:主要实现消息的显示,并能从前到后一条条显示,当到最后一条记录时,又回到文件的头部,重新开始显示。首先介绍程序变量的初始化和头文件信息:
#include <winreg.h>
#include <sys/stat.h>
#include <sys/types.h>

#define MAX_BUFLEN 1000//记录长度的定义
//初始化变量
TCHAR szTip[] = _T("Tip");
TCHAR szTipIntFilePos[] = _T("FilePos");
TCHAR szTipTimeStamp[] = _T("TimeStamp");
TCHAR szTipIntStartup[] = _T("StartUp");
    (1)定位到构造函数CTipDlg::CTipDlg
 CWinApp* pApp = AfxGetApp();
 m_bStartup = !pApp->GetProfileInt(szTip, szTipIntStartup, 0);
 UINT iFilePos = pApp->GetProfileInt(szTip, szTipIntFilePos, 0);
 m_didYouKonwStr ="知道 TIP 吗?";
 lpTipOfTheDayFileName = "c://TipLoc.txt";//文件存放的路径
 m_pStream = fopen(lpTipOfTheDayFileName, "r");//读取文件
 if (m_pStream == NULL)
 {
  MessageBox("文件没有找到!");
  return;
 }
//读取文件中的内容
 struct _stat buf;
 _fstat(_fileno(m_pStream), &buf);
 CString strCurrentTime = ctime(&buf.st_ctime);
 strCurrentTime.TrimRight();
 CString strStoredTime =
  pApp->GetProfileString(szTip, szTipTimeStamp, NULL);
 if (strCurrentTime != strStoredTime)
 {
  iFilePos = 0;
  pApp->WriteProfileString(szTip, szTipTimeStamp, strCurrentTime);
 }
 if (fseek(m_pStream, iFilePos, SEEK_SET) == 0) 
 {
  GetNextTipString(m_strTip);
  makeMultiLine(m_strTip);
 }
    (2)初始化对话框OnInitDialog()
 if (m_pStream == NULL)
  GetDlgItem(IDOK)->EnableWindow(FALSE);
 CButton *pButton;
 pButton = (CButton*)GetDlgItem(IDC_STARTUP);
 pButton->SetCheck(m_bStartup);//设置选择按钮
     (3)初始化界面OnPaint()
 CWnd* pStatic = GetDlgItem(IDC_BULB);
 CRect rect;
 pStatic->GetWindowRect(&rect);
 ScreenToClient(&rect);
 CBrush brush;
 brush.CreateStockObject(WHITE_BRUSH);
 dc.FillRect(rect, &brush);
 CBitmap bmp;
 bmp.LoadBitmap(IDB_LIGHTBULB);//加载提示图片
 BITMAP bmpInfo;
 bmp.GetBitmap(&bmpInfo);
 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);
 CString strMessage;
 strMessage = m_didYouKonwStr;
 rect.left += bmpInfo.bmWidth;
 dc.DrawText(strMessage, rect, DT_VCENTER | DT_SINGLELINE);//加载提示题目
    (4)信息的分条显示
void CTipDlg::OnOK()
{
 GetNextTipString(m_strTip);
 makeMultiLine(m_strTip);
 UpdateData(FALSE);
}
void CTipDlg::makeMultiLine(CString& m_strTip)
{
 char eol[3] = {13, 10};
 CString multiLineStr, srcStr, extStr, tmpStr;
 multiLineStr = _T("");
 srcStr = m_strTip;
 int  idx;
 while(!srcStr.IsEmpty()) {
  idx = srcStr.Find("//n");//以/n问判断标记
  if(idx != -1) {
   extStr = srcStr.Left(idx);
   tmpStr.Format("%s%s", extStr, eol);
   multiLineStr += tmpStr;
   srcStr = srcStr.Mid(idx + 2);
  } else {
   multiLineStr += srcStr;
   break;
  }
 }
 idx = multiLineStr.ReverseFind('/n'); // end of the ONE tip
 if(idx != -1) {
  multiLineStr = multiLineStr.Left(idx);
  tmpStr.Format("%s%s", multiLineStr, eol);
  multiLineStr = tmpStr;
 }
 m_strTip = multiLineStr;
}

void CTipDlg::GetNextTipString(CString &strNext)
{
 LPTSTR lpsz = strNext.GetBuffer(MAX_BUFLEN);
 BOOL bStop = FALSE;
 while (!bStop)
 {//判断是否为空,或是超过字段最大范围,或是遇到特殊字符
  if (_fgetts(lpsz, MAX_BUFLEN, m_pStream) == NULL)
  {
   if (fseek(m_pStream, 0, SEEK_SET) != 0)
   MessageBox("不能读 '每日提示' 文件");
  }
  else
  {
   if (*lpsz != ' ' && *lpsz != '/t' &&
    *lpsz != '/n' && *lpsz != ';')
   {
     bStop = TRUE;
   }
  }
 }
 strNext.ReleaseBuffer();
}
四、结语
    通过“每日提示”对话框的设计,从某种程度上讲,可以增强应用软件成熟性,虽然只是一个微小的细节,有时候可以达到事半功倍的效果。
参考文献:
[1] MSDN Library - January 2001.
[2] Visual C++ 6.0 MFC类库参考手册.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值