Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Windows Forms / Drawing / April 2008

Tip: Looking for answers? Try searching our database.

Bitmap + Clipboard + Transparency = Blue Background?

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
mcse3010 - 11 Apr 2008 17:20 GMT
Hey folks, I think this is my first time asking a question here, so please go
easy on me

I have an application wherein I render a transparent bitmap (to be specific
-- a chart with a transparent background).... When I do, I then try to copy
it to the clipboard using:

bmp.Save(filename); // Save to FS
Clipboard.SetImage(bmp); // Save to Clipboard

Now if I open Excel, and click Paste (from the clipboard), I end up with a
copy of my chart with this lovely blue background wherever the transparency
color was.

If I, instead, use Excel's Insert->Image->From File, the chart's
transparency is preserved... (same bitmap as above, just one is saved to file
system, the other is copied via clipboard)

Am I copying the bitmap to clipboard incorrectly, are transparent bitmaps  
supported cross-application this way? (I suspect they are, because I can copy
that same bitmap in excel (CTRL+C) and paste it into powerpoint without loss
of transparency)

Thanks in Advance!
Bob Powell [MVP] - 11 Apr 2008 18:09 GMT
This is because a saved bitmap has no transparency information as it's 24
bits per pixel. Try copying to the clipboard in a specific format and / or
saving as a PNG that has transparency.

Signature

--
Bob Powell [MVP]
Visual C#, System.Drawing

Ramuseco Limited .NET consulting
http://www.ramuseco.com

Find great Windows Forms articles in Windows Forms Tips and Tricks
http://www.bobpowell.net/tipstricks.htm

Answer those GDI+ questions with the GDI+ FAQ
http://www.bobpowell.net/faqmain.htm

All new articles provide code in C# and VB.NET.
Subscribe to the RSS feeds provided and never miss a new article.

> Hey folks, I think this is my first time asking a question here, so please
> go
[quoted text clipped - 27 lines]
>
> Thanks in Advance!
Bob Powell [MVP] - 11 Apr 2008 18:09 GMT
This is because a saved bitmap has no transparency information as it's 24
bits per pixel. Try copying to the clipboard in a specific format and / or
saving as a PNG that has transparency.

Signature

--
Bob Powell [MVP]
Visual C#, System.Drawing

Ramuseco Limited .NET consulting
http://www.ramuseco.com

Find great Windows Forms articles in Windows Forms Tips and Tricks
http://www.bobpowell.net/tipstricks.htm

Answer those GDI+ questions with the GDI+ FAQ
http://www.bobpowell.net/faqmain.htm

All new articles provide code in C# and VB.NET.
Subscribe to the RSS feeds provided and never miss a new article.

> Hey folks, I think this is my first time asking a question here, so please
> go
[quoted text clipped - 27 lines]
>
> Thanks in Advance!
mcse3010 - 11 Apr 2008 19:51 GMT
The only way I've found to specify a specific format (like PNG) is to save it
physically to disk, and specify the format using the ImageFormat
enumeration.. how would I copy this to the clipboard in PNG format?

TIA
Chadwick

> This is because a saved bitmap has no transparency information as it's 24
> bits per pixel. Try copying to the clipboard in a specific format and / or
[quoted text clipped - 31 lines]
> >
> > Thanks in Advance!
Michael Phillips, Jr. - 11 Apr 2008 20:28 GMT
> how would I copy this to the clipboard in PNG format?

MemoryStream ms = new MemoryStream();
bmp.Save(ms, ImageFormat.Png);
IDataObject dataObject = new DataObject();
dataObject.SetData("PNG", false, ms);
System.Windows.Forms.Clipboard.SetDataObject(dataObject, false);

> The only way I've found to specify a specific format (like PNG) is to save
> it
[quoted text clipped - 45 lines]
>> >
>> > Thanks in Advance!
mcse3010 - 11 Apr 2008 21:20 GMT
FANTASTIC!

Both of you guys have seriously solved a problem that I've had for quite a
while... thank you SO Much!

> > how would I copy this to the clipboard in PNG format?
>
[quoted text clipped - 53 lines]
> >> >
> >> > Thanks in Advance!
mcse3010 - 11 Apr 2008 22:21 GMT
Don't you just hate it when you speak too soon? I should have asked both
questions, instead of assuming the same solution would solve both problems I
had.  

The other issue I had was in attempts to drag and drop the same image I was
copying and pasting before.  Now excel (and powerpoint) recognize the
IDataObject, the drag and drop curiously enough doesn't?

Any pointers on where to look?  I have looked at the IDataObject interface
and searched google, most of what seems relevant is all in unmanaged C++....

TIA

> FANTASTIC!
>
[quoted text clipped - 58 lines]
> > >> >
> > >> > Thanks in Advance!
Michael Phillips, Jr. - 11 Apr 2008 23:09 GMT
The DataObject in .Net implements the IOleDataObject and IDataObject
interfaces.

You can query to see if a particular format is supported by the DataObject
with GetDataPresent and use GetData  to retrieve it.

> Don't you just hate it when you speak too soon? I should have asked both
> questions, instead of assuming the same solution would solve both problems
[quoted text clipped - 84 lines]
>> > >> >
>> > >> > Thanks in Advance!
mcse3010 - 11 Apr 2008 23:25 GMT
Sorry I should have been more clear... I want to drag from a picturebox in
.NET onto Excel and drop the PNG that we generated with the clipboard...
something like:

IDataObject dataObj = CreateDataObjectFromBmp(bmp);
this.DoDragDrop(dataObj, DragDropEffects.All);

but the drop onto excel doesn't work the way the paste did....  I can do the
DoDragDrop on the bmp object, but then I'm back to the blue background on
that...

How can I do the dragdrop while preserving the transparency as with the
clipboard and the DataObject?

Thanks

> The DataObject in .Net implements the IOleDataObject and IDataObject
> interfaces.
[quoted text clipped - 90 lines]
> >> > >> >
> >> > >> > Thanks in Advance!
Michael Phillips, Jr. - 12 Apr 2008 00:34 GMT
> IDataObject dataObj = CreateDataObjectFromBmp(bmp);
> this.DoDragDrop(dataObj, DragDropEffects.All);
[quoted text clipped - 6 lines]
> How can I do the dragdrop while preserving the transparency as with the
> clipboard and the DataObject?

MemoryStream ms = new MemoryStream();
bmp.Save(ms, ImageFormat.Png);
IDataObject dataObject = new DataObject();
dataObject.SetData("PNG", false, ms);
this.DoDragDrop(dataObject, DragDropEffects.All);

Only Office 2007 understands images with transparency.  As long as, you
create a DataObject and place a PNG in it, then Office 2007 will recognize
the "PNG" format and display it with transparency.

I have not tried to drag an alpha channel image out of a picturebox.  It is
possible that it is not supported without extra work.

> Sorry I should have been more clear... I want to drag from a picturebox in
> .NET onto Excel and drop the PNG that we generated with the clipboard...
[quoted text clipped - 120 lines]
>> >> > >> >
>> >> > >> > Thanks in Advance!
mcse3010 - 12 Apr 2008 00:43 GMT
Thanks for the info... for now I will trap the end of the drag drop event,
open the shape using automation and reload the shape from file...

Thanks

