Hi, here is a patch, which improves System.Windows.Forms.Clipboard class:
1. It implements static void SetDataObject(object data, bool copy, int
retryTimes, int retryDelay) properly using supplied retryTimes and
retryDelay (got rid of MonoTODO)
2. It changes implementations of SetDataObject(object data),
SetDataObject(object data, bool copy) to behave as described in MSDN
(default parameter values are copy=false, retryTimes=10, retryDelay=100
3. XplatUI.ClipboardStore implementation in drivers should check for errors
and throw ExternalException if necessary
Index: class/Managed.Windows.Forms/System.Windows.Forms/Clipboard.cs
===================================================================
--- class/Managed.Windows.Forms/System.Windows.Forms/Clipboard.cs
(revision 76555)
+++ class/Managed.Windows.Forms/System.Windows.Forms/Clipboard.cs
(working copy)
@@ -200,11 +200,14 @@
#endif
public static void SetDataObject(object data) {
- SetDataObject(data, true);
-
+ SetDataObject(data, false); // MSDN says default
behavior is to place non-persistent data to clipboard
}
public static void SetDataObject(object data, bool copy) {
+ SetDataObject(data, copy, 10, 100); // MSDN says
default behavior is to try 10 times with 100 ms delay
+ }
+
+ internal static void SetDataObjectImpl(object data, bool copy) {
IntPtr clipboard_handle;
XplatUI.ObjectToClipboard converter;
int native_format;
@@ -239,10 +242,13 @@
}
XplatUI.ClipboardClose(clipboard_handle);
}
-
+
#if NET_2_0
- [MonoTODO ("Actually respect retryTimes, retryDelay.")]
- public static void SetDataObject (object data, bool copy, int
retryTimes, int retryDelay)
+ public
+#else
+ internal
+#endif
+ static void SetDataObject(object data, bool copy, int
retryTimes, int retryDelay)
{
if (data == null)
throw new ArgumentNullException("data");
@@ -250,10 +256,26 @@
throw new
ArgumentOutOfRangeException("retryTimes");
if (retryDelay < 0)
throw new
ArgumentOutOfRangeException("retryDelay");
-
- SetDataObject(data, copy);
+
+ // MS implementation actually puts data to clipboard
even when retryTimes == 0
+ bool retry = true;
+ do
+ {
+ retry = false;
+ --retryTimes;
+ try
+ {
+ SetDataObjectImpl(data, copy);
+ } catch (ExternalException) {
+ if (retryTimes <= 0)
+ throw;
+ retry = true;
+ Threading.Thread.Sleep(retryDelay);
+ }
+ } while (retry && retryTimes > 0);
}
+#if NET_2_0
[MonoInternalNote ("Needs additional checks for valid paths,
see MSDN")]
public static void SetFileDropList (StringCollection filePaths)
{
Index: class/Managed.Windows.Forms/System.Windows.Forms/XplatUIWin32.cs
===================================================================
--- class/Managed.Windows.Forms/System.Windows.Forms/XplatUIWin32.cs
(revision 76555)
+++ class/Managed.Windows.Forms/System.Windows.Forms/XplatUIWin32.cs
(working copy)
@@ -2552,7 +2552,8 @@
if (obj == null) {
// Just clear it
- Win32EmptyClipboard();
+ if (!Win32EmptyClipboard())
+ throw new
ExternalException("Win32EmptyClipboard");
return;
}
@@ -2566,18 +2567,21 @@
if (type == DataFormats.GetFormat(DataFormats.Rtf).Id) {
hmem = Marshal.StringToHGlobalAnsi((string)obj);
- Win32SetClipboardData((uint)type, hmem);
+ if (Win32SetClipboardData((uint)type, hmem) ==
IntPtr.Zero )
+ throw new
ExternalException("Win32SetClipboardData");
return;
} else switch((ClipboardFormats)type) {
case ClipboardFormats.CF_UNICODETEXT: {
hmem =
Marshal.StringToHGlobalUni((string)obj);
- Win32SetClipboardData((uint)type, hmem);
+ if (Win32SetClipboardData((uint)type,
hmem) == IntPtr.Zero)
+ throw new
ExternalException("Win32SetClipboardData");
return;
}
case ClipboardFormats.CF_TEXT: {
hmem =
Marshal.StringToHGlobalAnsi((string)obj);
- Win32SetClipboardData((uint)type, hmem);
+ if (Win32SetClipboardData((uint)type,
hmem) == IntPtr.Zero)
+ throw new
ExternalException("Win32SetClipboardData");
return;
}
@@ -2589,7 +2593,8 @@
hmem_ptr = Win32GlobalLock(hmem);
Marshal.Copy(data, 0, hmem_ptr,
data.Length);
Win32GlobalUnlock(hmem);
-
Win32SetClipboardData((uint)ClipboardFormats.CF_DIB, hmem);
+ if
(Win32SetClipboardData((uint)ClipboardFormats.CF_DIB, hmem) == IntPtr.Zero)
+ throw new
ExternalException("Win32SetClipboardData");
return;
}
@@ -2599,7 +2604,8 @@
hmem_ptr =
Win32GlobalLock(hmem);
Marshal.Copy(data, 0, hmem_ptr,
data.Length);
Win32GlobalUnlock(hmem);
-
Win32SetClipboardData((uint)type, hmem);
+ if
(Win32SetClipboardData((uint)type, hmem) == IntPtr.Zero)
+ throw new
ExternalException("Win32SetClipboardData");
}
return;
}
_______________________________________________
Mono-winforms-list maillist - [email protected]
http://lists.ximian.com/mailman/listinfo/mono-winforms-list