Error copying shape or diagram as image in NShape Designer app

Feb 8, 2013 at 8:50 AM

Steps to reproduce:
  • Start NShape Designer,
  • Open any project (I opened demo project "Flow Chart" shipped with NShape),
  • Right-click on the Diagram or on any of its shapes and select context menu item "Copy as Image" - it works without errors,
  • Select menu item "Copy as Image" from the "Edit" menu ---> a debug assertion error will be shown (2 or 3 times).
So error presence depends on how do we "copy as image" - through context menu item or through main menu item. Code of these two items really differs:

In Display.CreateCopyImageMenuItemDef() method:
return new DelegateMenuItemDef(title, icon, description, isFeasible, permission,
    (a, p) => {
        IEnumerable<Shape> shapes = (selectedShapes.Count > 0) ? selectedShapes : null;
        int margin = (selectedShapes.Count > 0) ? 10 : 0;
        // Clear clipboard
        // Copy diagram/selected shapes to clipboard as PNG bitmap image file
        Bitmap pngImage = (Bitmap)diagram.CreateImage(ImageFileFormat.Png, shapes, margin, (shapes == null), System.Drawing.Color.Empty);
        Clipboard.SetData(DataFormats.Bitmap, pngImage);
        // Copy diagram/selected shapes to clipboard as EMF vector graphic file
        Metafile emfImage = (Metafile)diagram.CreateImage(ImageFileFormat.EmfPlus, shapes, margin, (shapes == null), System.Drawing.Color.Empty);
        EmfHelper.PutEnhMetafileOnClipboard(Handle, emfImage, false);
In MainForm.copyAsImageToolStripMenuItem_Click() method:
if (CurrentDisplay != null && CurrentDisplay.Diagram != null) {
    // Copy image as PNG and EMFPlusDual formats to clipboard
    CurrentDisplay.CopyImageToClipboard(ImageFileFormat.Png, true);
    CurrentDisplay.CopyImageToClipboard(ImageFileFormat.EmfPlus, false);
    // Ensure that both file formats are in the clipboard
Feb 8, 2013 at 2:26 PM
Edited Feb 22, 2013 at 8:48 AM
I think you can ignore the Assertion failures:
When you paste the picture in Word (2007 or newer), a EMF picture will be inserted.
You can check this by zooming in -> No pixels, all edges stay sharp.

When comparing code differences, you should compare CurrentDisplay.CopyImageToClipboard, which uses more similiar code.
In fact, the parts of the code that really does some work are the same:
  • Diagram.CreateImage(..) for creating the image
  • Clipboard.SetData(...) for copying bitmap images to the clipboard
  • EmfHelper.PutEnhMetafileOnClipboard(...) for copying the EMF images to the clipboard - the built-in clipboard methods do not work for EMF files... :(
Anyway, I will investigate this issue closer.
Feb 22, 2013 at 7:42 AM
KurtHolzinger wrote:
Anyway, I will investigate this issue closer.
Please reply when you find the reason.
Apr 12, 2013 at 8:56 AM
I've found the reason: This was simply a timing problem:
The metafile image is copied to the clipboard using the Windows API function "CopyEnhMetaFile(...)" which is executed asynchroneously but the check via "Debug.Assert()" was done immideatly after the call to the mentioned API funktion.
So it the meta file consisted of more than one or two shapes, the copy action took longer than returning from the helper class' method and the check failed because the meta file was not copied to the clipboard conpletly.

Inserting a breakpoint (or pausing the thread for some milliseconds solved the problem.
For the next release, I've removed this (unnecessary) check.