2007-05-07 Jonathan Pobst <monkey@jpobst.com>
authorJonathan Pobst <monkey@jpobst.com>
Mon, 7 May 2007 20:51:44 +0000 (20:51 -0000)
committerJonathan Pobst <monkey@jpobst.com>
Mon, 7 May 2007 20:51:44 +0000 (20:51 -0000)
Applying contributed patch from Sergey Volk.

* Clipboard.cs: Implement SetDataObject retry logic and new overload
of SetDataObject.
* XplatUIWin32.cs: Throw an ExternalException if the clipboard set fails.

svn path=/trunk/mcs/; revision=76873

mcs/class/Managed.Windows.Forms/System.Windows.Forms/ChangeLog
mcs/class/Managed.Windows.Forms/System.Windows.Forms/Clipboard.cs
mcs/class/Managed.Windows.Forms/System.Windows.Forms/XplatUIWin32.cs

index 7e20b42a5651617fede3b45ab6fed1ee935d6578..fcc747654b03e90d2534316a96d7ce72f4c237ac 100644 (file)
@@ -1,3 +1,10 @@
+2007-05-07  Jonathan Pobst  <monkey@jpobst.com>
+       Applying contributed patch from Sergey Volk.
+
+       * Clipboard.cs: Implement SetDataObject retry logic and new overload
+       of SetDataObject.
+       * XplatUIWin32.cs: Throw an ExternalException if the clipboard set fails.
+
 2007-05-07  Jonathan Pobst  <monkey@jpobst.com>
 
        * Control.cs: Implement DrawToBitmap.
index 2e325514e9588a4769160feca27d6b6576f6dcd9..2c9dabe2d82246b7420dca4f5e043612b442532c 100644 (file)
@@ -200,11 +200,14 @@ namespace System.Windows.Forms {
 #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 @@ namespace System.Windows.Forms {
                        }
                        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 @@ namespace System.Windows.Forms {
                                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 e61f8a7d95e67995582dfd1b7c2bc13f5f1a5e13..031d7bfc4bb367ab20acfbe0a34b5f2a95797a3c 100644 (file)
@@ -2557,7 +2557,8 @@ namespace System.Windows.Forms {
 
                        if (obj == null) {
                                // Just clear it
-                               Win32EmptyClipboard();
+                               if (!Win32EmptyClipboard())
+                                       throw new ExternalException("Win32EmptyClipboard");
                                return;
                        }
 
@@ -2571,18 +2572,21 @@ namespace System.Windows.Forms {
 
                        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;
                                }
 
@@ -2594,7 +2598,8 @@ namespace System.Windows.Forms {
                                        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;
                                }
 
@@ -2604,7 +2609,8 @@ namespace System.Windows.Forms {
                                                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;
                                }