I want to create a form on a second thread that will receive messages in it's WndProc method. What is the recommended way to create an invisible form like this? Is setting "ShowInTaskbar=false" and "Visible=false" enough, or is there a "cleaner" way?
5 Answers
I'm not sure what you mean by "cleaner". The standard way to create a form that is invisible to the user is to set Visible and ShowInTaskbar to false.

- 3,666
- 1
- 21
- 24
-
It's true, but I was wondering if there was a way to have a WndProc without even having the form at all. :) – Jon Tackabury May 21 '09 at 18:47
-
In windows, a message loop requires a window handle. It is certainly possible to create a window handle and pass messages to it without ever actually displaying the window, but there is nothing exposed in the .NET framework to help you do that. You will have to use unmanaged APIs. – David Nelson May 21 '09 at 20:13
-
Windows does have a message only window for that purpose, but I don't believe that is exposed in the in WinForms. See http://msdn.microsoft.com/en-us/library/ms632599%28VS.85%29.aspx#message_only – shf301 Feb 05 '10 at 02:50
You won't be able to receive windows messages if you set your ShowInTaskbar to false. The only way to do it is by hiding your form instead (it still hides the taskbar icon).

- 4,190
- 2
- 48
- 63
use:
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
or
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
note: you can change the lpClassName
or lpWindowName
to string
or long
in the declaration
make sure to use "Static" as the lpClassName
member - this is the invisible window style you want that is usually used for recieve wndproc windows.
the return value from this api is the hwnd(handle) that you can subclass to get the messages it will receive all standard windows messages or you can send custom messages to it, so it won't fire your code accidentally when a standard message is received.
example:
hwnd_main
is the hwnd of its parent window
dim hwnd_recieve as long
hwnd_recieve = CreateWindowEx(num_zero, "Static", "",0,0,0,0,0, hwnd_main,0,0,0)
subclass this and have fun!

- 26,990
- 7
- 84
- 140
The code in this project has a neat way of dealing with this problem: http://www.codeproject.com/KB/dotnet/XDMessaging.aspx
I'm not copying the code here because it's copyrighted, but you can use it for reference by downloading it yourself.
The XDListener class extends NativeWindow, so it is able to receive messages. In the constructor some attributes are set on the window which make it invisible. The method WndProc is overridden in that class to process messages that arrive. I tested that this code works on Win 7 with a C# app while all my Forms are all hidden and not being displayed in the TaskBar.

- 12,419
- 7
- 54
- 59
As far as I know, what you're doing is against the rules (although, these things do work sometimes) ... all UI stuff is supposed to be in the main thread.
As for your question, you should be able to just set Visible to false. Setting ShowInTaskbar would only be important for the main application form, I believe, and if you did that users wouldn't have a way to get back to your app from the taskbar.

- 4,127
- 24
- 28
-
UI elements can be run on separate threads, as long as invoking is used to communicate between them. Ideally I would like to keep everything on 1 thread for simplicity, but in this case I have no choice. – Jon Tackabury May 20 '09 at 13:41