Application类(位于System.Windows.Forms命名空间)公开了Run方法,可以调用该方法来调度应用程序进入消息循环。Run方法有三个重载

1、第一个重载版本不带任何参数,比较少使用

2、static void Run(System.Windows.Forms.Form mainForm)  调用这个重载,只需要吧希望作为主窗口的Form实例(包括从Form类派生的类)传递给mianForm参数即可。一旦mainForm关闭,整个消息循环就会退出,Run方法返回,应用程序就会退出。

3、static void Run(System.Windows.Forms.ApplicationContext context) 这是Run方法中重载最灵活的。通常的做法是从ApplicationContext类派生,并写入实现代码。ApplicationContext类也允许设置一个Form实例制作为主窗口,也可以不设置主窗口。这个Run方法会在ApplicationContext对象进行消息循环。调用ApplicationContext类的ExitThread方法会导致ApplicationContext上的消息循环终止。

手动创建一个类:产生三个窗口,只有把三个窗口全部关闭程序才终止运行(基于第三种Run方法)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms; //从ApplicationContext派生一个类出来,
public class MyApplication : ApplicationContext
{ static int WindowsCount;//用于记录窗口个数
private Form Windows1, Windows2, Windows3;//申请三个Form窗口 private只限于本类成员访问 //构造函数,分别实例化三个窗口
public MyApplication()
{
WindowsCount = ;
/*实例化Windows1*/
Windows1 = new Form();
Windows1.Text = "窗口1";
Windows1.Size = new System.Drawing.Size(, );
Windows1.Location = new System.Drawing.Point(, );
Windows1.Name = "Form1";
Windows1.FormClosed += OnMainFormClosed;//处理事件(窗口关闭的处理事件)
WindowsCount += ;//窗口总数加一 Windows2 = new Form();
Windows2.Text = "窗口2";
Windows2.Size = new System.Drawing.Size(, );
Windows2.Location = new System.Drawing.Point(, );
Windows2.Name = "Form2";
Windows2.FormClosed += OnMainFormClosed;//处理事件(窗口关闭的处理事件)
WindowsCount += ;//窗口总数加一 Windows3 = new Form();
Windows3.Text = "窗口3";
Windows3.Size = new System.Drawing.Size(, );
Windows3.Location = new System.Drawing.Point(, );
Windows3.Name = "Form3";
Windows3.FormClosed += OnMainFormClosed;//处理事件(窗口关闭的处理事件)
WindowsCount += ;//窗口总数加一 //显示3个窗口
Windows1.Show();
Windows2.Show();
Windows3.Show(); }
private void OnMainFormClosed(object sender,FormClosedEventArgs e)
{
WindowsCount -= ;
if (WindowsCount == )
ExitThread();//调用ExitThead终止消息循环 } }
namespace application1
{
static class Program
{
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MyApplication());
}
}
}

出处:https://www.cnblogs.com/hjxzjp/p/7674300.html

===============================================================

下面的代码示例显示两个窗体,并在两个窗体都关闭时退出应用程序。在应用程序启动和退出时,它会记住每个窗体的位置。此示例演示如何使用 ApplicationContext 和 Application.Run(context) 方法在启动应用程序时显示多个窗体。

类 MyApplicationContext 从 ApplicationContext 继承,并跟踪每个窗体关闭的时间,然后在这两个窗体均关闭时退出当前线程。该类为用户存储每个窗体的位置。窗体位置数据存储在标题为 Appdata.txt 的文件中,该文件在 UserAppDataPath 确定的位置中创建。

给定 ApplicationContext 的情况下,Main 方法调用 Application.Run(context) 启动应用程序。

using System;
using System.Drawing;
using System.Windows.Forms;
using System.ComponentModel;
using System.Text;
using System.IO;

