Fixed tabs/spaces indentation mistake.
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / InternalWindowManager.cs
index f0484ca1dcdb9d39ee52424f424b2f130283aa27..5acda6776cdb752c6bc119faeacca08f1530c0b2 100644 (file)
@@ -27,6 +27,8 @@
 
 using System;
 using System.Drawing;
+using System.Runtime.InteropServices;
+
 
 namespace System.Windows.Forms {
 
@@ -34,32 +36,29 @@ namespace System.Windows.Forms {
 
                private static Color titlebar_color;
 
-               private int BorderWidth = 3;
                private Size MinTitleBarSize = new Size (115, 25);
 
                internal Form form;
 
-               private TitleButton close_button;
-               private TitleButton maximize_button;
-               private TitleButton minimize_button;
-
+               internal TitleButton close_button;
+               internal TitleButton maximize_button;
+               internal TitleButton minimize_button;
+               protected Rectangle icon_rect;
+               
                private TitleButton [] title_buttons = new TitleButton [3];
                
                // moving windows
                internal Point start;
-               private State state;
+               internal State state;
                private FormPos sizing_edge;
                internal Rectangle virtual_position;
-               private Rectangle prev_virtual_position;
-               private Rectangle prev_bounds;
-               private bool maximized;
 
-               private class TitleButton {
+               public class TitleButton {
                        public Rectangle Rectangle;
                        public ButtonState State;
                        public CaptionButton Caption;
                        public EventHandler Clicked;
-                       
+
                        public TitleButton (CaptionButton caption, EventHandler clicked)
                        {
                                Caption = caption;
@@ -67,14 +66,14 @@ namespace System.Windows.Forms {
                        }
                }
 
-               private enum State {
+               public enum State {
                        Idle,
                        Moving,
                        Sizing,
                }
 
                [Flags]
-               private enum FormPos {
+               public enum FormPos {
                        None,
 
                        TitleBar = 1,
@@ -98,6 +97,8 @@ namespace System.Windows.Forms {
                        titlebar_color = Color.FromArgb (255, 0, 0, 255);
                        this.form = form;
 
+                       form.SizeChanged += new EventHandler (FormSizeChangedHandler);
+
                        CreateButtons ();
                }
 
@@ -105,8 +106,28 @@ namespace System.Windows.Forms {
                        get { return form; }
                }
 
-               public bool Maximized {
-                       get { return maximized; }
+               public Rectangle CloseButtonRect {
+                       get { return close_button.Rectangle; }
+                       set { close_button.Rectangle = value; }
+               }
+
+               public Rectangle MinimizeButtonRect {
+                       get { return minimize_button.Rectangle; }
+                       set { minimize_button.Rectangle = value; }
+               }
+
+               public Rectangle MaximizeButtonRect {
+                       get { return maximize_button.Rectangle; }
+                       set { maximize_button.Rectangle = value; }
+               }
+
+               public Rectangle IconRect {
+                       get { return icon_rect; }
+                       set { value = icon_rect; }
+               }
+
+               public int IconWidth {
+                       get { return TitleBarHeight - 5; }
                }
 
                public bool HandleMessage (ref Message m)
@@ -129,23 +150,109 @@ namespace System.Windows.Forms {
                        case Msg.WM_LBUTTONDOWN:
                                return HandleButtonDown (ref m);
 
-                       case Msg.WM_NCMOUSEMOVE:
-                               return HandleNCMouseMove (form, ref m);
+                       case Msg.WM_NCHITTEST:
+                               int x = Control.LowOrder ((int) m.LParam.ToInt32 ());
+                               int y = Control.HighOrder ((int) m.LParam.ToInt32 ());
+
+                               NCPointToClient (ref x, ref y);
+
+                               FormPos pos = FormPosForCoords (x, y);
+                               
+                               if (pos == FormPos.TitleBar) {
+                                       m.Result = new IntPtr ((int) HitTest.HTCAPTION);
+                                       return true;
+                               }
+
+                               if (!IsSizable)
+                                       return false;
+
+                               switch (pos) {
+                               case FormPos.Top:
+                                       m.Result = new IntPtr ((int) HitTest.HTTOP);
+                                       break;
+                               case FormPos.Left:
+                                       m.Result = new IntPtr ((int) HitTest.HTLEFT);
+                                       break;
+                               case FormPos.Right:
+                                       m.Result = new IntPtr ((int) HitTest.HTRIGHT);
+                                       break;
+                               case FormPos.Bottom:
+                                       m.Result = new IntPtr ((int) HitTest.HTBOTTOM);
+                                       break;
+                               case FormPos.TopLeft:
+                                       m.Result = new IntPtr ((int) HitTest.HTTOPLEFT);
+                                       break;
+                               case FormPos.TopRight:
+                                       m.Result = new IntPtr ((int) HitTest.HTTOPRIGHT);
+                                       break;
+                               case FormPos.BottomLeft:
+                                       m.Result = new IntPtr ((int) HitTest.HTBOTTOMLEFT);
+                                       break;
+                               case FormPos.BottomRight:
+                                       m.Result = new IntPtr ((int) HitTest.HTBOTTOMRIGHT);
+                                       break;
+                               default:
+                                       // We return false so that DefWndProc handles things
+                                       return false;
+                               }
+                               return true;
 
+                               // Return true from these guys, otherwise win32 will mess up z-order
                        case Msg.WM_NCLBUTTONUP:
-                               return HandleNCLButtonUp (ref m);
+                               HandleNCLButtonUp (ref m);
+                               return true;
 
                        case Msg.WM_NCLBUTTONDOWN:
-                               return HandleNCLButtonDown (ref m);
+                               HandleNCLButtonDown (ref m);
+                               return true;
+
+                       case Msg.WM_NCLBUTTONDBLCLK:
+                               HandleNCLButtonDblClick (ref m);
+                               break;
 
                        case Msg.WM_MOUSE_LEAVE:
                                FormMouseLeave (ref m);
                                break;
 
-                       case Msg.WM_NCPAINT:
-                               PaintWindowDecorations ();
+                       case Msg.WM_NCCALCSIZE:
+                               XplatUIWin32.NCCALCSIZE_PARAMS  ncp;
+
+                               if (m.WParam == (IntPtr) 1) {
+                                       ncp = (XplatUIWin32.NCCALCSIZE_PARAMS) Marshal.PtrToStructure (m.LParam,
+                                                       typeof (XplatUIWin32.NCCALCSIZE_PARAMS));
+
+                                       int bw = ThemeEngine.Current.ManagedWindowBorderWidth (this);
+
+                                       if (HasBorders) {
+                                               ncp.rgrc1.top += TitleBarHeight + bw;
+                                               ncp.rgrc1.bottom -= bw;
+                                               ncp.rgrc1.left += bw;
+                                               ncp.rgrc1.right -= bw;
+                                       }
+
+                                       Marshal.StructureToPtr(ncp, m.LParam, true);
+                               }
+
                                break;
+
+                       case Msg.WM_NCPAINT:
+                               PaintEventArgs pe = XplatUI.PaintEventStart (form.Handle, false);
+
+                               Rectangle clip;
+                               // clip region is not correct on win32.
+                               // if (m.WParam.ToInt32 () > 1) {
+                               //      Region r = Region.FromHrgn (m.WParam);
+                               //      RectangleF rf = r.GetBounds (pe.Graphics);
+                               //      clip = new Rectangle ((int) rf.X, (int) rf.Y, (int) rf.Width, (int) rf.Height);
+                               //} else {      
+                               clip = new Rectangle (0, 0, form.Width, form.Height);
+                               //}
+
+                               ThemeEngine.Current.DrawManagedWindowDecorations (pe.Graphics, clip, this);
+                               XplatUI.PaintEventEnd (form.Handle, false);
+                               return true;
                        }
+
                        return false;
                }
 
@@ -161,9 +268,43 @@ namespace System.Windows.Forms {
                        CreateButtons ();
                }
 
+               public void HandleMenuMouseDown (MainMenu menu, int x, int y)
+               {
+                       Point pt = MenuTracker.ScreenToMenu (menu, new Point (x, y));
+
+                       foreach (TitleButton button in title_buttons) {
+                               if (button != null && button.Rectangle.Contains (pt)) {
+                                       button.Clicked (this, EventArgs.Empty);
+                                       button.State = ButtonState.Pushed;
+                                       return;
+                               }
+                       }
+               }
+
+               public virtual void SetWindowState (FormWindowState old_state, FormWindowState window_state)
+               {
+               }
+
+               public virtual FormWindowState GetWindowState ()
+               {
+                       return form.window_state;
+               }
+
                public virtual void PointToClient (ref int x, ref int y)
                {
-                       // toolwindows stay in screencoords
+                       // toolwindows stay in screencoords we just have to make sure
+                       // they obey the working area
+                       Rectangle working = SystemInformation.WorkingArea;
+
+                       if (x > working.Right)
+                               x = working.Right;
+                       if (x < working.Left)
+                               x = working.Left;
+
+                       if (y < working.Top)
+                               y = working.Top;
+                       if (y > working.Bottom)
+                               y = working.Bottom;
                }
 
                public virtual void PointToScreen (ref int x, ref int y)
@@ -176,13 +317,45 @@ namespace System.Windows.Forms {
                        return style != FormBorderStyle.FixedToolWindow && style != FormBorderStyle.SizableToolWindow;
                }
 
-               private void CreateButtons ()
+               protected virtual void Activate ()
+               {
+                       // Hack to get a paint
+                       //NativeWindow.WndProc (form.Handle, Msg.WM_NCPAINT, IntPtr.Zero, IntPtr.Zero);
+                       form.Refresh ();
+               }
+
+               public virtual bool IsActive ()
+               {
+                       return true;
+               }
+
+
+               private void FormSizeChangedHandler (object sender, EventArgs e)
+               {
+                       ThemeEngine.Current.ManagedWindowSetButtonLocations (this);
+                       Message m = new Message ();
+                       m.Msg = (int) Msg.WM_NCPAINT;
+                       m.HWnd = form.Handle;
+                       m.LParam = IntPtr.Zero;
+                       m.WParam = new IntPtr (1);
+                       XplatUI.SendMessage (ref m);
+               }
+
+               protected void CreateButtons ()
                {
                        switch (form.FormBorderStyle) {
                        case FormBorderStyle.None:
                                close_button = null;
                                minimize_button = null;
                                maximize_button = null;
+                               if (IsMaximized || IsMinimized)
+                                       goto case FormBorderStyle.Sizable;
+                               break;
+                       case FormBorderStyle.FixedToolWindow:
+                       case FormBorderStyle.SizableToolWindow:
+                               close_button = new TitleButton (CaptionButton.Close, new EventHandler (CloseClicked));
+                               if (IsMaximized || IsMinimized)
+                                       goto case FormBorderStyle.Sizable;
                                break;
                        case FormBorderStyle.FixedSingle:
                        case FormBorderStyle.Fixed3D:
@@ -192,49 +365,45 @@ namespace System.Windows.Forms {
                                minimize_button = new TitleButton (CaptionButton.Minimize, new EventHandler (MinimizeClicked));
                                maximize_button = new TitleButton (CaptionButton.Maximize, new EventHandler (MaximizeClicked));
                                break;
-                       case FormBorderStyle.FixedToolWindow:
-                       case FormBorderStyle.SizableToolWindow:
-                               close_button = new TitleButton (CaptionButton.Close, new EventHandler (CloseClicked));
-                               break;
                        }
 
                        title_buttons [0] = close_button;
                        title_buttons [1] = minimize_button;
                        title_buttons [2] = maximize_button;
+
+                       ThemeEngine.Current.ManagedWindowSetButtonLocations (this);
                }
 
                protected virtual bool HandleButtonDown (ref Message m)
                {
-                       form.BringToFront ();
+                       Activate ();
                        return false;
                }
 
                protected virtual bool HandleNCLButtonDown (ref Message m)
                {
-                       form.BringToFront ();
-
-                       int x = Control.LowOrder ((int) m.LParam.ToInt32 ());
-                       int y = Control.HighOrder ((int) m.LParam.ToInt32 ());
+                       Activate ();
 
                        start = Cursor.Position;
                        virtual_position = form.Bounds;
 
-                       form.PointToClient (ref x, ref y);
+                       int x = Control.LowOrder ((int) m.LParam.ToInt32 ());
+                       int y = Control.HighOrder ((int) m.LParam.ToInt32 ());
+                       
                        // Need to adjust because we are in NC land
-                       y += TitleBarHeight;
+                       NCPointToClient (ref x, ref y);
                        FormPos pos = FormPosForCoords (x, y);
-
+                       
                        if (pos == FormPos.TitleBar) {
                                HandleTitleBarDown (x, y);
                                return true;
                        }
 
                        if (IsSizable) {
-                               SetCursorForPos (pos);
-                       
                                if ((pos & FormPos.AnyEdge) == 0)
                                        return false;
 
+                               virtual_position = form.Bounds;
                                state = State.Sizing;
                                sizing_edge = pos;
                                form.Capture = true;
@@ -244,7 +413,11 @@ namespace System.Windows.Forms {
                        return false;
                }
 
-               private void HandleTitleBarDown (int x, int y)
+               protected virtual void HandleNCLButtonDblClick (ref Message m)
+               {
+               }
+
+               protected virtual void HandleTitleBarDown (int x, int y)
                {
                        foreach (TitleButton button in title_buttons) {
                                if (button != null && button.Rectangle.Contains (x, y)) {
@@ -253,10 +426,10 @@ namespace System.Windows.Forms {
                                }
                        }
 
-                       if (maximized)
+                       if (IsMaximized)
                                return;
 
-                       state = State.Moving;                        
+                       state = State.Moving;
                        form.Capture = true;
                }
 
@@ -287,51 +460,10 @@ namespace System.Windows.Forms {
                        return false;
                }
 
-               private bool HandleNCMouseMove (Form form, ref Message m)
-               {
-                       if (IsSizable) {
-                               int x = Control.LowOrder ((int) m.LParam.ToInt32 ());
-                               int y = Control.HighOrder ((int) m.LParam.ToInt32 ());
-                               FormPos pos = FormPosForCoords (x, y);
-
-                               SetCursorForPos (pos);
-
-                               ClearVirtualPosition ();
-                               state = State.Idle;
-                       }
-
-                       return false;
-               }
-
                private void FormMouseLeave (ref Message m)
                {
                        form.ResetCursor ();
                }
-
-               private void SetCursorForPos (FormPos pos)
-               {
-                       switch (pos) {
-                       case FormPos.TopLeft:
-                       case FormPos.BottomRight:
-                               form.Cursor = Cursors.SizeNWSE;
-                               break;
-                       case FormPos.TopRight:
-                       case FormPos.BottomLeft:
-                               form.Cursor = Cursors.SizeNESW;
-                               break;
-                       case FormPos.Top:
-                       case FormPos.Bottom:
-                               form.Cursor = Cursors.SizeNS;
-                               break;
-                       case FormPos.Left:
-                       case FormPos.Right:
-                               form.Cursor = Cursors.SizeWE;
-                               break;
-                       default:
-                               form.ResetCursor ();
-                               break;
-                       }
-               }
        
                protected virtual void HandleWindowMove (Message m)
                {
@@ -343,45 +475,51 @@ namespace System.Windows.Forms {
 
                private void HandleSizing (Message m)
                {
-                       Point move = MouseMove (m);
                        Rectangle pos = virtual_position;
-                       int mw = MinTitleBarSize.Width + (BorderWidth * 2);
-                       int mh = MinTitleBarSize.Height + (BorderWidth * 2);
-                       
+                       int bw = ThemeEngine.Current.ManagedWindowBorderWidth (this);
+                       int mw = MinTitleBarSize.Width + (bw * 2);
+                       int mh = MinTitleBarSize.Height + (bw * 2);
+                       int x = Cursor.Position.X;
+                       int y = Cursor.Position.Y;
+
+                       PointToClient (ref x, ref y);
+
                        if ((sizing_edge & FormPos.Top) != 0) {
-                               int height = form.Height - move.Y;
-                               if (height <= mh) {
-                                       move.Y += height - mh;
-                                       height = mh;
-                               }
-                               pos.Y = form.Top + move.Y;
-                               pos.Height = height;
+                               if (pos.Bottom - y < mh)
+                                       y = pos.Bottom - mh;
+                               pos.Height = pos.Bottom - y;
+                               pos.Y = y;
                        } else if ((sizing_edge & FormPos.Bottom) != 0) {
-                               int height = form.Height + move.Y;
+                               int height = y - pos.Top;
                                if (height <= mh)
-                                       move.Y -= height - mh;
-                               pos.Height = form.Height + move.Y;
+                                       height = mh;
+                               pos.Height = height;
                        }
 
                        if ((sizing_edge & FormPos.Left) != 0) {
-                               int width = form.Width - move.X;
-                               if (width <= mw) {
-                                       move.X += width - mw;
-                                       width = mw;
-                               }
-                               pos.X = form.Left + move.X;
-                               pos.Width = width;
+                               if (pos.Right - x < mw)
+                                       x = pos.Right - mw;
+                               pos.Width = pos.Right - x;
+                               pos.X = x;
                        } else if ((sizing_edge & FormPos.Right) != 0) {
-                               int width = form.Width + move.X;
+                               int width = x - form.Left;
                                if (width <= mw)
-                                       move.X -= width - mw;
-                               pos.Width = form.Width + move.X;
+                                       width = mw;
+                               pos.Width = width;
                        }
 
                        UpdateVP (pos);
                }
 
-               private bool IsSizable {
+               public bool IsMaximized {
+                       get { return GetWindowState () == FormWindowState.Maximized; }
+               }
+
+               public bool IsMinimized {
+                       get { return GetWindowState () == FormWindowState.Minimized; }
+               }
+
+               public bool IsSizable {
                        get {
                                switch (form.FormBorderStyle) {
                                case FormBorderStyle.Sizable:
@@ -393,13 +531,13 @@ namespace System.Windows.Forms {
                        }
                }
 
-               private bool HasBorders {
+               public bool HasBorders {
                        get {
                                return form.FormBorderStyle != FormBorderStyle.None;
                        }
                }
 
-               private bool IsToolWindow {
+               public bool IsToolWindow {
                        get {
                                if (form.FormBorderStyle == FormBorderStyle.SizableToolWindow ||
                                                form.FormBorderStyle == FormBorderStyle.FixedToolWindow)
@@ -408,13 +546,9 @@ namespace System.Windows.Forms {
                        }
                }
 
-               private int TitleBarHeight {
+               public int TitleBarHeight {
                        get {
-                               if (IsToolWindow)
-                                       return 19;
-                               if (form.FormBorderStyle == FormBorderStyle.None)
-                                       return 0;
-                               return 26;
+                               return ThemeEngine.Current.ManagedWindowTitleBarHeight (this);
                        }
                }
 
@@ -448,17 +582,25 @@ namespace System.Windows.Forms {
                        form.Capture = false;
                        form.Bounds = virtual_position;
                        state = State.Idle;
+
+                       OnWindowFinishedMoving ();
                }
 
                private bool HandleNCLButtonUp (ref Message m)
                {
+                       if (form.Capture) {
+                               ClearVirtualPosition ();
+
+                               form.Capture = false;
+                               state = State.Idle;
+                               if (form.MdiContainer != null)
+                                       form.MdiContainer.SizeScrollBars();
+                       }
+                               
                        int x = Control.LowOrder ((int) m.LParam.ToInt32 ());
                        int y = Control.HighOrder ((int) m.LParam.ToInt32 ());
 
-                       form.PointToClient (ref x, ref y);
-
-                       // Need to adjust because we are in NC land
-                       y += TitleBarHeight;
+                       NCPointToClient (ref x, ref y);
 
                        foreach (TitleButton button in title_buttons) {
                                if (button != null && button.Rectangle.Contains (x, y)) {
@@ -469,109 +611,42 @@ namespace System.Windows.Forms {
 
                        return true;
                }
-
-               private void PaintWindowDecorations ()
-               {
-                       Graphics dc = XplatUI.GetMenuDC (form.Handle, IntPtr.Zero);
-
-                       if (HasBorders) {
-                               Rectangle borders = new Rectangle (0, 0, form.Width, form.Height);
-                       
-                               ControlPaint.DrawBorder3D (dc, borders, Border3DStyle.Raised);
-
-                               if (IsSizable) {
-                                       borders.Inflate (-1, -1);
-                                       ControlPaint.DrawFocusRectangle (dc, borders);
-                               }
-                       }
-
-                       Color color = ThemeEngine.Current.ColorControlDark;
-
-                       if (form.Focused && !maximized)
-                               color = titlebar_color;
-
-                       Rectangle tb = new Rectangle (BorderWidth, BorderWidth,
-                                       form.Width - (BorderWidth * 2), TitleBarHeight - 1);
-
-                       dc.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (color), tb);
-
-                       dc.DrawLine (new Pen (Color.White, 1), BorderWidth,
-                                       TitleBarHeight + BorderWidth, form.Width - BorderWidth,
-                                       TitleBarHeight + BorderWidth);
-
-                       if (!IsToolWindow) {
-                               tb.X += 18; // Room for the icon and the buttons
-                               tb.Width = (form.Width - 62) - tb.X;
-                       }
-
-                       if (form.Text != null) {
-                               StringFormat format = new StringFormat ();
-                               format.FormatFlags = StringFormatFlags.NoWrap;
-                               format.Trimming = StringTrimming.EllipsisCharacter;
-                               format.LineAlignment = StringAlignment.Center;
-                               dc.DrawString (form.Text, form.Font,
-                                               ThemeEngine.Current.ResPool.GetSolidBrush (Color.White),
-                                               tb, format);
-                       }
-
-                       if (!IsToolWindow && HasBorders) {
-                               if (form.Icon != null) {
-                                       dc.DrawIcon (form.Icon, new Rectangle (BorderWidth + 3,
-                                                                    BorderWidth + 3, 16, 16));
-                               }
-                                       
-                               minimize_button.Rectangle = new Rectangle (form.Width - 62,
-                                               BorderWidth + 2, 18, 22);
-
-                               maximize_button.Rectangle = new Rectangle (form.Width - 44,
-                                               BorderWidth + 2, 18, 22);
-                               
-                               close_button.Rectangle = new Rectangle (form.Width - 24,
-                                               BorderWidth + 2, 18, 22);
-
-                               DrawTitleButton (dc, minimize_button);
-                               DrawTitleButton (dc, maximize_button);
-                               DrawTitleButton (dc, close_button);
-                       } else if (IsToolWindow) {
-                               close_button.Rectangle = new Rectangle (form.Width - BorderWidth - 2 - 13,
-                                               BorderWidth + 2, 13, 13);
-                               DrawTitleButton (dc, close_button);
-                       }
-               }
                
-               private void DrawTitleButton (Graphics dc, TitleButton button)
+               protected void DrawTitleButton (Graphics dc, TitleButton button, Rectangle clip)
                {
+                       if (!button.Rectangle.IntersectsWith (clip))
+                               return;
+
                        dc.FillRectangle (SystemBrushes.Control, button.Rectangle);
 
                        ControlPaint.DrawCaptionButton (dc, button.Rectangle,
                                        button.Caption, ButtonState.Normal);
                }
 
-               private void CloseClicked (object sender, EventArgs e)
+               public virtual void DrawMaximizedButtons (object sender, PaintEventArgs pe)
+               {
+               }
+
+               protected virtual void CloseClicked (object sender, EventArgs e)
                {
                        form.Close ();
-                       // form.Close should set visibility to false somewhere
-                       // in it's closing chain but currently does not.
-                       form.Visible = false;
                }
 
                private void MinimizeClicked (object sender, EventArgs e)
                {
-                       form.SuspendLayout ();
-                       form.Width = MinTitleBarSize.Width + (BorderWidth * 2);
-                       form.Height = MinTitleBarSize.Height + (BorderWidth * 2);
-                       form.ResumeLayout ();
+                       if (GetWindowState () != FormWindowState.Minimized) {
+                               form.WindowState = FormWindowState.Minimized;
+                       } else {
+                               form.WindowState = FormWindowState.Normal;
+                       }
                }
 
                private void MaximizeClicked (object sender, EventArgs e)
                {
-                       if (maximized) {
-                               form.Bounds = prev_bounds;
-                               maximized = false;
+                       if (GetWindowState () != FormWindowState.Maximized) {
+                               form.WindowState = FormWindowState.Maximized;
                        } else {
-                               prev_bounds = form.Bounds;
-                               form.Bounds = form.Parent.Bounds;
-                               maximized = true;
+                               form.WindowState = FormWindowState.Normal;
                        }
                }
 
@@ -583,7 +658,7 @@ namespace System.Windows.Forms {
 
                protected virtual void DrawVirtualPosition (Rectangle virtual_position)
                {
-                       form.Location = virtual_position.Location;
+                       form.Bounds = virtual_position;
                        start = Cursor.Position;
                }
 
@@ -592,43 +667,58 @@ namespace System.Windows.Forms {
                        
                }
 
-               private FormPos FormPosForCoords (int x, int y)
+               protected virtual void OnWindowFinishedMoving ()
                {
-                       if (y < TitleBarHeight + BorderWidth) {
+               }
 
-                               if (y > BorderWidth && x > BorderWidth &&
-                                               x < form.Width - BorderWidth)
+               protected virtual void NCPointToClient(ref int x, ref int y) {
+                       form.PointToClient(ref x, ref y);
+                       y += TitleBarHeight;
+                       y += ThemeEngine.Current.ManagedWindowBorderWidth (this);
+               }
+
+               protected FormPos FormPosForCoords (int x, int y)
+               {
+                       int bw = ThemeEngine.Current.ManagedWindowBorderWidth (this);
+                       if (y < TitleBarHeight + bw) {
+                               //      Console.WriteLine ("A");
+                               if (y > bw && x > bw &&
+                                               x < form.Width - bw)
                                        return FormPos.TitleBar;
 
-                               if (x < BorderWidth || (x < 20 && y < BorderWidth))
+                               if (x < bw || (x < 20 && y < bw))
                                        return FormPos.TopLeft;
 
-                               if (x > form.Width - BorderWidth ||
-                                       (x > form.Width - 20 && y < BorderWidth))
+                               if (x > form.Width - bw ||
+                                       (x > form.Width - 20 && y < bw))
                                        return FormPos.TopRight;
 
-                               if (y < BorderWidth)
+                               if (y < bw)
                                        return FormPos.Top;
 
                        } else if (y > form.Height - 20) {
-
-                               if (x < BorderWidth ||
-                                               (x < 20 && y > form.Height - BorderWidth))
+                               //      Console.WriteLine ("B");
+                               if (x < bw ||
+                                               (x < 20 && y > form.Height - bw))
                                        return FormPos.BottomLeft;
 
-                               if (x > form.Width - BorderWidth ||
+                               if (x > form.Width - (bw * 2) ||
                                                (x > form.Width - 20 &&
-                                                y > form.Height - BorderWidth))
+                                                y > form.Height - bw))
                                        return FormPos.BottomRight;
 
-                               if (y > form.Height - BorderWidth)
+                               if (y > form.Height - (bw * 2))
                                        return FormPos.Bottom;
 
 
-                       } else if (x < BorderWidth) {
+                       } else if (x < bw) {
+                               //      Console.WriteLine ("C");
                                return FormPos.Left;
-                       } else if (x > form.Width - BorderWidth) {
+                       } else if (x > form.Width - (bw * 2)) {
+//                             Console.WriteLine ("D");
                                return FormPos.Right;
+                       } else {
+                               //                      Console.WriteLine ("E   {0}", form.Width - bw);
                        }
                        
                        return FormPos.None;