Form.ShowInTaskBar / Process.MainWindowHandle

.net, c#, taskbar, windows, winforms

Solution

I found an alternative way to do it by stepping back to Win32 stuff and using window titles. It's messy, but it works for my situation.

The example has the context menu of one application instance closing all instances of that application.

[DllImport("user32.dll")]
public static extern int EnumWindows(EnumWindowsCallback x, int y);
public delegate bool EnumWindowsCallback(int hwnd, int lParam);
[DllImport("user32.dll")]
public static extern void GetWindowText(int h, StringBuilder s, int nMaxCount);
[DllImport("user32.dll")]
public static extern IntPtr PostMessage(IntPtr hWnd, int msg, int wParam, int lParam);
private void ContextMenu_Quit_All(object sender, EventArgs ea)
{
    EnumWindowsCallback itemHandler = (hwnd, lParam) =>
    {
        StringBuilder sb = new StringBuilder(1024);
        GetWindowText(hwnd, sb, sb.Capacity);

        if ((sb.ToString() == MainWindow.APP_WINDOW_TITLE) &&
            (hwnd != mainWindow.Handle.ToInt32())) // Don't close self yet
        {
            PostMessage(new IntPtr(hwnd), /*WM_CLOSE*/0x0010, 0, 0);
        }

        // Continue enumerating windows. There may be more instances to close.
        return true;
    };

    EnumWindows(itemHandler, 0);
    // Close self ..
}

Problem

When an application's main `Form` - the one passed to `Application.Run()` - has ``` this.ShowInTaskBar = false; ``` then, an instance of `Process` representing that application has a `MainWindowHandle` of `0`, meaning that `Process.CloseMainWindow()` does not work. How can I get around this? I need to cleanly close down the `Form` via the `Process` instance.

Original source