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. Nginx教程--02.Nginx虚拟主机的配置

    1.Nginx虚拟主机的配置 1.1 在conf目录下,使用命令 : vim nginx.conf 对上图解释: //全局区 worker _processes 1; //表示当前有1个工作的子进程, ...

  2. leecode第一百六十九题(求众数)

    class Solution { public: void quick_sort(vector<int>& nums,int res,int res_end) { )//错过,不能 ...

  3. Linux wc -l 统计文件行数存在的问题

    1.使用这种方式效率较低,而且不注意可能出现错误 find  . -name "*.pc" |xargs wc -l 直接查看 total 不是正确的值. 原因: 这种方式存在一个 ...

  4. postman(三):添加断言

    进行接口测试时,添加断言时必不可少的,断言就是判断响应内容与预期返回是否一致 进行接口测试时,添加断言时必不可少的,断言就是判断响应内容与预期返回是否一致   postman可以在请求模块的Tests ...

  5. xml和tomcat介绍

    一 xml介绍: xml:可扩展性的文件 功能: 1.作为框架的配置文件 2.方便在网络中传输数据 <a> <b></b> <c></c> ...

  6. python模块--re模块

    常用的正则表达式模式: .  匹配除换行符以外的任意字符 \d  匹配一个数字字符.等价于 [0-9]. \D  匹配一个非数字字符.等价于 [^0-9]. \s  匹配任何空白字符,包括空格.制表符 ...

  7. 《剑指offer》总结二 之二叉树

    目录 17.树的子结构(27ms,5836k) 18.二叉树的镜像(38ms) 22.从上往下打印二叉树(50ms,5832k) 24.二叉树中和为某一值的路径(26ms,5728k) 38.二叉树的 ...

  8. Python3+pyshark捕获数据包并保存为文件

    一.直接使用wireshark捕获数据包并保存为文件 可以使用wireshark通过图形界面的操作来实现捕获数据包并保存为文件. wireshark默认捕获的数据包保存为临时文件,如果最后退出时不选择 ...

  9. gdb pretty printer for STL debug in Linux

    Check your gcc version. If it is less than 4.7, you need use another printer.py file. Get the file f ...

  10. js获取html元素在可视区域的位置

    1)html节点在可视区域的位置 obj.getBoundingClientRect().top obj.getBoundingClientRect().left 2) 获取鼠标按下的位置 event ...