2006-12-01 Chris Toshok <toshok@ximian.com>
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / XplatUIWin32.cs
index 20301cd8403da9c80540a47b16c0ad89a29a03fd..af4ef6bbc03a42658c5f550c57ce76f6f4abc741 100644 (file)
@@ -17,7 +17,7 @@
 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
-// Copyright (c) 2004 Novell, Inc.
+// Copyright (c) 2004-2006 Novell, Inc.
 //
 // Authors:
 //     Peter Bartok    pbartok@novell.com
@@ -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)
                }
@@ -308,9 +320,9 @@ namespace System.Windows.Forms {
                }
 
                internal struct COLORREF {
-                       internal byte                   B;
-                       internal byte                   G;
                        internal byte                   R;
+                       internal byte                   G;
+                       internal byte                   B;
                        internal byte                   A;
                }
 
@@ -334,10 +346,10 @@ namespace System.Windows.Forms {
                        internal int                    tmOverhang;
                        internal int                    tmDigitizedAspectX;
                        internal int                    tmDigitizedAspectY;
-                       internal byte                   tmFirstChar; 
-                       internal byte                   tmLastChar; 
-                       internal byte                   tmDefaultChar; 
-                       internal byte                   tmBreakChar; 
+                       internal short                  tmFirstChar; 
+                       internal short                  tmLastChar; 
+                       internal short                  tmDefaultChar; 
+                       internal short                  tmBreakChar; 
                        internal byte                   tmItalic; 
                        internal byte                   tmUnderlined; 
                        internal byte                   tmStruckOut; 
@@ -509,15 +521,6 @@ namespace System.Windows.Forms {
                        GCL_HICONSM                     = -34
                }
 
-               [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
-               internal struct MINMAXINFO {
-                       internal POINT                  ptReserved;
-                       internal POINT                  ptMaxSize;
-                       internal POINT                  ptMaxPosition;
-                       internal POINT                  ptMinTrackSize;
-                       internal POINT                  ptMaxTrackSize;
-               }
-
                [Flags]
                internal enum GAllocFlags : uint {
                        GMEM_FIXED                      = 0x0000,
@@ -598,6 +601,31 @@ namespace System.Windows.Forms {
                        HS_CROSS                        = 4,
                        HS_DIAGCROSS                    = 5
                }
+
+               [Flags]
+               internal enum SndFlags : int {
+                       SND_SYNC                        = 0x0000,
+                       SND_ASYNC                       = 0x0001,
+                       SND_NODEFAULT                   = 0x0002,
+                       SND_MEMORY                      = 0x0004,
+                       SND_LOOP                        = 0x0008,
+                       SND_NOSTOP                      = 0x0010,
+                       SND_NOWAIT                      = 0x00002000,
+                       SND_ALIAS                       = 0x00010000,
+                       SND_ALIAS_ID                    = 0x00110000,
+                       SND_FILENAME                    = 0x00020000,
+                       SND_RESOURCE                    = 0x00040004,
+                       SND_PURGE                       = 0x0040,
+                       SND_APPLICATION                 = 0x0080,
+               }
+
+               [Flags]
+               internal enum LayeredWindowAttributes : int {
+                       LWA_COLORKEY            = 0x1,
+                       LWA_ALPHA                       = 0x2,
+               }
+
+               
                #endregion
 
                #region Constructor & Destructor
@@ -635,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, 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
@@ -690,65 +721,88 @@ namespace System.Windows.Forms {
                }
 
                internal static Image DIBtoImage(IntPtr dib_data) {
-                       MemoryStream            ms;
-                       byte[]                  header;
-                       byte[]                  buffer;
-                       Bitmap                  bmp;
                        BITMAPINFOHEADER        bmi;
                        int                     ncolors;
-                       int                     palettesize;
                        int                     imagesize;
-                       int                     size;
-                       int                     offset;
-
-                       header = new byte[54];  // Size of a BMP file header, without palette
-                       // Grab the header
-                       header[0] = (byte)'B';
-                       header[1] = (byte)'M';
-                       // 2, 3, 4 and 5 = unsigned int size
-                       // 6, 7, 8 and 9 = reserved
-                       // 10, 11, 12 and 13 = offset to image data
-
-                       // Create a fake BMP header
+                       //int                   palettesize;
+                       Bitmap                  bmp;
+                       BitmapData              bits;
+                       ColorPalette            pal;
+                       int[]                   palette;
+                       byte[]                  imagebits;
+                       int                     bytesPerLine;
+
                        bmi = (BITMAPINFOHEADER)Marshal.PtrToStructure(dib_data, typeof(BITMAPINFOHEADER));
 
                        ncolors = (int)bmi.biClrUsed;
                        if (ncolors == 0) {
-                               if (bmi.biBitCount != 24) {
+                               if (bmi.biBitCount < 24) {
                                        ncolors = (int)(1 << bmi.biBitCount);
                                }
                        }
-                       palettesize = ncolors * 4;
+                       //palettesize = ncolors * 4;
 
                        imagesize = (int)bmi.biSizeImage;
                        if (imagesize == 0) {
                                imagesize = (int)(((((bmi.biWidth * bmi.biBitCount) + 31) & ~31) >> 3) * bmi.biHeight);
                        }
 
-                       size = 54 + palettesize + imagesize;
-                       offset = 54 + palettesize;
-                       buffer = new byte[size];
+                       switch(bmi.biBitCount) {
+                               case 1: {       // Monochrome
+                                       bmp = new Bitmap(bmi.biWidth, bmi.biHeight, PixelFormat.Format1bppIndexed);
+                                       palette = new int[2];
+                                       break;
+                               }
+
+                               case 4: {       // 4bpp
+                                       bmp = new Bitmap(bmi.biWidth, bmi.biHeight, PixelFormat.Format4bppIndexed);
+                                       palette = new int[16];
+                                       break;
+                               }
+
+                               case 8: {       // 8bpp
+                                       bmp = new Bitmap(bmi.biWidth, bmi.biHeight, PixelFormat.Format8bppIndexed);
+                                       palette = new int[256];
+                                       break;
+                               }
+
+                               case 24:
+                               case 32: {      // 32bpp
+                                       bmp = new Bitmap(bmi.biWidth, bmi.biHeight, PixelFormat.Format32bppArgb);
+                                       palette = new int[0];
+                                       break;
+                               }
+
+                               default: {
+                                       throw new Exception("Unexpected number of bits:" + bmi.biBitCount.ToString());
+                               }
+                       }
+
+                       if (bmi.biBitCount < 24) {
+                               pal = bmp.Palette;                              // Managed palette
+                               Marshal.Copy((IntPtr)((int)dib_data + Marshal.SizeOf(typeof(BITMAPINFOHEADER))), palette, 0, palette.Length);
 
-                       // Copy the fake BMP file header
-                       header[2] = (byte)size;
-                       header[3] = (byte)(size >> 8);
-                       header[4] = (byte)(size >> 16);
-                       header[5] = (byte)(size >> 24);
+                               for (int i = 0; i < ncolors; i++) {
+                                       pal.Entries[i] = Color.FromArgb(palette[i] | unchecked((int)0xff000000));
+                               }
+                               bmp.Palette = pal;
+                       }
+
+                       bytesPerLine = (int)((((bmi.biWidth * bmi.biBitCount) + 31) & ~31) >> 3);
+                       bits = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.WriteOnly, bmp.PixelFormat);
 
-                       header[10] = (byte)offset;
-                       header[11] = (byte)(offset >> 8);
-                       header[12] = (byte)(offset >> 16);
-                       header[13] = (byte)(offset >> 24);
+                       imagebits = new byte[bytesPerLine];
 
-                       Array.Copy(header, 0, buffer, 0, 14);
+                       for (int y = 0; y < bmi.biHeight; y++) {
+                               // Copy from source to managed
+                               Marshal.Copy((IntPtr)((int)dib_data + Marshal.SizeOf(typeof(BITMAPINFOHEADER)) + palette.Length * 4 + bytesPerLine * y), imagebits, 0, bytesPerLine);
 
-                       for (int i = 14; i < size; i++) {
-                               buffer[i] = Marshal.ReadByte(dib_data, i - 14);
+                               // Copy from managed to dest
+                               Marshal.Copy(imagebits, 0, (IntPtr)((int)bits.Scan0 + bits.Stride * (bmi.biHeight - 1 - y)), imagebits.Length);
                        }
 
-                       ms = new MemoryStream(buffer, 0, size, false);
-                       bmp = new Bitmap(ms);
-                       ms.Close();
+                       bmp.UnlockBits(bits);
+
                        return bmp;
                }
 
@@ -826,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;
@@ -945,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
@@ -977,8 +1084,8 @@ namespace System.Windows.Forms {
                        Console.WriteLine("Xplat version $revision: $");
                }
 
-               internal override void Exit() {
-                       Win32PostQuitMessage(0);
+               internal override void AudibleAlert() {
+                       Win32PlaySound("Default", IntPtr.Zero, SndFlags.SND_ALIAS | SndFlags.SND_ASYNC | SndFlags.SND_NOSTOP | SndFlags.SND_NOWAIT);
                }
 
                internal override void GetDisplaySize(out Size size) {
@@ -997,7 +1104,6 @@ namespace System.Windows.Forms {
                        IntPtr  WindowHandle;
                        IntPtr  ParentHandle;
                        Hwnd    hwnd;
-                       IntPtr  lParam;
 
                        hwnd = new Hwnd();
 
@@ -1005,21 +1111,22 @@ namespace System.Windows.Forms {
 
                        if ((ParentHandle==IntPtr.Zero) && (cp.Style & (int)(WindowStyles.WS_CHILD))!=0) {
                                // We need to use our foster parent window until this poor child gets it's parent assigned
-                               ParentHandle=FosterParent;
+                               ParentHandle = FosterParent;
                        }
 
-                       lParam = IntPtr.Zero;
-                       if (cp.Param != null && cp.Param is CLIENTCREATESTRUCT) {
-                               lParam = Marshal.AllocHGlobal(Marshal.SizeOf(cp.Param));
-                               Marshal.StructureToPtr(cp.Param, lParam, false);
+                       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;
                        }
 
-                       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, lParam);
-
-                       if (lParam != IntPtr.Zero) {
-                               Marshal.FreeHGlobal(lParam);
+                       // 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) {
                                uint error = Win32GetLastError();
 
@@ -1060,6 +1167,11 @@ namespace System.Windows.Forms {
                        return;
                }
 
+               internal override void SetWindowMinMax(IntPtr handle, Rectangle maximized, Size min, Size max) {
+                       // We do nothing, Form has to handle WM_GETMINMAXINFO
+               }
+
+
                internal override FormWindowState GetWindowState(IntPtr handle) {
                        uint style;
 
@@ -1075,32 +1187,99 @@ namespace System.Windows.Forms {
                internal override void SetWindowState(IntPtr hwnd, FormWindowState state) {
                        switch(state) {
                                case FormWindowState.Normal: {
-                                       Win32ShowWindow(hwnd, WindowPlacementFlags.SW_SHOWNORMAL);
+                                       Win32ShowWindow(hwnd, WindowPlacementFlags.SW_RESTORE);
                                        return;
                                }
 
                                case FormWindowState.Minimized: {
-                                       Win32ShowWindow(hwnd, WindowPlacementFlags.SW_SHOWMINIMIZED);
+                                       Win32ShowWindow(hwnd, WindowPlacementFlags.SW_MINIMIZE);
                                        return;
                                }
 
                                case FormWindowState.Maximized: {
-                                       Win32ShowWindow(hwnd, WindowPlacementFlags.SW_SHOWMAXIMIZED);
+                                       Win32ShowWindow(hwnd, WindowPlacementFlags.SW_MAXIMIZE);
                                        return;
                                }
                        }
                }
 
                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);
+                       COLORREF clrRef = new COLORREF();
+                       if (key != Color.Empty) {
+                               clrRef.R = key.R;
+                               clrRef.G = key.G;
+                               clrRef.B = key.B;
+                               lwa = (LayeredWindowAttributes)( (int)lwa | (int)LayeredWindowAttributes.LWA_COLORKEY );
+                       }
+                       RECT rc;
+                       rc.right = 1000;
+                       rc.bottom = 1000;
+                       Win32SetLayeredWindowAttributes(handle, clrRef, opacity, lwa);
+               }
+
+               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;
@@ -1115,34 +1294,56 @@ namespace System.Windows.Forms {
 
                        hwnd = Hwnd.ObjectFromHandle(handle);
 
-                       if (Win32GetUpdateRect(handle, ref rect, false)) {
-                               hdc = Win32BeginPaint(handle, ref ps);
+                       if (client) {
+                               if (Win32GetUpdateRect(handle, ref rect, false)) {
+                                       hdc = Win32BeginPaint(handle, ref 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.user_data = (object)ps;
+                                       hwnd.drawing_stack.Push (null);
 
-                               clip_rect = new Rectangle(ps.rcPaint.left, ps.rcPaint.top, ps.rcPaint.right-ps.rcPaint.left, ps.rcPaint.bottom-ps.rcPaint.top);
+                                       clip_rect = new Rectangle(rect.top, rect.left, rect.right-rect.left, rect.bottom-rect.top);
+                               }
                        } else {
-                               hdc = Win32GetDC(handle);
-                               // FIXME: Add the DC to internal list
-                               clip_rect = new Rectangle(rect.top, rect.left, rect.right-rect.left, rect.bottom-rect.top);
+                               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();
 
-                       if (hwnd.user_data != null) {
-                               ps = (PAINTSTRUCT)hwnd.user_data;
-                               Win32EndPaint(handle, ref ps);
+                       Graphics dc = (Graphics)hwnd.drawing_stack.Pop();
+                       dc.Dispose ();
+
+                       if (client) {
+                               object o = hwnd.drawing_stack.Pop();
+                               if (o != null) {
+                                       PAINTSTRUCT ps = (PAINTSTRUCT)o;
+                                       Win32EndPaint(handle, ref ps);
+                               }
+                       } else {
+                               IntPtr hdc = (IntPtr)hwnd.drawing_stack.Pop();
+                               Win32ReleaseDC(handle, hdc);
                        }
                }
 
@@ -1153,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;
 
@@ -1162,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;
 
@@ -1186,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;
@@ -1204,26 +1423,78 @@ namespace System.Windows.Forms {
                                Cursor.Current = null;
                        }
 
-                       while (Win32PeekMessage(ref msg, IntPtr.Zero, 0, 0, (uint)PeekMessageFlags.PM_REMOVE)!=true) {
-                               if (msg.message==Msg.WM_PAINT) {
-                                       XplatUI.TranslateMessage(ref msg);
-                                       XplatUI.DispatchMessage(ref msg);
-                               }
+                       while (GetMessage(ref msg, IntPtr.Zero, 0, 0, false)) {
+                               XplatUI.TranslateMessage(ref msg);
+                               XplatUI.DispatchMessage(ref msg);
                        }
                }
 
-               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);
                }
 
-               internal override bool GetMessage(ref MSG msg, IntPtr hWnd, int wFilterMin, int wFilterMax) {
+               internal override void PostQuitMessage(int exitCode) {
+                       Win32PostQuitMessage(exitCode);
+               }
+
+               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);
+               }
+
+               private bool GetMessage(ref MSG msg, IntPtr hWnd, int wFilterMin, int wFilterMax, bool blocking) {
                        bool            result;
 
                        if (RetrieveMessage(ref msg)) {
                                return true;
                        }
 
-                       result = Win32GetMessage(ref msg, hWnd, wFilterMin, wFilterMax);
+                       if (blocking) {
+                               result = Win32GetMessage(ref msg, hWnd, wFilterMin, wFilterMax);
+                       } else {
+                               result = Win32PeekMessage(ref msg, hWnd, wFilterMin, wFilterMax, (uint)PeekMessageFlags.PM_REMOVE);
+                               if (!result) {
+                                       return false;
+                               }
+                       }
 
                        // We need to fake WM_MOUSE_ENTER/WM_MOUSE_LEAVE
                        switch (msg.message) {
@@ -1284,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);
                                }
@@ -1352,23 +1637,63 @@ 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) {
-                               Win32ShowWindow(handle, WindowPlacementFlags.SW_SHOWNORMAL);
-                       } else {
-                               Win32ShowWindow(handle, WindowPlacementFlags.SW_HIDE);
+                               if (Control.FromHandle (handle) is Form) {
+                                       Form f;
+
+                                       f = (Form)Control.FromHandle (handle);
+                                       WindowPlacementFlags flags = WindowPlacementFlags.SW_SHOWNORMAL;
+                                       switch (f.WindowState) {
+                                               case FormWindowState.Normal: flags = WindowPlacementFlags.SW_SHOWNORMAL; break;
+                                               case FormWindowState.Minimized: flags = WindowPlacementFlags.SW_MINIMIZE; break;
+                                               case FormWindowState.Maximized: flags = WindowPlacementFlags.SW_MAXIMIZE; break;
+                                       }
+                                       
+                                       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);
                        }
                        return true;
                }
 
+               internal override bool IsEnabled(IntPtr handle) {
+                       return IsWindowEnabled (handle);
+               }
+               
                internal override bool IsVisible(IntPtr handle) {
                        return IsWindowVisible (handle);
                }
 
                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);
                }
@@ -1389,7 +1714,7 @@ namespace System.Windows.Forms {
                        grab_hwnd = IntPtr.Zero;
                }
 
-               internal override bool CalculateWindowRect(IntPtr hWnd, ref Rectangle ClientRect, int Style, int ExStyle, IntPtr MenuHandle, 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;
@@ -1397,7 +1722,7 @@ namespace System.Windows.Forms {
                        rect.right=ClientRect.Right;
                        rect.bottom=ClientRect.Bottom;
 
-                       if (!Win32AdjustWindowRectEx(ref rect, Style, MenuHandle != IntPtr.Zero, ExStyle)) {
+                       if (!Win32AdjustWindowRectEx(ref rect, Style, menu != null, ExStyle)) {
                                WindowRect = new Rectangle(ClientRect.Left, ClientRect.Top, ClientRect.Width, ClientRect.Height);
                                return false;
                        }
@@ -1508,19 +1833,44 @@ 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);
                }
 
+               internal override void EndLoop(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) {
-                       // we do nothing on Win32; Application.cs simulates modal dialogs by disabling all toplevel windows
+                       // we do nothing on Win32
                }
 
                internal override void GetCursorPos(IntPtr handle, out int x, out int y) {
@@ -1560,14 +1910,24 @@ namespace System.Windows.Forms {
                        y = pnt.y;
                }
 
-               internal override void ScreenToMenu(IntPtr handle, ref int x, ref int y) {
-                       ScreenToClient(handle, ref x, ref y);
-               }
-
-               internal override void MenuToScreen(IntPtr handle, ref int x, ref int y) {                      
-                       ClientToScreen(handle, ref x, ref y);
-               }
-
+               internal override void ScreenToMenu(IntPtr handle, ref int x, ref int y) {
+                       RECT    rect;
+                       Win32GetWindowRect(handle, out rect);
+                       x -= rect.left + SystemInformation.FrameBorderSize.Width;
+                       y -= rect.top + SystemInformation.FrameBorderSize.Height + ThemeEngine.Current.CaptionHeight;
+                       return;
+               }
+  
+               internal override void MenuToScreen(IntPtr handle, ref int x, ref int y) {                      
+                       RECT    rect;
+                       Win32GetWindowRect(handle, out rect);
+                       x += rect.left + SystemInformation.FrameBorderSize.Width;
+                       y += rect.top + SystemInformation.FrameBorderSize.Height + ThemeEngine.Current.CaptionHeight;
+                       return;
+               }
+  
                internal override void SendAsyncMethod (AsyncMethodData method)
                {
                        Win32PostMessage(FosterParent, Msg.WM_ASYNC_MESSAGE, IntPtr.Zero, (IntPtr)GCHandle.Alloc (method));
@@ -1604,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) {
@@ -1618,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);
                }
@@ -1663,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);
                }
 
@@ -1743,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;
+                                       exstyle |= (uint)WindowExStyles.WS_EX_CLIENTEDGE;
                                        break;
                                }
                        }
@@ -1767,39 +2145,19 @@ 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, IntPtr menu_handle) {
+               internal override void SetMenu(IntPtr handle, Menu menu) {
                        // Trigger WM_NCCALC
                        Win32SetWindowPos(handle, IntPtr.Zero, 0, 0, 0, 0, SetWindowPosFlags.SWP_FRAMECHANGED | SetWindowPosFlags.SWP_NOMOVE | SetWindowPosFlags.SWP_NOSIZE);
                }
 
 
-               internal override Graphics GetMenuDC(IntPtr hwnd, IntPtr ncpaint_region) {
-                       IntPtr          hdc;
-                       Graphics        g;
-
-                       // GDI+ Broken:
-                       // hdc = Win32GetDCEx(hwnd, ncpaint_region, DCExFlags.DCX_WINDOW | DCExFlags.DCX_INTERSECTRGN | DCExFlags.DCX_USESTYLE);
-                       hdc = Win32GetDCEx(hwnd, ncpaint_region, DCExFlags.DCX_WINDOW);
-
-                       g = Graphics.FromHdc(hdc);
-
-                       Win32ReleaseDC(hwnd, hdc);
-
-                       return g;
-               }
-
                internal override Point GetMenuOrigin(IntPtr handle) {
                        return new Point(SystemInformation.FrameBorderSize.Width, SystemInformation.FrameBorderSize.Height + ThemeEngine.Current.CaptionHeight);
                }
 
-
-               internal override void ReleaseMenuDC(IntPtr hwnd, Graphics dc) {
-                       dc.Dispose();
-               }
-
                internal override void SetIcon(IntPtr hwnd, Icon icon) {
                        Win32SendMessage(hwnd, Msg.WM_SETICON, (IntPtr)1, icon.Handle); // 1 = large icon (0 would be small)
                }
@@ -1835,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;
                }
@@ -1968,6 +2327,7 @@ namespace System.Windows.Forms {
                                        return;
                                }
 
+                               case ClipboardFormats.CF_BITMAP:
                                case ClipboardFormats.CF_DIB: {
                                        data = ImageToDIB((Image)obj);
 
@@ -1975,7 +2335,7 @@ namespace System.Windows.Forms {
                                        hmem_ptr = Win32GlobalLock(hmem);
                                        Marshal.Copy(data, 0, hmem_ptr, data.Length);
                                        Win32GlobalUnlock(hmem);
-                                       Win32SetClipboardData((uint)type, hmem);
+                                       Win32SetClipboardData((uint)ClipboardFormats.CF_DIB, hmem);
                                        return;
                                }
 
@@ -2025,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)) {
@@ -2043,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);
                }
 
