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.
Comments (6)
  1. Michael Joyce says:

    Any possibility of using EnhMetaFileBits from VBA?

    RE: Whitespace

    I think this is a problem with Word itself. Try selecting text & use PasteSpecial to past it as an EMF. There is a lot of whitespace to the right.

  2. CMDev says:

    Is this possible with a aspx page with GDI+


  3. guowu says:

    Michael: you should be able to call GDI related win32 APIs from VBA to manipulate the EMF bits as long as you are good enough with GDI. I can not help you with that though. Also thanks for the comments about extra spaces. I will look into that.

    CMDev: I think it is. But keep in mind that automating Microsoft Word (as well as most other Office client products) from a Web server is not supported by Microsoft.

  4. CMDev says:


    I was wondering because I ran across this website http://www.speedysigns.com/lettering/lettering_tool.asp

    Pretty nice, the effect styles dropdown seem to me uses wordart shapes. Do you think this a 3rd party component? I figured if it could do it I could as well, I just can’t seem to find any objects or classes to support changing shape of the text on the fly.



  5. guowu says:

    I can not tell whether the web site you mentioned is using Word to create the signs or not. My guess is not though. Still you could do it using Word, as long as you know this kind of usage is not supported by Microsoft.

    To change the text of a WordArt on the fly, use InlineShape or Shape object’s texteffect property. For example: Selection.InlineShapes(1).TextEffect.Text = "abc" would change the text to "abc".

Comments are closed.

Skip to main content