none
Word document page size and position RRS feed

  • Question

  • Hello!

     

    I am developing an application that automates word. I am already able to insert a freeform shape and set its properties like color and thickness. Therefore I am not able to set its position inside the second page of the document. I have scan all the Word Object Model looking for how to get the size and position of the current visible page of the current document, but I could not find it yet.

    How can I have the size and position of the current visible page?

    Thanks


    Adriano Signature
    Monday, November 28, 2011 6:40 PM

Answers

  • Hi Adriano

    I think I'm following what you want to do. In general terms, anyway.

    FWIW ConvertToShape means that the starting point is an InlineShape. That's the only type of object in Word that has a method of this name. Any Shape created from an InlineShape will appear on the same page on which the InlineShape was inserted. So before you even get to this point you have to have a target range that's on the correct page.

    The tricky thing with Word is that the Selection (where the cursor is located) doesn't have to be on what you're seeing in the Word window. And Word isn't really designed to do this kind of thing.

    The RangeFromPoint method might be able to help you:
    http://msdn.microsoft.com/en-us/library/bb209544(office.12).aspx

    If you can get the Range more or less where you need the Shape, then pass that Range to the method that creates the Shape (or InlineShape), then it should be fairly close to where you need it...


    Cindy Meister, VSTO/Word MVP
    Tuesday, November 29, 2011 3:04 PM
    Moderator

