none
Watermark only on even Pages when "First page different" and "Even and Odd Pages different" (VSTO 4, C#, Word) RRS feed

  • Question

  • Hi,

    I know that this topic has been discussed many times, but I couldn´t find any solution for this problem.

    We also want to add a watermark to all pages in the headers. Our solution works fine as long as the First pages AND the Even Odd Pages checkbox aren´t checked. If so then the watermark is at the first page (oddly the AllPagesHeader) and the watermarks for even odd pages and for first page are stacked on the even pages.

    I also already tried all different possibilites with anchors when I create the watermark but nothing works completely with all configurations of first page and even odd different.

    Is also tried the version from the macro recorder (Seekview etc.) but this neither works.

    Is there any error in the code or is it just impossible?

     

     

    public void AddWatermark(string watermarkText)
      {
       //Für jede Section im Dokument
       foreach (Section wordSection in _doc.Sections)
       {
        //In den primären Header ein Wasserzeichen schreiben
        var watermark = wordSection.Headers[WdHeaderFooterIndex.wdHeaderFooterPrimary];
        CreateWatermark(watermark, watermarkText, ID_WATERMARK);
    
        //Wenn Erste Seite anders dann in den diese ein Wasserzeichen einfügen
        if (wordSection.PageSetup.DifferentFirstPageHeaderFooter == WORD_TRUE)
        {
         var watermark1 = wordSection.Headers[WdHeaderFooterIndex.wdHeaderFooterFirstPage];
         CreateWatermark(watermark1, watermarkText, ID_WATERMARK_FIRST_PAGE);
        }
        //Wenn gerade Seiten anders, dann Wasserzeichen dort reinschreiben.
        if (wordSection.PageSetup.OddAndEvenPagesHeaderFooter == WORD_TRUE)
        {
         var watermark2 = wordSection.Headers[WdHeaderFooterIndex.wdHeaderFooterEvenPages];
         CreateWatermark(watermark2, watermarkText, ID_WATERMARK_EVEN_PAGES);
        }
       }
      }
    
      //Methode zum erstellen des Wasserzeichens
      private void CreateWatermark(HeaderFooter watermark, string watermarkText, string id)
      {
       var missing = Type.Missing;
    
       var wmShape = watermark.Shapes.AddTextEffect(
        MsoPresetTextEffect.msoTextEffect1,
        watermarkText, "Times New Roman", 1,
        MsoTriState.msoFalse,
        MsoTriState.msoFalse,
        0, 0, watermark.Range);
    
       wmShape.Name = id;
       wmShape.AlternativeText = id;
       wmShape.TextEffect.NormalizedHeight = MsoTriState.msoFalse;
       wmShape.Line.Visible = MsoTriState.msoFalse;
       wmShape.Fill.Visible = MsoTriState.msoTrue;
       wmShape.Fill.Solid();
       wmShape.Fill.ForeColor.RGB = (int) WdColor.wdColorGray25;
       wmShape.Fill.Transparency = 0.5f;
       wmShape.Rotation = -45.0f;
       wmShape.LockAspectRatio = MsoTriState.msoTrue;
       wmShape.Height = _doc.Application.InchesToPoints(1.82f);
       wmShape.Width = _doc.Application.InchesToPoints(4.64f);
       wmShape.WrapFormat.AllowOverlap = -1; //true
       wmShape.WrapFormat.Side = WdWrapSideType.wdWrapBoth;
       wmShape.WrapFormat.Type = WdWrapType.wdWrapNone; //3
       wmShape.RelativeHorizontalPosition =
        WdRelativeHorizontalPosition.wdRelativeHorizontalPositionMargin;
    
       wmShape.RelativeVerticalPosition =
        WdRelativeVerticalPosition.wdRelativeVerticalPositionMargin
        ;
       wmShape.Left = (float) WdShapePosition.wdShapeCenter;
       wmShape.Top = (float) WdShapePosition.wdShapeCenter;
      }
    

     


    Thanks in advice for you help

    Wompi


    Viele Grüße Mark
    • Moved by Cindy Meister MVPModerator Wednesday, August 17, 2011 4:19 PM Word object model specific (From:Visual Studio Tools for Office)
    Wednesday, August 17, 2011 1:32 PM

Answers

  • Hallo Mark

    <SEUFZ>I was working in PowerPoint at the time and it was fine there. This is the new graphics engine that was introduced in Office 2007. I knew Word 2007 only implemented it partially, but was under the impression that 2010 had picked up more of the functionality.

    Apparently not completely.

    Some of the "Word Art" formatting is available directly through properties such as Glow, Reflection, Shadow, SoftEdge and ThreeD.

    I guess what I'd try to do is recreate in a texbox something you can use. Either save that as a Building Block and insert it as required. Or track down all the property settings (as far as possible) and incorporate those into the code you use to create the TextBox.

    Edit: You could also try creating the thing you want in PowerPoint then right click and "export" that (save as a graphics file). Try inserting it directly. If that doesn't work, try inserting it into a text box.


    Cindy Meister, VSTO/Word MVP
    Saturday, August 20, 2011 12:22 PM
    Moderator
  • It could have been so easy :)

    object omiss = Type.Missing;
                Document doc = Globals.ThisAddIn.Application.ActiveDocument;
                Application app = Globals.ThisAddIn.Application;
                
                //Step #1: Add shape to primary header            
                Microsoft.Office.Interop.Word.Shape shw = doc.Sections.First.Headers[WdHeaderFooterIndex.wdHeaderFooterPrimary].
                    Shapes.AddTextEffect(MsoPresetTextEffect.msoTextEffect1, watermarkText, "Arial", 30, MsoTriState.msoFalse, MsoTriState.msoFalse, 100, 100, ref omiss);
    
                //Step #2: Copy shape from primary header
                app.ActiveWindow.ActivePane.View.SeekView = WdSeekView.wdSeekPrimaryHeader;
                shw.Select(ref omiss);
                app.Selection.Copy();
    
                //Step #3: Paste shape to even header
                if (doc.Sections.First.PageSetup.OddAndEvenPagesHeaderFooter == WORD_TRUE)
                {
                    doc.Sections.First.Headers[WdHeaderFooterIndex.wdHeaderFooterEvenPages].Range.Paste();
                }
    
                //Step #4: Paste shape to first page header
                if (doc.Sections.First.PageSetup.DifferentFirstPageHeaderFooter == WORD_TRUE)
                {
                    doc.Sections.First.Headers[WdHeaderFooterIndex.wdHeaderFooterFirstPage].Range.Paste();
                }
                
    //Remove shape from clipboard
                doc.Paragraphs.First.Range.Copy();
    
    
    Thanks again for your effort Cindy.


    Viele Grüße Mark
    • Marked as answer by Wompi Tuesday, September 6, 2011 6:36 AM
    Tuesday, September 6, 2011 6:34 AM

