【问题标题】:WndProc with no visible form?没有可见形式的 WndProc?
【发布时间】:2010-10-27 10:23:11
【问题描述】:

我想在第二个线程上创建一个表单,该表单将在其 WndProc 方法中接收消息。创建这样的不可见表单的推荐方法是什么?设置“ShowInTaskbar=false”和“Visible=false”是否足够,或者有没有“更干净”的方式?

【问题讨论】:

    标签: c# .net winforms wndproc


    【解决方案1】:

    我不确定您所说的“更清洁”是什么意思。创建对用户不可见的表单的标准方法是将 Visible 和 ShowInTaskbar 设置为 false。

    【讨论】:

    • 这是真的,但我想知道是否有一种方法可以让 WndProc 甚至完全没有表单。 :)
    • 在 windows 中,消息循环需要一个窗口句柄。当然可以创建一个窗口句柄并将消息传递给它而无需实际显示窗口,但 .NET 框架中没有任何内容可以帮助您做到这一点。您将不得不使用非托管 API。
    • Windows 确实有一个仅用于此目的的消息窗口,但我不相信它在 WinForms 中公开。见msdn.microsoft.com/en-us/library/…
    【解决方案2】:

    据我所知,你所做的是违反规则的(尽管这些事情有时确实有效)......所有 UI 的东西都应该在主线程中。

    至于您的问题,您应该可以将 Visible 设置为 false。我相信,设置 ShowInTaskbar 只对主应用程序表单很重要,如果你这样做了,用户将无法从任务栏返回到你的应用程序。

    【讨论】:

    • UI 元素可以在单独的线程上运行,只要它们之间使用调用进行通信。理想情况下,为了简单起见,我希望将所有内容都保留在 1 个线程上,但在这种情况下,我别无选择。
    【解决方案3】:

    这个项目中的代码有一个巧妙的方法来处理这个问题:http://www.codeproject.com/KB/dotnet/XDMessaging.aspx

    这里的代码我没有复制,因为它是受版权保护的,但您可以自己下载它以供参考。

    XDListener 类扩展了 NativeWindow,因此它能够接收消息。在构造函数中,在窗口上设置了一些属性,使其不可见。 WndProc 方法在该类中被重写以处理到达的消息。我测试了这段代码可以在 Win 7 上使用 C# 应用程序运行,而我的所有表单都被隐藏并且没有显示在任务栏中。

    【讨论】:

      【解决方案4】:

      如果您将 ShowInTaskbar 设置为 false,您将无法接收 Windows 消息。唯一的方法是隐藏您的表单(它仍然隐藏任务栏图标)。

      【讨论】:

        【解决方案5】:

        使用:

        Public Declare Function CreateWindowExA Lib "user32" (ByVal dwExStyle As Long, 
            ByVal lpClassName As String, ByVal lpWindowName As String, ByVal dwStyle As Long, 
            ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, 
            ByVal hWndParent As Long, ByVal hMenu As Long, ByVal hInstance As Long, lpParam As Any) 
            As Long
        

        Public Declare Function CreateWindowExW Lib "user32" (ByVal dwExStyle As Long, 
            ByVal lpClassName As Long, ByVal lpWindowName As Long, ByVal dwStyle As Long, 
            ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, 
            ByVal hWndParent As Long, ByVal hMenu As Long, ByVal hInstance As Long, lpParam As Long) 
            As Long
        

        注意:您可以在声明中将lpClassNamelpWindowName 更改为stringlong 确保使用“静态”作为 lpClassName 成员 - 这是您想要的不可见窗口样式,通常用于接收 wndproc 窗口。

        此 api 的返回值是 hwnd(handle),您可以对其进行子类化以获取消息 它将接收所有标准 Windows 消息,或者您可以向其发送自定义消息,因此在收到标准消息时它不会意外触发您的代码。

        示例: hwnd_main是其父窗口的hwnd

        dim hwnd_recieve as long
        hwnd_recieve = CreateWindowEx(num_zero, "Static", "",0,0,0,0,0, hwnd_main,0,0,0)
        

        继承这个并玩得开心!

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-07-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多