X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fclass%2FManaged.Windows.Forms%2FSystem.Windows.Forms%2FXplatUIWin32.cs;h=efc464d5d124bb11c44f58f23b742727b2c59bac;hb=444495ff9c9f9371046e50a0ac98a822cfae7762;hp=92debd3bce9127df5a6def26766dc5346ee8824b;hpb=b209530f9aeffbaa7063415f0186030b0209c3e7;p=mono.git diff --git a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIWin32.cs b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIWin32.cs index 92debd3bce9..efc464d5d12 100644 --- a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIWin32.cs +++ b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIWin32.cs @@ -53,7 +53,6 @@ namespace System.Windows.Forms { internal static Rectangle grab_area; 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; @@ -653,11 +652,7 @@ namespace System.Windows.Forms { internal int uTimeoutOrVersion; [MarshalAs(UnmanagedType.ByValTStr, SizeConst=64)] internal string szInfoTitle; -#if NET_2_0 internal ToolTipIcon dwInfoFlags; -#else - internal int dwInfoFlags; -#endif } [Flags] @@ -843,6 +838,9 @@ namespace System.Windows.Forms { mouse_state = MouseButtons.None; mouse_position = Point.Empty; + grab_confined = false; + grab_area = Rectangle.Empty; + message_queue = new Queue(); themes_enabled = false; @@ -1209,7 +1207,6 @@ namespace System.Windows.Forms { get { return GetSystemParametersInfoBool (SPIAction.SPI_GETMENUDROPALIGNMENT) == true ? LeftRightAlignment.Left : LeftRightAlignment.Right; } } -#if NET_2_0 internal override PowerStatus PowerStatus { get { SYSTEMPOWERSTATUS p = new SYSTEMPOWERSTATUS (); @@ -1221,7 +1218,6 @@ namespace System.Windows.Forms { return ps; } } -#endif internal override int SizingBorderWidth { get { return Win32GetSystemMetrics (SystemMetrics.SM_CXSIZEFRAME); } @@ -1566,8 +1562,27 @@ namespace System.Windows.Forms { Console.WriteLine("Xplat version $revision: $"); } - internal override void AudibleAlert() { - Win32PlaySound("Default", IntPtr.Zero, SndFlags.SND_ALIAS | SndFlags.SND_ASYNC | SndFlags.SND_NOSTOP | SndFlags.SND_NOWAIT); + string GetSoundAlias (AlertType alert) + { + switch (alert) { + case AlertType.Error: + return "SystemHand"; + case AlertType.Question: + return "SystemQuestion"; + case AlertType.Warning: + return "SystemExclamation"; + case AlertType.Information: + return "SystemAsterisk"; + default: + return "SystemDefault"; + } + } + + internal override void AudibleAlert(AlertType alert) { + Win32PlaySound(GetSoundAlias (alert), IntPtr.Zero, SndFlags.SND_ALIAS_ID | SndFlags.SND_ASYNC | SndFlags.SND_NOSTOP | SndFlags.SND_NOWAIT); + } + + internal override void BeginMoveResize (IntPtr handle) { } internal override void GetDisplaySize(out Size size) { @@ -1612,6 +1627,11 @@ namespace System.Windows.Forms { string class_name = RegisterWindowClass (cp.ClassStyle); HwndCreating = hwnd; + // We cannot actually send the WS_EX_MDICHILD flag to Windows because we + // are faking MDI, not uses Windows' version. + if ((cp.WindowExStyle & WindowExStyles.WS_EX_MDICHILD) == WindowExStyles.WS_EX_MDICHILD) + cp.WindowExStyle ^= WindowExStyles.WS_EX_MDICHILD; + WindowHandle = Win32CreateWindow (cp.WindowExStyle, class_name, cp.Caption, cp.WindowStyle, location.X, location.Y, cp.Width, cp.Height, ParentHandle, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero); HwndCreating = null; @@ -1638,7 +1658,7 @@ namespace System.Windows.Forms { create_params.Width = Width; create_params.Height = Height; - create_params.ClassName=XplatUI.DefaultClassName; + create_params.ClassName=XplatUI.GetDefaultClassName (GetType ()); create_params.ClassStyle = 0; create_params.ExStyle=0; create_params.Parent=IntPtr.Zero; @@ -1937,11 +1957,12 @@ namespace System.Windows.Forms { internal override void DoEvents() { MSG msg = new MSG(); - if (override_cursor != IntPtr.Zero) { - Cursor.Current = null; - } - while (GetMessage(ref msg, IntPtr.Zero, 0, 0, false)) { + Message m = Message.Create (msg.hwnd, (int)msg.message, msg.wParam, msg.lParam); + + if (Application.FilterMessage (ref m)) + continue; + XplatUI.TranslateMessage(ref msg); XplatUI.DispatchMessage(ref msg); } @@ -2056,6 +2077,8 @@ namespace System.Windows.Forms { if (msg.hwnd != prev_mouse_hwnd) { TRACKMOUSEEVENT tme; + mouse_state = Control.FromParamToMouseButtons ((int)msg.lParam.ToInt32()); + // The current message will be sent out next time around StoreMessage(ref msg); @@ -2077,7 +2100,9 @@ namespace System.Windows.Forms { case Msg.WM_NCMOUSEMOVE: { if (wm_nc_registered == null || !wm_nc_registered.Contains (msg.hwnd)) break; - + + mouse_state = Control.FromParamToMouseButtons ((int)msg.lParam.ToInt32 ()); + TRACKMOUSEEVENT tme; tme = new TRACKMOUSEEVENT (); @@ -2542,7 +2567,7 @@ namespace System.Windows.Forms { timer_list[index]=timer; } - if (Win32SetTimer(FosterParent, index, (uint)timer.Interval, IntPtr.Zero) == IntPtr.Zero) + if (Win32SetTimer(FosterParent, index, (uint)timer.Interval, IntPtr.Zero) != IntPtr.Zero) timer.window = FosterParent; else timer.window = IntPtr.Zero; @@ -2709,7 +2734,6 @@ namespace System.Windows.Forms { Win32Shell_NotifyIcon(NotifyIconMessage.NIM_DELETE, ref nid); } -#if NET_2_0 internal override void SystrayBalloon(IntPtr hwnd, int timeout, string title, string text, ToolTipIcon icon) { NOTIFYICONDATA nid; @@ -2727,7 +2751,6 @@ namespace System.Windows.Forms { Win32Shell_NotifyIcon(NotifyIconMessage.NIM_MODIFY, ref nid); } -#endif internal override void SetBorderStyle(IntPtr handle, FormBorderStyle border_style) { // Nothing to do on Win32 @@ -2740,10 +2763,19 @@ namespace System.Windows.Forms { internal override Point GetMenuOrigin(IntPtr handle) { Form form = Control.FromHandle (handle) as Form; + if (form != null) { - Hwnd.Borders borders = Hwnd.GetBorders (form.GetCreateParams (), null); - return new Point(borders.left, borders.top); + if (form.FormBorderStyle == FormBorderStyle.None) + return Point.Empty; + + int bordersize = (form.Width - form.ClientSize.Width) / 2; + + if (form.FormBorderStyle == FormBorderStyle.FixedToolWindow || form.FormBorderStyle == FormBorderStyle.SizableToolWindow) + return new Point (bordersize, bordersize + SystemInformation.ToolWindowCaptionHeight); + else + return new Point (bordersize, bordersize + SystemInformation.CaptionHeight); } + return new Point(SystemInformation.FrameBorderSize.Width, SystemInformation.FrameBorderSize.Height + ThemeEngine.Current.CaptionHeight); } @@ -2876,10 +2908,9 @@ namespace System.Windows.Forms { } - internal override void ClipboardStore(IntPtr handle, object obj, int type, XplatUI.ObjectToClipboard converter) { - byte[] data; - IntPtr hmem; - IntPtr hmem_ptr; + internal override void ClipboardStore(IntPtr handle, object obj, int type, XplatUI.ObjectToClipboard converter, bool copy) + { + byte[] data = null; if (handle != clip_magic) { throw new ArgumentException("handle is not a valid clipboard handle"); @@ -2901,52 +2932,106 @@ namespace System.Windows.Forms { } if (type == DataFormats.GetFormat(DataFormats.Rtf).Id) { - hmem = Marshal.StringToHGlobalAnsi((string)obj); - if (Win32SetClipboardData((uint)type, hmem) == IntPtr.Zero ) - throw new ExternalException("Win32SetClipboardData"); - return; + data = StringToAnsi ((string)obj); } else switch((ClipboardFormats)type) { case ClipboardFormats.CF_UNICODETEXT: { - hmem = Marshal.StringToHGlobalUni((string)obj); - if (Win32SetClipboardData((uint)type, hmem) == IntPtr.Zero) - throw new ExternalException("Win32SetClipboardData"); - return; + data = StringToUnicode ((string)obj); + break; } case ClipboardFormats.CF_TEXT: { - hmem = Marshal.StringToHGlobalAnsi((string)obj); - if (Win32SetClipboardData((uint)type, hmem) == IntPtr.Zero) - throw new ExternalException("Win32SetClipboardData"); - return; + data = StringToAnsi ((string)obj); + break; } case ClipboardFormats.CF_BITMAP: case ClipboardFormats.CF_DIB: { - data = ImageToDIB((Image)obj); - - hmem = Win32GlobalAlloc(GAllocFlags.GMEM_MOVEABLE | GAllocFlags.GMEM_DDESHARE, data.Length); - hmem_ptr = Win32GlobalLock(hmem); - Marshal.Copy(data, 0, hmem_ptr, data.Length); - Win32GlobalUnlock(hmem); - if (Win32SetClipboardData((uint)ClipboardFormats.CF_DIB, hmem) == IntPtr.Zero) - throw new ExternalException("Win32SetClipboardData"); - return; + data = ImageToDIB ((Image)obj); + type = (int)ClipboardFormats.CF_DIB; + break; } default: { - if (converter != null && converter(ref type, obj, out data)) { - hmem = Win32GlobalAlloc(GAllocFlags.GMEM_MOVEABLE | GAllocFlags.GMEM_DDESHARE, data.Length); - hmem_ptr = Win32GlobalLock(hmem); - Marshal.Copy(data, 0, hmem_ptr, data.Length); - Win32GlobalUnlock(hmem); - if (Win32SetClipboardData((uint)type, hmem) == IntPtr.Zero) - throw new ExternalException("Win32SetClipboardData"); + if (converter != null && !converter(ref type, obj, out data)) { + data = null; // ensure that a failed conversion leaves null. } - return; + break; } } + if (data != null) { + SetClipboardData ((uint)type, data); + } + } + + internal static byte[] StringToUnicode (string text) + { + return Encoding.Unicode.GetBytes (text + "\0"); } + internal static byte[] StringToAnsi (string text) + { + // FIXME, follow the behaviour of the previous code using UTF-8, + // but this should be 'ANSI' on Windows, i.e. the current code page. + // Does Encoding.Default work on Windows? + return Encoding.UTF8.GetBytes (text + "\0"); + } + + private void SetClipboardData (uint type, byte[] data) + { + if (data.Length == 0) + // Shouldn't call Win32SetClipboard with NULL, as, from MSDN: + // "This parameter can be NULL, indicating that the window provides data + // in the specified clipboard format (renders the format) upon request." + // and I don't think we support that... + // Note this is unrelated to the fact that passing a null obj to + // ClipboardStore is actually a request to empty the clipboard! + return; + IntPtr hmem = CopyToMoveableMemory (data); + if (hmem == IntPtr.Zero) + // As above, should not call with null. + // (Not that CopyToMoveableMemory should ever return null!) + throw new ExternalException ("CopyToMoveableMemory failed."); + if (Win32SetClipboardData (type, hmem) == IntPtr.Zero) + throw new ExternalException ("Win32SetClipboardData"); + } + + /// + /// Creates a memory block with GlobalAlloc(GMEM_MOVEABLE), copies the data + /// into it, and returns the handle to the memory. + /// + /// - + /// The data. Must not be null or zero-length — + /// see the exception notes. + /// - + /// The *handle* to the allocated GMEM_MOVEABLE block. + /// - + /// The data was null or zero + /// length. This is disallowed since a zero length allocation can't be made + /// + /// The allocation, + /// or locking (handle->pointer) failed. + /// Either out of memory or the handle table is full (256 max currently). + /// Note Win32Exception is a subclass of ExternalException so this is OK in + /// the documented Clipboard interface. + /// + internal static IntPtr CopyToMoveableMemory (byte[] data) + { + if (data == null || data.Length == 0) + // detect this before GlobalAlloc does. + throw new ArgumentException ("Can't create a zero length memory block."); + + IntPtr hmem = Win32GlobalAlloc (GAllocFlags.GMEM_MOVEABLE | GAllocFlags.GMEM_DDESHARE, data.Length); + if (hmem == IntPtr.Zero) + throw new Win32Exception (); + IntPtr hmem_ptr = Win32GlobalLock (hmem); + if (hmem_ptr == IntPtr.Zero) // If the allocation was valid this shouldn't occur. + throw new Win32Exception (); + Marshal.Copy (data, 0, hmem_ptr, data.Length); + Win32GlobalUnlock (hmem); + return hmem; + } + + internal override void SetAllowDrop(IntPtr hwnd, bool allowed) { if (allowed) { Win32DnD.RegisterDropTarget(hwnd);