[转载]C#程序启动欢迎窗体实现(转)
当程序在启动过程中需要花一些时间去加载资源时,我们希望程序能显示一个欢迎界面,能简单介绍软件功能的同时还能告知用户该程序还在加载中,
使得用户体验更友好。
实现如下:
1. 添加欢迎界面的窗体(比如Frm_Welcom),做以下调整:
将FormBorderStyle属性设成None,即没有窗体边框
将ShowInTaskbar属性设成False,这样窗体不显示在任务栏中
将StartPosition属性设成CenterScreen,即总是居中
将TopMost属性设成True,即总是在顶部
将UseWaitCursor属性设成Ture,即显示等待光标,让人感觉后台还在运行
增加一个PictureBox控件,与欢迎图片大小一致,窗体的大小也设成一致
增加一个ProgressBar控件,将Style设成Marquee,将MarqueeAnimationSpeed设成50
增加一个Label控件,将BackColor属性设成透明(Transparent),然后给定其text一个初始值,同时在窗体的Load函数中添加以下代码
1 private void Frm_Welcom_Load(object sender, EventArgs e) 2 { 3 pictureBox1.Controls.Add(labelX1);//把label1整到picturebox控件里,通俗的讲就是让后者把前者给包起来,加上它才能显示图片 4 label1.Location = new Point(5, 10); //这个很重要,就是改变一下label的位置,后面的参数你自己随便定 5 //如果不加这一条的话背景透明了但字体也会不见(事实证明不加也可以) 6 7 }
2. 主界面的构造函数改成以下代码:
//先在整个类中定义两个全局变量 public Thread showSplashThread; public Frm_Welcom sForm; //构造函数代码 public Frm_Main() { //启动一个线程 showSplashThread = new Thread(new ThreadStart(ShowSplash)); showSplashThread.Start(); //下边为原有代码 InitializeComponent(); .......... }
3. 显示SplashForm的线程函数
1 private void ShowSplash() 2 { 3 try 4 { 5 sForm = new Frm_Welcom(); 6 sForm.ShowDialog(); 7 //等待两秒,使主线程充分显示 8 Thread.Sleep(2000); 9 } 10 catch (ThreadAbortException e) 11 { 12 throw e; 13 } 14 finally 15 { 16 sForm = null; 17 } 18
4. 在主窗体的Load事件加激活自己的代码
1 [DllImport("User32.dll")] 2 public static extern void SetForegroundWindow(IntPtr hwnd); 3 private delegate void txtHandeler(object obj,string str); 4 5 //定义需要代理的函数 6 private void evaluateTxt(object obj,string str) 7 { 8 sForm.labelX1.Text = str; 9 } 10 11 private void Frm_Main_Load(object sender, EventArgs e) 12 { 13 //显示欢迎界面的进度条 14 SetForegroundWindow(Process.GetCurrentProcess().MainWindowHandle); 15 16 txtHandeler txthandler = new txtHandeler(evaluateTxt); 17 string str = "正在分配权限,请稍候..."; 18 object obj = null; 19 sForm.labelX1.Invoke(txthandler, new object[] { obj,str }); //sForm.labelX1为欢迎界面中用来显示操作的label控件 20 21 //以下方法错误,如果不用以上代理的方法不能给textBox赋值,因为不是从创建它的线程访问它; 22 //sForm.labelX1.Text = "正在分配权限,请稍候..."; 23 24 25 //////////////////////////原有代码区域开始//////////////////////////////////////////////////////////// 26 //功能相关全部不可见 27 basictool.FormFunClear(this); 28 if (GlobalParams.StrGUserId == "hjadmin") 29 { 30 //得到所有权限 31 basictool.FormFunall(this); 32 //进行主菜单设置 33 //对主菜单是否可见进行设置 34 this.office2007StartButton1.Visible = true; 35 36 set_mainmenu(); 37 } 38 else 39 { 40 //进行权限初始化 41 basictool.FormFunInit(this); 42 //进行主菜单设置 43 //对主菜单是否可见进行设置 44 this.office2007StartButton1.Visible = false; 45 DataSet dsFun = new DataSet(); 46 dsFun = BusinessDb.GetAllFunByUserId(GlobalParams.StrGUserId.Trim(), this); 47 foreach (DataRow deFunTemp in dsFun.Tables[0].Rows) 48 { 49 string strtype = deFunTemp[1].ToString(); 50 if (deFunTemp[1].ToString() == "1") 51 { 52 string funname = deFunTemp[0].ToString(); 53 //如果有此功能设置可见 54 if (deFunTemp[0].ToString().Equals("office2007StartButton1")) 55 { 56 this.office2007StartButton1.Visible = true; 57 58 } 59 } 60 61 } 62 set_mainmenu(); 63 } 64 //右键菜单权限进行设置 65 66 basictool.SetRightButtonFun(contextMenuStrip1FrmMain, this); 67 basictool.SetRightButtonFun(contextMenuStrip2FrmMain, this); 68 basictool.SetRightButtonFun(contextMenuStrip3FrmMain, this); 69 basictool.SetRightButtonFun(contextMenuStrip4_Theme, this); 70 71 //同样需要用代理的方法赋值 72 str = "正在加载地图,请稍候..."; 73 sForm.labelX1.Invoke(txthandler, new object[] { obj, str }); 74 //sForm.labelX1.Text = "正在加载地图,请稍候..."; 75 76 //解析出工程目录 77 path = BasicTool.getRelativePath(); 78 79 getSpaceMaps(); 80 //宗地查询窗口初始化 81 this.Btn_TestPanel_Click(null, null); 82 itemPanel1.BackgroundStyle.BackColor = Color.FromArgb(191,219,255); 83 itemPanel2.BackgroundStyle.BackColor = Color.FromArgb(191, 219, 255); 84 85 leftlayout(); 86 //////////////////////////原有代码区域结束//////////////////////////////////////////////////////////// 87 88 //中止欢迎界面的线程 89 showSplashThread.Abort(); 90 showSplashThread.Join(); // Wait until the thread aborted 91 showSplashThread = null; 92 }
参考链接:http://www.lordong.cn/blog/post/18.html
使PictureBox控件透明的方法还可以用:
设置PictureBox控件上的Label控件透明的步骤:
1) 新建一个PictureBox控件,名称是pbxImage
2) 新建一些Label控件,放在PictureBox上
3) 添加PictureBox的Paint事件
4) 添加如下代码:
1 //pbxImage is PictureBox control 2 private void pbxImage_Paint(object sender, PaintEventArgs e) 3 { 4 foreach (Control C in this.Controls) 5 { 6 if (C is Label) 7 { 8 Label L = (Label)C; 9 L.Visible = false; 10 e.Graphics.DrawString(L.Text, L.Font, new 11 SolidBrush(L.ForeColor), L.Left - picBack.Left, L.Top - picBack.Top); 12 } 13 } 14 }