namespace ScreenSplit
{
    static class Program
    {
        // 初始化窗体1大小及标题文本
        public class AppForm1 : System.Windows.Forms.Form
        {
            public AppForm1()
            {
                Screen screen = Screen.FromRectangle(new Rectangle(0, 0, 0, 0));
                this.Size = new System.Drawing.Size(screen.WorkingArea.Width / 2, screen.WorkingArea.Height);
                this.Text = "AppForm1";
            }
        }

// 初始化窗体2大小及标题文本
        public class AppForm2 : System.Windows.Forms.Form
        {
            public AppForm2()
            {
                Screen screen = Screen.FromRectangle(new Rectangle(0, 0, 0, 0));
                this.Size = new System.Drawing.Size(screen.WorkingArea.Width / 2, screen.WorkingArea.Height);
                this.Text = "AppForm2";
            }
        }

// 利用ApplicationContext类处理程序的启动、关闭
        class MyApplicationContext : ApplicationContext
        {

private int formCount;
            private AppForm1 form1;
            private AppForm2 form2;

private Rectangle form1Position;
            private Rectangle form2Position;

private FileStream userData;

private MyApplicationContext()
            {
                formCount = 0;

// 应用程序退出
                Application.ApplicationExit += new EventHandler(this.OnApplicationExit);

try
                {
                    // 在用户目录使用appdata.txt文件保存窗体退出时的位置与大小
                    userData = new FileStream(Application.UserAppDataPath + "//appdata.txt", FileMode.OpenOrCreate);

}
                catch (IOException e)
                {
                    // 程序退出时异常处理.
                    MessageBox.Show("An error occurred while attempting to show the application." +
                                    "The error is:" + e.ToString());

// 退出当前主线程
                    ExitThread();
                }

//窗体关闭
                form1 = new AppForm1();
                form1.Closed += new EventHandler(OnFormClosed);
                form1.Closing += new CancelEventHandler(OnFormClosing);
                formCount++;

form2 = new AppForm2();
                form2.Closed += new EventHandler(OnFormClosed);
                form2.Closing += new CancelEventHandler(OnFormClosing);
                formCount++;

// 从文件中读取保存窗体位置与大小的参数
                if (ReadFormDataFromFile())
                {
                    Screen screen = Screen.FromRectangle(new Rectangle(0, 0, 0, 0));
                    form1.Top = 0; form1.Left = 0;
                    form2.Top = 0; form2.Left = screen.WorkingArea.Width / 2;
                    form1.StartPosition = FormStartPosition.Manual;
                    form2.StartPosition = FormStartPosition.Manual;

form1.Bounds = form1Position;
                    form2.Bounds = form2Position;
                }

// 显示双窗体
                form1.Show();
                form2.Show();
            }

private void OnApplicationExit(object sender, EventArgs e)
            {
                // 保存窗体位置与大小
                WriteFormDataToFile();

try
                {
                    // 忽略窗体关闭时可能出现的错误
                    userData.Close();
                }
                catch { }
            }

private void OnFormClosing(object sender, CancelEventArgs e)
            {
                // 保存窗体位置与大小
                if (sender is AppForm1)
                    form1Position = ((Form)sender).Bounds;
                else if (sender is AppForm2)
                    form2Position = ((Form)sender).Bounds;
            }

private void OnFormClosed(object sender, EventArgs e)
            {
                // 关闭所有窗体,退出主线程
                formCount--;
                if (formCount == 0)
                {
                    ExitThread();
                }
            }

private bool WriteFormDataToFile()
            {
                // 保存窗体位置与大小到用户文件
                UTF8Encoding encoding = new UTF8Encoding();

RectangleConverter rectConv = new RectangleConverter();
                String form1pos = rectConv.ConvertToString(form1Position);
                String form2pos = rectConv.ConvertToString(form2Position);

byte[] dataToWrite = encoding.GetBytes("~" + form1pos + "~" + form2pos);

try
                {
                    userData.Seek(0, SeekOrigin.Begin);
                    userData.Write(dataToWrite, 0, dataToWrite.Length);
                    userData.Flush();

userData.SetLength(dataToWrite.Length);
                    return true;

}
                catch
                {
                    return false;
                }

}

private bool ReadFormDataFromFile()
            {
                // 从文件中读取窗体大小与位置
                UTF8Encoding encoding = new UTF8Encoding();
                String data;

if (userData.Length != 0)
                {
                    byte[] dataToRead = new Byte[userData.Length];

try
                    {
                        userData.Seek(0, SeekOrigin.Begin);
                        userData.Read(dataToRead, 0, dataToRead.Length);

}
                    catch (IOException e)
                    {
                        String errorInfo = e.ToString();
                        return false;
                    }
                   
                    data = encoding.GetString(dataToRead);

try
                    {
                        // 转换数据文件为 rectangles
                        RectangleConverter rectConv = new RectangleConverter();
                        String form1pos = data.Substring(1, data.IndexOf("~", 1) - 1);

form1Position = (Rectangle)rectConv.ConvertFromString(form1pos);

String form2pos = data.Substring(data.IndexOf("~", 1) + 1);
                        form2Position = (Rectangle)rectConv.ConvertFromString(form2pos);

return true;

}
                    catch
                    {
                        return false;
                    }

}
                else
                {
                    // 无数据文件时,缺省窗体位置与大小
                    return false;
                }
            }

[STAThread]
            static void Main(string[] args)
            {
                MyApplicationContext context = new MyApplicationContext();
                Application.Run(context);
            }
        }

}
}

//以上代码保存成Program.cs,修改form名称后可以直接使用。源自MSDN,稍作修改

出处:https://blog.csdn.net/guohu99/article/details/5115757

