【问题标题】: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
        

        注意:您可以在声明中将lpClassName 或lpWindowName 更改为string 或long 确保使用“静态”作为 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
          相关资源
          最近更新 更多