还遗憾!我装的VisualStudio2008中并未找到这个Splash screen组件。

但是也不必遗憾,软件的一大特点就是可移植,软件攻城狮的特点就是站在巨人的肩膀上---其实就是一个字“抄”。

本文是完全参考孙鑫MFC编程第9课的VC6.0代码完成!如果有MFC编程经验和C++软件编程经验的同志,请直接跳到本文“2.参考代码”看代码即可,因为不难,就是拷贝代码而已!本文是对0基础讲解!

1.移植过程↓

首先在找一副图片,图片格式是*.bmp的。如果你没有bmp格式的,就用画图工具转换一下。

这里我就用仙女座启动界面。把图片放到你工程文件.../res/ 目录下,这个目录保存了很多工程资源。

VS2008 MFC 的components和controls中的组件Splash Screen的启动界面

接下来就是导入位图,在 资源视图 中任意文件处 右键->填添加资源 ,然后找到并选择刚才的bmp图片。

VS2008 MFC 的components和controls中的组件Splash Screen的启动界面

VS2008 MFC 的components和controls中的组件Splash Screen的启动界面这个时候一个位图资源就添加了,

VS2008 MFC 的components和controls中的组件Splash Screen的启动界面

刚创建的位图资源ID默认应该都是IDB_BITMAP1,我这里讲位图的ID改为IDB_SPLASH.改的方法是右键点击IDB_BITMAP1->属性,找到ID栏,就可以修改。

接下来就是把“2.参考代码”中的Splash.cpp和Splash.h放到工程目录下,然后在“解决方案资源管理器”分别通过右键 添加->现有项 加入到“头文件”和“源文件”中。这个时候可以编译了,编译后会在类视图中显示CSplashWnd类,如不会显示,则重启下VS2008;(以上是直接使用参考代码,当然你也可以直接在类视图添加CSplashWnd类,父类选择CWnd,然后根据参考代码一步步完成类成员,这种比较麻烦点。)

再在CMainFrain::OnCreate中增加Splash的显示函数,即在框架构建显示前调用CSplashWnd中的ShowSplashScreen函数来显示启动位图。

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
        //...省略系统代码
CSplashWnd::ShowSplashScreen(this);

return 0;
}

当然这个时候启动位图还是不能显示的,因为ShowSplashScreen函数中有个判断

if (!c_bShowSplashWnd || c_pSplashWnd != NULL){....}

其中c_bShowSplashWnd 是静态BOOL类型变量,通过略读ShowSplashScreen函数体,可以知道只有c_bShowSplashWnd 为真才能继续执行,我们只要让它为TRUE就可以咯,甚至可以把它删除不做判断也行,因为是静态的成员所以无法在构造函数中初始化咯。

们通过查找可以发现c_bShowSplashWnd 是在void CSplashWnd::EnableSplashScreen(BOOL bEnable /*= TRUE*/)中被执行赋值的,而这个EnableSplashScreen函数的形参有个默认的参数为TRUE,所以我们只要在代码运行时,在合适的地方调用EnableSplashScreen函数即可,那么放在那里好呢,这里推荐放到App类的InitInstance()中,当然要记得把Splash.h头文件放到App类中。注意代码放置的位置。

BOOL CLesson91App::InitInstance()
{

    //省略系统代码...
    CSplashWnd::EnableSplashScreen(TRUE/*BOOL bEnable = TRUE*/);
// 调度在命令行中指定的命令。如果
// 用 /RegServer、/Register、/Unregserver 或 /Unregister 启动应用程序,则返回 FALSE。
if (!ProcessShellCommand(cmdInfo))
return FALSE;
// 唯一的一个窗口已初始化,因此显示它并对其进行更新
m_pMainWnd->ShowWindow(SW_SHOW);
m_pMainWnd->UpdateWindow();
// 仅当具有后缀时才调用 DragAcceptFiles
//  在 SDI 应用程序中,这应在 ProcessShellCommand 之后发生

return TRUE;
}

当然也可以把孙鑫老师通过Splash组自动生成的代码加入更为地道。

BOOL CLesson91App::InitInstance()
{
\
{
\
CCommandLineInfo cmdInfo;
\
ParseCommandLine(cmdInfo);
\


\
CSplashWnd::EnableSplashScreen(cmdInfo.m_bShowSplash);
\
}

// 如果一个运行在 Windows XP 上的应用程序清单指定要
// 使用 ComCtl32.dll 版本 6 或更高版本来启用可视化方式,
//则需要 InitCommonControlsEx()。否则,将无法创建窗口。
INITCOMMONCONTROLSEX InitCtrls;
InitCtrls.dwSize = sizeof(InitCtrls);
// 将它设置为包括所有要在应用程序中使用的
       //....省略系统代码
return TRUE;
}

