//------------------------------------------------------
        //
        //  Interface ITransformProvider
        //
        //------------------------------------------------------

        #region Interface ITransformProvider

        void ITransformProvider.Move( double x, double y )
        {
            if ( ! ((ITransformProvider)this).CanMove )
                throw new InvalidOperationException(SR.Get(SRID.OperationCannotBePerformed));

            int extendedStyle = GetWindowExStyle();
            if ( IsBitSet(extendedStyle, SafeNativeMethods.WS_EX_MDICHILD) )
            {
                // we always deal in screen pixels.  But if its an MDI window it interprets these as
                // client pixels so convert them to get the expected results.
                NativeMethods.POINT point = new NativeMethods.POINT((int)x, (int)y);
                NativeMethods.HWND hwndParent = SafeNativeMethods.GetAncestor(NativeMethods.HWND.Cast(_hwnd), SafeNativeMethods.GA_PARENT);
                if (!MapWindowPoints(NativeMethods.HWND.NULL, hwndParent, ref point, 1))
                {
                    throw new InvalidOperationException(SR.Get(SRID.OperationCannotBePerformed));
                }
                x = point.x;
                y = point.y;

                // Make sure the MDI child stays on the parents client area.
                NativeMethods.RECT currentRect = new NativeMethods.RECT();
                if (!Misc.GetWindowRect(_hwnd, out currentRect))
                {
                    throw new InvalidOperationException(SR.Get(SRID.OperationCannotBePerformed));
                }
                int currentHeight = currentRect.bottom - currentRect.top;
                int currentWidth = currentRect.right - currentRect.left;

                int dx = SafeNativeMethods.GetSystemMetrics(SafeNativeMethods.SM_CXHSCROLL);
                int dy = SafeNativeMethods.GetSystemMetrics(SafeNativeMethods.SM_CYHSCROLL);

                // If to far to the left move right edge to be visible.
                // Move the left edge the absalute differance of the right to the origin plus a little more to be visible.
                if (x + currentWidth < 0)
                {
                    x += ((x + currentWidth) * -1 + dx);
                }
                // If to far off the top move bottom edge down to be visible.
                // Move the top edge the absalute differance of the bottom to the origin plus a little more to be visible.
                if (y + currentHeight < 0)
                {
                    y += ((y + currentHeight) * -1 + dy);
                }

                NativeMethods.RECT parentRect = new NativeMethods.RECT();
                if (!Misc.GetClientRect(hwndParent, out parentRect))
                {
                    throw new InvalidOperationException(SR.Get(SRID.OperationCannotBePerformed));
                }
                // If to far to the right move left edge to be visible.
                // Move the left edge back the diffance of it and the parent's client area right side plus a little more to be visible.
                if (x > parentRect.right)
                {
                    x -= (x - parentRect.right + dx);
                }
                // If to far off the bottome move top edge down to be visible.
                // Move the top edge up the diffance of it and the parent's client area bottom side plus a little more to be visible.
                if (y > parentRect.bottom)
                {
                    y -= (y - parentRect.bottom + dy);
                }
            }

            // position the window keeping the zorder the same and not resizing.
            // We do this first so that the window is moved in terms of screen coordinates.
            // The WindowPlacement APIs take in to account the workarea which ends up
            // putting the window in the wrong place
            if (!Misc.SetWindowPos(_hwnd, NativeMethods.HWND.NULL, (int)x, (int)y, 0, 0, UnsafeNativeMethods.SWP_NOSIZE | UnsafeNativeMethods.SWP_NOZORDER | UnsafeNativeMethods.SWP_NOACTIVATE))
            {
                throw new InvalidOperationException(SR.Get(SRID.OperationCannotBePerformed));
            }

            UnsafeNativeMethods.WINDOWPLACEMENT wp = new UnsafeNativeMethods.WINDOWPLACEMENT();
            wp.length = Marshal.SizeOf(typeof(UnsafeNativeMethods.WINDOWPLACEMENT));

            // get the WINDOWPLACEMENT information.  This includes the coordinates in
            // terms of the workarea.
            if (!Misc.GetWindowPlacement(_hwnd, ref wp))
            {
                throw new InvalidOperationException(SR.Get(SRID.OperationCannotBePerformed));
            }

            int style = GetWindowStyle();
            if (style == 0)
            {
                throw new InvalidOperationException(SR.Get(SRID.OperationCannotBePerformed));
            }
            if ( IsBitSet(style, SafeNativeMethods.WS_MINIMIZE) )
            {
                // If the window is minimized the parameters have to be setup differently
                wp.ptMinPosition.y = (int) y;
                wp.ptMinPosition.x = (int) x;
                wp.flags = UnsafeNativeMethods.WPF_SETMINPOSITION;

                // Use SetWindowPlacement to move the window because it handles the case where the
                // window is move completly off the screen even in the multi-mon case.  If this happens
                // it will place the window on the primary monitor at a location closest to the taget.
                if (!Misc.SetWindowPlacement(_hwnd, ref wp))
                {
                    throw new InvalidOperationException(SR.Get(SRID.OperationCannotBePerformed));
                }
            }
            else
            {
                NativeMethods.RECT currentRect = new NativeMethods.RECT();

                if (!Misc.GetWindowRect(_hwnd, out currentRect))
                {
                    throw new InvalidOperationException(SR.Get(SRID.OperationCannotBePerformed));
                }

                // Use SetWindowPlacement to move the window because it handles the case where the
                // window is move completly off the screen even in the multi-mon case.  If this happens
                // it will place the window on the primary monitor at a location closest to the taget.
                if (!Misc.SetWindowPlacement(_hwnd, ref wp))
                {
                    throw new InvalidOperationException(SR.Get(SRID.OperationCannotBePerformed));
                }

                // check to make sure SetWindowPlacement has not changed the size of our window
                // There may be a bug in SetWindowPlacement.
                int currentHeight = currentRect.bottom - currentRect.top;
                int currentWidth = currentRect.right - currentRect.left;

                if (!Misc.GetWindowPlacement(_hwnd, ref wp))
                {
                    throw new InvalidOperationException(SR.Get(SRID.OperationCannotBePerformed));
                }

                int newHeight = wp.rcNormalPosition.bottom - wp.rcNormalPosition.top;
                int newWidth = wp.rcNormalPosition.right -wp.rcNormalPosition.left;

                if ( currentHeight != newHeight || currentWidth != newWidth )
                {
                    wp.rcNormalPosition.bottom = wp.rcNormalPosition.top + currentHeight;
                    wp.rcNormalPosition.right = wp.rcNormalPosition.left + currentWidth;

                    if (!Misc.SetWindowPlacement(_hwnd, ref wp))
                    {
                        throw new InvalidOperationException(SR.Get(SRID.OperationCannotBePerformed));
                    }
                }
            }
        }
        void ITransformProvider.Resize( double width, double height )
        {
            if ( !SafeNativeMethods.IsWindow( _hwnd ) )
                throw new ElementNotAvailableException();

            int widthInt = (int) width;
            int heightInt = (int) height;

            if ( ! ((ITransformProvider)this).CanResize )
                throw new InvalidOperationException(SR.Get(SRID.OperationCannotBePerformed));

            UnsafeNativeMethods.MINMAXINFO minMaxInfo = new UnsafeNativeMethods.MINMAXINFO();

            // get the largest window size that can be produced by using the borders to size the window
            int x = SafeNativeMethods.GetSystemMetrics(SafeNativeMethods.SM_CXMAXTRACK);
            int y = SafeNativeMethods.GetSystemMetrics(SafeNativeMethods.SM_CYMAXTRACK);

            minMaxInfo.ptMaxSize = new NativeMethods.POINT( x, y );
            minMaxInfo.ptMaxPosition = new NativeMethods.POINT(0, 0);
            minMaxInfo.ptMinTrackSize = new NativeMethods.POINT(1, 1);
            minMaxInfo.ptMaxTrackSize = new NativeMethods.POINT( x, y );

            // if the window stopped responding there is a chance that resizing will not work
            // Don't check the return from SendMessageTimeout and go ahead
            // and try to resize in case it works.  The minMaxInfo struct has resonable
            // values even if this fails.
            Misc.SendMessageTimeout(_hwnd, UnsafeNativeMethods.WM_GETMINMAXINFO, IntPtr.Zero, ref minMaxInfo);

            if ( widthInt < minMaxInfo.ptMinTrackSize.x )
                widthInt = minMaxInfo.ptMinTrackSize.x;

            if ( heightInt < minMaxInfo.ptMinTrackSize.y )
                heightInt = minMaxInfo.ptMinTrackSize.y;

            if ( widthInt > minMaxInfo.ptMaxTrackSize.x )
                widthInt = minMaxInfo.ptMaxTrackSize.x;

            if ( heightInt > minMaxInfo.ptMaxTrackSize.y )
                heightInt = minMaxInfo.ptMaxTrackSize.y;

            UnsafeNativeMethods.WINDOWPLACEMENT wp = new UnsafeNativeMethods.WINDOWPLACEMENT();
            wp.length = Marshal.SizeOf(typeof(UnsafeNativeMethods.WINDOWPLACEMENT));

            // get the WINDOWPLACEMENT information
            if (!Misc.GetWindowPlacement(_hwnd, ref wp))
            {
                throw new InvalidOperationException(SR.Get(SRID.OperationCannotBePerformed));
            }

            // Calculate the new right and bottom for how the user wants the window resized and update the struct
            wp.rcNormalPosition.right = (widthInt + wp.rcNormalPosition.left);
            wp.rcNormalPosition.bottom = (heightInt + wp.rcNormalPosition.top);

            // Use SetWindowPlacement to move the window because it handles the case where the
            // window is sized completly off the screen even in the multi-mon case.  If this happens
            // it will place the window on the primary monitor at a location closes to the taget.
            if (!Misc.SetWindowPlacement(_hwnd, ref wp))
            {
                throw new InvalidOperationException(SR.Get(SRID.OperationCannotBePerformed));
            }
        }
        //------------------------------------------------------
        //
        //  Interface IWindowProvider
        //
        //------------------------------------------------------

        #region Interface IWindowProvider

        void IWindowProvider.SetVisualState( WindowVisualState state )
        {
            if ( !SafeNativeMethods.IsWindow( _hwnd ) )
                throw new ElementNotAvailableException();

            switch ( state )
            {
                case WindowVisualState.Normal:
                {
                    // you can't really do anything to a disabled window
                    if ( IsBitSet(GetWindowStyle(), SafeNativeMethods.WS_DISABLED) )
                        throw new InvalidOperationException(SR.Get(SRID.OperationCannotBePerformed));

                    // If already in the normal state, do not need to do anything.
                    if (((IWindowProvider)this).VisualState == WindowVisualState.Normal)
                    {
                        return;
                    }

                    ClearMenuMode();
                    UnsafeNativeMethods.WINDOWPLACEMENT wp = new UnsafeNativeMethods.WINDOWPLACEMENT();

                    wp.length = Marshal.SizeOf(typeof(UnsafeNativeMethods.WINDOWPLACEMENT));

                    // get the WINDOWPLACEMENT information
                    if (!Misc.GetWindowPlacement(_hwnd, ref wp))
                    {
                        throw new InvalidOperationException(SR.Get(SRID.OperationCannotBePerformed));
                    }

                    wp.showCmd = UnsafeNativeMethods.SW_RESTORE;

                    // Use SetWindowPlacement to set state to normal because if the window is maximized then minimized
                    // sending SC_RESTORE puts it back to maximized instead of normal.
                    if (!Misc.SetWindowPlacement(_hwnd, ref wp))
                    {
                        throw new InvalidOperationException(SR.Get(SRID.OperationCannotBePerformed));
                    }

                    return;
                }

                case WindowVisualState.Minimized:
                {
                    if (!((IWindowProvider)this).Minimizable)
                        throw new InvalidOperationException(SR.Get(SRID.OperationCannotBePerformed));

                    // If already minimzed, do not need to do anything.
                    if (((IWindowProvider)this).VisualState == WindowVisualState.Minimized)
                    {
                        return;
                    }

                    ClearMenuMode();

                    if (!Misc.PostMessage(_hwnd, UnsafeNativeMethods.WM_SYSCOMMAND, (IntPtr)UnsafeNativeMethods.SC_MINIMIZE, IntPtr.Zero))
                    {
                        throw new InvalidOperationException(SR.Get(SRID.OperationCannotBePerformed));
                    }

                    return;
                }

                case WindowVisualState.Maximized:
                {
                    if ( ! ((IWindowProvider)this).Maximizable )
                        throw new InvalidOperationException(SR.Get(SRID.OperationCannotBePerformed));

                    // If already maximized, do not need to do anything.
                    if (((IWindowProvider)this).VisualState == WindowVisualState.Maximized)
                    {
                        return;
                    }

                    ClearMenuMode();

                    if (!Misc.PostMessage(_hwnd, UnsafeNativeMethods.WM_SYSCOMMAND, (IntPtr)UnsafeNativeMethods.SC_MAXIMIZE, IntPtr.Zero))
                    {
                        throw new InvalidOperationException(SR.Get(SRID.OperationCannotBePerformed));
                    }

                    return;
                }

                default:
                {
                    Debug.Assert(false,"unexpected switch() case:");
                    throw new ArgumentException(SR.Get(SRID.UnexpectedWindowState),"state");
                }

            }

        }