> > IDataObject dataObj = CreateDataObjectFromBmp(bmp);
> > this.DoDragDrop(dataObj, DragDropEffects.All);
[quoted text clipped - 144 lines]
> >> >> > >> >
> >> >> > >> > Thanks in Advance!
Christopher Ireland - 14 Apr 2008 10:12 GMT
Hello Michael,

> MemoryStream ms = new MemoryStream();
> bmp.Save(ms, ImageFormat.Png);
> IDataObject dataObject = new DataObject();
> dataObject.SetData("PNG", false, ms);
> this.DoDragDrop(dataObject, DragDropEffects.All);

This code looks great and could be just what I need as well, however, I
can't get it to work as I think it should do. When I copy my bitmap onto the
clipboard, Paint.NET tells me "The clipboard doesn't contain an image". Is
this a bug in Paint.NET ('normal' paint does nothing when the image is
pasted in .. no error message and no image) or is it a problem with my code
below? The file saved to disk in the example, mycontrol.png, looks fine in
Paint.NET with the checker-board transparency color present. Any thoughts
gratefully received!

namespace WindowsFormsApplication1
{
public partial class Form3 : Form
{
 public Form3()
 {
  InitializeComponent();
   InitializeControl();
 }

 private void InitializeControl()
 {
  myControl1 = new MyControl();
  myControl1.Location = new System.Drawing.Point(40, 12);
  myControl1.Size = new System.Drawing.Size(600, 400);
  Controls.Add(myControl1);

  myControl1.BackColor = Color.Transparent;
  myControl1.AString = "My Control";

  myControl1.Save(@"C:\temp\mycontrol.png");
 }

 private MyControl myControl1;

 private void button1_Click(object sender, EventArgs e)
 {
  myControl1.CopyToClipboard();
 }
}

public class MyControl : Control
{
 public MyControl()
  : base()
 {
  SetStyle(ControlStyles.OptimizedDoubleBuffer, false);
  SetStyle(ControlStyles.SupportsTransparentBackColor, true);
 }

 protected override void OnPaint(PaintEventArgs e)
 {
  Rectangle rect = ClientRectangle;
  rect.Inflate(-1, -1);
  e.Graphics.DrawString(AString, new Font("Verdana", 12), Brushes.Black,
new PointF(10, 10));
  e.Graphics.DrawRectangle(Pens.Red, rect);
 }

 public string AString { get; set; }

 public void CopyToClipboard()
 {
  Rectangle rect = ClientRectangle;
  Bitmap b = new Bitmap(rect.Width, rect.Height);
  DrawToBitmap(b, rect);

  MemoryStream ms = new MemoryStream();
  b.Save(ms, Encoder, EncoderParams);
  IDataObject dataObject = new DataObject();
  dataObject.SetData("PNG", false, ms);
  Clipboard.Clear();
  Clipboard.SetDataObject(dataObject, false);
 }

 public void Save(string path)
 {
  Rectangle rect = ClientRectangle;
  Bitmap bmp = new Bitmap(rect.Width, rect.Height);
  DrawToBitmap(bmp, rect);
  bmp.Save(path, Encoder, EncoderParams);
 }

 private ImageCodecInfo Encoder
 {
     get { return GetEncoderInfo(Format.Guid); }
   }

 private ImageFormat Format
 {
  get { return System.Drawing.Imaging.ImageFormat.Png; }
 }

 private ImageCodecInfo GetEncoderInfo(Guid g)
 {
  ImageCodecInfo[] encoders = ImageCodecInfo.GetImageEncoders();
  for (int t = 0; t < encoders.Length; t++)
  {
   if (encoders[t].FormatID == g)
    return encoders[t];
  }
  return null;
 }

 private EncoderParameters EncoderParams
 {
  get { return null; }
 }
}
}

Signature

Thank you,

Christopher Ireland
http://shunyata-kharg.doesntexist.com

"All understanding begins with our not accepting the world as it appears."
Alan C. Kay

Michael Phillips, Jr. - 14 Apr 2008 13:59 GMT
Try using the clipbrd.exe utility that is present in all versions of
Windows.

This clipboard viewer is invaluable for testing your code for compliance
with the clipboard API.

If you see the "PNG" format with this utility, try a paste with Word 2007 or
MS Paint.

I do not know if Paint.Net supports the "PNG" clipboard format.

> Hello Michael,
>
[quoted text clipped - 113 lines]
> }
> }
Christopher Ireland - 14 Apr 2008 14:18 GMT
Michael,

Thank you for your reply!

> Try using the clipbrd.exe utility that is present in all versions of
> Windows.
>
> This clipboard viewer is invaluable for testing your code for
> compliance with the clipboard API.

Using the code I sent in my previous message, clipbrd.exe gave me the
following error:
"ClipBook Viewer cannot display the information in its current format. To
view the information, try pasting it into a document."

> If you see the "PNG" format with this utility, try a paste with Word
> 2007 or MS Paint.

When I mentioned "normal Paint" in my last message, I meant MS Paint. MS
Paint neither gives me an error nor displays the image when I try to paste
the clipboard contents of the code I posted.

> I do not know if Paint.Net supports the "PNG" clipboard format.

No, neither do I!

Signature

Thank you,

Christopher Ireland

Michael Phillips, Jr. - 14 Apr 2008 16:37 GMT
MS Paint does not recognize the "PNG" clipboard format.

However, Office 2007 does regognize the "PNG" clipboard format.

I am able to past the "PNG" clipboard format with no problems.

You can either write code to paste the "PNG" clipboard format into your own
test form or try another application such as Word2007, Excel2007, etc. to
test that you placed the clipboard format on to the clipboard correctly.

> Michael,
>
[quoted text clipped - 21 lines]
>
> No, neither do I!
Christopher Ireland - 14 Apr 2008 16:49 GMT
Michael,

Thanks again for your time!

> MS Paint does not recognize the "PNG" clipboard format.

I see.

> However, Office 2007 does regognize the "PNG" clipboard format.

clipbrd.exe should also recognise the "PNG" clipboard format, even without
Office2007 installed (which is my case here), shouldn't it?

> You can either write code to paste the "PNG" clipboard format into
> your own test form or try another application such as Word2007,
> Excel2007, etc. to test that you placed the clipboard format on to
> the clipboard correctly.

Yes, I did write some code to test which doesn't seem to work here. Would
you be so kind as to test the code at your end? Here it is again (this is
simple, complete code which will run "as-is"):

namespace WindowsFormsApplication1
{
public partial class Form3 : Form
{
 public Form3()
 {
  InitializeComponent();
   InitializeControl();
 }

 private void InitializeControl()
 {
  myControl1 = new MyControl();
  myControl1.Location = new System.Drawing.Point(40, 12);
  myControl1.Size = new System.Drawing.Size(600, 400);
  Controls.Add(myControl1);

  myControl1.BackColor = Color.Transparent;
  myControl1.AString = "My Control";

  myControl1.Save(@"C:\temp\mycontrol.png");
 }

 private MyControl myControl1;

 private void button1_Click(object sender, EventArgs e)
 {
  myControl1.CopyToClipboard();
 }
}

public class MyControl : Control
{
 public MyControl()
  : base()
 {
  SetStyle(ControlStyles.OptimizedDoubleBuffer, false);
  SetStyle(ControlStyles.SupportsTransparentBackColor, true);
 }

