ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

MFC对话框程序:实现程序启动画面

2021-09-03 17:32:58  阅读:193  来源: 互联网

标签:MFC 函数 对话框 pSplashDlg 程序 线程 UI CSplashThread


MFC对话框程序:实现程序启动画面

对于比较大的程序,在启动的时候都会显示一个画面,以告诉用户程序正在加载,或者显示一些关于软件的信息,如Visual C++,Word, PhotoShop等。那么对于基于对话框的程序如何实现了?

因为显示启动画面的同时还要进行程序的加载工作,所以要用到多线程。MFC区分了两种不同类型的多线程:用户界面(UI)线程和工作者线程。两者的区别是UI线程有消息循环,而工作者线程没有,UI线程能够创建窗口并处理发送给窗口的消息。工作者线程用来执行后台任务,这些后台任务不直接接受用户输入,因此不需要窗口和消息循环。 因为这里要显示一个画面,所以要使用UI线程。http://blog.sina.com.cn/s/blog_63a881060102w01h.html

一、准备阶段

具体的操作方法如下:

1、创建一个基于对话框的工程,名曰“TestStartBmp”,系统会自动生成一些文件。包含一个Dlg,这是主函数的Dlg。

2、在资源管理器中插入一个新的对话框和一张位图,ID设置为IDD_SPLASH,在上面一个picture控件,类型设为”Bitmap”,图象选择刚才插入的位图。如下:

image-20210903163239864

设置对话框的Style为Popup,Border为None,去掉TitleBar属性,并调整对话框的大小与位图等大,这样对话框显示的时候,你看到的只是图片。

3、右键界面,点击‘添加类”,建立一个新类CSplashDlg,基类为CDialog。

image-20210903163527578

4、接下来创建一个UI线程。使用快捷键Ctrl+shift+X 打开类向导,点击最上面右边的添加类旁边的小三角,选择“MFC类”,类名叫CSplashThread,基类是CWinThread。如下图:

image-20210903164259241

然后在生成的SplashThread.h 中加入 #include"SplashDlg.h",并添加一个protected型指针变量,如下:

#include"SplashDlg.h"
class CSplashThread : public CWinThread
{
...
protected:
	CSplashDlg* m_pSplashDlg;
...
};

在UI线程的 InitInstance() 函数中调用刚才创建的对话框并显示。

BOOL CSplashThread::InitInstance()
{
	// TODO:    在此执行任意逐线程初始化
	::AttachThreadInput(m_nThreadID, AfxGetApp()->m_nThreadID, TRUE);
	//:通常系统内的每个线程都有自己的输入队列。本函数允许线程和进程共享输入队列。连接了线程后,输入焦点、窗口激活、鼠标捕获、键盘状态以及输入队列状态都会进入共享状态 . (这个函数可以不用)
	m_pSplashDlg = new CSplashDlg;
	m_pSplashDlg->Create(IDD_SPLASH);
	m_pSplashDlg->ShowWindow(SW_SHOW);
	return TRUE;
}

为CSplashThread类添加一个函数 HideSplash() , 用来隐藏启动画面(即关闭对话框)

void CSplashThread::HideSplash()
{
	m_pSplashDlg->SendMessage(WM_CLOSE);
}

在主函数创建完之后是需要把这个界面给影藏掉的,或者销毁掉,所以在线程退出函数哪里写上如下代码:

int CSplashThread::ExitInstance()
{
	// TODO:    在此执行任意逐线程清理
	m_pSplashDlg->DestroyWindow();
	if (m_pSplashDlg != NULL)
	{
		delete m_pSplashDlg;
	}
	return CWinThread::ExitInstance();
}

二、开始使用

1、在应用程序进入的地方,也就是本项目的 CTestStartBmpApp(也就是TestStartBmp.h)的初始化函数中。

引入上面生成的两个文件,并在public中添加两个变量,如下:

#include "resource.h"		// 主符号
#include "SplashThread.h"

class CTestStartBmpApp : public CWinApp
{
public:
    ...
	CSplashThread* pSplashThread;
	CSplashDlg* m_pSplashDlg;
    ...
}

在初始化函数中 InitInstance(),打开主函数界面之前,启动UI线程

...
	SetRegistryKey(_T("应用程序向导生成的本地应用程序"));
	// 这里开始
	pSplashThread = (CSplashThread*)AfxBeginThread(
		RUNTIME_CLASS(CSplashThread),
		THREAD_PRIORITY_NORMAL,
		0, CREATE_SUSPENDED);

	ASSERT(pSplashThread->IsKindOf(RUNTIME_CLASS(CSplashThread)));
	pSplashThread->ResumeThread();

	Sleep(10);
	
	// 这里结束
	CTestStartBmpDlg dlg;
	m_pMainWnd = &dlg;
	INT_PTR nResponse = dlg.DoModal();
...

之后再需要关闭启动画面的地方添加如下函数,调用HideSplash:

// CTestStartBmpApp是主函数APP的名字
if (((CTestStartBmpApp*)AfxGetApp())->pSplashThread != NULL)
    ((CTestStartBmpApp*)AfxGetApp())->pSplashThread->HideSplash();

至此就完成了启动图片的功能,效果图如下:

image-20210903170905639


醉里挑灯看剑,梦回吹角连营,八百里分麾下炙,五十弦翻塞外声,沙场秋点兵!

标签:MFC,函数,对话框,pSplashDlg,程序,线程,UI,CSplashThread
来源: https://www.cnblogs.com/Abraverman/p/15224029.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有