Hi,
I have come across some strange behaviour in GDI+ when using Metafiles. The attached
code demonstrates the problem. The drawing code
displays some numbers down the screen. Clicking the button uses the very same drawing
code to copy the image into a metafile and place it
on the clipboard. Now pasting this into Word (using Edit/Paste Special/Picture
(Enhanced Metafile)) produces an image where only 2 of the
numbers are showing!
All the numbers are in the pasted image, as can be seen by choosing "Edit Picture" on
word's context menu. It is just that the original image
does not display them.
The code works fine if you choose StringAlignment.Near
Any help in resolving this would be much appreciated.
regards,
Richard Stratford
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
namespace MetafileBug
{
public class Form1 : System.Windows.Forms.Form
{
[DllImport("user32.dll")]
static extern bool OpenClipboard(IntPtr hWndNewOwner);
[DllImport("user32.dll")]
static extern bool EmptyClipboard();
[DllImport("user32.dll")]
static extern IntPtr SetClipboardData(uint uFormat, IntPtr hMem);
[DllImport("user32.dll")]
static extern bool CloseClipboard();
[DllImport("gdi32.dll")]
static extern IntPtr CopyEnhMetaFile(IntPtr hemfSrc, IntPtr hNULL);
[DllImport("gdi32.dll")]
static extern bool DeleteEnhMetaFile(IntPtr hemf);
private System.Windows.Forms.PictureBox pictureBox1;
private System.Windows.Forms.Button copyButton;
private System.ComponentModel.Container components = null;
public Form1()
{
InitializeComponent();
}
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.pictureBox1 = new System.Windows.Forms.PictureBox();
this.copyButton = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// pictureBox1
//
this.pictureBox1.Dock = System.Windows.Forms.DockStyle.Top;
this.pictureBox1.Location = new System.Drawing.Point(0, 0);
this.pictureBox1.Name = "pictureBox1";
this.pictureBox1.Size = new System.Drawing.Size(376, 344);
this.pictureBox1.TabIndex = 0;
this.pictureBox1.TabStop = false;
this.pictureBox1.Paint += new
System.Windows.Forms.PaintEventHandler(this.pictureBox1_Paint);
//
// copyButton
//
this.copyButton.Anchor =
((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom |
System.Windows.Forms.AnchorStyles.Left)));
this.copyButton.Location = new System.Drawing.Point(16, 360);
this.copyButton.Name = "copyButton";
this.copyButton.Size = new System.Drawing.Size(64, 24);
this.copyButton.TabIndex = 1;
this.copyButton.Text = "Copy";
this.copyButton.Click += new
System.EventHandler(this.copyButton_Click);
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(376, 398);
this.Controls.Add(this.copyButton);
this.Controls.Add(this.pictureBox1);
this.Name = "Form1";
this.Text = "Form1";
this.ResumeLayout(false);
}
#endregion
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
private void copyButton_Click(object sender, System.EventArgs e)
{
System.IO.MemoryStream stream = new System.IO.MemoryStream();
System.Drawing.Imaging.Metafile mf;
Graphics g = this.CreateGraphics();
IntPtr hdc = g.GetHdc();
mf = new System.Drawing.Imaging.Metafile(stream, hdc);
g.ReleaseHdc(hdc);
g.Dispose();
g = Graphics.FromImage(mf);
DrawNumbers(g);
g.Dispose();
PutEnhMetafileOnClipboard(this.Handle, mf);
}
private void pictureBox1_Paint(object sender,
System.Windows.Forms.PaintEventArgs e)
{
DrawNumbers(e.Graphics);
}
void DrawNumbers(Graphics g)
{
Font f = new Font("Arial",8);
StringFormat sf= new StringFormat();
sf.Alignment = StringAlignment.Far;
SolidBrush sb = new SolidBrush(Color.Black);
g.DrawString("11",f,sb,47,7,sf);
g.DrawString("10",f,sb,47,33,sf);
g.DrawString("9",f,sb,47,59,sf);
g.DrawString("8",f,sb,47,86,sf);
g.DrawString("7",f,sb,47,112,sf);
g.DrawString("6",f,sb,47,138,sf);
g.DrawString("5",f,sb,47,165,sf);
g.DrawString("4",f,sb,47,191,sf);
g.DrawString("3",f,sb,47,217,sf);
g.DrawString("2",f,sb,47,244,sf);
g.DrawString("1",f,sb,47,270,sf);
g.DrawString("0",f,sb,47,297,sf);
}
static public bool PutEnhMetafileOnClipboard( IntPtr hWnd, Metafile
mf )
{
bool bResult = false;
IntPtr hEMF, hEMF2;
hEMF = mf.GetHenhmetafile(); // invalidates mf
if( ! hEMF.Equals( new IntPtr(0) ) )
{
hEMF2 = CopyEnhMetaFile( hEMF, new IntPtr(0) );
if( ! hEMF2.Equals( new IntPtr(0) ) )
{
if( OpenClipboard( hWnd ) )
{
if( EmptyClipboard() )
{
IntPtr hRes =
SetClipboardData( 14 /*CF_ENHMETAFILE*/,
hEMF2 );
bResult = hRes.Equals( hEMF2 );
CloseClipboard();
}
}
}
DeleteEnhMetaFile( hEMF );
} return bResult;
}
}
}
---- Message sent via Totalise Webmail - http://www.totalise.co.uk/
===================================
This list is hosted by DevelopMentor� http://www.develop.com
Some .NET courses you may be interested in:
NEW! Guerrilla ASP.NET, 26 Jan 2004, in Los Angeles
http://www.develop.com/courses/gaspdotnetls
View archives and manage your subscription(s) at http://discuss.develop.com