 protected override void OnPaint(PaintEventArgs e)
 {
  Rectangle rect = ClientRectangle;
  rect.Inflate(-1, -1);
  e.Graphics.DrawString(AString, new Font("Verdana", 12), Brushes.Black,
new PointF(10, 10));
  e.Graphics.DrawRectangle(Pens.Red, rect);
 }

 public string AString { get; set; }

 public void CopyToClipboard()
 {
  Rectangle rect = ClientRectangle;
  Bitmap b = new Bitmap(rect.Width, rect.Height);
  DrawToBitmap(b, rect);

  MemoryStream ms = new MemoryStream();
  b.Save(ms, Encoder, EncoderParams);
  IDataObject dataObject = new DataObject();
  dataObject.SetData("PNG", false, ms);
  Clipboard.Clear();
  Clipboard.SetDataObject(dataObject, false);
 }

 public void Save(string path)
 {
  Rectangle rect = ClientRectangle;
  Bitmap bmp = new Bitmap(rect.Width, rect.Height);
  DrawToBitmap(bmp, rect);
  bmp.Save(path, Encoder, EncoderParams);
 }

 private ImageCodecInfo Encoder
 {
     get { return GetEncoderInfo(Format.Guid); }
   }

 private ImageFormat Format
 {
  get { return System.Drawing.Imaging.ImageFormat.Png; }
 }

 private ImageCodecInfo GetEncoderInfo(Guid g)
 {
  ImageCodecInfo[] encoders = ImageCodecInfo.GetImageEncoders();
  for (int t = 0; t < encoders.Length; t++)
  {
   if (encoders[t].FormatID == g)
    return encoders[t];
  }
  return null;
 }

 private EncoderParameters EncoderParams
 {
  get { return null; }
 }
}
}

Signature

Thank you,

Christopher Ireland
http://shunyata-kharg.doesntexist.com

"The only good is knowledge and the only evil is ignorance."
Socrates

Michael Phillips, Jr. - 14 Apr 2008 19:19 GMT
Your code works perfectly.

If you wish to verify the image, then paste the image into a PictureBox
control and display it or simply save it to a new file and compare to the
original.

System.Windows.Forms.IDataObject iData = Clipboard.GetDataObject();
if ( null != iData)
{
   if ( iData.GetDataPresent("PNG", false))
  {
       MemoryStream strm = (MemoryStrem)iData.GetData("PNG");
       if ( null != strm)
       {
           // display in a PictureBox control
           PictureBox1.Image = (Bitmap)Image.FromStream(strm,true);
           // and/or save it
           Image image = (Bitmap)Image.FromStream(strm,true);
           image.Save(@"c:\temp\ControlPasteTest.png", ImageFormat.Png);
       }
   }
}

> Michael,
>
[quoted text clipped - 118 lines]
> }
> }
Christopher Ireland - 14 Apr 2008 20:20 GMT
Michael,

> Your code works perfectly.

That's great, thank you for taking the time to test it for me!

> If you wish to verify the image, then paste the image into a
> PictureBox control and display it or simply save it to a new file and
> compare to the original.

Ok, I haven't had a chance to test it here but I'll assume it will work.

Now for the million dollar question (I bet you can see it coming :-) ... do
you know of a way to replicate this functionality in managed code to allow
the clipboard's contents (transparent png) to be pasted into a much wider
range of documents (other than Visual Studio forms and Office2007
documents)?

Signature

Thank you,

Christopher Ireland
http://shunyata-kharg.doesntexist.com

"We confess our little faults to persuade people that we have no large
ones."
Francois de La Rochefoucauld

Michael Phillips, Jr. - 14 Apr 2008 21:47 GMT
> Now for the million dollar question (I bet you can see it coming :-) ...
> do you know of a way to replicate this functionality in managed code to
> allow the clipboard's contents (transparent png) to be pasted into a much
> wider range of documents (other than Visual Studio forms and Office2007
> documents)?

An application chooses which, if any, clipboard formats it wishes to
support.

You do not have any control as to how an application will choose a
particular clipboard format.

The best rule is to place as many formats as you can on the clipboard and
hope that an application will choose one of the formats that you placed on
the clipboard.

I usually place the following .Net clipboard formats on the clipboard:
"Bitmap"
"Palette"
"DeviceIndependentBitmap"
"Format17"
"MetaFilePict"
"EnhancedMetafile"
"PNG"
"JPG"
"TIFF"
"GIF"

Most applications will support one or more of the above clipboard formats.

For transparent images, I use "PNG" and the bitmap varieties.  I
specifically scan the image for the presence of a valid alpha channel.

> Michael,
>
[quoted text clipped - 13 lines]
> wider range of documents (other than Visual Studio forms and Office2007
> documents)?
Christopher Ireland - 15 Apr 2008 08:25 GMT
Michael,

> The best rule is to place as many formats as you can on the clipboard
> and hope that an application will choose one of the formats that you
> placed on the clipboard.

Many thanks for the tip!

> I usually place the following .Net clipboard formats on the clipboard:
> "Bitmap"
[quoted text clipped - 7 lines]
> "TIFF"
> "GIF"

Only five of these (Bitmap, Palette, MetaFilePict, EnhancedMetafile, TIFF)
are in the System.Windows.Forms.DataFormats class. Are all the others new
formats types for Office2007 as well?

> For transparent images, I use "PNG" and the bitmap varieties.  I
> specifically scan the image for the presence of a valid alpha channel.

Presumably you mean that you scan for a valid alpha channel when data (an
image) is pasted into your application from the clipboard, right? Is there a
managed code way of using the Bitmap dataformat to reliably copy transparent
PNG images to the clipboard? Most documents I've had experience with seem to
support the Bitmap dataformat and it would be great to hear that you have
been able to copy and paste transparent PNG images using it with managed
code.

Signature

Thank you,

Christopher Ireland
http://shunyata-kharg.doesntexist.com

"Western science is a major response to minor needs."
Mattheiu Ricard

Michael Phillips, Jr. - 15 Apr 2008 14:41 GMT
> Only five of these (Bitmap, Palette, MetaFilePict, EnhancedMetafile, TIFF)
> are in the System.Windows.Forms.DataFormats class. Are all the others new
> formats types for Office2007 as well?

"DeviceIndependentBitmap" == CF_DIB
"Format17" == CF_DIBV5

The formats below are packed formats using a MemoryStream backed by global
shared memory.
They are not new.  Except for "PNG", they were used in all Microsoft's OS's
prior to WindowsXP.

"PNG"
"JPG"
"JFIF"
"TIFF"
"GIF"

Office2007 recognizes all of the clipboard formats that I outlined.

In addition, Office supports OLE1, OLE2 clipboard formats and proprietary
formats.

If you use the clipboard viewer, you will see all of the clipboard formats
that Office presents to the clipboard.

> Presumably you mean that you scan for a valid alpha channel when data (an
> image) is pasted into your application from the clipboard, right? Is there
[quoted text clipped - 3 lines]
> great to hear that you have been able to copy and paste transparent PNG
> images using it with managed code.

Scanning for an alpha channel is only required for bitmaps.  The gdiplus
decoder will decode an alpha channel "PNG" automatically.

I use the Format17 clipboard format to represent alpha channel bitmaps.

