views:

509

answers:

1

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.

A: 

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 ..
}
frou