Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>After much gnashing of teeth and pulling of hair, I was able to come up with a workable solution. It seems there is some undocumented strangeness going on under the covers with .NET and its OLE drag and drop support. It appears to be trying to use .NET remoting when performing drag and drop between .NET applications, but is this documented anywhere? No, I don't think it is. </p> <p>So the solution I came up with involves a helper class to help marshal the bitmap data between processes. First, here is the class.</p> <pre><code>[Serializable] public class BitmapTransfer { private byte[] buffer; private PixelFormat pixelFormat; private Size size; private float dpiX; private float dpiY; public BitmapTransfer(Bitmap source) { this.pixelFormat = source.PixelFormat; this.size = source.Size; this.dpiX = source.HorizontalResolution; this.dpiY = source.VerticalResolution; BitmapData bitmapData = source.LockBits( new Rectangle(new Point(0, 0), source.Size), ImageLockMode.ReadOnly, source.PixelFormat); IntPtr ptr = bitmapData.Scan0; int bufferSize = bitmapData.Stride * bitmapData.Height; this.buffer = new byte[bufferSize]; System.Runtime.InteropServices.Marshal.Copy(ptr, buffer, 0, bufferSize); source.UnlockBits(bitmapData); } public Bitmap ToBitmap() { Bitmap bitmap = new Bitmap( this.size.Width, this.size.Height, this.pixelFormat); bitmap.SetResolution(this.dpiX, this.dpiY); BitmapData bitmapData = bitmap.LockBits( new Rectangle(new Point(0, 0), bitmap.Size), ImageLockMode.WriteOnly, bitmap.PixelFormat); IntPtr ptr = bitmapData.Scan0; int bufferSize = bitmapData.Stride * bitmapData.Height; System.Runtime.InteropServices.Marshal.Copy(this.buffer, 0, ptr, bufferSize); bitmap.UnlockBits(bitmapData); return bitmap; } } </code></pre> <p>To use the class in a manner that will support both .NET and unmanaged recipients of the bitmap, a DataObject class is used for the drag and drop operation as follows.</p> <p>To start the drag operation:</p> <pre><code>DataObject dataObject = new DataObject(); dataObject.SetData(typeof(BitmapTransfer), new BitmapTransfer((sender as PictureBox).Image as Bitmap)); dataObject.SetData(DataFormats.Bitmap, (sender as PictureBox).Image as Bitmap); (sender as PictureBox).DoDragDrop(dataObject, DragDropEffects.All); </code></pre> <p>To complete the operation:</p> <pre><code>if (dea.Data.GetDataPresent(typeof(BitmapTransfer))) { BitmapTransfer bitmapTransfer = (BitmapTransfer)dea.Data.GetData(typeof(BitmapTransfer)); (sender as PictureBox).Image = bitmapTransfer.ToBitmap(); } else if(dea.Data.GetDataPresent(DataFormats.Bitmap)) { Bitmap b = (Bitmap)dea.Data.GetData(DataFormats.Bitmap); (sender as PictureBox).Image = b; } </code></pre> <p>The check for the customer BitmapTransfer is performed first so it takes precedence over the existence of a regular Bitmap in the data object. The BitmapTransfer class could be placed in a shared library for use with multiple applications. It must be marked serializable as shown for drag and drop between applications. I tested it with drag and drop of bitmaps within an application, between applications, and from a .NET application to Wordpad.</p> <p>Hope this helps you out.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload