2006-12-01 Chris Toshok <toshok@ximian.com>
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / XplatUIWin32.cs
index 35692599f97a311d521cd597d82c86bece8d970c..af4ef6bbc03a42658c5f550c57ce76f6f4abc741 100644 (file)
@@ -53,11 +53,15 @@ namespace System.Windows.Forms {
                internal static WndProc         wnd_proc;
                internal static IntPtr          prev_mouse_hwnd;
                internal static IntPtr          override_cursor;
+               internal static bool            caret_visible;
 
                internal static bool            themes_enabled;
                private Hashtable               timer_list;
                private static Queue            message_queue;
                private static IntPtr           clip_magic = new IntPtr(27051977);
+               private static int              scroll_width;
+               private static int              scroll_height;
+               private static Hashtable        wm_nc_registered;
 
                private static Win32DnD         DnD;
                #endregion      // Local Variables
@@ -85,6 +89,10 @@ namespace System.Windows.Forms {
                        internal int            top;
                        internal int            right;
                        internal int            bottom;
+                       public override string ToString() {
+                               return String.Format("RECT left={0}, top={1}, right={2}, bottom={3}, width={4}, height={5}", left, top, right, bottom, right-left, bottom-top);
+                       }
+
                }
 
                [StructLayout(LayoutKind.Sequential)]
@@ -94,7 +102,10 @@ namespace System.Windows.Forms {
                }
 
                internal enum SPIAction {
-                       SPI_GETWORKAREA         = 0x0030
+                       SPI_GETWORKAREA         = 0x0030,
+                       SPI_GETMOUSEHOVERWIDTH  = 0x0062,
+                       SPI_GETMOUSEHOVERHEIGHT = 0x0064,
+                       SPI_GETMOUSEHOVERTIME   = 0x0066,
                }
 
                internal enum WindowPlacementFlags {
@@ -137,6 +148,7 @@ namespace System.Windows.Forms {
                private enum TMEFlags {
                        TME_HOVER               = 0x00000001,
                        TME_LEAVE               = 0x00000002,
+                       TME_NONCLIENT           = 0x00000010,
                        TME_QUERY               = unchecked((int)0x40000000),
                        TME_CANCEL              = unchecked((int)0x80000000)
                }
@@ -651,12 +663,15 @@ namespace System.Windows.Forms {
                                Win32MessageBox(IntPtr.Zero, "Could not register the "+XplatUI.DefaultClassName+" window class, win32 error " + Win32GetLastError().ToString(), "Oops", 0);
                        }
 
-                       FosterParent=Win32CreateWindow(0, "static", "Foster Parent Window", (int)(WindowStyles.WS_OVERLAPPEDWINDOW | WindowStyles.WS_EX_TOOLWINDOW), 0, 0, 0, 0, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);
+                       FosterParent=Win32CreateWindow((int)WindowExStyles.WS_EX_TOOLWINDOW, "static", "Foster Parent Window", (int)WindowStyles.WS_OVERLAPPEDWINDOW, 0, 0, 0, 0, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);
 
                        if (FosterParent==IntPtr.Zero) {
                                Win32MessageBox(IntPtr.Zero, "Could not create foster window, win32 error " + Win32GetLastError().ToString(), "Oops", 0);
                        }
 
+                       scroll_height = Win32GetSystemMetrics(SystemMetrics.SM_CYHSCROLL);
+                       scroll_width = Win32GetSystemMetrics(SystemMetrics.SM_CXVSCROLL);
+
                        timer_list = new Hashtable ();
                }
                #endregion      // Constructor & Destructor
@@ -709,7 +724,7 @@ namespace System.Windows.Forms {
                        BITMAPINFOHEADER        bmi;
                        int                     ncolors;
                        int                     imagesize;
-                       int                     palettesize;
+                       //int                   palettesize;
                        Bitmap                  bmp;
                        BitmapData              bits;
                        ColorPalette            pal;
@@ -725,7 +740,7 @@ namespace System.Windows.Forms {
                                        ncolors = (int)(1 << bmi.biBitCount);
                                }
                        }
-                       palettesize = ncolors * 4;
+                       //palettesize = ncolors * 4;
 
                        imagesize = (int)bmi.biSizeImage;
                        if (imagesize == 0) {
@@ -768,8 +783,9 @@ namespace System.Windows.Forms {
                                Marshal.Copy((IntPtr)((int)dib_data + Marshal.SizeOf(typeof(BITMAPINFOHEADER))), palette, 0, palette.Length);
 
                                for (int i = 0; i < ncolors; i++) {
-                                       pal.Entries[i] = Color.FromArgb(palette[i] & unchecked((int)0xff000000));
+                                       pal.Entries[i] = Color.FromArgb(palette[i] | unchecked((int)0xff000000));
                                }
+                               bmp.Palette = pal;
                        }
 
                        bytesPerLine = (int)((((bmi.biWidth * bmi.biBitCount) + 31) & ~31) >> 3);
@@ -864,6 +880,51 @@ namespace System.Windows.Forms {
                        }
                }
 
+               internal override Size MouseHoverSize {
+                       get {
+                               int     width = 4;
+                               int     height = 4;
+
+                               Win32SystemParametersInfo(SPIAction.SPI_GETMOUSEHOVERWIDTH, 0, ref width, 0);
+                               Win32SystemParametersInfo(SPIAction.SPI_GETMOUSEHOVERWIDTH, 0, ref height, 0);
+                               return new Size(width, height);
+                       }
+               }
+
+               internal override int MouseHoverTime {
+                       get {
+                               int time = 500;
+
+                               Win32SystemParametersInfo(SPIAction.SPI_GETMOUSEHOVERTIME, 0, ref time, 0);
+                               return time;
+                       }
+               }
+
+               internal override int HorizontalScrollBarHeight {
+                       get {
+                               return scroll_height;
+                       }
+               }
+
+               internal override bool UserClipWontExposeParent {
+                       get {
+                               return false;
+                       }
+               }
+
+
+               internal override int VerticalScrollBarWidth {
+                       get {
+                               return scroll_width;
+                       }
+               }
+
+               internal override int MenuHeight {
+                       get {
+                               return Win32GetSystemMetrics(SystemMetrics.SM_CYMENU);
+                       }
+               }
+
                internal override bool DropTarget {
                        get {
                                return false;
@@ -983,6 +1044,14 @@ namespace System.Windows.Forms {
                                //return new Rectangle(0, 0, Win32GetSystemMetrics(SystemMetrics.SM.SM_CXSCREEN), Win32GetSystemMetrics(SystemMetrics.SM_CYSCREEN));
                        }
                }
+
+               internal override bool ThemesEnabled {
+                       get {
+                               return XplatUIWin32.themes_enabled;
+                       }
+               }
+
                #endregion      // Static Properties
 
                #region Singleton Specific Code
@@ -1045,12 +1114,17 @@ namespace System.Windows.Forms {
                                ParentHandle = FosterParent;
                        }
 
-                       if ( ((cp.Style & (int)(WindowStyles.WS_CHILD))==0) && ((cp.ExStyle & (int)WindowStyles.WS_EX_APPWINDOW) == 0)) {
+                       if ( ((cp.Style & (int)(WindowStyles.WS_CHILD | WindowStyles.WS_POPUP))==0) && ((cp.ExStyle & (int)WindowExStyles.WS_EX_APPWINDOW) == 0)) {
                                // If we want to be hidden from the taskbar we need to be 'owned' by 
                                // something not on the taskbar. FosterParent is just that
                                ParentHandle = FosterParent;
                        }
 
+                       // Since we fake MDI dont tell Windows that this is a real MDI window
+                       if ((cp.ExStyle & (int) WindowExStyles.WS_EX_MDICHILD) != 0) {
+                               SetMdiStyles (cp);
+                       }
+
                        WindowHandle = Win32CreateWindow((uint)cp.ExStyle, cp.ClassName, cp.Caption, (uint)cp.Style, cp.X, cp.Y, cp.Width, cp.Height, ParentHandle, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);
 
                        if (WindowHandle==IntPtr.Zero) {
@@ -1130,11 +1204,27 @@ namespace System.Windows.Forms {
                }
 
                internal override void SetWindowStyle(IntPtr handle, CreateParams cp) {
+
+                       if ((cp.ExStyle & (int) WindowExStyles.WS_EX_MDICHILD) != 0) {
+                               SetMdiStyles (cp);
+                       }
+
                        Win32SetWindowLong(handle, WindowLong.GWL_STYLE, (uint)cp.Style);
                        Win32SetWindowLong(handle, WindowLong.GWL_EXSTYLE, (uint)cp.ExStyle);
                }
 
-               
+               internal override double GetWindowTransparency(IntPtr handle)
+               {
+                       LayeredWindowAttributes lwa;
+                       COLORREF clrRef;
+                       byte alpha;
+
+                       if (0 == Win32GetLayeredWindowAttributes (handle, out clrRef, out alpha, out lwa))
+                               return 1.0;
+
+                       return ((double)alpha) / 255.0;
+               }
+
                internal override void SetWindowTransparency(IntPtr handle, double transparency, Color key) {
                        LayeredWindowAttributes lwa = LayeredWindowAttributes.LWA_ALPHA;
                        byte opacity = (byte)(transparency*255);
@@ -1151,16 +1241,45 @@ namespace System.Windows.Forms {
                        Win32SetLayeredWindowAttributes(handle, clrRef, opacity, lwa);
                }
 
-               internal override bool SupportsTransparency() {
-                       // We might check with the OS, but I think we're only >=W2k
-                       return true;
+               TransparencySupport support;
+               bool queried_transparency_support;
+               internal override TransparencySupport SupportsTransparency() {
+                       if (queried_transparency_support)
+                               return support;
+
+                       bool flag;
+                       support = TransparencySupport.None;
+
+                       flag = true;
+                       try {
+                               Win32SetLayeredWindowAttributes (IntPtr.Zero, new COLORREF (), 255, LayeredWindowAttributes.LWA_ALPHA);
+                       }
+                       catch (EntryPointNotFoundException) { flag = false; }
+                       catch { /* swallow everything else */ }
+
+                       if (flag) support |= TransparencySupport.Set;
+
+                       flag = true;
+                       try {
+                               LayeredWindowAttributes lwa;
+                               COLORREF clrRef;
+                               byte alpha;
+
+                               Win32GetLayeredWindowAttributes (IntPtr.Zero, out clrRef, out alpha, out lwa);
+                       }
+                       catch (EntryPointNotFoundException) { flag = false; }
+                       catch { /* swallow everything else */ }
+
+                       if (flag) support |= TransparencySupport.Get;
+
+                       queried_transparency_support = true;
+                       return support;
                }
 
                internal override void UpdateWindow(IntPtr handle) {
                        Win32UpdateWindow(handle);
                }
 
-               [MonoTODO("FIXME - Add support for internal table of windows/DCs for cleanup; handle client=false to draw in NC area")]
                internal override PaintEventArgs PaintEventStart(IntPtr handle, bool client) {
                        IntPtr          hdc;
                        PAINTSTRUCT     ps;
@@ -1179,45 +1298,52 @@ namespace System.Windows.Forms {
                                if (Win32GetUpdateRect(handle, ref rect, false)) {
                                        hdc = Win32BeginPaint(handle, ref ps);
 
-                                       hwnd.user_data = (object)ps;
+                                       hwnd.drawing_stack.Push (ps);
 
                                        clip_rect = new Rectangle(ps.rcPaint.left, ps.rcPaint.top, ps.rcPaint.right-ps.rcPaint.left, ps.rcPaint.bottom-ps.rcPaint.top);
                                } else {
                                        hdc = Win32GetDC(handle);
                                        // FIXME: Add the DC to internal list
+
+                                       hwnd.drawing_stack.Push (null);
+
                                        clip_rect = new Rectangle(rect.top, rect.left, rect.right-rect.left, rect.bottom-rect.top);
                                }
                        } else {
-                               // GDI+ Broken:
-                               // hdc = Win32GetDCEx(hwnd, ncpaint_region, DCExFlags.DCX_WINDOW | DCExFlags.DCX_INTERSECTRGN | DCExFlags.DCX_USESTYLE);
-                               hdc = Win32GetWindowDC(handle);
-                               hwnd.user_data = (object)hdc;
+                               hdc = Win32GetWindowDC (handle);
+
+                               hwnd.drawing_stack.Push (hdc);
+
+                               // HACK this in for now
+                               Win32GetWindowRect (handle, out rect);
+                               clip_rect = new Rectangle(0, 0, rect.right-rect.left, rect.bottom-rect.top);
                        }
 
-                       hwnd.client_dc = Graphics.FromHdc(hdc);
-                       paint_event = new PaintEventArgs(hwnd.client_dc, clip_rect);
+                       Graphics dc = Graphics.FromHdc(hdc);
+                       hwnd.drawing_stack.Push (dc);
+
+                       paint_event = new PaintEventArgs(dc, clip_rect);
 
                        return paint_event;
                }
 
                internal override void PaintEventEnd(IntPtr handle, bool client) {
                        Hwnd            hwnd;
-                       PAINTSTRUCT     ps;
 
                        hwnd = Hwnd.ObjectFromHandle(handle);
-                       hwnd.client_dc.Dispose();
+
+                       Graphics dc = (Graphics)hwnd.drawing_stack.Pop();
+                       dc.Dispose ();
 
                        if (client) {
-                               if (hwnd.user_data != null) {
-                                       ps = (PAINTSTRUCT)hwnd.user_data;
+                               object o = hwnd.drawing_stack.Pop();
+                               if (o != null) {
+                                       PAINTSTRUCT ps = (PAINTSTRUCT)o;
                                        Win32EndPaint(handle, ref ps);
-                                       hwnd.user_data = null;
                                }
                        } else {
-                               if (hwnd.user_data != null) {
-                                       Win32ReleaseDC(handle, (IntPtr)hwnd.user_data);
-                                       hwnd.user_data = null;
-                               }
+                               IntPtr hdc = (IntPtr)hwnd.drawing_stack.Pop();
+                               Win32ReleaseDC(handle, hdc);
                        }
                }
 
@@ -1228,6 +1354,7 @@ namespace System.Windows.Forms {
                }
 
                internal override void GetWindowPos(IntPtr handle, bool is_toplevel, out int x, out int y, out int width, out int height, out int client_width, out int client_height) {
+                       IntPtr  parent;
                        RECT    rect;
                        POINT   pt;
 
@@ -1237,7 +1364,10 @@ namespace System.Windows.Forms {
 
                        pt.x=rect.left;
                        pt.y=rect.top;
-                       Win32ScreenToClient(Win32GetParent(handle), ref pt);
+
+                       parent = Win32GetParent(handle);
+                       Win32ScreenToClient(parent, ref pt);
+
                        x = pt.x;
                        y = pt.y;
 
@@ -1261,6 +1391,20 @@ namespace System.Windows.Forms {
                        Win32InvalidateRect(handle, ref rect, clear);
                }
 
+
+               internal override void InvalidateNC (IntPtr handle)
+               {
+                       // found this gem at
+                       // http://www.dotnet247.com/247reference/msgs/58/292037.aspx
+                       Win32SetWindowPos(handle, IntPtr.Zero,
+                                         0, 0, 0, 0,
+                                         SetWindowPosFlags.SWP_NOMOVE |
+                                         SetWindowPosFlags.SWP_NOSIZE |
+                                         SetWindowPosFlags.SWP_NOZORDER |
+                                         SetWindowPosFlags.SWP_NOACTIVATE |
+                                         SetWindowPosFlags.SWP_DRAWFRAME);
+               }
+
                internal override IntPtr DefWndProc(ref Message msg) {
                        msg.Result=Win32DefWindowProc(msg.HWnd, (Msg)msg.Msg, msg.WParam, msg.LParam);
                        return msg.Result;
@@ -1285,7 +1429,7 @@ namespace System.Windows.Forms {
                        }
                }
 
-               internal override bool PeekMessage(ref MSG msg, IntPtr hWnd, int wFilterMin, int wFilterMax, uint flags) {
+               internal override bool PeekMessage(Object queue_id, ref MSG msg, IntPtr hWnd, int wFilterMin, int wFilterMax, uint flags) {
                        return Win32PeekMessage(ref msg, hWnd, wFilterMin, wFilterMax, flags);
                }
 
@@ -1293,7 +1437,46 @@ namespace System.Windows.Forms {
                        Win32PostQuitMessage(exitCode);
                }
 
-               internal override bool GetMessage(ref MSG msg, IntPtr hWnd, int wFilterMin, int wFilterMax) {
+               internal override void RequestAdditionalWM_NCMessages(IntPtr hwnd, bool hover, bool leave)
+               {
+                       if (wm_nc_registered == null)
+                               wm_nc_registered = new Hashtable ();
+                               
+                       TMEFlags flags = TMEFlags.TME_NONCLIENT;
+                       if (hover)
+                               flags |= TMEFlags.TME_HOVER;
+                       if (leave)
+                               flags |= TMEFlags.TME_LEAVE;
+
+                       if (flags == TMEFlags.TME_NONCLIENT) {
+                               if (wm_nc_registered.Contains (hwnd)) {
+                                       wm_nc_registered.Remove (hwnd);
+                               }
+                       } else {
+                               if (!wm_nc_registered.Contains (hwnd)) {
+                                       wm_nc_registered.Add (hwnd, flags);
+                               } else {
+                                       wm_nc_registered [hwnd] = flags;
+                               }
+                       }
+               }
+
+               internal override void RequestNCRecalc(IntPtr handle) {
+                       Win32SetWindowPos(handle, IntPtr.Zero, 0, 0, 0, 0, SetWindowPosFlags.SWP_FRAMECHANGED | SetWindowPosFlags.SWP_NOOWNERZORDER | SetWindowPosFlags.SWP_NOSIZE | SetWindowPosFlags.SWP_NOMOVE);
+               }
+
+               internal override void ResetMouseHover(IntPtr handle) {
+                       TRACKMOUSEEVENT tme;
+
+                       tme = new TRACKMOUSEEVENT();
+                       tme.size = Marshal.SizeOf(tme);
+                       tme.hWnd = handle;
+                       tme.dwFlags = TMEFlags.TME_LEAVE | TMEFlags.TME_HOVER;
+                       Win32TrackMouseEvent(ref tme);
+               }
+
+
+               internal override bool GetMessage(Object queue_id, ref MSG msg, IntPtr hWnd, int wFilterMin, int wFilterMax) {
                        return GetMessage(ref msg, hWnd, wFilterMin, wFilterMax, true);
                }
 
@@ -1372,6 +1555,20 @@ namespace System.Windows.Forms {
                                        break;
                                }
 
+                               case Msg.WM_NCMOUSEMOVE: {
+                                       if (wm_nc_registered == null || !wm_nc_registered.Contains (msg.hwnd))
+                                               break;
+                                               
+                                       TRACKMOUSEEVENT tme;
+
+                                       tme = new TRACKMOUSEEVENT ();
+                                       tme.size = Marshal.SizeOf(tme);
+                                       tme.hWnd = msg.hwnd;
+                                       tme.dwFlags = (TMEFlags)wm_nc_registered[msg.hwnd];
+                                       Win32TrackMouseEvent (ref tme);
+                                       return result;
+                               }
+
                                case Msg.WM_DROPFILES: {
                                        return Win32DnD.HandleWMDropFiles(ref msg);
                                }
@@ -1440,22 +1637,34 @@ namespace System.Windows.Forms {
                        return true;
                }
 
-               internal override bool SetVisible(IntPtr handle, bool visible) {
+               internal override bool SetVisible (IntPtr handle, bool visible, bool activate)
+               {
                        if (visible) {
-                               if (Control.FromHandle(handle) is Form) {
+                               if (Control.FromHandle (handle) is Form) {
                                        Form f;
 
-                                       f = (Form)Control.FromHandle(handle);
+                                       f = (Form)Control.FromHandle (handle);
+                                       WindowPlacementFlags flags = WindowPlacementFlags.SW_SHOWNORMAL;
                                        switch (f.WindowState) {
-                                               case FormWindowState.Normal:    Win32ShowWindow(handle, WindowPlacementFlags.SW_SHOWNORMAL); break;
-                                               case FormWindowState.Minimized: Win32ShowWindow(handle, WindowPlacementFlags.SW_MINIMIZE); break;
-                                               case FormWindowState.Maximized: Win32ShowWindow(handle, WindowPlacementFlags.SW_MAXIMIZE); break;
+                                               case FormWindowState.Normal: flags = WindowPlacementFlags.SW_SHOWNORMAL; break;
+                                               case FormWindowState.Minimized: flags = WindowPlacementFlags.SW_MINIMIZE; break;
+                                               case FormWindowState.Maximized: flags = WindowPlacementFlags.SW_MAXIMIZE; break;
                                        }
-                               } else {
-                                       Win32ShowWindow(handle, WindowPlacementFlags.SW_SHOWNORMAL);
+                                       
+                                       if (Hwnd.ObjectFromHandle (handle).no_activate)
+                                               flags |= WindowPlacementFlags.SW_SHOWNOACTIVATE;
+                                               
+                                       Win32ShowWindow (handle, flags);
+                               }
+                               else {
+                                       if (Hwnd.ObjectFromHandle (handle).no_activate)
+                                               Win32ShowWindow (handle, WindowPlacementFlags.SW_SHOWNOACTIVATE);
+                                       else
+                                               Win32ShowWindow (handle, WindowPlacementFlags.SW_SHOWNORMAL);
                                }
-                       } else {
-                               Win32ShowWindow(handle, WindowPlacementFlags.SW_HIDE);
+                       }
+                       else {
+                               Win32ShowWindow (handle, WindowPlacementFlags.SW_HIDE);
                        }
                        return true;
                }
@@ -1469,9 +1678,22 @@ namespace System.Windows.Forms {
                }
 
                internal override IntPtr SetParent(IntPtr handle, IntPtr parent) {
-                       return Win32SetParent(handle, parent);
+                       Control c = Control.FromHandle (handle);
+                       if (parent == IntPtr.Zero) {
+                               if (!(c is Form)) {
+                                       Win32ShowWindow(handle, WindowPlacementFlags.SW_HIDE);
+                               }
+                       }
+                       else
+                               SetVisible (handle, c.is_visible, true);
+                               
+                       if (parent == IntPtr.Zero)
+                               return Win32SetParent (handle, FosterParent);
+                       else
+                               return Win32SetParent(handle, parent);
                }
 
+               // If we ever start using this, we should probably replace FosterParent with IntPtr.Zero
                internal override IntPtr GetParent(IntPtr handle) {
                        return Win32GetParent(handle);
                }
@@ -1492,7 +1714,7 @@ namespace System.Windows.Forms {
                        grab_hwnd = IntPtr.Zero;
                }
 
-               internal override bool CalculateWindowRect(IntPtr hWnd, ref Rectangle ClientRect, int Style, int ExStyle, Menu menu, out Rectangle WindowRect) {
+               internal override bool CalculateWindowRect(ref Rectangle ClientRect, int Style, int ExStyle, Menu menu, out Rectangle WindowRect) {
                        RECT    rect;
 
                        rect.left=ClientRect.Left;
@@ -1611,13 +1833,30 @@ namespace System.Windows.Forms {
 
                [MonoTODO]
                internal override void GetCursorInfo(IntPtr cursor, out int width, out int height, out int hotspot_x, out int hotspot_y) {
-                       throw new NotImplementedException ();
+                       width = 20;
+                       height = 20;
+                       hotspot_x = 0;
+                       hotspot_y = 0;
                }
 
                internal override void SetCursorPos(IntPtr handle, int x, int y) {
                        Win32SetCursorPos(x, y);
                }
 
+               internal override Region GetClipRegion(IntPtr hwnd) {
+                       Region region;
+
+                       region = new Region();
+
+                       Win32GetWindowRgn(hwnd, region.GetHrgn(Graphics.FromHwnd(hwnd)));
+
+                       return region;
+               }
+
+               internal override void SetClipRegion(IntPtr hwnd, Region region) {
+                       Win32SetWindowRgn(hwnd, region.GetHrgn(Graphics.FromHwnd(hwnd)), true);
+               }
+
                internal override void EnableWindow(IntPtr handle, bool Enable) {
                        Win32EnableWindow(handle, Enable);
                }
@@ -1626,8 +1865,8 @@ namespace System.Windows.Forms {
                        // Nothing to do
                }
 
-               internal override void StartLoop(System.Threading.Thread thread) {
-                       // Nothing to do
+               internal override object StartLoop(System.Threading.Thread thread) {
+                       return null;
                }
 
                internal override void SetModal(IntPtr handle, bool Modal) {
@@ -1725,8 +1964,15 @@ namespace System.Windows.Forms {
                        Console.WriteLine("CaretCallback hit");
                }
 
+               private void SetMdiStyles (CreateParams cp)
+               {
+                       cp.Style = (int)WindowStyles.WS_CHILD | (int)WindowStyles.WS_CLIPCHILDREN | (int)WindowStyles.WS_CLIPSIBLINGS;
+                       cp.ExStyle = 0;
+               }
+       
                internal override void CreateCaret(IntPtr hwnd, int width, int height) {
                        Win32CreateCaret(hwnd, IntPtr.Zero, width, height);
+                       caret_visible = false;
                }
 
                internal override void DestroyCaret(IntPtr hwnd) {
@@ -1739,12 +1985,22 @@ namespace System.Windows.Forms {
 
                internal override void CaretVisible(IntPtr hwnd, bool visible) {
                        if (visible) {
-                               Win32ShowCaret(hwnd);
+                               if (!caret_visible) {
+                                       Win32ShowCaret(hwnd);
+                                       caret_visible = true;
+                               }
                        } else {
-                               Win32HideCaret(hwnd);
+                               if (caret_visible) {
+                                       Win32HideCaret(hwnd);
+                                       caret_visible = false;
+                               }
                        }
                }
 
+               internal override IntPtr GetFocus() {
+                       return Win32GetFocus();
+               }
+
                internal override void SetFocus(IntPtr hwnd) {
                        Win32SetFocus(hwnd);
                }
@@ -1784,7 +2040,7 @@ namespace System.Windows.Forms {
                        rect.right = rectangle.Right;
                        rect.bottom = rectangle.Bottom;
 
-                       Win32ScrollWindowEx(hwnd, XAmount, YAmount, ref rect, ref rect, IntPtr.Zero, IntPtr.Zero, ScrollWindowExFlags.SW_INVALIDATE | ScrollWindowExFlags.SW_ERASE | (with_children ? ScrollWindowExFlags.SW_SCROLLCHILDREN : ScrollWindowExFlags.SW_NONE));
+                       Win32ScrollWindowEx(hwnd, XAmount, YAmount, IntPtr.Zero, ref rect, IntPtr.Zero, IntPtr.Zero, ScrollWindowExFlags.SW_INVALIDATE | ScrollWindowExFlags.SW_ERASE | (with_children ? ScrollWindowExFlags.SW_SCROLLCHILDREN : ScrollWindowExFlags.SW_NONE));
                        Win32UpdateWindow(hwnd);
                }
 
@@ -1864,22 +2120,23 @@ namespace System.Windows.Forms {
                        style = Win32GetWindowLong(handle, WindowLong.GWL_STYLE);
                        exstyle = Win32GetWindowLong(handle, WindowLong.GWL_EXSTYLE);
 
+
                        switch (border_style) {
                                case FormBorderStyle.None: {
                                        style &= ~(uint)WindowStyles.WS_BORDER;
-                                       exstyle &= ~(uint)WindowStyles.WS_EX_CLIENTEDGE;
+                                       exstyle &= ~(uint)WindowExStyles.WS_EX_CLIENTEDGE;
                                        break;
                                }
 
                                case FormBorderStyle.FixedSingle: {
                                        style |= (uint)WindowStyles.WS_BORDER;
-                                       exstyle &= ~(uint)WindowStyles.WS_EX_CLIENTEDGE;
+                                       exstyle &= ~(uint)WindowExStyles.WS_EX_CLIENTEDGE;
                                        break;
                                }
 
                                case FormBorderStyle.Fixed3D: {
-                                       style |= (uint)WindowStyles.WS_BORDER;
-                                       exstyle |= (uint)WindowStyles.WS_EX_CLIENTEDGE;
+                                       style &= ~(uint)WindowStyles.WS_BORDER;
+                                       exstyle |= (uint)WindowExStyles.WS_EX_CLIENTEDGE;
                                        break;
                                }
                        }
@@ -1888,7 +2145,7 @@ namespace System.Windows.Forms {
                        Win32SetWindowLong(handle, WindowLong.GWL_EXSTYLE, exstyle);
                        
                        Win32SetWindowPos(handle, IntPtr.Zero, 0, 0, 0, 0, 
-                               SetWindowPosFlags.SWP_FRAMECHANGED | SetWindowPosFlags.SWP_NOMOVE | SetWindowPosFlags.SWP_NOSIZE | SetWindowPosFlags.SWP_NOACTIVATE);
+                               SetWindowPosFlags.SWP_FRAMECHANGED | SetWindowPosFlags.SWP_NOMOVE | SetWindowPosFlags.SWP_NOSIZE | SetWindowPosFlags.SWP_NOACTIVATE | SetWindowPosFlags.SWP_NOOWNERZORDER | SetWindowPosFlags.SWP_NOZORDER);
                }
 
                internal override void SetMenu(IntPtr handle, Menu menu) {
@@ -1936,7 +2193,8 @@ namespace System.Windows.Forms {
                        return (int)Win32RegisterClipboardFormat(format);
                }
 
-               internal override IntPtr ClipboardOpen() {
+               internal override IntPtr ClipboardOpen(bool primary_selection) {
+                       // Win32 does not have primary selection
                        Win32OpenClipboard(FosterParent);
                        return clip_magic;
                }
@@ -2127,7 +2385,12 @@ namespace System.Windows.Forms {
                        Win32SetROP2(hdc, ROP2DrawMode.R2_NOT);
                        oldpen = Win32SelectObject(hdc, pen);
 
-                       // We might need to add clipping to the WindowRect of 'handle' - right now we're drawing on the desktop
+                       Control c = Control.FromHandle (handle);
+                       if (c != null) {
+                               Region r = new Region(new Rectangle(c.PointToScreen (c.Location), c.Size));
+
+                               Win32ExtSelectClipRgn(hdc, r.GetHrgn (Graphics.FromHdc (hdc)), (int) ClipCombineMode.RGN_AND);
+                       }
 
                        Win32MoveToEx(hdc, pt.x + rect.Left, pt.y + rect.Top, IntPtr.Zero);
                        if ((rect.Width > 0) && (rect.Height > 0)) {
@@ -2145,6 +2408,9 @@ namespace System.Windows.Forms {
 
                        Win32SelectObject(hdc, oldpen);
                        Win32DeleteObject(pen);
+                       if (c != null)
+                               Win32ExtSelectClipRgn(hdc, IntPtr.Zero, (int) ClipCombineMode.RGN_COPY);
+
                        Win32ReleaseDC(IntPtr.Zero, hdc);
                }
 
@@ -2193,10 +2459,6 @@ namespace System.Windows.Forms {
                
                internal override event EventHandler Idle;
 
-               // Santa's little helper
-               static void Where() {
-                       Console.WriteLine("Here: {0}", new StackTrace().ToString());
-               }
                #endregion      // Public Static Methods
 
                #region Win32 Imports
@@ -2353,6 +2615,9 @@ namespace System.Windows.Forms {
                [DllImport ("user32.dll", EntryPoint="SetLayeredWindowAttributes", CallingConvention=CallingConvention.StdCall)]
                private extern static uint Win32SetLayeredWindowAttributes (IntPtr hwnd, COLORREF crKey, byte bAlpha, LayeredWindowAttributes dwFlags);
 
+               [DllImport ("user32.dll", EntryPoint="GetLayeredWindowAttributes", CallingConvention=CallingConvention.StdCall)]
+               private extern static uint Win32GetLayeredWindowAttributes (IntPtr hwnd, out COLORREF pcrKey, out byte pbAlpha, out LayeredWindowAttributes pwdFlags);
+
                [DllImport ("gdi32.dll", EntryPoint="DeleteObject", CallingConvention=CallingConvention.StdCall)]
                private extern static bool Win32DeleteObject(IntPtr o);
 
@@ -2377,6 +2642,9 @@ namespace System.Windows.Forms {
                [DllImport ("user32.dll", EntryPoint="SetFocus", CallingConvention=CallingConvention.StdCall)]
                internal extern static IntPtr Win32SetFocus(IntPtr hwnd);
 
+               [DllImport ("user32.dll", EntryPoint="GetFocus", CallingConvention=CallingConvention.StdCall)]
+               internal extern static IntPtr Win32GetFocus();
+
                [DllImport ("user32.dll", EntryPoint="CreateCaret", CallingConvention=CallingConvention.StdCall)]
                internal extern static bool Win32CreateCaret(IntPtr hwnd, IntPtr hBitmap, int nWidth, int nHeight);
 
@@ -2405,11 +2673,20 @@ namespace System.Windows.Forms {
                private extern static bool Win32ScrollWindowEx(IntPtr hwnd, int dx, int dy, ref RECT prcScroll, ref RECT prcClip, IntPtr hrgnUpdate, out RECT prcUpdate, ScrollWindowExFlags flags);
 
                [DllImport ("user32.dll", EntryPoint="ScrollWindowEx", CallingConvention=CallingConvention.StdCall)]
-               private extern static bool Win32ScrollWindowEx(IntPtr hwnd, int dx, int dy, ref RECT prcScroll, ref RECT prcClip, IntPtr hrgnUpdate, IntPtr prcUpdate, ScrollWindowExFlags flags);
+               private extern static bool Win32ScrollWindowEx(IntPtr hwnd, int dx, int dy, IntPtr prcScroll, ref RECT prcClip, IntPtr hrgnUpdate, out RECT prcUpdate, ScrollWindowExFlags flags);
+
+               [DllImport ("user32.dll", EntryPoint="ScrollWindowEx", CallingConvention=CallingConvention.StdCall)]
+               private extern static bool Win32ScrollWindowEx(IntPtr hwnd, int dx, int dy, ref RECT prcScroll, IntPtr prcClip, IntPtr hrgnUpdate, out RECT prcUpdate, ScrollWindowExFlags flags);
+
+               [DllImport ("user32.dll", EntryPoint="ScrollWindowEx", CallingConvention=CallingConvention.StdCall)]
+               private extern static bool Win32ScrollWindowEx(IntPtr hwnd, int dx, int dy, IntPtr prcScroll, ref RECT prcClip, IntPtr hrgnUpdate, IntPtr prcUpdate, ScrollWindowExFlags flags);
 
                [DllImport ("user32.dll", EntryPoint="ScrollWindowEx", CallingConvention=CallingConvention.StdCall)]
                private extern static bool Win32ScrollWindowEx(IntPtr hwnd, int dx, int dy, ref RECT prcScroll, IntPtr prcClip, IntPtr hrgnUpdate, IntPtr prcUpdate, ScrollWindowExFlags flags);
 
+               [DllImport ("user32.dll", EntryPoint="ScrollWindowEx", CallingConvention=CallingConvention.StdCall)]
+               private extern static bool Win32ScrollWindowEx(IntPtr hwnd, int dx, int dy, ref RECT prcScroll, ref RECT prcClip, IntPtr hrgnUpdate, IntPtr prcUpdate, ScrollWindowExFlags flags);
+
                [DllImport ("user32.dll", EntryPoint="ScrollWindowEx", CallingConvention=CallingConvention.StdCall)]
                private extern static bool Win32ScrollWindowEx(IntPtr hwnd, int dx, int dy, IntPtr prcScroll, IntPtr prcClip, IntPtr hrgnUpdate, IntPtr prcUpdate, ScrollWindowExFlags flags);
 
@@ -2443,6 +2720,12 @@ namespace System.Windows.Forms {
                [DllImport ("user32.dll", EntryPoint="SystemParametersInfoW", CharSet=CharSet.Unicode, CallingConvention=CallingConvention.StdCall)]
                private extern static bool Win32SystemParametersInfo(SPIAction uiAction, uint uiParam, ref RECT rect, uint fWinIni);
 
+               [DllImport ("user32.dll", EntryPoint="SystemParametersInfoW", CharSet=CharSet.Unicode, CallingConvention=CallingConvention.StdCall)]
+               private extern static bool Win32SystemParametersInfo(SPIAction uiAction, uint uiParam, ref uint value, uint fWinIni);
+
+               [DllImport ("user32.dll", EntryPoint="SystemParametersInfoW", CharSet=CharSet.Unicode, CallingConvention=CallingConvention.StdCall)]
+               private extern static bool Win32SystemParametersInfo(SPIAction uiAction, uint uiParam, ref int value, uint fWinIni);
+
                [DllImport ("user32.dll", EntryPoint="OpenClipboard", CallingConvention=CallingConvention.StdCall)]
                private extern static bool Win32OpenClipboard(IntPtr hwnd);
 
@@ -2509,8 +2792,20 @@ namespace System.Windows.Forms {
                [DllImport ("gdi32.dll", EntryPoint="CreateHatchBrush", CallingConvention=CallingConvention.StdCall)]
                internal extern static IntPtr Win32CreateHatchBrush(HatchStyle fnStyle, ref COLORREF color);
 
+               [DllImport("gdi32.dll", EntryPoint = "ExcludeClipRect", CallingConvention = CallingConvention.StdCall)]
+               internal extern static int Win32ExcludeClipRect (IntPtr hdc, int left, int top,  int right, int bottom);
+
+               [DllImport ("gdi32.dll", EntryPoint="ExtSelectClipRgn", CallingConvention=CallingConvention.StdCall)]
+               internal extern static int Win32ExtSelectClipRgn(IntPtr hdc, IntPtr hrgn, int mode);
+
                [DllImport ("winmm.dll", EntryPoint="PlaySoundW", CallingConvention=CallingConvention.StdCall, CharSet=CharSet.Unicode)]
                internal extern static IntPtr Win32PlaySound(string pszSound, IntPtr hmod, SndFlags fdwSound);
+
+               [DllImport ("user32.dll", EntryPoint="SetWindowRgn", CallingConvention=CallingConvention.StdCall, CharSet=CharSet.Unicode)]
+               internal extern static int Win32SetWindowRgn(IntPtr hWnd, IntPtr hRgn, bool redraw);
+
+               [DllImport ("user32.dll", EntryPoint="GetWindowRgn", CallingConvention=CallingConvention.StdCall, CharSet=CharSet.Unicode)]
+               internal extern static IntPtr Win32GetWindowRgn(IntPtr hWnd, IntPtr hRgn);
                #endregion
        }
 }