@@ -2058,6 +2426,14 @@ namespace System.Windows.Forms {
                        return new SizeF(width, font.Height);
                }
 
+               internal override IntPtr SendMessage (IntPtr hwnd, Msg message, IntPtr wParam, IntPtr lParam) {
+                       return Win32SendMessage(hwnd, message, wParam, lParam);
+               }
+
+               internal override bool PostMessage (IntPtr hwnd, Msg message, IntPtr wParam, IntPtr lParam) {
+                       return Win32PostMessage(hwnd, message, wParam, lParam);
+               }
+
                internal override int KeyboardSpeed {
                        get {
                                Console.WriteLine ("KeyboardSpeed: need to query Windows");
@@ -2083,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
@@ -2171,6 +2543,9 @@ namespace System.Windows.Forms {
                [DllImport ("user32.dll", EntryPoint="GetDC", CallingConvention=CallingConvention.StdCall)]
                private extern static IntPtr Win32GetDC(IntPtr hWnd);
 
+               [DllImport ("user32.dll", EntryPoint="GetWindowDC", CallingConvention=CallingConvention.StdCall)]
+               private extern static IntPtr Win32GetWindowDC(IntPtr hWnd);
+
                [DllImport ("user32.dll", EntryPoint="GetDCEx", CallingConvention=CallingConvention.StdCall)]
                private extern static IntPtr Win32GetDCEx(IntPtr hWnd, IntPtr hRgn, DCExFlags flags);
 
@@ -2237,12 +2612,15 @@ namespace System.Windows.Forms {
                [DllImport ("user32.dll", EntryPoint="GetWindowLong", CallingConvention=CallingConvention.StdCall)]
                private extern static uint Win32GetWindowLong(IntPtr hwnd, WindowLong index);
 
+               [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);
 
-               [DllImport ("user32.dll", EntryPoint="PostMessage", CallingConvention=CallingConvention.StdCall)]
-               private extern static bool Win32PostMessage(IntPtr hwnd, Msg msg, IntPtr wParam, IntPtr lParam);
-
                [DllImport ("user32.dll", EntryPoint="GetKeyState", CallingConvention=CallingConvention.StdCall)]
                private extern static short Win32GetKeyState(VirtualKeys nVirtKey);
 
@@ -2264,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);
 
@@ -2292,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);
 
@@ -2312,6 +2702,9 @@ namespace System.Windows.Forms {
                [DllImport ("gdi32.dll", EntryPoint="CreateRectRgn", CallingConvention=CallingConvention.StdCall)]
                internal extern static IntPtr Win32CreateRectRgn(int nLeftRect, int nTopRect, int nRightRect, int nBottomRect);
 
+               [DllImport ("user32.dll", EntryPoint="IsWindowEnabled", CallingConvention=CallingConvention.StdCall)]
+               private extern static bool IsWindowEnabled(IntPtr hwnd);
+
                [DllImport ("user32.dll", EntryPoint="IsWindowVisible", CallingConvention=CallingConvention.StdCall)]
                private extern static bool IsWindowVisible(IntPtr hwnd);
 
@@ -2319,11 +2712,20 @@ namespace System.Windows.Forms {
                private extern static bool Win32SetClassLong(IntPtr hwnd, ClassLong nIndex, IntPtr dwNewLong);
 
                [DllImport ("user32.dll", EntryPoint="SendMessageW", CharSet=CharSet.Unicode, CallingConvention=CallingConvention.StdCall)]
-               private extern static bool Win32SendMessage(IntPtr hwnd, Msg msg, IntPtr wParam, IntPtr lParam);
+               private extern static IntPtr Win32SendMessage(IntPtr hwnd, Msg msg, IntPtr wParam, IntPtr lParam);
+
+               [DllImport ("user32.dll", EntryPoint="PostMessageW", CharSet=CharSet.Unicode, CallingConvention=CallingConvention.StdCall)]
+               private extern static bool Win32PostMessage(IntPtr hwnd, Msg msg, IntPtr wParam, IntPtr lParam);
 
                [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);
 
@@ -2389,6 +2791,21 @@ 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
        }
 }