[Mono-winforms-list] [PATCH] System.Windows.Forms.Clipboard improvements

Sergey Volk sergey.volk at gmail.com
Wed May 2 06:13:52 EDT 2007


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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.ximian.com/pipermail/mono-winforms-list/attachments/20070502/78fb518f/attachment.html 
-------------- next part --------------
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;
 				}


More information about the Mono-winforms-list mailing list