Per the MSDN documentation, the version 5 BITMAPV5HEADER allows you to
specify a valid alpha channel by filling in the bitfield masks and using
BI_BITFIELDS compression.

One painless method of determining a valid alpha channel is to use
Microsoft's IImageList.GetItemFlags method with the ILIF_ALPHA flag.

It only works with Windows XP and above.

You create an image list and add the bitmap that you wish to test to the
list and use the GetItemFlags with ILIF_ALPHA.

If the returned flag is logically "AND" with the ILIF_ALPHA flag then your
bitmap contains a valid alpha channel.

You just declare the COM Interface and use p-invoke with com interop.
Christopher Ireland - 15 Apr 2008 17:33 GMT
Michael,

Thank you for your continuing help. Your patience is much appreciated.

> "DeviceIndependentBitmap" == CF_DIB
> "Format17" == CF_DIBV5

I see.

> They are not new.  Except for "PNG", they were used in all
> Microsoft's OS's prior to WindowsXP.

Ok, thank you for the information.

> Scanning for an alpha channel is only required for bitmaps.  The
> gdiplus decoder will decode an alpha channel "PNG" automatically.

Is "PNG" the only alpha channel that is decoded automatically by gdiplus? I
ask because "JPG" doesn't seem to behave in the same way. In the code below,
uncommenting the png lines and commenting the jpg lines produces the desired
result - an image which pastes to and copies from the clipboard preserving
its transparency. However, leaving the code "as-is" produces an image with
the color black where the color transparent should be.

The other issue is that if, when using the code "as-is" below, I comment out
the code that copies the image from the clipboard to file and instead paste
the image into a Word2003 document, nothing is pasted in (no image is
visualised). Clipbrd.exe tells me "ClipBook Viewer cannot display the
information in its current format. To view the information, try pasting it
into a document." From what you said I had understood that at least this
"JPG" clipboard format should be recognised by pre-Office2007 documents.

namespace WindowsFormsApplication1
{
public partial class Form3 : Form
{
 public Form3()
 {
  InitializeComponent();
  InitializeControl();
 }

 private void InitializeControl()
 {
  myControl1 = new MyControl();
  myControl1.Location = new System.Drawing.Point(40, 12);
  myControl1.Size = new System.Drawing.Size(600, 400);
  Controls.Add(myControl1);

  myControl1.BackColor = Color.Transparent;
  myControl1.AString = "My Control";

  myControl1.CopyToClipboard();

  System.Windows.Forms.IDataObject iData = Clipboard.GetDataObject();
  if (null != iData)
  {
   //if (iData.GetDataPresent("PNG", false))
   if (iData.GetDataPresent("JPG", false))
   {
    //MemoryStream strm = (MemoryStream)iData.GetData("PNG");
    MemoryStream strm = (MemoryStream)iData.GetData("JPG");
    if (null != strm)
    {
     Image image = (Bitmap)Image.FromStream(strm, true);
     //image.Save(@"c:\temp\mycontrol_pasted.png", ImageFormat.Png);
     image.Save(@"c:\temp\mycontrol_pasted.jpg", ImageFormat.Jpeg);
    }
   }
  }
 }
 private MyControl myControl1;
}

public class MyControl : Control
{
 public MyControl()
  : base()
 {
  SetStyle(ControlStyles.OptimizedDoubleBuffer, false);
  SetStyle(ControlStyles.SupportsTransparentBackColor, true);
 }

 protected override void OnPaint(PaintEventArgs e)
 {
  Rectangle rect = ClientRectangle;
  rect.Inflate(-1, -1);
  e.Graphics.DrawString(AString, new Font("Verdana", 12), Brushes.Black,
new PointF(10, 10));
  e.Graphics.DrawRectangle(Pens.Red, rect);
 }

 public string AString { get; set; }

 public void CopyToClipboard()
 {
  Rectangle rect = ClientRectangle;
  Bitmap b = new Bitmap(rect.Width, rect.Height);
  DrawToBitmap(b, rect);

  MemoryStream ms = new MemoryStream();
  b.Save(ms, Encoder, EncoderParams);
  IDataObject dataObject = new DataObject();
  //dataObject.SetData("PNG", false, ms);
  dataObject.SetData("JPG", false, ms);
  Clipboard.Clear();
  Clipboard.SetDataObject(dataObject, false);
 }

 public void Save(string path)
 {
  Rectangle rect = ClientRectangle;
  Bitmap bmp = new Bitmap(rect.Width, rect.Height);
  DrawToBitmap(bmp, rect);
  bmp.Save(path, Encoder, EncoderParams);
 }

 private ImageCodecInfo Encoder
 {
  get { return GetEncoderInfo(Format.Guid); }
 }

 private ImageFormat Format
 {
  //get { return System.Drawing.Imaging.ImageFormat.Png; }
  get { return System.Drawing.Imaging.ImageFormat.Jpeg; }
 }

 private ImageCodecInfo GetEncoderInfo(Guid g)
 {
  ImageCodecInfo[] encoders = ImageCodecInfo.GetImageEncoders();
  for (int t = 0; t < encoders.Length; t++)
  {
   if (encoders[t].FormatID == g)
    return encoders[t];
  }
  return null;
 }

 private EncoderParameters EncoderParams
 {
  get { return null; }
 }
}
}

Signature

Thank you,

Christopher Ireland
http://shunyata-kharg.doesntexist.com

"So little time, so little to do."
Oscar Levant

Michael Phillips, Jr. - 15 Apr 2008 17:57 GMT
> Is "PNG" the only alpha channel that is decoded automatically by gdiplus?
> I ask because "JPG" doesn't seem to behave in the same way. In the code
[quoted text clipped - 3 lines]
> produces an image with the color black where the color transparent should
> be.

Not all of the image formats that are supported by gdiplus allow for alpha
channel images.

For non alpha channel image formats, you should convert the image to a non
alpha channel format before placing it on the clipboard.

For a 32bpp alpha channel image, simply create a new 32bpp
PixelFormat.Format32bppRgb image and fill the new empty image with the
background color of your choice and then use DrawImage with SourceOver to
alpha blend the alpha bitmap with the new non alpha channel bitmap.

The background color that you choose will replace the alpha channel.

For a jpeg image, after converting to a non alpha channel bitmap, create a
24bpp jpeg version by using DrawImage or saving it to a stream with the jpeg
encoder.

When you are finished, place that image on the clipboard.  No more black
backgrounds.

> The other issue is that if, when using the code "as-is" below, I comment
> out the code that copies the image from the clipboard to file and instead
[quoted text clipped - 3 lines]
> into a document." From what you said I had understood that at least this
> "JPG" clipboard format should be recognised by pre-Office2007 documents

Just because the Operating System supports a clipboard format does not mean
that a particular application will use it.

The best way to determine what an application supports is to copy an image
from that application to the clipboard and then examine the supported
clipboard formats with the clipboard viewer utility.
Christopher Ireland - 16 Apr 2008 10:21 GMT
Michael,

Thank you again for your help, Michael. I really feel I'm making progress in
this area thanks to you.

> Not all of the image formats that are supported by gdiplus allow for
> alpha channel images.

I don't suppose you have a list (or a link) to the image formats for which
gdiplus allows alpha channels? From the tests I've made here on the image
formats I'm interested in, PNG, EMF and TIFF save with alpha channels in
tact whereas GIF and JPG do not.

