C#: 启动画面设计
Windows Form经常会在启动主界面的时候预先有启动画面,这也是因为用户体验的需要,用户知道已经启动application,而不是在load resource的时候等待。因此这里不能用单线程的思路,单单只是设计一个界面而已,而需要在splash画面的时候同时Load resource。那么这个技术有两个线程,一个是splash画面,二是load resource。搜了一些资料,下面进行一些总结:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using System.Threading;
namespace WindowsTest
{
static class Program
{
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Thread thUI = new Thread(new ThreadStart(ShowSplashWindow));
thUI.Name = "Splash UI";
thUI.Priority = ThreadPriority.Normal;
thUI.Start();
Thread th = new Thread(new ThreadStart(LoadResources));
th.Name = "Resource Loader";
//th.Priority = ThreadPriority.Highest;
th.Priority = ThreadPriority.Normal;
th.Start();
th.Join();
if (splashForm != null)
{
splashForm.Invoke(new MethodInvoker(delegate { splashForm.Close(); }));
}
thUI.Join();
Application.Run(new MainForm());
}
public static SplashForm splashForm
{
get;
set;
}
private static void ShowSplashWindow()
{
splashForm = new SplashForm();
Application.Run(splashForm);
}
private static void LoadResources()
{
; i <= ; i++)
{
if (splashForm != null)
{
splashForm.Invoke(new MethodInvoker(delegate { splashForm.label1.Text = "Loading some things... " + DateTime.Now.ToString(); }));
}
Thread.Sleep();
}
splashForm.Invoke(new MethodInvoker(delegate { splashForm.label1.Text = "Done. " + DateTime.Now.ToString(); }));
}
}
}
这段代码的问题在于画面启动完主界面是最小化了,不解为何如此
http://www.sufeinet.com/forum.php?mod=viewthread&action=printable&tid=2697
这里的代码比较成熟了,我做了一些小小的改变。用ApplicationContext来解决splash form和main form之间的转换,而在Program的类的InitApp function里如果要改变splash from的label1则需要Invoke来异步调用SplashFrom的PrintMsg function,否则会卡卡面。在SplashForm_Load函数里用到了线程池技术,这里不能用invoke,因为invoke必须使用类实例,而Program是static类,InitApp也是static的,在InitApp里可以用线程池来实现。另外贴下线程池的适用场合

