Why does my application not close gracefully when using an Appbar?

60 Views Asked by At

Playing with Appbars via https://www.codeproject.com/Articles/6741/AppBar-using-C and https://github.com/tip2tail/t2tWinFormAppBarLib , I noticed that .NET 6 applications do not exit properly:

  1. The code reaches the bottom of Program.Main (i.e., Application.Run(new Form1()); completes), but the application remains running.
  2. If I call Environment.Exit(0); at the bottom of Program.Main, that call hangs.
  3. If the form has no child controls after its constructor runs, the issue does not happen.
  4. The issue does not happen in .Net Framework 4.8, but does in .NET 6 (as well as in .NET 7)
  5. Adding Process.GetCurrentProcess().Kill(); to the bottom of Program.Main "fixes" the problem.
  6. Commenting out Controls.Add(q) "fixes" the problem.

Below is sample application. Note that this is an intentionally simplified, self-contained reproduction. For example, it doesn't bother to position the window against the dock nor does it handle AppBar messaging. I was also able to reproduce the problem by directly using both of the libraries mentioned above, but felt that a self-contained example would be easier to follow.

Warning: If you run this code, close the window so that SHAppBarMessage((UInt32)AppBarMessages.Remove, ref msgData); has a chance to run. Otherwise, you'll likely lose a chunk of screen real estate until you reboot.

public partial class Form1 : Form
{
    [DllImport("shell32.dll")]
    public static extern UInt32 SHAppBarMessage(UInt32 dwMessage, ref APPBARDATA pData);

    [StructLayout(LayoutKind.Sequential)]
    public struct RECT
    {
        public Int32 left;
        public Int32 top;
        public Int32 right;
        public Int32 bottom;
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct APPBARDATA
    {
        public UInt32 cbSize;
        public IntPtr hWnd;
        public UInt32 uCallbackMessage;
        public UInt32 uEdge;
        public RECT rc;
        public Int32 lParam;
    }

    public enum AppBarMessages
    {
        New = 0x00,
        Remove = 0x01,
        QueryPos = 0x02,
        SetPos = 0x03,
        GetState = 0x04,
        GetTaskBarPos = 0x05,
        Activate = 0x06,
        GetAutoHideBar = 0x07,
        SetAutoHideBar = 0x08,
        WindowPosChanged = 0x09,
        SetState = 0x0a
    }

    Control q;
    public Form1()
    {
        InitializeComponent();

        APPBARDATA msgData = new APPBARDATA();
        msgData.cbSize = (UInt32)Marshal.SizeOf(msgData);
        msgData.hWnd = Handle;
        msgData.uCallbackMessage = 0x410; //0x400 WM_User

        SHAppBarMessage((UInt32)AppBarMessages.New, ref msgData);

        msgData = new APPBARDATA();
        msgData.cbSize = (UInt32)Marshal.SizeOf(msgData);
        msgData.hWnd = Handle;
        msgData.uEdge = (UInt32)1; //ABE_Top
        msgData.rc = new RECT()
        {
            left = 0,
            right = SystemInformation.PrimaryMonitorSize.Width,
            bottom = 50,
            top = 0
        };


        SHAppBarMessage((UInt32)AppBarMessages.SetPos, ref msgData);

        q = new Button();
        Controls.Add(q);
    }

    protected override void OnClosing(CancelEventArgs e)
    {
        APPBARDATA msgData = new APPBARDATA();
        msgData.cbSize = (UInt32)Marshal.SizeOf(msgData);
        msgData.hWnd = Handle;
        SHAppBarMessage((UInt32)AppBarMessages.Remove, ref msgData);
        base.OnClosing(e);
    }

    protected override void OnClosed(EventArgs e)
    {
        base.OnClosed(e);
    }
}

Why does my application not close gracefully when using an Appbar?

0

There are 0 best solutions below