2013-02-20 150 views
0

我在C#中有一个应用程序,它创建一个窗体并将它堆叠到另一个应用程序窗口的前面。 我通过使用SetParent来做到这一点。但是,(新)父窗口冻结。使用SetParent冻结父窗口

我该如何解决这个问题?这是线程问题吗?

这是工作:

private void Test(object sender, EventArgs e) 
     { 
      FormCover cov = new FormCover(); 
      IntPtr hwnd = Win32Utils.FindWindowByCaptionStart(IntPtr.Zero, TrackerName, null); 

      Win32Utils.SetParent(cov.Handle, hwnd); 
      cov.SetDesktopLocation(0, 0); 

      cov.Show(); 
     } 

但是,这(与定时经过事件)是

public partial class Form1 : Form 
    { 

FormCover cover; 

void tmrCheck_Elapsed(object sender, System.Timers.ElapsedEventArgs e) 
     { 
      ShowCover(); 
     } 

private void ShowCover() 
     { 
      cover = new FormCover(); 
      IntPtr hwnd = Win32Utils.FindWindowByCaptionStart(IntPtr.Zero, TrackerName, null); 

      cover.CoverInitialize(hwnd); 
      cover.Activate(); 
     } 
} 
//------ 

public partial class FormCover : Form 
    { 
     public delegate void IntPtrDlg(IntPtr param); 

     public FormCover() 
     { 
      InitializeComponent(); 
     } 

     internal void CoverInitialize(IntPtr hwdnParent) 
     { 
      if (this.InvokeRequired) 
      { 
       this.Invoke(new IntPtrDlg(CoverInitialize), new object[] { hwdnParent }); 
      } 
      else 
      { 
       Win32Utils.SetParent(this.Handle, hwdnParent); 
       this.SetDesktopLocation(0, 0); 
      } 
     } 

     internal void CoverActivate(IntPtr handleFormulario) 
     { 
      if (!Visible) 
       this.Show(); 
     } 

     internal void CoverFinalize() 
     { 
      Hide(); 
      Win32ParentUtils.SetParent(Handle, new IntPtr()); 
     } 
    } 

的是这两个样本之间的区别?第一个工作正常,第二个冻结初始窗口。

+0

我想你不能只是像这样创建一个窗口......窗口需要消息泵,当它不是模态窗口时。 – 2013-02-20 09:30:44

+0

尝试在GUI线程上运行整个ShowCover方法(通过使用(Begin)Invoke方法),就像在CoverInitialize中做的那样 – Bond 2013-02-20 09:34:15

回答

1

正如我刚才所说的,您需要为您的表单创建一个消息泵。 尝试

Thread thread = new Thread(() => 
{ 
    var formCover = new FormCover(); 
    Application.Run(formCover); 
}); 
thread.ApartmentState = ApartmentState.STA; 
thread.Start(); 

然后,您应该能够设置您的窗体的父。

参见here作进一步参考。

+0

这很好地工作。但是,当我调整父窗口的大小时,子窗口消失。当我移动父窗口,或者关注它的任何子控件时,它不会发生。当窗口被调整大小时,它只被发送到z-index。我想我应该叫BringToFront,但它永远不会被调用。我想我应该开始另一个问题。 – 2013-02-20 10:25:22

+0

第二个问题发布在这里:http://stackoverflow.com/questions/14979341/capture-resize-from-external-window-in-c-sharp – 2013-02-20 11:59:46