首 页 ┆ 源码下载 ┆ IT学院 ┆ 字体下载 ┆ 模板下载 ┆ 源码发布 ┆ 广告合作 ┆ 网站地图 ┆ 虚拟主机 ┆ 中文域名
► 设为首页
► 加入收藏
► 联系我们
源码下载 >> ASP源码 | PHP源码 | ASP.net源码 | JSP源码 | CGI源码 | VC/C++源码 | VB源码 | Delphi源码 | Flash源码
文章学院 >> 网络编程 | 网页设计 | 图形图象 | 数据库 | 服务器 | 网络媒体 | 网络安全 | 操作系统 | 办公软件 | 软件开发 | 黑客知识
字体下载 >> 精制字体 | 非英字体 | 艺术字体 | 著名字体 | 哥特式 | 简单字体 | 手写体 | 节假日 | 图案字体 | 精度像素 | 中文字体
模板下载 >> 企业门户 | 数码网络 | 休闲娱乐 | 影视音乐 | 旅游名胜 | 文化艺术 | 电子商务 | 个性展示 | 登陆导航 | Flash模板
►►您当前的位置:源码园 → IT学院 → 软件开发 → VC编程 → 文章内容

VC++工程中加入 SplashScreen 原理释解

作者:Abbey  来源:网上收集  发布时间:2007-3-27 10:14:26

VC++工程中加入 SplashScreen 原理释解


作者:Abbey

下载源代码

摘要
  本文旨在剖析
VC++工程中加入 SplashScreen 的原理,并给出在VC++ MFC(exe)工程中加入 SplashScreen 的步骤。

关键字 SplashScreen,原理

环境:
Windows 98SE/2000,
VC++ 6.0
  SplashScreen - 我们使用
Word 之类的软件在启动的短暂时间里就会看到它的身影。它通常用以在程序启动时显示程序及用户名称,版权信息等。我也不知道它准确的名称是什么(是闪屏吗?),就这样称呼吧。也许你也想在自己的工程里加入这样的特性,本文将以创建实际工程的方式逐步剖析其实现原理。

注意
:为避免实际所使用工程名给类或对象名带来的干扰,除非特别说明,在本文中将使用基类名如CWinApp、CMainFrame、CDialog来代替实际工程中的相应派生类名进行描述。
  Visual
C++是一个相当强大的C++开发工具,它内嵌了对SplashScreen的支持。但是在MFC EXE类型工程中只是对带有主框架类的SDI或MDI工程提供了这一支持,基于对话框类的工程则被排除在外。现在让我们开始吧。第一步是在SDI工程中加入SplashScreen。
  首先利用AppWizard生成一个SDI工程,除了其中Docking ToolBar必须选择外(我认为这是MFC的一个Bug,当然这与本文讨论的SplashScreen没有关系),其他的文档-视图支持、状态条之类的都可以不要,这样可以尽量减少无用的代码。
  通过IDE中的菜单Project->Add to Project->Components and Controls,我们就可以从Visual
C++ Components中选择Splash Screen这个组件插入工程。



  在点击了"Insert"后会弹出一个如下图所示的对话框,这是设置插入该工程中的SplashScreen的类名、显示用位图的ID及文件名,采用缺省值即可。



  通过以上几步的操作,就会在工程目录下生成Splash.CPP和Splash.H文件,这便是CSplashWnd类的实现文件与头文件。同时工程中CWinApp与CMainFrame类中的部分代码也会被修改,以实现CSplashWnd窗口的消息处理。
  接着我们来看看 CSplashWnd 类的声明与主要的代码(已经过删减):

//类的声明