All replies

  • Hallo Wompi

    I'm going to move this question to the Word for Developer forum because it's probably a "niggle" in Word and not VSTO-related. You'll find many more application specialists there than here...

    I don't have time to research this at the moment, but a couple of remarks:

    1. Sometimes, "Embed interop types" for a COM library can do "funny things". If you have that activated (and that is the default for .NET 4.0) turn it off and test again. I don't think this is the problem, but it's simple enough to test and then we can be sure it's not the issue.

    2. It's important you tell us the version of Word involved. Some weird things have been going on with headers/footers in Word 2010 so it's important for us to know in which version we should test your scenario.

    3. Now, here's where I suspect the problem could be. "Under the covers", Word manages all Shapes for the headers/footers, across all header/footer types and sections, in a central storage. This can cause issues such as you describe. Often, specifying the anchor point (RANGE) in the Shapes.Add[whatevertype] method helps. You do specify the HEADER range, I see, but that's a bit general. Does it make any difference if you use watermark.Range.Paragraphs[1].Range instead, which would specifically anchor the Shape to the first paragraph, rather than letting Word decide where in the header to put that anchor?


    Cindy Meister, VSTO/Word MVP
    Wednesday, August 17, 2011 4:19 PM
    Moderator
  • Hi Cindy,

    thank you very much for your answer.

    Sorry, I forgot those informations. We are still using .NET 3.5 not .Net 4.0. My dev environment is with Office 2007 but I already tested this on Office 2010 and it has the same behavior.

    I will try your advice with the anchor and tell you if it has worked. :)

    Thanks


    Viele Grüße Mark
    Thursday, August 18, 2011 7:05 AM
  • The Paragraph[1].Range doesn´t make any difference.

    Is it possible to add a textbox shape to the header and then add the watermark to the textbox. If I do this by hand it is possible but I haven´t found any possibility to add a Wordart to a textbox yet. :-(

    I saw that the textboxes work fine with all the settings of the two checkboxes, so this could be a possible workaround.


    Viele Grüße Mark
    Thursday, August 18, 2011 9:26 AM
  • Hallo Mark

    I was researching something else and came across something a couple of minutes ago that might help. Note that this assumes we're talking about the "new" WordArt and not Word's old, built-in WordArt.

    The textbox is a member of the Shapes collection, or a ShapeRange collection. The following example assumes you've declared shp As Word.Shape and assigned the textbox to this when the Add method was used:

    shp.TextFrame2.WordArtFormat = Office.MsoPresetTextEffect.msoTextEffect3


    Cindy Meister, VSTO/Word MVP
    Thursday, August 18, 2011 2:48 PM
    Moderator
  • Hi Cindy,

    when I try to access the shp.TextFrame2 Property it throws me a NotImplemented-Exception. I even tried it with a new Word 2010 Add-In with .Net 4.0 but the same.

    Here´s the test code:

    Microsoft.Office.Interop.Word.Shape shape = Doc.Shapes.AddTextbox(MsoTextOrientation.msoTextOrientationHorizontal, 0, 0,
                               100, 100);
    
          shape.TextFrame2.WordArtformat = MsoPresetTextEffect.msoTextEffect3;
    

    Do I have to change something or cast it to a different interface?


    Viele Grüße Mark
    Friday, August 19, 2011 7:42 AM
  • Hallo Mark

    <SEUFZ>I was working in PowerPoint at the time and it was fine there. This is the new graphics engine that was introduced in Office 2007. I knew Word 2007 only implemented it partially, but was under the impression that 2010 had picked up more of the functionality.

    Apparently not completely.

    Some of the "Word Art" formatting is available directly through properties such as Glow, Reflection, Shadow, SoftEdge and ThreeD.

    I guess what I'd try to do is recreate in a texbox something you can use. Either save that as a Building Block and insert it as required. Or track down all the property settings (as far as possible) and incorporate those into the code you use to create the TextBox.

    Edit: You could also try creating the thing you want in PowerPoint then right click and "export" that (save as a graphics file). Try inserting it directly. If that doesn't work, try inserting it into a text box.


    Cindy Meister, VSTO/Word MVP
    Saturday, August 20, 2011 12:22 PM
    Moderator
  • :) Thank you very much for your effort Cindy.

    I'll give it a try.

    I also opened a support ticket at MS with this case and will give you feedback if they find a solution.

     


    Viele Grüße Mark
    Tuesday, August 23, 2011 8:27 AM
  • It could have been so easy :)

    object omiss = Type.Missing;
                Document doc = Globals.ThisAddIn.Application.ActiveDocument;
                Application app = Globals.ThisAddIn.Application;
                
                //Step #1: Add shape to primary header            
                Microsoft.Office.Interop.Word.Shape shw = doc.Sections.First.Headers[WdHeaderFooterIndex.wdHeaderFooterPrimary].
                    Shapes.AddTextEffect(MsoPresetTextEffect.msoTextEffect1, watermarkText, "Arial", 30, MsoTriState.msoFalse, MsoTriState.msoFalse, 100, 100, ref omiss);
    
                //Step #2: Copy shape from primary header
                app.ActiveWindow.ActivePane.View.SeekView = WdSeekView.wdSeekPrimaryHeader;
                shw.Select(ref omiss);
                app.Selection.Copy();
    
                //Step #3: Paste shape to even header
                if (doc.Sections.First.PageSetup.OddAndEvenPagesHeaderFooter == WORD_TRUE)
                {
                    doc.Sections.First.Headers[WdHeaderFooterIndex.wdHeaderFooterEvenPages].Range.Paste();
                }
    
                //Step #4: Paste shape to first page header
                if (doc.Sections.First.PageSetup.DifferentFirstPageHeaderFooter == WORD_TRUE)
                {
                    doc.Sections.First.Headers[WdHeaderFooterIndex.wdHeaderFooterFirstPage].Range.Paste();
                }
                
    //Remove shape from clipboard
                doc.Paragraphs.First.Range.Copy();
    
    
    Thanks again for your effort Cindy.


    Viele Grüße Mark
    • Marked as answer by Wompi Tuesday, September 6, 2011 6:36 AM
    Tuesday, September 6, 2011 6:34 AM