例如:
有两个form,分别为form1和form2,在form1种有个Button1,在Button1中的点击事件中,打开form2
private void Button1_Click()
{
   form2 f = new form2(); 
   f.Show();
}
在以上的代码中form2是同时可以打开多个的。我的问题是:在Button1的点击事件是否能够判断:当form2已经有一个实例打开时,就不再打开新的form2;如果还没有form2的实例打开,则打开一个form2。如果是子窗口的模式,是可以通过以下代码判断出某个子窗体是否已经打开:
form2 f = new form2();
foreach(Form key in this.MdiChildren)
{
    if(key.Name.ToUpper() == f.Name.ToUpper())
    {
       return;
    }
}
f.Show();但对于非子窗口的form不知怎么判断是否已经打开?

解决方案 »

  1.   

    private Form2 f=null;
    private void button1_Click(object sender, System.EventArgs e) {
    if (f==null || f.IsDisposed ) {
    f=new Form2(); 
    }
    f.Show(); 
      }
      

  2.   

    Form2:
    public string strHe=null;
    private void He_Load(object sender, System.EventArgs e)
    {
    strHe=this.Handle.ToString();
    }
    Form1:
    private string  GetStrHe=null;
    Form2 frm=new Form2();
    //GetStrHe=Form2.strHe;
    if(GetStrHe==null)
    {

    frm.Show();
    GetStrHe=Form2.strHe;
    }
    else
    {
    MessageBox.Show("窗体已打开");
    }
      

  3.   

    用API:
    [DllImport("user32.dll", EntryPoint="FindWindow")]
    public static extern int FindWindow (
    string lpClassName,
    string lpWindowName
    );
    lpClassName ----  String,指向包含了窗口类名的空中止(C语言)字串的指针;或设为零,表示接收任何类  lpWindowName ---  String,指向包含了窗口文本(或标签)的空中止(C语言)字串的指针;或设为零,表示接收任何窗口标题
      

  4.   

    浪子大哥  你好:
        问个问题啊,你这是不是API的反射调用
    相比之下 用哪一个好呢
    相对来说 哪一个会效率高一点呢
      

  5.   

    还有一种办法,在form2类中定义一个static变量,每打开一个就设置+1,这时候你可以由这个值来知道已经打开几个这种类的实例即窗体了,当然,你就要能用这种方法来控制有n个这种实例了.
      

  6.   

    窗口是自己开得用usepc(usepc) 得办法,
    是别的程序开得用dazhu2(边城浪子【倚天不出,谁与争锋】) 的办法;
    另外如果是托管的窗口,探测程序也是托管的,不要用api,封送效率很低。
      

  7.   

    用 FindWindow还有, 你上面的代码 最好 用 ShowDialog 而不要用 Show
      

  8.   

    shit,为了积分,还是下点功夫,怕别人看不懂我写的,呵呵上面写的意思代码是这样滴:public class Form2 
    {
       public static int m_Static_InstanceCount=0;
    }调用与判断的代码是:
    public class Form1
    {
       private void functionName()
       { 
              //在此n值由用户决定这个窗体类实例的个数
              //判断Form2类实例的个数
    if(Form2.m_Static_InstanceCount <n)
    {
    Form2 frm=new Form2();
                      //实例加一
    Form2.m_Static_InstanceCount++;
                      //show出来
    frm.Show();
    }
       }
    }======
    我觉得这样的好一些,不用在两个类都写那么多烦人松散的代码了。
      

  9.   

    在form1中定义一个static变量,在每次实例化时先判断变量是否为空,如果为空,就可以实例化
    在form2的dispost事件中把static变量一关闭就清空。
    这样可以做到只实例化一次或几次form2
    以前在项目中做过,你可以试下!!!!
      

  10.   

    我上边的代码可以优化一下,奶奶的好久不写c++,把好多有用的东西给忘了
    整理后的代码如下:public class Form2 
    {
       public static int m_Static_InstanceCount=0;
       public Form2()
       { 
          Form2.m_Static_InstanceCount++;
       }
       protected override void Dispose( bool disposing )
       {
         //其它代码
         Form2.m_Static_InstanceCount--;
        }
       
    }
    public class Form1
    {
       private void functionName()
       { 
              //在此n值由用户决定这个窗体类实例的个数
              //判断Form2类实例的个数
    if(Form2.m_Static_InstanceCount <n)
    {
    Form2 frm=new Form2();
                      //show出来
    frm.Show();
    }
       }
    }
      

  11.   

    因为我是需要做成一个函数,供别人调用的,所以只能采用dazhu2(边城浪子【倚天不出,谁与争锋】) 的方法:
    [DllImport("user32.dll", EntryPoint="FindWindow")]
    public static extern int FindWindow (
    string lpClassName,
    string lpWindowName
    );
    而不能采用与form2之间传递互调用的方法。但FindWindow是怎么用的?
    我如下这样使用无效:
    form2 f = new form2();
    int i = FindWindow(f.Name, f.text);
    if (i == 0)
    {
       f.Show();
    }
    else
    {  return;
    }//以上FindWindow的两个参数不知道该传入什么值?
      

  12.   

    9sun888(九个太阳)的方法不是很好吗,搞这么复杂
      

  13.   

    用标志变量是不行的,因为,该函数是不知道需要打开那些form,也不知道有多少调用,更不能要求别人在调用时来帮你设置这个标志变量。
      

  14.   

    Form2 form2 = new Form2;
    if(form2.showDialog(this) == DialogResult.OK)
    {
    }
    form2.Dispose();
      

  15.   

    我在一测试程序里这样使用:
    int i = FindWindow(null, f.text);//把lpClassName参数设为空值
    这样是可以达到我预想的效果,
    但把同样的代码移植到另一个我正式需要运用的程序里却不能达到我想要的效果。
    而且第一次打开时返回值都为非0值。
    还有一个疑惑:即使以上的代码可以,但f.text的值可能是非唯一值,可能也会导致问题。到底该怎么办?
      

  16.   

    ffjing(猪头不卖) :
    我的天啊?我这么短的代码,还复杂?天地良心啊?
      

  17.   

    if(FindWindow(null,窗体标题)>0)
     MessageBox.Show(" 有这个窗体!!");
    else
      MessageBox.Show(" 没有这个窗体!!");
      

  18.   

    to 边城浪子:
    我在前面已经写过,使用了FindWindow(null, form.Text)的方法,在我的正式环境中并不能达到我预想的效果,而且这样使用还有一个问题就是,form的标题信息的可以重复的,这样也将导致出现问题。此问题,再等一天,如果还没有高手来提出更好的解决方法,就要结贴了!
      

  19.   

    form2 frm=new form2();
    frm.ShowDialog();
      

  20.   

    我已经搞定这个问题了,关键代码如下:
    1、在Form1中定义两个Hashtable变量:
       System.Collections.Hashtable hashTable1;
       System.Collections.Hashtable hashTable2;2、在Form1的Load事件中初始化以上两个变量:
       hashTable1 = new Hashtable();
       hashTable2 = new Hashtable();3、ShowForm方法:
       private void ShowForm(object sender, Form oForm)
       {
    Form frmToInvoke;
    string key;
    key = sender.GetHashCode().ToString() + "-" + oForm.GetType().ToString();
    if (hashTable1[key] == null)
    {
        frmToInvoke = oForm;
        frmToInvoke.Closing += new CancelEventHandler(this.Form_Closing);
           if (bIsMdiChildren)
        {
    frmToInvoke.MdiParent = this;
        }
        hashTable1.Add(key, frmToInvoke);
        hashTable2.Add(oForm.GetHashCode(), key);
    }
    else
    {
        frmToInvoke = (System.Windows.Forms.Form)hashTable1[key];
    }
    frmToInvoke.Show();
    frmToInvoke.Activate();
       }4、在Form1中增加如下事件(在Form2关闭时驱动发生):
       private void Form_Closing(object sender, System.ComponentModel.CancelEventArgs e)
       {
    hashTable1.Remove(hashTable2[sender.GetHashCode()]);
    hashTable2.Remove(sender.GetHashCode());
       }5、在Form1中驱动打开Form2的代码中写如下调用ShowForm(这里为button事件):
       private void button1_Click(object sender, System.EventArgs e)
       {
    ShowForm(sender, new FrmCreateNew());
       }
      

  21.   

    好意思,以上ShowForm方法缺少了一个参数,我开始以为没有用到这个参数,则把它删了,下面补充完整:
    private void ShowForm(object sender, Form oForm, bool bIsMdiChildren)
    //sender:
    //oForm: 需要打开的Form
    //bIsMdiChildren:打开的oForm是否为子窗口模式打开。