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=e0ac8ba11e3e813b5264c3166b54deb2d2762dc6;hpb=c1d1167d02cb27cdb0d101db7ad87411ee881ca0;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 e0ac8ba11e3..efc464d5d12 100644
--- a/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIWin32.cs
+++ b/mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIWin32.cs
@@ -35,6 +35,7 @@ using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
+using System.Threading;
/// Win32 Version
@@ -52,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;
@@ -652,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]
@@ -842,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;
@@ -1188,6 +1187,14 @@ namespace System.Windows.Forms {
}
}
+ public override Size MenuButtonSize {
+ get {
+ return new Size (
+ Win32GetSystemMetrics (SystemMetrics.SM_CXMENUSIZE),
+ Win32GetSystemMetrics (SystemMetrics.SM_CYMENUSIZE));
+ }
+ }
+
internal override int MenuShowDelay {
get { return GetSystemParametersInfoInt (SPIAction.SPI_GETMENUSHOWDELAY); }
}
@@ -1200,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 ();
@@ -1212,7 +1218,6 @@ namespace System.Windows.Forms {
return ps;
}
}
-#endif
internal override int SizingBorderWidth {
get { return Win32GetSystemMetrics (SystemMetrics.SM_CXSIZEFRAME); }
@@ -1505,8 +1510,26 @@ namespace System.Windows.Forms {
return XplatUIWin32.themes_enabled;
}
}
-
+ internal override bool RequiresPositiveClientAreaSize {
+ get {
+ return false;
+ }
+ }
+
+ public override int ToolWindowCaptionHeight {
+ get {
+ return Win32GetSystemMetrics (SystemMetrics.SM_CYSMCAPTION);
+ }
+ }
+
+ public override Size ToolWindowCaptionButtonSize {
+ get {
+ return new Size (
+ Win32GetSystemMetrics (SystemMetrics.SM_CXSMSIZE),
+ Win32GetSystemMetrics (SystemMetrics.SM_CYSMSIZE));
+ }
+ }
#endregion // Static Properties
#region Singleton Specific Code
@@ -1539,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) {
@@ -1585,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;
@@ -1611,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;
@@ -1853,6 +1900,16 @@ namespace System.Windows.Forms {
internal override void Activate(IntPtr handle) {
Win32SetActiveWindow(handle);
+ // delayed timer enabled
+ lock (timer_list) {
+ foreach (Timer t in timer_list.Values) {
+ if (t.Enabled && t.window == IntPtr.Zero) {
+ t.window = handle;
+ int id = t.GetHashCode ();
+ Win32SetTimer(handle, id, (uint)t.Interval, IntPtr.Zero);
+ }
+ }
+ }
}
internal override void Invalidate(IntPtr handle, Rectangle rc, bool clear) {
@@ -1900,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);
}
@@ -2019,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);
@@ -2040,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 ();
@@ -2505,7 +2567,10 @@ namespace System.Windows.Forms {
timer_list[index]=timer;
}
- Win32SetTimer(FosterParent, index, (uint)timer.Interval, IntPtr.Zero);
+ if (Win32SetTimer(FosterParent, index, (uint)timer.Interval, IntPtr.Zero) != IntPtr.Zero)
+ timer.window = FosterParent;
+ else
+ timer.window = IntPtr.Zero;
}
internal override void KillTimer (Timer timer)
@@ -2514,7 +2579,7 @@ namespace System.Windows.Forms {
index = timer.GetHashCode();
- Win32KillTimer(FosterParent, index);
+ Win32KillTimer(timer.window, index);
lock (timer_list) {
timer_list.Remove(index);
@@ -2669,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;
@@ -2687,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
@@ -2700,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);
}
@@ -2836,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");
@@ -2861,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);
@@ -3373,7 +3498,7 @@ namespace System.Windows.Forms {
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);
+ public extern static bool Win32DeleteObject(IntPtr o);
[DllImport ("user32.dll", EntryPoint="GetKeyState", CallingConvention=CallingConvention.StdCall)]
private extern static short Win32GetKeyState(VirtualKeys nVirtKey);