> For non alpha channel image formats, you should convert the image to
> a non alpha channel format before placing it on the clipboard.

Yes, that's pretty straightforward to do.

> Just because the Operating System supports a clipboard format does
> not mean that a particular application will use it.

We are talking about pasting images into documents here, where both the
operating system and the documents are written by the same software company.
I won't labour the point any more than that :-)

> The best way to determine what an application supports is to copy an
> image from that application to the clipboard and then examine the
> supported clipboard formats with the clipboard viewer utility.

Ok, I insert one of the correctly formed transparent PNG images from my
tests into a Word2003 document. The transparency is preserved correctly
within the Word2003 document. I select the image and copy it. The "View"
menu within ClipBook Viewer shows me a long list that includes the "PNG"
format but only the "Enhanced Metafile, Picture, DIB Bitmap and Bitmap"
formats are written in black text. All the other formats, including the
"PNG" format, are written in grey text. I've had a look in the ClipBook
Viewer help file looking for an explanation of these greyed out formats, but
can't find one. Do you have any idea?

I also don't understand why I can copy a transparent PNG, EMF or TIFF file
by selecting it in Windows Explorer and then using Ctrl+C and have it
successfully paste into a Word2003 document with its transparency preserved
but when I use c# to do the same it doesn't work. When I look in ClipBook
Viewer having copied a file from Windows Explorer it tells me that the
format is "Drag-Drop Data", but using DataFormats.FileDrop when I set the
data to the clipboard in c# doesn't work in the same way.

Another difficulty I am experiencing is being able to copy EMF files to the
clipboard at all using c#. I include a full code example below. In the code
below, GetDataPresent returns true but the MemoryStream strm is always
false. I know I am being very demanding on your time and patience, but if
you could take a quick look at the code I would be very grateful.

namespace WindowsFormsApplication1
{
public partial class Form3 : Form
{
 public Form3()
 {
  InitializeComponent();
  this.BackColor = Color.Yellow;
  InitializeControl();
 }

 private void InitializeControl()
 {
  myControl1 = new MyControl();
  myControl1.Location = new System.Drawing.Point(40, 12);
  myControl1.Size = new System.Drawing.Size(600, 400);
  Controls.Add(myControl1);

  myControl1.BackColor = Color.Transparent;
  myControl1.AString = "My Control";

  myControl1.CopyToClipboard();
  myControl1.Save(@"C:\temp\mycontrol.emf");

  System.Windows.Forms.IDataObject iData = Clipboard.GetDataObject();
  if (null != iData)
  {
   if (iData.GetDataPresent(DataFormats.EnhancedMetafile, false))
   {
    MemoryStream strm =
(MemoryStream)iData.GetData(DataFormats.EnhancedMetafile);
    if (null != strm)
    {
     Image image = (Bitmap)Image.FromStream(strm, true);
     image.Save(@"c:\temp\mycontrol_pasted.emf", ImageFormat.Emf);
    }
   }
  }
 }
 private MyControl myControl1;
}

public class MyControl : Control
{
 public MyControl()
  : base()
 {
  SetStyle(ControlStyles.OptimizedDoubleBuffer, false);
  SetStyle(ControlStyles.SupportsTransparentBackColor, true);
 }

 protected override void OnPaint(PaintEventArgs e)
 {
  Draw(e.Graphics);
 }

 public void Draw(Graphics g)
 {
  Rectangle rect = ClientRectangle;
  rect.Inflate(-1, -1);
  g.DrawString(AString, new Font("Verdana", 12), Brushes.Black, new
PointF(10, 10));
  g.DrawRectangle(Pens.Red, rect);
 }

 public Metafile Metafile(Graphics gRef, Stream stream)
 {
  IntPtr hDC = gRef.GetHdc();
  Metafile mf = new System.Drawing.Imaging.Metafile(stream, hDC);
  gRef.ReleaseHdc(hDC);
  gRef.Dispose();

  gRef = Graphics.FromImage(mf);
  try
  {
   Draw(gRef);
  }
  finally
  {
   gRef.Dispose();
  }

  return mf;
 }

 public string AString { get; set; }

 public void CopyToClipboard()
 {
  MemoryStream ms = new MemoryStream();
  Save(ms);

  IDataObject dataObject = new DataObject();
  dataObject.SetData(DataFormats.EnhancedMetafile, false, ms);
  Clipboard.Clear();
  Clipboard.SetDataObject(dataObject, false);
 }

 public void Save(string path)
 {
  FileStream fs = File.Create(path);
  Save(fs);
 }

 public void Save(Stream stream)
 {
  Bitmap bitmap = new Bitmap(1, 1, PixelFormat.Format24bppRgb);
  Graphics gRef = Graphics.FromImage(bitmap);
  Metafile meta = Metafile(gRef, stream);
  stream.Flush();
  stream.Close();
 }

 private ImageCodecInfo Encoder
 {
  get { return GetEncoderInfo(Format.Guid); }
 }

 private ImageFormat Format
 {
  get { return System.Drawing.Imaging.ImageFormat.Emf; }
 }

 private ImageCodecInfo GetEncoderInfo(Guid g)
 {
  ImageCodecInfo[] encoders = ImageCodecInfo.GetImageEncoders();
  for (int t = 0; t < encoders.Length; t++)
  {
   if (encoders[t].FormatID == g)
    return encoders[t];
  }
  return null;
 }

 private EncoderParameters EncoderParams
 {
  get { return null; }
 }
}
}

Signature

Thank you,

Christopher Ireland
http://shunyata-kharg.doesntexist.com

"The ultimate authority must always rest with the individual's own reason
and critical analysis."
Dalai Lama

Michael Phillips, Jr. - 16 Apr 2008 14:18 GMT
> I don't suppose you have a list (or a link) to the image formats for which
> gdiplus allows alpha channels? From the tests I've made here on the image
> formats I'm interested in, PNG, EMF and TIFF save with alpha channels in
> tact whereas GIF and JPG do not.

That pretty much covers it.  You can try the MSDN documentation to get the
official supported pixel formats.

> Ok, I insert one of the correctly formed transparent PNG images from my
> tests into a Word2003 document. The transparency is preserved correctly
[quoted text clipped - 5 lines]
> Viewer help file looking for an explanation of these greyed out formats,
> but can't find one. Do you have any idea?

The clipboard viewer utility is old.  It was never updated to support the
viewing of newer clipboard formats.  That is why you see grayed out
clipboard formats. Nevertheless, the grayed out formats show you what is
supported by the application.

If you check MSDN, you can write your own clipboard viewer that will support
the formats that you need for testing purposes.

> I also don't understand why I can copy a transparent PNG, EMF or TIFF file
> by selecting it in Windows Explorer and then using Ctrl+C and have it
[quoted text clipped - 3 lines]
> that the format is "Drag-Drop Data", but using DataFormats.FileDrop when I
> set the data to the clipboard in c# doesn't work in the same way.

If I understand you correctly, the above operation is a drag and drop of a
image file not a copy and paste of an image.

There are plenty of code examples on MSDN in c# for drag and drop support.

> Another difficulty I am experiencing is being able to copy EMF files to
> the clipboard at all using c#. I include a full code example below. In the
> code below, GetDataPresent returns true but the MemoryStream strm is
> always false. I know I am being very demanding on your time and patience,
> but if you could take a quick look at the code I would be very grateful.