All replies

  • Hi Adriano

    I'm afraid I don't understand your question completely:
    <<How can I have the size and position of the current visible page?>>

    Do you mean you want to change the paper size of the second page? Or change the Zoom factor (magnify)?

    Or do you mean you want to change where the Shape is located?

    Please show us the code you have for inserting and formatting the Shape.

    Which version of Word are we discussing, and which programming language do you use?


    Cindy Meister, VSTO/Word MVP
    Tuesday, November 29, 2011 9:03 AM
    Moderator
  • Hi Cindy!

    Thanks for your attention.

    I'm trying to change where the Shape is located.

    I'm working wiht Word 2010. I'm using VS 2010.  It is a WPF project.

    Following is the code snapshot:

    using System;
    using System.Diagnostics;
    using System.Diagnostics.CodeAnalysis;
    using System.Runtime.InteropServices;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Ink;
    using System.Windows.Input;
    using System.Windows.Media;
    using Excel = Microsoft.Office.Interop.Excel;
    using PowerPoint = Microsoft.Office.Interop.PowerPoint;
    using Word = Microsoft.Office.Interop.Word;
    
    namespace MergeOffice
    {
        /// <summary>
        /// Interaction logic for MainWindow.xaml
        /// </summary>
        public partial class MainWindow : Window
        {
            //http://msdn.microsoft.com/en-us/library/ff684173(v=vs.85).aspx
            private const float PIXEL_TO_POINT_RATIO = 72f / 96f;
            private const float POINT_TO_PIXEL_RATIO = 96f / 72f;        
    
            public MainWindow()
            {
                InitializeComponent();
            }
    
            private void Thumb_DragDelta(object sender, System.Windows.Controls.Primitives.DragDeltaEventArgs e)
            {
                this.Left += e.HorizontalChange;
                this.Top += e.VerticalChange;
            }
    
            private void MenuItemSelectClick(object sender, RoutedEventArgs e)
            {
                DrawingCanvas.EditingMode = InkCanvasEditingMode.Select;
            }
    
            private void MenuItemPenClick(object sender, RoutedEventArgs e)
            {
                DrawingCanvas.EditingMode = InkCanvasEditingMode.Ink;
            }
    
            private void button2_Click(object sender, RoutedEventArgs e)
            {
                DrawingCanvas.Strokes.Clear();
            }
    
            private void button1_Click(object sender, RoutedEventArgs e)
            {
                Close();
            }
    
            private void MenuItemWordClick(object sender, RoutedEventArgs e)
            {
                //
                // get running word application
                //
                Object officeInstance = null;
                try
                {
                    officeInstance = System.Runtime.InteropServices.Marshal.GetActiveObject("Word.Application");
                }
                catch (COMException)
                {
                    MessageBox.Show("Unable to attach to Word application.");
                    return;
                }
                Word.Application WordApp = officeInstance as Word.Application;
    
                float offsetX = ((float)(WordApp.Width - WordApp.ActiveDocument.PageSetup.PageWidth)) / 2f;
    
                //
                //TODO: calculate horizontal and vertical offsets to position free forms accordingly to the scroll.
                // current pageOffsetY is an attempt to do it.
                //
                float pageOffsetY = WordApp.ActiveDocument.PageSetup.PageHeight * POINT_TO_PIXEL_RATIO;
    
                if (WordApp.ActiveWindow.VerticalPercentScrolled > 0)
                {
                    pageOffsetY = (pageOffsetY * WordApp.ActiveWindow.VerticalPercentScrolled) / 100;
                }
                else
                {
                    pageOffsetY = 0;
                }
    
                //
                // transform InkCanvas strokes into a free form shape.
                //
                foreach (Stroke stroke in DrawingCanvas.Strokes)
                {
                    //start creating the free form begining at the first stroke point
                    Word.FreeformBuilder freeFormBuilder = WordApp.ActiveDocument.Shapes.BuildFreeform(Microsoft.Office.Core.MsoEditingType.msoEditingAuto, (((float)stroke.StylusPoints[0].X) * PIXEL_TO_POINT_RATIO) - offsetX, ((float)stroke.StylusPoints[0].Y) * PIXEL_TO_POINT_RATIO + pageOffsetY);
    
                    //add each stroke point to free form
                    for (int i = 1; i < stroke.StylusPoints.Count; i++)
                    {
                        freeFormBuilder.AddNodes(Microsoft.Office.Core.MsoSegmentType.msoSegmentCurve, Microsoft.Office.Core.MsoEditingType.msoEditingAuto, (((float)stroke.StylusPoints[i].X) * PIXEL_TO_POINT_RATIO) - offsetX, ((float)stroke.StylusPoints[i].Y) * PIXEL_TO_POINT_RATIO + pageOffsetY);
                    }
    
                    //insert the free form into the active document.
                    Word.Shape shape = freeFormBuilder.ConvertToShape();
    
                    shape.Line.ForeColor.RGB = ColorRGB(stroke.DrawingAttributes.Color);
                    shape.Line.Weight = (float)stroke.DrawingAttributes.Width;
                    shape.Line.Transparency = ColorTransparency(stroke.DrawingAttributes.Color);
                }
            }
    
            //return 0 for 100% opacity
            //return 1 for 100% transparency
            static private float ColorTransparency(Color color)
            {
                return 1f - (color.A / 255f);
            }
    
            // set opacity to 0 in order to generate a 100% transparency
            // set opacity to 1 in order to generate a 0% transparency
            public static Color SetTransparency(Color color, float opacity)
            {
                color.A = (byte)((1f - opacity) * 255f);
                return color;
            }
    
            static private int ColorRGB(Color color)
            {
                return (color.A << 24) | (color.B << 16) | (color.G << 8) | (color.R);
            }
    
    
    

    Thanks!


    Adriano Signature


    Tuesday, November 29, 2011 10:35 AM
  • Hi Adriano

    I'm going to start here:

                  //insert the free form into the active document.
                    Word.Shape shape = freeFormBuilder.ConvertToShape();

    I take it that freeFormBuilder generates a member of the InlineShapes collection? Can you tell me how it instantiates the InlineShape (AddPicture method, or whatever, including what values are passed in an parameters). Mainly, I'm interested in what's going into the RANGE parameter as that will determine which PAGE the graphic ends up on.

    Then

           //TODO: calculate horizontal and vertical offsets to position free forms accordingly to the scroll.

    I'm understanding correctly that you're trying to keep the graphic on-screen when the user scrolls? Can you explain the "why" of that? Is the idea that it's always at a certain point in the document window? Are you expecting the graphic to move from page to page? 


    Cindy Meister, VSTO/Word MVP
    Tuesday, November 29, 2011 11:24 AM
    Moderator
  • Hi Cindy

    I don't think freeFormBuilder.ConvertToShape(); generates a InlineShape. I believe it creates an element inside Shapes collection.

    I apologize because I do not completely understand the object model.

    What I am trying to do is to create a simple application with a InkCanvas that allows me to have the drawing replicated inside the Word document.

    The code talks about scroll because it was an attempt to calculate the offset of the visible page.

    Let me explain a little different. What I have is a transparent application positioned over Microsoft Word. Then I perform some drawing in that application. In the end I choose to get the drawings and insert into the Word document. It works fine for the first page. But if i have more than one page and the second page is the current visible page then the drawing is not positioned where it would be desired. The desired position is the position the drawing have on the screen.

    This is POC application. I can upload it if it is possible.

     

    Thanks.


    Adriano Signature

    • Edited by AdrianoFO Tuesday, November 29, 2011 11:46 AM
    Tuesday, November 29, 2011 11:36 AM
  • Hi Adriano

    I think I'm following what you want to do. In general terms, anyway.

    FWIW ConvertToShape means that the starting point is an InlineShape. That's the only type of object in Word that has a method of this name. Any Shape created from an InlineShape will appear on the same page on which the InlineShape was inserted. So before you even get to this point you have to have a target range that's on the correct page.

    The tricky thing with Word is that the Selection (where the cursor is located) doesn't have to be on what you're seeing in the Word window. And Word isn't really designed to do this kind of thing.

    The RangeFromPoint method might be able to help you:
    http://msdn.microsoft.com/en-us/library/bb209544(office.12).aspx

    If you can get the Range more or less where you need the Shape, then pass that Range to the method that creates the Shape (or InlineShape), then it should be fairly close to where you need it...


    Cindy Meister, VSTO/Word MVP
    Tuesday, November 29, 2011 3:04 PM
    Moderator
  • Thank you for your kindness help.

    I believe that I can go a little further now.

    I'll try to follow you suggestion. If I get stuck again I'll be back.

    Thanks once again.

    Best regards,

    Adriano


    Adriano Signature
    Tuesday, November 29, 2011 3:39 PM