最近开发IM项目的时候,遇到一个问题:客户端收到消息的时候,要弹出对话款。
我是单开一个线程来监听服务器消息的,当收到消息的时候如果窗口没打开,则自动打开。
问题出现了,窗体打开后即死掉,反白。
首先想到的是可能代码写错了,于是检查几次,都未发现问题。于是想到可能是线程里创建窗体权限的问题。有在主窗体上拖个按钮,写上创建新窗体的代码,运行发现一切正常。
这时候就确定是线程的问题了。
主窗口用于主线程,用以接收各种系统消息。可能是我的子线程和系统交互的消息受阻。
这时候尝试在
Form frmObj = new Form ( );
frmObj. Show ( System. Windows. Forms. IWin32Window );
查阅了一些网文,找到了一篇看似有帮助的帖子。代码是vb.net的,然后把它翻译成C#。代码如下:
实现了IWin32Window接收,
public class WindowWrapper : System. Windows. Forms. IWin32Window
{
private System. IntPtr _hwnd;
public WindowWrapper ( System. IntPtr handle )
{
_hwnd = handle;
}
public System. IntPtr Handle
{
get { return _hwnd; }
}
}
然后在封装系统的一个获取当前主窗体的API.
[System. Runtime. InteropServices. DllImport ( "user32")]
public static extern System. IntPtr GetForegroundWindow();
System. IntPtr IntPart;
IntPart = GetForegroundWindow ( );
WindowWrapper OwinForm = new WindowWrapper ( IntPart );
frmChat frmObj = new frmChat ( cm );
frmObj. Show ( OwinForm );
本以为新创建的窗体已经依附于主窗体了,应该可以像正常窗体一下。
结果发现还是死掉。
思考中。。。既然是主线程才能创建的窗体对象,那我就用拥有主线程的主窗体来创建。哈哈。
当前窗体拥有主线程,所以一切就顺利起来了。
代码:
void GetActiveWindowMehtod ( )
{
@H_703_404@ //在拥有主窗体的线程上创建子窗体
this. Invoke ( new GetActiveWindowHandle ( GetActiveWindow ));
}
delegate void GetActiveWindowHandle ( );
void GetActiveWindow ( )
{
frmChat fc = new frmChat ( );
fc. Show ( );
}
然后在子线程的方法了调用 GetActiveWindowMehtod();
运行窗体正常显示。
这么几句代码,每天都在写好多遍。遇到问题就不一定能像的起来。越是简单的问题越要仔细。