This is a known bug.  The enhanced metafile is not a packed format that can
be passed by a MemoryStream backed by global memory.  You need to pass a
HENHMETAFILE handle using the CF_ENHMETAFILE clipboard format.  You can use
Metafile.GetHenhmetafile().  Pass the handle with P-Invoke SetClipboardData.
Christopher Ireland - 17 Apr 2008 09:12 GMT
Michael,

> That pretty much covers it.  You can try the MSDN documentation to
> get the official supported pixel formats.

Great, thank you!

> The clipboard viewer utility is old.  It was never updated to support
> the viewing of newer clipboard formats.  That is why you see grayed
> out clipboard formats. Nevertheless, the grayed out formats show you
> what is supported by the application.

Mmmm, something here then doesn't add up. Using the code for the PNG format
I posted earlier in this thread, I cannot get the image copied via c# to the
clipboard using the "PNG" format to paste into either a Word2003 nor a
Word2007 document. According to ClipBook Viewer, both these document formats
support "PNG" (although PNG is greyed out in both).

> If I understand you correctly, the above operation is a drag and drop
> of a image file not a copy and paste of an image.

As far as I understand, drag and drop involves the use of the mouse. I
probably didn't explain myself very well, but was I was trying to say was
that I was using the keyboard strokes Ctrl+C on the png image within Windows
Explorer and then Ctrl+V within Word2003.

> This is a known bug.  The enhanced metafile is not a packed format
> that can be passed by a MemoryStream backed by global memory.  You
> need to pass a HENHMETAFILE handle using the CF_ENHMETAFILE clipboard
> format.  You can use Metafile.GetHenhmetafile().  Pass the handle
> with P-Invoke SetClipboardData.

Great, thank you very much, that works perfectly. I include the code below
for completeness:

namespace WindowsFormsApplication1
{
 public partial class Form3 : Form
 {
   public Form3()
   {
     InitializeComponent();
     this.BackColor = Color.Yellow;
     InitializeControl();
   }

   private void InitializeControl()
   {
     myControl1 = new MyControl();
     myControl1.Location = new System.Drawing.Point(40, 12);
     myControl1.Size = new System.Drawing.Size(600, 400);
     Controls.Add(myControl1);

     myControl1.BackColor = Color.Transparent;
     myControl1.AString = "My Control";

     myControl1.CopyToClipboard();
   }
   private MyControl myControl1;
 }

 public class MyControl : Control
 {
   public MyControl()
     : base()
   {
     SetStyle(ControlStyles.OptimizedDoubleBuffer, false);
     SetStyle(ControlStyles.SupportsTransparentBackColor, true);
   }

   protected override void OnPaint(PaintEventArgs e)
   {
     Draw(e.Graphics);
   }

   public void Draw(Graphics g)
   {
     Rectangle rect = ClientRectangle;
     rect.Inflate(-1, -1);
     g.DrawString(AString, new Font("Verdana", 12), Brushes.Black, new
  PointF(10, 10));
     g.DrawRectangle(Pens.Red, rect);
   }

   public Metafile Metafile(Graphics gRef, Stream stream)
   {
     IntPtr hDC = gRef.GetHdc();
     Metafile mf = new System.Drawing.Imaging.Metafile(stream, hDC);
     gRef.ReleaseHdc(hDC);
     gRef.Dispose();

     gRef = Graphics.FromImage(mf);
     try
     {
       Draw(gRef);
     }
     finally
     {
       gRef.Dispose();
     }
     return mf;
   }

   public string AString { get; set; }

   [DllImport("user32.dll")]
   public static extern IntPtr SetClipboardData(uint uFormat, IntPtr hMem);

   [DllImport("user32.dll")]
   public static extern bool OpenClipboard(IntPtr hWndNewOwner);

   [DllImport("user32.dll")]
   public static extern bool CloseClipboard();

   [DllImport("user32.dll")]
   static extern IntPtr GetOpenClipboardWindow();

   public void CopyToClipboard()
   {
     MemoryStream ms = new MemoryStream();
     Metafile meta = Save(ms);
     uint format = 14; //CF_ENHMETAFILE
     IntPtr handleWnd = GetOpenClipboardWindow();
     if (OpenClipboard(handleWnd))
     {
       IntPtr result = SetClipboardData(format, meta.GetHenhmetafile());
       if (result != IntPtr.Zero)
       {
         CloseClipboard();
       }
     }
   }

   public void Save(string path)
   {
     FileStream fs = File.Create(path);
     Save(fs);
   }

   public Metafile Save(Stream stream)
   {
     Bitmap bitmap = new Bitmap(1, 1, PixelFormat.Format24bppRgb);
     Graphics gRef = Graphics.FromImage(bitmap);
     Metafile meta = Metafile(gRef, stream);
     stream.Flush();
     stream.Close();
     return meta;
   }
 }
}

Signature

Thank you,

Christopher Ireland
http://shunyata-kharg.doesntexist.com

"Egotism is the anesthetic that dulls the pain of stupidity."
Frank Leahy

Michael Phillips, Jr. - 17 Apr 2008 14:22 GMT
> Mmmm, something here then doesn't add up. Using the code for the PNG
> format I posted earlier in this thread, I cannot get the image copied via
> c# to the clipboard using the "PNG" format to paste into either a Word2003
> nor a Word2007 document. According to ClipBook Viewer, both these document
> formats support "PNG" (although PNG is greyed out in both).

Your code correctly places the "PNG" clipboard format on to the clipboard.

The clipboard utility verifies this fact.

Office 2003 may not support the "PNG" format.  To test, copy a .png image
from Office 2003 and then check the clipboard viewer to see if you see the
"PNG" clipboard format.  If so, then check your code to see if you can paste
the image.

> As far as I understand, drag and drop involves the use of the mouse. I
> probably didn't explain myself very well, but was I was trying to say was
> that I was using the keyboard strokes Ctrl+C on the png image within
> Windows Explorer and then Ctrl+V within Word2003.

Explorer was designed to use either a mouse or keyboard.

If you check the clipboard utility, then you will see that Ctrl+C is in fact
the same as a drag and drop of an image file.

I am happy to see that you have made progress and that your code is now
working.
Christopher Ireland - 17 Apr 2008 15:52 GMT
Michael,

> Office 2003 may not support the "PNG" format.  To test, copy a .png
> image from Office 2003 and then check the clipboard viewer to see if
> you see the "PNG" clipboard format.

Using code that I have already posted for the creation of a PNG image, I
saved that image to disk and then inserted it into a Word2003 document. I
then selected that image within the word document and did a Ctrl+C -
ClipBook Viewer showed the "PNG" format greyed in the list generated by the
"View" menu.

> If so, then check your code to
> see if you can paste the image.

Again, using the same code I copied the PNG image to the clipboard using the
"PNG" format and tried to paste it into a Word2003 document. The hourglass
cursor appeared momentarily but no image was pasted into the document.

> If you check the clipboard utility, then you will see that Ctrl+C is
> in fact the same as a drag and drop of an image file.

Indeed, as I have already mentioned, the ClipBoard Viewer shows the format
as being "Drag-Drop Data". It seems that this clipboard data format is
capable of preserving the transparency of a PNG file. My question is how to
use the clipboard's "Drag-Drop Data" format in C#, given the lack of success
I've been experiencing with the "PNG" clipboard format.

