Taking snapshots for part of a Word document - the new EnhMetaFileBits property

In Word 2003 object model a new property named EnhMetaFileBits for Range and Selection object is introduced. From the documentation, you'd see that it is supposed to help getting the picture representation for a portion of a Word document. Very interesting, isn't it? However the sample included with Word VBA help is too simple to make any real use of it. I searched the web a little and did not find anything helpful. So I decided to try it out myself to see how it works. And the result? Check out this nice little screenshot:


EnhMetaFileBits test screenshot


What I did was to create my favorite "rainbow" WordArt in Word, then use EnhMetaFileBits to get its EMF representation and draw that in the picture box on my windows form. The skeleton of my c# code is as following:


using Office = Microsoft.Office.Core;

using Word = Microsoft.Office.Interop.Word;


object missing = System.Reflection.Missing.Value;


// Get the Graphics object from the picture box

Graphics g = pictureBox1.CreateGraphics();

// Clear the picture box


g.DrawString("Starting Microsoft Word, please wait...",this.Font,new SolidBrush(Color.Black),new PointF(0F,0F));


// Start a new Word instance if necessary

if (wdApp == null)

wdApp = new Word.ApplicationClass();

// Create a new document

Word.Document wdDoc = wdApp.Documents.Add(ref missing, ref missing, ref missing, ref missing);


// Add a WordArt with text from textBox1 to the new document

Word.Shape wdShape = wdDoc.Shapes.AddTextEffect(

    Office.MsoPresetTextEffect.msoTextEffect16, //the rainbow wordart

    this.textBox1.Text, "Arial Black", 16,

    Office.MsoTriState.msoFalse, Office.MsoTriState.msoFalse,

    0, 0, ref missing);

// Select the shape so that EnhMetaFileBits can be retrieved from the Selection object

// This is unnecessary if you have a Range object handy

wdShape.Select(ref missing);


// Create a meta file using the byte array returned from EnhMetaFileBits

byte[] emfData = (byte[])wdApp.Selection.EnhMetaFileBits;

System.IO.MemoryStream ms = new System.IO.MemoryStream(emfData);

Metafile mf = new Metafile(ms);


// Draw the meta file in the picture box


g.DrawImageUnscaled(mf, 0, 0);



As you can see it is pretty easy and straigtforward. However, there is one caveat: the Metafile object created this way may be much wider than it should be: a very big extra white margin may appear to the right. That is why I am using the DrawImageUnscaled method to crop the image. I am still trying to figure out the cause. It might be something I did wrong because I know very little about System.Drawing namespace. Any GDI experts out there care to comment?


The sample VS.Net 2003 solution is available for download here.