i'm working on a Word VSTO Add-In to automate some Corporate Identity Stuff for the Company i work at.
I want to replace certain Images both before and after a call to PrintOut
This is the Method i'm currently using
public static void PrintDocumentAsPDF(this WordRibbon _, string printerName = "Microsoft Print to PDF")
{
try
{
// Un-Protected Document
Globals.ThisAddIn.Application.ActiveDocument.Unprotect("");
}
catch (COMException) { }
// Replace Images in Document
Extensions.ReplaceImage(Constants.ImageType.DesignElement, Constants.ImageVariant.FullResolution);
Extensions.ReplaceImage(Constants.ImageType.Logo, Constants.ImageVariant.FullResolution);
// Get last Active Printer
string lastPrinter = Globals.ThisAddIn.Application.ActivePrinter;
try
{
// Set temporary Active Printer
Globals.ThisAddIn.Application.ActivePrinter = printerName;
}
catch (Exception)
{
MessageBox.Show("Drucker konnte nicht konfiguriert werden!", "Fehler", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
try
{
// Print Document
Globals.ThisAddIn.Application.PrintOut(
Constants.FalseObject, // Background
Constants.Missing, // Append
Constants.Missing, // Range
Constants.Missing, // Output File Name
Constants.Missing, // From
Constants.Missing, // To
Constants.Missing, // Item
Constants.Missing, // Copies
Constants.Missing, // Pages
Constants.Missing, // PageType
Constants.Missing, // PrintToFile
Constants.Missing, // Collate
Constants.Missing, // ActivePrinterMacGX
Constants.Missing, // ManualDuplexPrint
Constants.Missing, // PrintZoomColumn
Constants.Missing, // PrintZoomRow
Constants.Missing, // PrintZoomPaperWidth
Constants.Missing // PrintZoomPaperHeight
);
}
catch (Exception)
{
MessageBox.Show("Dokument konnte nicht gedruckt werden!", "Fehler", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
// Restore Active Printer
try
{
Globals.ThisAddIn.Application.ActivePrinter = lastPrinter;
}
catch (Exception)
{
MessageBox.Show("Ursprüngliche Druckereinstellungen konnte nicht wiederhergestellt werden!", "Fehler", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
// Replace Images with low-resolution Versions
Extensions.ReplaceImage(Constants.ImageType.DesignElement, Constants.ImageVariant.LowResolution);
Extensions.ReplaceImage(Constants.ImageType.Logo, Constants.ImageVariant.LowResolution);
try
{
// Protect Document
Globals.ThisAddIn.Application.ActiveDocument.Protect(WdProtectionType.wdAllowOnlyFormFields, Constants.FalseObject, "");
}
catch (COMException) { }
}
This is the Code for Extensions.ReplaceImage(...)
public static void ReplaceImage(ImageType image, ImageVariant imageVariant)
{
try
{
foreach (Range storyRange in Globals.ThisAddIn.Application.ActiveDocument.StoryRanges)
{
foreach (Shape shape in storyRange.ShapeRange)
{
if (shape.AlternativeText == ImageRepository[image][imageVariant].Name)
{
object anchor = shape.Anchor;
Shape newShape = Globals.ThisAddIn.Application.ActiveDocument.Shapes.AddPicture(
ImageRepository[image][imageVariant].Path /* Image Path */,
// ref Constants.Missing,
// ref Constants.Missing,
// ref Constants.Missing,
// ref Constants.Missing,
// ref Constants.Missing,
// ref Constants.Missing,
Anchor: ref anchor);
newShape.Top = shape.Top;
newShape.Left = shape.Left;
newShape.Width = shape.Width;
newShape.Height = shape.Height;
newShape.AlternativeText = shape.AlternativeText;
shape.Delete();
}
}
foreach (InlineShape inlineShape in storyRange.InlineShapes)
{
if (inlineShape.AlternativeText == ImageRepository[image][imageVariant].Name)
{
InlineShape newInlineShape = Globals.ThisAddIn.Application.ActiveDocument.InlineShapes.AddPicture(
ImageRepository[image][imageVariant].Path,
ref Missing,
ref Missing,
inlineShape.Range
);
newInlineShape.Width = inlineShape.Width;
newInlineShape.Height = inlineShape.Height;
newInlineShape.AlternativeText = inlineShape.AlternativeText;
inlineShape.Delete();
}
}
}
}
catch (COMException comException)
{
MessageBox.Show(comException.Message, "COM Fehler", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Fehler", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
Definition for Constants.FalseObject: public static object FalseObject = false;
Definition for Constants.Missing: public static object Missing = System.Reflection.Missing.Value;
And these are the definitions for ImageType
and ImageVariant
public enum ImageType
{
DesignElement,
Logo
}
public enum ImageVariant
{
LowResolution,
FullResolution
}
public class ImageElement
{
public string Path { get; }
public string Name { get; }
public ImageElement(string path, string name)
{
Path = path;
Name = name;
}
}
public static Dictionary<ImageType, Dictionary<ImageVariant, ImageElement>> ImageRepository = new Dictionary<ImageType, Dictionary<ImageVariant, ImageElement>>()
{
[ImageType.DesignElement] = new Dictionary<ImageVariant, ImageElement>()
{
[ImageVariant.FullResolution] = new ImageElement(Path.Combine(LocalResourceBasePath, "Images", "DocumentTitle.png"), "Designelement"),
[ImageVariant.LowResolution] = new ImageElement(Path.Combine(LocalResourceBasePath, "Images", "DocumentTitle_lowres.png"), "Designelement")
},
[ImageType.Logo] = new Dictionary<ImageVariant, ImageElement>()
{
[ImageVariant.FullResolution] = new ImageElement(Path.Combine(LocalResourceBasePath, "Images", "Logo_rgb.png"), "Logo"),
[ImageVariant.LowResolution] = new ImageElement(Path.Combine(LocalResourceBasePath, "Images", "Logo_rgb_lowres.png"), "Logo")
},
};
The issue is, that the second call(s) to ReplaceImage after the PrintOut()-Call are done before the First Replacement and Print is done.
I saw that there was a Event called DocumentBeforePrint
that gets invoked before anything is being printed. Is something similar like DocumentAfterPrint
?
I also attempted to use this Post to fix it, but this wouldn't work either.
Can anyone help ? ( if my code is complete garbage - which would not surprise me - i'm also open to suggestions on how to do this better )