> I am happy to see that you have made progress and that your code is
> now working.

Yes indeed, so am I. Thank you again for all your help so far!

Signature

Thank you,

Christopher Ireland
http://shunyata-kharg.doesntexist.com

"One man alone can be pretty dumb sometimes, but for real bona fide
stupidity, there ain't nothing can beat teamwork."
Edward Abbey

Michael Phillips, Jr. - 17 Apr 2008 17:42 GMT
> Again, using the same code I copied the PNG image to the clipboard using
> the "PNG" format and tried to paste it into a Word2003 document. The
> hourglass cursor appeared momentarily but no image was pasted into the
> document.

I do not have access to Office 2003.  I am unable to test your scenario.

Try this:
Insert your png into Word2003 and then crl-c to copy to the clipboard.
If the clipboard viewer shows the "PNG" clipboard format, then open Excel
2003 and try to paste the image.
If the "PNG" clipboard format is supported by Office 2003, then the paste
should succeed in any of their applications.

Additionally, you may try to create a test windows form application to test
the pasting of an image from the clipboard and additionally saving it as a
file.

If the test is successfull, then your code supports the copy and pasting of
the "PNG" clipboard format.

As I stated, you have no control whatsoever as to what a third party
application supports for image clipboard formats.

Adobe Photoshop supports their own private clipboard formats and so does
Microsoft.  If your code, works then you are done!

> Michael,
>
[quoted text clipped - 29 lines]
>
> Yes indeed, so am I. Thank you again for all your help so far!
Christopher Ireland - 18 Apr 2008 08:25 GMT
Michael,

> I do not have access to Office 2003.  I am unable to test your
> scenario.

You may be interested in testing the same scenario in Office 2007, if you
have access to it. I just tested it here and again, although ClipBoard
Viewer suggests that the PNG format is supported, PNG images cannot be
pasted into a Word2007 document having been copied to the clipboard using
the PNG format code.

> If the test is successfull, then your code supports the copy and
> pasting of the "PNG" clipboard format.

In my experience, the only application that supports the PNG format is the
one we wrote in C# to support it. My clients are not going to be very
impressed that they cannot paste transparent PNG images into their favourite
applications when the image has been copied to the clipboard using the PNG
format. For practical purposes, then, the PNG format seems somewhat limited,
hence my interest in being able to replicate the "Drag-Drop Data" clipboard
format in C# code, a format that does seem able to maintain PNG transparency
while being support by Office 2003 and 2007 (at least). Do you have any idea
how I can replicate the "Drag-Drop Data" clipboard format in C# code?

Many thanks again for your invaluable help!

Signature

Thank you,

Christopher Ireland
http://shunyata-kharg.doesntexist.com

"You cannot step into the same river twice."
Heraclitus

Michael Phillips, Jr. - 18 Apr 2008 14:40 GMT
> My clients are not going to be very impressed that they cannot paste
> transparent PNG images into their favourite applications when the image
> has been copied to the clipboard using the PNG format.

Adobe Photoshop uses a proprietary clipboard format for copy and paste of
images.

All of the Office 2007 products use proprietary clipboard formats to support
their imaging requirements.

Your clients may not be happy, but you cannot control the software
requirements for third party applications.

If your application supports copy and pasting of alpha channel images, then
that is a plus for your marketing efforts.

> You may be interested in testing the same scenario in Office 2007, if you
> have access to it. I just tested it here and again, although ClipBoard
> Viewer suggests that the PNG format is supported, PNG images cannot be
> pasted into a Word2007 document having been copied to the clipboard using
> the PNG format code.

I used your code to copy a test an alpha channel .png to the clipboard.
I was able to paste the image into Word 2007 and Excel 2007.
The image displayed with transparency.

Additionally, I dragged and dropped an alpha channel .png into Word 2007 and
did a copy to the clipboard.

The following clipboard formats were presented by Word 2007 to the
clipboard:
"Art::GVML ClipFormat"
"Bitmap"
"PNG"
"JFIF"
"GIF"
"EnhancedMetafile"
"MetaFilePict"
"Object Descriptor" ----> "Microsoft Office Word Document"

Only the first clipboard format is proprietary.  "PNG" is supported.

> Do you have any idea how I can replicate the "Drag-Drop Data" clipboard
> format in C# code?

http://support.microsoft.com/kb/307966
http://www.codeproject.com/KB/cs/DragDropImage.aspx
Christopher Ireland - 18 Apr 2008 15:13 GMT
Michael,

> I used your code to copy a test an alpha channel .png to the
> clipboard. I was able to paste the image into Word 2007 and Excel 2007.
> The image displayed with transparency.

That's great! Thank you very much for taking the time! Would you be so kind
as to paste the code you used into your next reply (if you there is one!)
and some indications of the steps you took to use it? It would be fantastic
if I could reproduce the same behaviour on my machine.

> http://support.microsoft.com/kb/307966
> http://www.codeproject.com/KB/cs/DragDropImage.aspx

Thank you for the links, but neither of them make any mention of the
clipboard. The are talking about drag and drop behaviour. I was talking
about the "Drag-Drop Data" format of the clipboard (a format shown by the
ClipBoard Viewer utility on coping (Ctrl+C) and image file from Windows
Explorer).

Signature

Thank you,

Christopher Ireland
http://shunyata-kharg.doesntexist.com

"If you are always busy doing something, you cannot enjoy the world."
Lao Tzu

Michael Phillips, Jr. - 18 Apr 2008 16:32 GMT
I am unable to reply to you latest message so I Hijacked this one!

> Thank you for the links, but neither of them make any mention of the
> clipboard. The are talking about drag and drop behaviour. I was talking
> about the "Drag-Drop Data" format of the clipboard (a format shown by the
> ClipBoard Viewer utility on coping (Ctrl+C) and image file from Windows
> Explorer).

You place an IDataObject on the clipboard.  It is mainly used by Shell
Extensions that add functionality to Explorer.

> That's great! Thank you very much for taking the time! Would you be so
> kind as to paste the code you used into your next reply (if you there is
> one!) and some indications of the steps you took to use it? It would be
> fantastic if I could reproduce the same behaviour on my machine.

Here you go:
1) New Windows Application
2) Add MenuStrip, PictureBox, TextBox and Label
3) Add the following code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Text;
using System.Windows.Forms;

namespace CopyPastePNG
{
   public partial class Form1 : Form
   {
       private Bitmap bm;

       public Form1()
       {
           InitializeComponent();
       }

       private void UpdateFormats()
       {
           textBox1.Clear();

           foreach (string format in
System.Windows.Forms.Clipboard.GetDataObject().GetFormats())
           {
               textBox1.Text += format + "\r" + "\n";
           }

           if (textBox1.Text == "") textBox1.Text = "Clipboard is emtpy";
       }