class CSplashWnd : public CWnd{CSplashWnd();~CSplashWnd();virtual void PostNcDestroy();static void EnableSplashScreen(BOOL bEnable = TRUE);static void ShowSplashScreen(CWnd* pParentWnd = NULL);static BOOL PreTranslateAppMessage(MSG* pMsg);BOOL Create(CWnd* pParentWnd = NULL);void HideSplashScreen();afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);afx_msg void OnPaint();afx_msg void OnTimer(UINT nIDEvent);CBitmap m_bitmap;  //SplashScreen窗口显示用的位图对象static BOOL c_bShowSplashWnd; //是否要显示SplashScreen的标志量static CSplashWnd* c_pSplashWnd;};
//是否使用SplashScreen
void CSplashWnd::EnableSplashScreen(BOOL bEnable){c_bShowSplashWnd = bEnable;}
//创建CsplashWnd对象,并调用Create()创建窗口
void CSplashWnd::ShowSplashScreen(CWnd* pParentWnd){//如果不要显示SplashScreen或SplashWnd对象已经被创建则返回if (!c_bShowSplashWnd || c_pSplashWnd != NULL)return;c_pSplashWnd = new CSplashWnd;if (!c_pSplashWnd->Create(pParentWnd))delete c_pSplashWnd;elsec_pSplashWnd->UpdateWindow();}
//装入SplashScreen欲显示位图,通过CreateEx()激发OnCreate()完成窗口创建与设置
BOOL CSplashWnd::Create(CWnd* pParentWnd){if (!m_bitmap.LoadBitmap(IDB_SPLASH))return FALSE;BITMAP bm;m_bitmap.GetBitmap(&bm);return CreateEx(0, 
AfxRegisterWndClass(0,AfxGetApp()->LoadStandardCursor(IDC_ARROW)),
NULL,
WS_POPUP | WS_VISIBLE,
0,
0,
bm.bmWidth,
bm.bmHeight,
pParentWnd->GetSafeHwnd(),
NULL);
}
//销毁窗口,刷新框架
void CSplashWnd::HideSplashScreen(){DestroyWindow();AfxGetMainWnd()->UpdateWindow();}
//利用窗口创建结构创建窗口,并设置定时器在750ms后触发OnTimer()
int CSplashWnd::OnCreate(LPCREATESTRUCT lpCreateStruct){if (CWnd::OnCreate(lpCreateStruct) == -1)return -1;CenterWindow(); //窗口居中显示SetTimer(1, 750, NULL); //设置定时器return 0;}
//将键盘和鼠标消息传递给CSplashWnd对象,以销毁窗口
BOOL CSplashWnd::PreTranslateAppMessage(MSG* pMsg){if (c_pSplashWnd == NULL)return FALSE;if (pMsg->message == WM_KEYDOWN ||    pMsg->message == WM_SYSKEYDOWN ||    pMsg->message == WM_LBUTTONDOWN ||    pMsg->message == WM_RBUTTONDOWN ||    pMsg->message == WM_MBUTTONDOWN ||    pMsg->message == WM_NCLBUTTONDOWN ||    pMsg->message == WM_NCRBUTTONDOWN ||    pMsg->message == WM_NCMBUTTONDOWN){c_pSplashWnd->HideSplashScreen();return TRUE;}return FALSE;}void CSplashWnd::OnTimer(UINT nIDEvent){HideSplashScreen();}
再看看CWinApp和CMainFrame类中发生了什么样的改变:
(1)在CWinApp::InitInstance()中调用CSplashWnd::EnableSplashScreen()设置c_bShowSplashWnd;
在PreTranslateMessage()中调用CSplashWnd::PreTranslateAppMessage(),将键盘和鼠标消息传递给CSplashWnd对象,从而进一步调用CSplashWnd::HideSplashScreen()实现SplashScreen窗口的自身销毁。
(2)在CMainFrame对象的OnCreate()中调用CSplashWnd::ShowSplashScreen()创建一个静态的SplashScreen窗口对象c_pSplashWnd,并设置其父窗口为CMainFrame。在这个过程中,CSplashWnd自身会通过创建来设置一个定时器,然后定时器在第一个周期触发时便调用HideSplashScreen()销毁自己。
(3) 而CMainFrame对象的窗口创建消息则是由CWinApp对象在InitInstance()中通过
m_pMainWnd->ShowWindow()调用触发的。
  整个过程可以用下图表示,基本原理就是由CMainFrame来创建CSplashWnd,然后由CSplashWnd自己的定时器触发定时消息来销毁窗口。所以 CSplashWnd 的加入与SDI还是MDI都没有关系。



  第二步,我们再来看看如何在基于对话框的工程中加入 SplashScreen。
通过对以上SDI工程中加入SplashScreen原理的剖析,我想大家也想到如何在基于对话框的工程中加入这一特性了。其实质就是由CDialog类完成SDI工程中CMainFrame类的工作,实现步骤如下:
(1)利用ClassWizard为CMyDialog添加WM_CREATE消息的处理函数OnCreate();(这里使用CMyDialog是为了与函数内的基类名CDialog区别。)
int CMyDialog::OnCreate(LPCREATESTRUCT lpCreateStruct){if (CDialog::OnCreate(lpCreateStruct) == -1)return -1;CSplashWnd::ShowSplashScreen(this);return 0;}        
(2)利用ClassWizard为CWinApp添加消息转发处理函数PreTranslateMessage();
BOOL CWinApp::PreTranslateMessage(MSG* pMsg){if (CSplashWnd::PreTranslateAppMessage(pMsg))return TRUE;return CWinApp::PreTranslateMessage(pMsg);}
(3)CWinApp::InitInstance()中加入如下调用:CSplashWnd::EnableSplashScreen(TRUE);
(4)当然你还需要将上一个SDI工程中生成的Splash.CPP与Splash.H文件拷贝到当前工程目录下,并利用Project->Add to Project->Files将这两个文件引入工程。同时还要在CWinApp与CMainFrame的实现文件中#include "Splash.H"。
(5)然后在资源管理器里添加一个ID为IDB_SPLASH的位图。由于
VC++的IDE只能显示256色以下的位图,所以如果你想显示一幅真彩色的位图,就请用Import方式导入一幅预先制作好的位图。当然VC++会提示位图已经成功导入,只是无法在IDE的位图编辑器中显示,而在程序运行时就会显示了。如果你想象Word那样显示用户名等信息,可以在CSplashWnd::Create()中装载位图之后增加自己的代码来修改位图。
  通过以上这几步操作,我们就完成了在基于对话框的工程中加入SplashScreen的工作。清楚了吗?

[] [返回上一页] [打 印]
  • 上一篇文章:多功能标签CLabelEx
  • 下一篇文章:自绘菜单的实现

  • 相关文章:
  • 在VC++下对文件属性的获取与更改
  • VC++6.0中控制运行唯一实例
  • [图文]VC++ SMTP协议电子邮件传送剖析
  • [图文]C++/VC++编程的疑难问题及解答(二)
  • C++/VC++编程的疑难问题及解答
  • [图文]VC++通用GIS功能开发解决方案 2.0v 介绍
  • [图文]VC++界面一揽子解决方案(第三版) 介绍
  • [组图]VC++的Unicode编程
  • 用VC++设计语法编辑器
  • [图文]在VC++实现数据加密
  • [图文]DES算法及其在VC++6.0下的实现(上)
  • [组图]DES算法及其在VC++6.0下的实现(下)
关于本站 - 网站帮助 - 广告合作 - 下载声明 - 友情连接 - 网站地图 - 源码发布
Copyright © 2003-2009 Ymyasp.Com. All Rights Reserved .
备案序号:粤ICP备07029071号