熊 亮
摘要 本文主要介绍了制作“每日提示”对话框的全过程,使得读者制作的软件也和大型软件一样,具有绚丽的提示信息,并且随心所欲的修改提示内容。 关键词 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类库参考手册.
|