2009-06-01 47 views
1

我试图创建一个消息窗口来接收从MFC库类,在Winforms应用程序中的窗口消息。如何从Windows窗体创建仅消息窗口?

我试着子类NativeWindow,并在构造函数请求窗口句柄是这样的:

CreateParams cp = new CreateParams(); 
cp.Parent = (IntPtr)HWND_MESSAGE; 
this.CreateHandle(cp); 

,但我得到消息“错误创建窗口句柄”抛出Win32Exception。如何从Windows窗体创建仅消息窗口?正在使用NativeWindow正确的方法?

+0

你能标记答案吗? – 2011-02-23 17:52:15

+1

这些答案都不适用于我 - 最后,我不得不使用C++/CLI并深入研究Windows API。我会发布我使用的代码,但它属于前雇主。 – Simon 2011-02-24 07:45:07

回答

0

我相信你还需要指定一个窗口类。

+0

我应该怎样设置它?我尝试过“消息”和班级的名字,但都没有成功。 “消息”给我同样的错误,类名给我“窗口类名称无效”。 – Simon 2009-06-02 08:02:30

0

试一下:

[DllImport("user32.dll")] 
static extern IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent); 

static IntPtr HWND_MESSAGE = new IntPtr(-3); 

protected override void OnHandleCreated(EventArgs e) 
{ 
    base.OnHandleCreated(e); 
    SetParent(this.Handle, HWND_MESSAGE); 
} 
0

我怕你必须从Form派生,并迫使窗口不可见的。

另一种方法(在的情况下类库是可修改)是运行没有窗口消息泵(见Application.RunApplication.AddMessageFilter,或者如果你喜欢使用PeekMessage &有限公司pinvokes)。

在这种情况下,您可以使用PostThreadMessage通过使用运行Application.Run的线程ID来发送消息,但实际上,由于它不等待消息确认,因此实际上无法与应用程序消息泵线程同步。

1

我知道这是7.5岁,但如果有人发现这一点,我想我会回应。我使用微软的TimerNativeWindow code并删除了定时器功能。我结束了使用这种方法:

public class MyNativeWindow : NativeWindow 
    { 
     private readonly string _caption; 
     private const int WmClose = 0x0010; 

     [SuppressMessage("Microsoft.Reliability", "CA2006:UseSafeHandleToEncapsulateNativeResources")] 
     private static readonly HandleRef HwndMessage = new HandleRef(null, new IntPtr(-3)); 

     [DllImport("user32.dll", CharSet = CharSet.Auto)] 
     [ResourceExposure(ResourceScope.None)] 
     private static extern IntPtr PostMessage(HandleRef hwnd, int msg, int wparam, int lparam); 

     [DllImport("user32.dll", ExactSpelling = true, CharSet = CharSet.Auto)] 
     [ResourceExposure(ResourceScope.Process)] 
     private static extern int GetWindowThreadProcessId(HandleRef hWnd, out int lpdwProcessId); 

     [DllImport("kernel32.dll", ExactSpelling = true, CharSet = CharSet.Auto)] 
     [ResourceExposure(ResourceScope.Process)] 
     private static extern int GetCurrentThreadId(); 

     public MyNativeWindow(string caption) 
     { 
      _caption = caption; 
     } 

     public bool CreateWindow() 
     { 
      if (Handle == IntPtr.Zero) 
      { 
       CreateHandle(new CreateParams 
       { 
        Style = 0, 
        ExStyle = 0, 
        ClassStyle = 0, 
        Caption = _caption, 
        Parent = (IntPtr)HwndMessage 
       }); 
      } 
      return Handle != IntPtr.Zero; 
     } 


     public void DestroyWindow() 
     { 
      DestroyWindow(true, IntPtr.Zero); 
     } 

     private bool GetInvokeRequired(IntPtr hWnd) 
     { 
      if (hWnd == IntPtr.Zero) return false; 
      int pid; 
      var hwndThread = GetWindowThreadProcessId(new HandleRef(this, hWnd), out pid); 
      var currentThread = GetCurrentThreadId(); 
      return (hwndThread != currentThread); 
     } 

     private void DestroyWindow(bool destroyHwnd, IntPtr hWnd) 
     { 
      if (hWnd == IntPtr.Zero) 
      { 
       hWnd = Handle; 
      } 

      if (GetInvokeRequired(hWnd)) 
      { 
       PostMessage(new HandleRef(this, hWnd), WmClose, 0, 0); 
       return; 
      } 

      lock (this) 
      { 
       if (destroyHwnd) 
       { 
        base.DestroyHandle(); 
       } 
      } 
     } 

     public override void DestroyHandle() 
     { 
      DestroyWindow(false, IntPtr.Zero); 
      base.DestroyHandle(); 
     } 
    } 
相关问题