Program.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using System.Threading;
namespace WindowsTest
{
static class Program
{
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
MyApplicationContent appContent = new MyApplicationContent(new MainForm(), new SplashForm());
Application.Run(appContent);
}
//模拟耗时操作,这里假调程序需要访问网络来实现登录验证
//这是一个耗时操作,我们需要在执行的过程中,向用户实时显示一些信息
//那么,多线程是唯一的解决方案,在主线程执行这些,界面会死掉的
public static void InitApp(Object parm)
{
SplashForm startup = parm as SplashForm;
startup.Invoke(new UiThreadProc(startup.PrintMsg), "正在初始化...");
Thread.Sleep();
startup.Invoke(new UiThreadProc(startup.PrintMsg), "正在验证用户身份信息...");
Thread.Sleep();
startup.Invoke(new UiThreadProc(startup.PrintMsg), "用户身份验证成功。");
Thread.Sleep();
startup.Invoke(new UiThreadProc(startup.PrintMsg), "正在登录...");
Thread.Sleep();
bool loginSuccess = true;
//这里可以根据执行的结果判断,如果登录失败就退出程序,否则显示主窗体
if (loginSuccess)
{
startup.Invoke(new UiThreadProc(startup.PrintMsg), "登录成功,欢迎使用!");
Thread.Sleep();
startup.Invoke(new UiThreadProc(startup.CloseForm), false);
}
else
{
startup.Invoke(new UiThreadProc(startup.CloseForm), true);
}
}
}
public delegate void UiThreadProc(Object o);
//WinForm里,默认第一个创建的窗体是主窗体,所以需要用应用程序域来管理
public class MyApplicationContent : ApplicationContext
{
private Form realMainForm;
public MyApplicationContent(Form mainForm, Form flashForm)
: base(mainForm)
{
this.realMainForm = mainForm;
this.MainForm = flashForm;
}
protected override void OnMainFormClosed(object sender, EventArgs e)
{
if (sender is SplashForm)
{
SplashForm splashForm = sender as SplashForm;
if (!splashForm.Exit)
{
this.MainForm = realMainForm;
realMainForm.Show();
}
else
{
base.OnMainFormClosed(sender, e);
}
}
else
{
base.OnMainFormClosed(sender, e);
}
}
}
}
SplashForm.cs:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
namespace WindowsTest
{
public partial class SplashForm : Form
{
private bool exit;
public bool Exit
{
get { return exit; }
}
public SplashForm()
{
InitializeComponent();
}
//显示文字信息
public void PrintMsg(Object msg)
{
label1.Text = msg.ToString();
}
//关闭启动窗体,如果需要中止程序,传参数false
public void CloseForm(Object o)
{
this.exit = Convert.ToBoolean(o);
this.Close();
}
private void SplashForm_Load(object sender, EventArgs e)
{
ThreadPool.QueueUserWorkItem(new WaitCallback(Program.InitApp), this);
}
}
}
只需要将Program.cs里的InitApp里的Thread.Sleep改成实际的load resource代码即可
C#: 启动画面设计的更多相关文章
- 跨平台移动开发phonegap/cordova 3.3全系列教程-app启动画面
1.app启动画面设计 用photoshop设计启动画面,图片分辨率为720*1280 保存的文件名为splash.png 将splash.png复制到res\drawable,如图 PS:要先添加闪 ...
- 为你的Web程序加个启动画面
.Net开发者一定熟悉下面这个画面: 这就是宇宙第一IDE Visual Studio的启动画面,学名叫Splash Screen(或者Splash Window).同样,Javar们一定对Eclip ...
- IOS编程教程(八):在你的应用程序添加启动画面
IOS编程教程(八):在你的应用程序添加启动画面 虽然你可能认为你需要编写闪屏的代码,苹果已经可以非常轻松地把它做在Xcode中.不需要任何编码.你只需要做的是设置一些配置. 什么是闪屏 对于那些 ...
- MFC之窗体改动工具栏编程状态栏编程程序启动画面
1窗体外观的改动 (1)改动在CMainFrame::preCreateWindow(CREATESTRUCT& cs) 改动标题:cs.style&=FWS_ADDTOTITLE; ...
- android 之 启动画面的两种方法
现在,当我们打开任意的一个app时,其中的大部分都会显示一个启动界面,展示本公司的logo和当前的版本,有的则直接把广告放到了上面.启动画面的可以分为两种设置方式:一种是两个Activity实现,和一 ...
- Cordova应用程序修改启动画面或者Icon
1) 制作启动画面图片或icon ionic resources //同时生成icon和splash ionic resources --icon //只生成icon ionic resources ...
- iOS7的启动画面设置及asset catalogs简介
如果上网搜索一下“iOS App图标设置”或者“iOS App启动画面设置”肯定能找到不少文章,但内容大多雷同,就是让你按照某种尺寸制作若干张png图片,再按照苹果的命名规范,加入到项目中去,一行代码 ...
- iOS 启动画面 代码自定义
先来看一个可能会遇到的问题: 如果你已经删除了xcode为你的项目自动生成的LaunchScreen.storyboard, 然后你在测试你的app的时候发现,屏幕里出现了黑色的区域,如上图(画红线的 ...
- Qt5 程序启动画面动图效果
2333终于实现动图,先弄了一个窗口去掉标题栏假装就是启动画面了,还是那只萌萌的猫这次会动了! 基类用的是QWidget 类名称MainView #ifndef MAINVIEW_H #define ...
随机推荐
- Oracle用户、权限、角色管理(转)
http://blog.csdn.net/junmail/article/details/4381287 Oracle 权限设置一.权限分类:系统权限:系统规定用户使用数据库的权限.(系统权限是对用户 ...
- php面向对象之__toString()
似曾相识,在php面向对象编程之魔术方法__set,曾经介绍了什么是魔术方法,这一章又介绍一个魔术方法__tostring(). __toString()是快速获取对象的字符串信息的便捷方式,似乎魔术 ...
- spm完成dmp在windows系统上导入详细过程
--查询dmp字符集 cat spmprd_20151030.dmp ','xxxx')) from dual; spm完成dmp在windows系统上导入详细过程 create tablespace ...
- BlueDroid代码分析之GKI
目录 1. 概述 2. 线程 2.1 主要函数 2.2 功能 3. 事件 3.1 主要函数 3.2 功能 1. 概述 GKI以库libbt-brcm_gki.so(Static Lib?)的形式提供给 ...
- js判断图片是否存在,并做处理
<html> <head> <meta http-equiv="Content-Type" content="text/html; char ...
- 【Android测试】【随笔】在手机里用命令行创建中文文件夹
◆版权声明:本文出自胖喵~的博客,转载必须注明出处. 转载请注明出处:http://www.cnblogs.com/by-dream/p/4580319.html 不知道为啥当时自己写了一段在手机里用 ...
- ADO,OLEDB,ODBC,DAO的区别【转】
转载:http://blog.csdn.net/sunboy_2050/article/details/6624684 ODBC(Open Database Connectivity,开放数据库互连) ...
- android 5.0 (lollipop)源码编译环境搭建(Mac OS X)
硬件环境:MacBook Pro Retina, 13-inch, Late 2013 处理器 2.4 GHz Intel Core i5 内存 8 GB 1600 MHz DDR3 硬盘60G以 ...
- 将自己写的Python代码打包放到PyPI上
如果是开源的Python代码,为了能够让大家更方便的使用,放到PyPI上也许是个非常不错的主意(PyPI:Python Package Index).刚开始我以为要将代码打包放到PyPI上是一件非常复 ...
- iOS ARC环境下dealloc的使用
众所周知,iOS开发的时候,使用ARC的话,dealloc函数是不需要实现的,写了反而会出错. 但有些特殊的情况,dealloc函数还是需要的. 比如,在画面关闭的时候,需要把ViewControll ...