运行后当然可以看到启动的仙女座啦... 但只能显示3s,如果要修改显示时间,那么请修改Splash.cpp中的SetTimer吧。

VS2008 MFC 的components和controls中的组件Splash Screen的启动界面


2.参考代码

Splash.cpp

// CG: This file was added by the Splash Screen component.
// Splash.cpp : implementation file
//


#include "stdafx.h"  // e. g. stdafx.h
#include "resource.h"  // e.g. resource.h


#include "Splash.h"  // e.g. splash.h


#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif


/////////////////////////////////////////////////////////////////////////////
//   Splash Screen class


BOOL CSplashWnd::c_bShowSplashWnd;
CSplashWnd* CSplashWnd::c_pSplashWnd;
CSplashWnd::CSplashWnd()
{
}


CSplashWnd::~CSplashWnd()
{
// Clear the static window pointer.
ASSERT(c_pSplashWnd == this);
c_pSplashWnd = NULL;
}


BEGIN_MESSAGE_MAP(CSplashWnd, CWnd)
//{{AFX_MSG_MAP(CSplashWnd)
ON_WM_CREATE()
ON_WM_PAINT()
ON_WM_TIMER()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()


void CSplashWnd::EnableSplashScreen(BOOL bEnable /*= TRUE*/)
{
c_bShowSplashWnd = bEnable;
}


void CSplashWnd::ShowSplashScreen(CWnd* pParentWnd /*= NULL*/)
{
if (!c_bShowSplashWnd || c_pSplashWnd != NULL)
return;


// Allocate a new splash screen, and create the window.
c_pSplashWnd = new CSplashWnd;
if (!c_pSplashWnd->Create(pParentWnd))
delete c_pSplashWnd;
else
c_pSplashWnd->UpdateWindow();
}


BOOL CSplashWnd::PreTranslateAppMessage(MSG* pMsg)
{
if (c_pSplashWnd == NULL)
return FALSE;


// If we get a keyboard or mouse message, hide the splash screen.
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; // message handled here
}


return FALSE; // message not handled
}


BOOL CSplashWnd::Create(CWnd* pParentWnd /*= NULL*/)
{
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()
{
// Destroy the window, and update the mainframe.
DestroyWindow();
AfxGetMainWnd()->UpdateWindow();
}


void CSplashWnd::PostNcDestroy()
{
// Free the C++ class.
delete this;
}


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


// Center the window.
CenterWindow();


// Set a timer to destroy the splash screen.
SetTimer(1, 3000, NULL);


return 0;
}


void CSplashWnd::OnPaint()
{
CPaintDC dc(this);


CDC dcImage;
if (!dcImage.CreateCompatibleDC(&dc))
return;


BITMAP bm;
m_bitmap.GetBitmap(&bm);


// Paint the image.
CBitmap* pOldBitmap = dcImage.SelectObject(&m_bitmap);
dc.BitBlt(0, 0, bm.bmWidth, bm.bmHeight, &dcImage, 0, 0, SRCCOPY);
dcImage.SelectObject(pOldBitmap);
}


void CSplashWnd::OnTimer(UINT nIDEvent)
{
// Destroy the splash screen window.
HideSplashScreen();
}

Splash.h

// CG: This file was added by the Splash Screen component.


#ifndef _SPLASH_SCRN_
#define _SPLASH_SCRN_


// Splash.h : header file
//


/////////////////////////////////////////////////////////////////////////////
//   Splash Screen class


class CSplashWnd : public CWnd
{
// Construction
protected:
CSplashWnd();


// Attributes:
public:
CBitmap m_bitmap;


// Operations
public:
static void EnableSplashScreen(BOOL bEnable = TRUE);
static void ShowSplashScreen(CWnd* pParentWnd = NULL);
static BOOL PreTranslateAppMessage(MSG* pMsg);


// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CSplashWnd)
//}}AFX_VIRTUAL


// Implementation
public:
~CSplashWnd();
virtual void PostNcDestroy();


protected:
BOOL Create(CWnd* pParentWnd = NULL);
void HideSplashScreen();
static BOOL c_bShowSplashWnd;
static CSplashWnd* c_pSplashWnd;


// Generated message map functions
protected:
//{{AFX_MSG(CSplashWnd)
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnPaint();
afx_msg void OnTimer(UINT nIDEvent);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};




#endif

相关文章:

  • 2021-09-26
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-06-10
  • 2021-05-29
  • 2021-07-22
猜你喜欢
  • 2022-12-23
  • 2021-06-30
  • 2022-12-23
  • 2022-12-23
  • 2021-10-04
  • 2022-12-23
  • 2022-12-23
相关资源
相似解决方案