1. 新建一个MFC项目SDI或MDI。
2. 新建或导入一个ID为IDB_SPLASH的位图。
SplashWnd.cpp源代码:
4. 在App主程序实现代码中把上面的头文件包含进去,并在InitInstance函数中添加下面一段代码。
5. 最后,在主框架窗口实现代码中包含Splash头文件,在OnCreate函数return前调用CSplashWnd类的ShowSplashScreen函数即可。
6.在对话框中使用CSplashWnd类
(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的工作。
2. 新建或导入一个ID为IDB_SPLASH的位图。
3. 添加现有项SplashWnd.h和SplashWnd.cpp。
SplashWnd.h源代码
#pragma once
// CSplashWnd
class CSplashWnd : public CWnd
{
DECLARE_DYNAMIC(CSplashWnd)
public:
CSplashWnd();
virtual ~CSplashWnd();
protected:
virtual void PostNcDestroy();
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnTimer(UINT_PTR nIDEvent);
afx_msg void OnPaint();
BOOL Create(CWnd* pParentWnd=NULL);
void HideSplashScreen(void);
DECLARE_MESSAGE_MAP()
protected:
CBitmap m_bitmap;
static CSplashWnd* c_pSplashWnd;
static BOOL c_bShowSplashWnd;
public:
static void EnableSplashScreen(BOOL bEnable=TRUE);
static void ShowSplashScreen(CWnd* pParentWnd=NULL);
static BOOL PreTranslateAppMessage(MSG* pMsg);
};
SplashWnd.cpp源代码:
// SplashWnd.cpp : 实现文件
//
#include "stdafx.h"
#include "SplashWindow.h"
#include "SplashWnd.h"
#include "resource.h"
// CSplashWnd
CSplashWnd* CSplashWnd::c_pSplashWnd;
BOOL CSplashWnd::c_bShowSplashWnd;
IMPLEMENT_DYNAMIC(CSplashWnd, CWnd)
CSplashWnd::CSplashWnd()
{
}
CSplashWnd::~CSplashWnd()
{
ASSERT(c_pSplashWnd == this);
c_pSplashWnd = NULL;
}
BEGIN_MESSAGE_MAP(CSplashWnd, CWnd)
ON_WM_CREATE()
ON_WM_TIMER()
ON_WM_PAINT()
END_MESSAGE_MAP()
// CSplashWnd 消息处理程序
void CSplashWnd::EnableSplashScreen(BOOL bEnable)
{
c_bShowSplashWnd = bEnable;
}
void CSplashWnd::ShowSplashScreen(CWnd* pParentWnd)
{
if ( !c_bShowSplashWnd || c_pSplashWnd != NULL )
{
return;
}
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 ( 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::PostNcDestroy()
{
delete this;
}
int CSplashWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if ( CWnd::OnCreate(lpCreateStruct) == -1 )
{
return -1;
}
CenterWindow();
SetTimer(1, 3000, NULL);
return 0;
}
void CSplashWnd::OnTimer(UINT_PTR nIDEvent)
{
if ( nIDEvent == 1 )
{
HideSplashScreen();
}
}
void CSplashWnd::OnPaint()
{
CPaintDC dc(this);
CDC dcImg;
if ( !dcImg.CreateCompatibleDC(&dc) )
{
return;
}
BITMAP bm;
m_bitmap.GetBitmap(&bm);
CBitmap* pOldBit = dcImg.SelectObject(&m_bitmap);
dc.BitBlt(0, 0, bm.bmWidth, bm.bmHeight, &dcImg, 0, 0, SRCCOPY);
dcImg.SelectObject(pOldBit);
}
BOOL CSplashWnd::Create(CWnd* pParentWnd)
{
if ( !m_bitmap.LoadBitmap(IDB_BITMAP1) )
{
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();
}
4. 在App主程序实现代码中把上面的头文件包含进去,并在InitInstance函数中添加下面一段代码。
{
CCommandLineInfo cmdInfo;
ParseCommandLine(cmdInfo);
CSplashWnd::EnableSplashScreen(cmdInfo.m_bShowSplash);
}
5. 最后,在主框架窗口实现代码中包含Splash头文件,在OnCreate函数return前调用CSplashWnd类的ShowSplashScreen函数即可。
//显示Splash窗口
CSplashWnd::ShowSplashScreen(this);
6.在对话框中使用CSplashWnd类
其实质就是由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的工作。