/// <summary>
        /// <para>
        ///     Requests a size and screen position for an appbar. When the request is made, the message proposes a
        ///     screen edge and a bounding rectangle for the appbar.
        /// </para>
        /// <para>
        ///     The system adjusts the bounding rectangle so
        ///     that the appbar does not interfere with the Windows taskbar or any other appbars.
        /// </para>
        /// </summary>
        public void QueryPosition(ref Position position, DockPosition dock)
        {
            //TODO:

            //ABM_QUERYPOS seems to do nothing on Windows 10. It gives back the exact
            //same dimensions, not adjusting for the start bar

            //When the dock is docked to the left for example, it doesn't take the
            //entire screen length because the start bar is there. I used ABM_QUERYPOS
            //to tell me how much space Windows actually assigned to to the dock

            //Since ABM_QUERYPOS doesn't work properly on Windows 10, I've decided
            //to only allow the screen to be reserved when docked to top of the screen,
            //with the assumption that the start bar is always on the botton of the screen

            //The code is being left "as is" in case I figure out the solution to it

            APPBARDATA msgData = new APPBARDATA();

            msgData.cbSize = Marshal.SizeOf(msgData);
            msgData.hWnd   = _handle;
            msgData.uEdge  = (uint)dock.ToNative();
            position.ToNative(ref msgData.rc);

            Win32AppBar.SHAppBarMessage(ABM.ABM_QUERYPOS, ref msgData);
            position = Position.FromNative(ref msgData.rc);
        }
        /// <summary>
        /// Unregisters an appbar.
        /// </summary>
        public void Unregister()
        {
            APPBARDATA msgData = new APPBARDATA();

            msgData.cbSize = Marshal.SizeOf(msgData);
            msgData.hWnd   = _handle;

            Win32AppBar.SHAppBarMessage(ABM.ABM_REMOVE, ref msgData);
        }
        /// <summary>
        /// Notifies the system when an appbar's position has changed.
        /// </summary>
        void OnWindowPositionChanged()
        {
            APPBARDATA msgData = new APPBARDATA();

            msgData.cbSize = Marshal.SizeOf(msgData);
            msgData.hWnd   = _handle;

            Win32AppBar.SHAppBarMessage(ABM.ABM_WINDOWPOSCHANGED, ref msgData);
        }
        /// <summary>
        /// Notifies the system that an appbar has been activated.
        /// </summary>
        void OnActivate()
        {
            APPBARDATA msgData = new APPBARDATA();

            msgData.cbSize = Marshal.SizeOf(msgData);
            msgData.hWnd   = _handle;

            Win32AppBar.SHAppBarMessage(ABM.ABM_ACTIVATE, ref msgData);
        }
        public Position GetTaskbarPosition()
        {
            APPBARDATA msgData = new APPBARDATA();

            msgData.cbSize = Marshal.SizeOf(msgData);

            Win32AppBar.SHAppBarMessage(ABM.ABM_GETTASKBARPOS, ref msgData);
            return(Position.FromNative(ref msgData.rc));
        }
        /// <summary>
        /// Retrieves the handle to the appbar associated to the edge of the screen.
        /// </summary>
        /// <returns>
        /// Returns the handle to the autohide appbar. The return value is 0 if an error occurs or
        /// if no autohide appbar is associated with the given edge.
        /// </returns>
        public IntPtr GetAutoHide(DockPosition dock)
        {
            APPBARDATA msgData = new APPBARDATA();

            msgData.cbSize = Marshal.SizeOf(msgData);
            msgData.hWnd   = _handle;
            msgData.uEdge  = (uint)dock.ToNative();

            return(Win32AppBar.SHAppBarMessage(ABM.ABM_GETAUTOHIDEBAR, ref msgData));
        }
        /// <summary>
        /// Registers a new appbar.
        /// </summary>
        /// <returns>Returns true if successful, otherwise false</returns>
        public bool Register()
        {
            APPBARDATA msgData = new APPBARDATA();

            msgData.cbSize           = Marshal.SizeOf(msgData);
            msgData.hWnd             = _handle;
            msgData.uCallbackMessage = _callback;

            return(Win32AppBar.SHAppBarMessage(ABM.ABM_NEW, ref msgData).ToInt32() == Win32.TRUE);
        }
        /// <summary>
        /// Registers or unregisters an autohide appbar for an edge of the screen.
        /// </summary>
        /// <returns>
        /// Returns true if successful, or false if an error occurs or
        /// if an autohide appbar is already registered for the given edge.
        /// </returns>
        public bool SetAutoHide(DockPosition dock, bool autohide)
        {
            APPBARDATA msgData = new APPBARDATA();

            msgData.cbSize = Marshal.SizeOf(msgData);
            msgData.hWnd   = _handle;
            msgData.lParam = autohide ? Win32.TRUE : Win32.FALSE;
            msgData.uEdge  = (uint)dock.ToNative();

            return(Win32AppBar.SHAppBarMessage(ABM.ABM_SETAUTOHIDEBAR, ref msgData).ToInt32() == Win32.TRUE);
        }
        /// <summary>
        /// <para>
        ///     Sets the size and screen position of an appbar. The message specifies a
        ///     screen edge and the bounding rectangle for the appbar.
        /// </para>
        /// <para>
        ///     The system may adjust the bounding rectangle so that the appbar does not
        ///     interfere with the Windows taskbar or any other appbars.
        /// </para>
        /// </summary>
        public void SetPosition(ref Position position, DockPosition dock)
        {
            APPBARDATA msgData = new APPBARDATA();

            msgData.cbSize = Marshal.SizeOf(msgData);
            msgData.hWnd   = _handle;
            msgData.uEdge  = (uint)dock.ToNative();
            position.ToNative(ref msgData.rc);

            if (dock.Selected == DockEdge.Top)
            {
                msgData.rc.bottom = msgData.rc.bottom + 8;
            }

            Win32AppBar.SHAppBarMessage(ABM.ABM_SETPOS, ref msgData);
            position = Position.FromNative(ref msgData.rc);
        }