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 ...
随机推荐
-
Firefox渗透测试黑客插件集
前天看S哥用Firefox的hackbar进行手动注入进行渗透,觉得直接运用浏览器的插件进行渗透测试有很多优点,既可以直接在前端进行注入等操作,也可以省却了寻找各种工具的麻烦.前端还是最直接的!于是这 ...
-
深入研究java.lang.ProcessBuilder类
深入研究java.lang.ProcessBuilder类 一.概述 ProcessBuilder类是J2SE 1.5在java.lang中新添加的一个新类,此类用于创建操作系统进程,它 ...
-
HTTP ->; Asp.net (第一篇)
当用户在浏览器输入一个URL地址后,浏览器会发送一个请求到服务器.这时候在服务器上第一个负责处理请求的是IIS.然后IIS再根据请求的URL扩展名将请求分发给不同的ISAPI处理. 流程如下: 1.I ...
-
游戏Demo(持续更新中...)
格斗游戏 主要用于联系Unity的动画系统,并加入了通过检测按键触发不同的技能. WASD控制方向,AD为技能1,SW为技能2,右键跳跃,连续单机普通连招. 本来是要用遮罩实现跑动过程中的攻击动作,但 ...
-
内功心法 -- java.util.ArrayList<;E>; (6)
写在前面的话:读书破万卷,编码如有神--------------------------------------------------------------------下文主要对java.util ...
-
mysql目录迁移 更改mysql的存储目录
元旦节刚过完回来,忙了一天,现在的时间剩余不是很充足,所以更新简短的文章一篇! 正文: 正常情况下mysql的存储目录都是在/var/lib/mysql/下的,那么怎么将存储位置改到/data_mys ...
-
解决iar试调时程序无法进入主函数的问题
尼玛,我TM当时核心板上还接着摄像头,啊啊啊啊,必须吧摄像头关了,不然,k60初始化时会检测io口状态,状态不正确当然无法进入主函.摄像头上电即输出数据,会对单片机上电检测造成干扰.
-
JS及相关控件
1.radio 1)不选中任何值 2)获取选中的值 3)让某个选项选中 4)发生改变时的事件 5)让某个选项不能选 2.CheckBox 1)选中 2)取消 3.select 1)获取下拉框选中项的显 ...
-
网络通信中tcp多客户端连接
网络编程中的tcp实例太多了,自己也写了好几次(羞愧),今天在想一对一的TCP知道怎么写了,可是一对多的怎么办呢?服务器是如何知道要给那个发送数据呢?做开发的同学应该经常听说uid这个属性.可以为什么 ...
-
NOIP2002-2017提高组题解
给个人认为比较难的题目打上'*' NOIP2002(clear) //一个很吼的贪心题,将平均数减掉之后从左往右将影响消除 #include<bits/stdc++.h> using na ...