c#利用ApplicationContext类 同时启动双窗体的实现的更多相关文章

  1. C/S模式开发中如何利用WebBrowser控件制作导航窗体

    原文:C/S模式开发中如何利用WebBrowser控件制作导航窗体 转自: CSDN 相信不少同学们都做过MIS系统的开发,今天这里不讨论B/S模式开发的问题.来谈谈winform开发.用过市面上常见 ...

  2. 并发编程(二)--利用Process类开启进程、僵尸进程、孤儿进程、守护进程、互斥锁、队列与管道

    一.multiprocessing模块 1.multiprocessing模块用来开启子进程,并在子进程中执行我们定制的任务(比如函数),该模块与多线程模块threading的编程接口类似. 2.mu ...

  3. 并发编程(二)——利用Process类开启进程、僵尸进程、孤儿进程、守护进程、互斥锁、队列与管道

    Process类与开启进程.守护进程.互斥锁 一.multiprocessing模块 1.multiprocessing模块用来开启子进程,并在子进程中执行我们定制的任务(比如函数),该模块与多线程模 ...

  4. 【Android编程】Java利用Socket类编写Metasploit安卓载荷辅助模块

    /作者:Kali_MG1937 CSDN博客:ALDYS4 QQ:3496925334/ 注意!此文章被作者标记到 黑历史 专栏中,这意味着本篇文章可能存在 质量低下,流水账文,笔法低质 的问题 为了 ...

  5. 精尽Spring Boot源码分析 - SpringApplication 启动类的启动过程

    该系列文章是笔者在学习 Spring Boot 过程中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合我的源码注释 Spring Boot 源码分析 GitHub 地址 进行阅读 Sprin ...

  6. 利用File类过滤器列出目录下的指定目录或文件

    需求:列出d盘下的全部txt文件 实现方法:利用File类的过滤器功能 package com.test.common.util; import java.io.File; import java.i ...

  7. php利用smtp类轻松的发送电子邮件

    当你还在纠结php内置的mail()函数不能发送邮件时,那么你现在很幸运,此时的这篇文章可以帮助到你! php利用smtp类来发邮件真是屡试不爽,我用过很久了,基本上没出过问题.本博客后台,当博主回复 ...

  8. Qt中利用QTime类来控制时间,这里简单介绍一下QTime的成员函数的用法:

    Qt中利用QTime类来控制时间,这里简单介绍一下QTime的成员函数的用法: ------------------------------------------------------------ ...

  9. 一个利用pojo类从前端页面request中获取参数的小框架~

    写之前不知道Spring已经实现这样的功能,所以傻傻的写了这个东西! 实现原理挺有趣的在此记录一下.从去年十月参加java开发以来自己终于有了点小进步. 好开心. 解决问题(详解):前端form表单提 ...

随机推荐

  1. js 数组原型

    Array.isArray( Array.prototype ) // A. true // B. false // C. error // D. other 答案是A. 其实 Array.proto ...

  2. CSP中的选择

    P ∩ Q (P or Q) 由机器做出选择,环境无法控制,设计软件时只实现一个即可 P[]Q一般选择(Genral choice) 环境可以控制选择P或Q,若P不可接受这个动作,则执行Q,若Q不可接 ...

  3. datatables弹窗报错信息屏蔽方法

    在使用datatables的时候,总是会弹出这样的warning: Error: DataTables warning: table id=data_table- Requested unknown ...

  4. html代码换行造成空格间距问题

    连续几个内联标签或表单元素标签的换行在浏览器会被解释为一个空格. 比如下面代码: <span style="border:1px solid #f20">hello&l ...

  5. web 服务发布注意事项

    1.在发布的时候首先查看服务器对外开放的端口,如果没有最好和客户进行沟通需要开放那些对应的端口,要不外界无法访问发布的站点. 2.在oracle需要远程控制服务器的数据库的时候需要开发1521端口.

  6. vue 上拉加载自定义组件,超好用哦

    1.创建组件components > zj-roll > index.vue <template> <div> <slot></slot> ...

  7. 【JS】【5】request.getHeader("referer")的作用

    正文: request.getHeader("referer"):获取来访者地址 注意:只有通过链接访问当前页的时候,才能获取上一页的地址,以下情况是获取不到值的: 只有通过链接访 ...

  8. UTC,BJT时间的换算

    题目内容:UTC是世界协调时,BJT是北京时间,UTC时间相当于BJT减去8.现在,你的程序要读入一个整数,表示BJT的时和分.整数的个位和十位表示分,百位和千位表示小时.如果小时小于10,则没有千位 ...

  9. 解決 centos -bash: vim: command not found

    i. 那么如何安裝 vim 呢?输入rpm -qa|grep vim 命令, 如果 vim 已经正确安裝,会返回下面的三行代码: root@server1 [~]# rpm -qa|grep vim ...

  10. Python *Mix_w8

    文件操作的函数 文件可迭代 open(文件名(路径), mode="?", encoding="字符集") f = open("../Python/是 ...