       private void openToolStripMenuItem_Click(object sender, EventArgs e)
       {
           OpenFileDialog dlgOpen = new OpenFileDialog();

           dlgOpen.Filter = "Bitmap Files (*.bmp)|*.bmp|" +
                            "Png Files (*.png)|*.png|" +
                            "Gif Files (*.gif)|*.gif|" +
                            "Jpeg Files(*.jpg,*.jpeg)|*.jpg;*.jpeg|" +
                            "Tiff Files(*.tif,*.tiff)|*.tif;*.tiff";
           dlgOpen.FilterIndex = 1;
           dlgOpen.ShowReadOnly = true;
           dlgOpen.CheckFileExists = true;

           if (dlgOpen.ShowDialog() == DialogResult.Cancel)
               return;

           string fileName = dlgOpen.FileName;

           if (null != this.bm)
           {
               bm.Dispose();
               this.bm = null;
           }

           using (FileStream fs = new FileStream(fileName, FileMode.Open))
           {
               Cursor oldCursor = Cursor.Current;
               Cursor.Current = Cursors.WaitCursor;

               try
               {
                   this.bm = new Bitmap(fs, false);
                   pictureBox1.Image = this.bm;
               }
               finally
               {
                   Cursor.Current = oldCursor;
               }

               fs.Close();
           }

       }

       private void Form1_Load(object sender, EventArgs e)
       {
           this.bm = null;
       }

       private void Form1_Paint(object sender, PaintEventArgs e)
       {

       }

       private void copyToolStripMenuItem1_Click(object sender, EventArgs
e)
       {
           if (null != this.bm)
           {
               MemoryStream ms = new MemoryStream();
               this.bm.Save(ms, ImageFormat.Png);
               IDataObject dataObject = new DataObject();
               dataObject.SetData("PNG", false, ms);
               System.Windows.Forms.Clipboard.Clear();
               System.Windows.Forms.Clipboard.SetDataObject(dataObject,
false);
           }

           UpdateFormats();
       }

       private void pasteToolStripMenuItem_Click(object sender, EventArgs
e)
       {
           IDataObject idataObj =
System.Windows.Forms.Clipboard.GetDataObject();
           UpdateFormats();
           if (idataObj.GetDataPresent("PNG"))
           {
               MemoryStream ms = (MemoryStream)idataObj.GetData("PNG");

               if (this.bm != null)
               {
                   this.bm.Dispose();
                   this.bm = null;
               }

               this.bm = (Bitmap)Bitmap.FromStream(ms);
               pictureBox1.Image = this.bm;
               pictureBox1.Invalidate();
           }
       }

       private void exitToolStripMenuItem_Click(object sender, EventArgs e)
       {
           Close();
       }

       private void Form1_FormClosed(object sender, FormClosedEventArgs e)
       {
           if (null != this.bm)
               this.bm.Dispose();
       }

       private void Form1_DragEnter(object sender, DragEventArgs e)
       {
           if (e.Data.GetDataPresent(DataFormats.FileDrop))
               e.Effect = DragDropEffects.All;
           else
               e.Effect = DragDropEffects.None;
       }

       private void Form1_DragDrop(object sender, DragEventArgs e)
       {
           string[] s = (string[])e.Data.GetData(DataFormats.FileDrop,
false);

           if (s.Length != 0)
           {
               if (null != this.bm)
               {
                   this.bm.Dispose();
                   this.bm = null;
               }

               using (FileStream fs = new FileStream(s[0], FileMode.Open))
               {
                   Cursor oldCursor = Cursor.Current;
                   Cursor.Current = Cursors.WaitCursor;

                   try
                   {
                       this.bm = new Bitmap(fs, false);
                       pictureBox1.Image = this.bm;
                       pictureBox1.Invalidate();
                   }
                   finally
                   {
                       Cursor.Current = oldCursor;
                   }

                   fs.Close();
               }
           }

       }
   }
}
Christopher Ireland - 24 Apr 2008 09:33 GMT
Michael,

> I am unable to reply to you latest message so I Hijacked this one!

No problem. Sorry for not replying earlier and giving you thanks for your
reply, but I've been out of circulation for a couple of days.

> You place an IDataObject on the clipboard.  It is mainly used by Shell
> Extensions that add functionality to Explorer.

Can you use System.Windows.Forms.ClipBoard.SetDataObject() to put anything
other than an IDataObject on the clipboard? I was hoping to understand which
string, when passed to IDataObject.SetData, represented the "Drag-Drop Data"
type used by Windows Explorer.

> Here you go:
> 1) New Windows Application
> 2) Add MenuStrip, PictureBox, TextBox and Label
> 3) Add the following code:

Thank you very much! This, once again, establishes the fact that the "PNG"
format can be used successfully within Visual Studio. However, using your
code to copy a transparent PNG to the clipboard and then using Ctrl+V to
paste it into a Word2007 still does not work.

Signature

Thank you,

Christopher Ireland
http://shunyata-kharg.doesntexist.com

"If he cannot stop the mind that seeks after fame and profit, he will spend
his life without finding peace."
Shobogenzo Zuimonki

Michael Phillips, Jr. - 24 Apr 2008 14:13 GMT
For some unknown reason, my replies keep on getting rejected.

I will try again.

> Can you use System.Windows.Forms.ClipBoard.SetDataObject() to put anything
> other than an IDataObject on the clipboard?

No.

> I was hoping to understand which string, when passed to
> IDataObject.SetData, represented the "Drag-Drop Data" type used by Windows
> Explorer.

The clipboard format "Drag-Drop Data" is the string that SetData uses but
only before it is registered as a clipboard format for shell Drag and Drop
operations.  MSDN has several articles regarding the shell and Drag and
Drop. Further, Microsoft programmer Raymond Chen has published an extensive
series on this technology at his blog: http://blogs.msdn.com/oldnewthing/.

> However, using your code to copy a transparent PNG to the clipboard and
> then using Ctrl+V to paste it into a Word2007 still does not work.

It works perfectly with my installed Word 2007.  You must "Paste Special"
not use Ctrl+V.

When you "Paste Special", you will see Word display the "PNG" format that
was placed on the clipboard.

It will then paste the image into the document as a PNG decoded bitmap.
Christopher Ireland - 25 Apr 2008 10:13 GMT
Michael,

> For some unknown reason, my replies keep on getting rejected.

Strange. It's certainly not through a lack of wanting to receive them from
my side!

> I will try again.

Thank you!

> The clipboard format "Drag-Drop Data" is the string that SetData uses
> but only before it is registered as a clipboard format for shell Drag
> and Drop operations.  MSDN has several articles regarding the shell
> and Drag and Drop. Further, Microsoft programmer Raymond Chen has
> published an extensive series on this technology at his blog:
> http://blogs.msdn.com/oldnewthing/.

I see. Drag Drop in the context of window's shell operations. It was this
context that I was missing. There are a series of three excellent articles
written in C#, rather than C++, on the subject here:
http://blogs.msdn.com/adamroot/archive/2008/02/01/shell-style-drag-and-drop-in-n
et-wpf-and-winforms.aspx


This is not suitable for me, as it appears that in this instance one of the
interfaces called through Interop is not consistent across all MS platforms
(a different one has to be used under Vista).

> It works perfectly with my installed Word 2007.  You must "Paste
> Special" not use Ctrl+V.

"Paste Special", those were the magic words. Now everything's working fine!

Case closed. Thank you very much once again, Michael, for all of your
patient help!

Signature

Thank you,

Christopher Ireland
http://shunyata-kharg.doesntexist.com

"The greatest obstacle to discovery is not ignorance - it is the illusion of
knowledge."
Daniel J. Boorstin


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.