VC利用GDI+技术制作基于CWnd类的Spalsh启动画面

最近想做个程序的启动画面,原因当然就是为了使程序更加美观、好看一些。原来记得VC5中有个Splash Screen组件,可以直接做启动画面的,结果在VC .Net中,这个组件已经找不到了。是不是取消了这个功能,本人不太清楚。于是网上搜了一些关于Splash启动画面的资料,研究了一番,结果都不太满意。有一篇流传比较广的,是基于Dialog做的,效果一样,但是如果为了做一个启动画面,就得加一个Dialog资源,感觉比较“原始”一点。另外有几篇是基于CWnd类做的,这才是制作Spalsh本来的技术嘛,不过这几篇,要么是在项目内加一个BMP资源,要么用CPicture类从文件加载图像资源,现在不是有GDI+技术嘛,于是研究了一下,完成了这个利用GDI+技术制作基于CWnd类的Splash启动画面的程序。

 

一、在程序中增加GDI+支持

1、在APP的头文件或者stdafx.h中引用Gdiplus头文件,并使用GDI名空间。

#include "gdiplus.h" // 使用GDI+技术
// 使用GDI+名空间
using namespace Gdiplus;
#pragma comment(lib,"gdiplus.lib") // 添加GDI+库文件

 2、启动GDI系统资源初始化和注销,这个可以在APP类中实现,也可以在启动画面类CSplashWnd类中实现,根据具体情况来定。但要在类中添加一个protected型的变量m_gdiplusToken,代码如下:

protected:

 // GDI+程序启动的标识
 ULONG_PTR m_gdiplusToken;

 

 // GDI+系统资源初始化
 Gdiplus::GdiplusStartupInput gdiplusStartupInput;
 Gdiplus::GdiplusStartup(&m_gdiplusToken, &gdiplusStartupInput,NULL); // 启动GDI+资源

 

 // 销毁GDI+系统资源
 Gdiplus::GdiplusShutdown(m_gdiplusToken); // 关闭GDI+资源

 

二、项目上添加启动画面的CSplashWnd类

1、程序中添加基于CWnd类的CSplashWnd类,并把CSplash类的构造函数修改,增加文件名的参数。

CSplashWnd::CSplashWnd(LPCWSTR lpszFileName)

并在类中增加一些private型变量:

private:
 LPCWSTR m_sImageName;  
 Image * m_pImage;
 UINT nWidth;
 UINT nHeight;

 然后添加WM_CREATE和WM_PAINT消息的响应函数

 afx_msg void OnPaint();
 afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);

 

 

2、编写构造函数和析构函数

CSplashWnd::CSplashWnd(LPCWSTR lpszFileName)
{
 m_sImageName = lpszFileName;
 nWidth = 0;
 nHeight = 0;
 m_pImage = NULL;

 

CSplashWnd::~CSplashWnd(void)
{
 if(m_pImage) delete m_pImage;
 m_pImage = NULL;
}

 

3、从文件加载图像并弹出启动画面

在类中添加一个CreateWnd(CWnd* pParentWnd = NULL)函数,设为public型。
声明: BOOL CreateWnd(CWnd* pParentWnd = NULL);

定义:// 建立启动画面的弹出式窗口
BOOL CSplashWnd::CreateWnd(CWnd* pParentWnd /*= NULL*/)
{
 m_pImage = new Image(m_sImageName);
 if (!m_pImage)
 {
  TRACE0(_T("图像文件不存在"));
  return FALSE;
 }

 nWidth = m_pImage->GetWidth();
 nHeight = m_pImage->GetHeight();

 LPCTSTR strSplashWndClass;

strSplashWndClass = AfxRegisterWndClass(CS_VREDRAW | CS_HREDRAW | CS_PARENTDC, AfxGetApp()->LoadStandardCursor(IDC_ARROW),
  0,AfxGetApp()->LoadIcon(IDR_MAINFRAME));

 return CreateEx(0,strSplashWndClass,NULL, WS_POPUP|WS_VISIBLE, 0, 0, nWidth, nHeight, pParentWnd->GetSafeHwnd(), NULL);
}

 

4、编写OnPaint()和OnCreate()函数

void CSplashWnd::OnPaint()
{
 CPaintDC pDC(this); // device context for painting
 // TODO: 在此处添加消息处理程序代码
 // 不为绘图消息调用 CWnd::OnPaint()
 Graphics p_Graphics(pDC.m_hDC);
 p_Graphics.DrawImage(m_pImage,0,0,nWidth,nHeight);
}

 

int CSplashWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
 if (CWnd::OnCreate(lpCreateStruct) == -1)
  return -1;

 // TODO:  在此添加您专用的创建代码
 CenterWindow();//使弹出窗口居中

 return 0;
}

 

5、为防止内存溢出,窗口销毁后要释放CSplashWnd对象,为此,我们重载虚拟函数PostNcDestroy,此函数在窗口销毁后调用。

void CSplashWnd::PostNcDestroy()
{
 // TODO: 在此添加专用代码和/或调用基类
 delete this;
 CWnd::PostNcDestroy();
}

 

6、在CSplashWnd的.Cpp文件中,添加Resource.h文件的引用

#include "Resource.h"

 

三、Splash画面的启动方法

Splash画面可以有2种启动方式,一种是用Sleep()阻断进程,启动画面,另一种是用定时器开设新线程,来启动画面,2种方式各有各的益处。于是本人设计通过一个参数,来实现不同的启动方式。

 

1、增加显示时间变量

在CSplashWnd类中添加一个整形变量,表示画面显示的时间,同样设为private型变量

private:

UINT nSplashTime;

 

 2、添加WM_TIMER定时器消息的响应函数OnTimer(),代码如下:

void CSplashWnd::OnTimer(UINT nIDEvent)
{
 // TODO: 在此添加消息处理程序代码和/或调用默认值
 if(IsWindowVisible())
 {
  SetActiveWindow(); //把启动画面设置为当前活动窗口
  UpdateWindow();
  ::Sleep(nSplashTime); //修改此处可更改画面显示时间
  SendMessage(WM_CLOSE); //关闭对话框
 }
 else
 {
  AfxGetMainWnd()->SetActiveWindow(); // 激动主框架窗口
  KillTimer(nIDEvent) ;  //清除WM_TIMER事件
 }
 //CWnd::OnTimer(nIDEvent);
}

 

3、增加显示画面的函数ShowSplashScreen(),这个函数应该是public型的,代码如下:

// 显示启动画面 nSeconds表示显示的毫秒,nMode表示显示的方法,0-阻断显示,1-定时器显示
void CSplashWnd::ShowSplashScreen(UINT nSeconds,UINT nMode)
{
 // 显示启动画面
 if (!CreateWnd(AfxGetMainWnd())) {
  delete this;
  return; }

 nSplashTime = nSeconds;
 

 if(nMode == 0)
 { 
  UpdateWindow();
  ::Sleep(nSeconds);
  DestroyWindow();
 }
 if(nMode == 1) SetTimer(1,100,NULL); //启动ID为1的定时器
}

 

四、在CMainFrame框架类中,启动CSplashWnd类

在OnCreate()函数的最后面,添加如下代码:

 CSplashWnd * pSplashWnd;
 pSplashWnd = new CSplashWnd(L"splash1.jpg");
 pSplashWnd->ShowSplashScreen(2000,0); // 显示时间为2秒,方式为阻断模式

 

最后一个完美的Splash启动画面就完成了。如果想使用定时器模式,只需要将最后一句代码修改成下面。

 pSplashWnd->ShowSplashScreen(2000,1); // 显示时间为2秒,方式为定时器模式

 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值