none
Set the cursor location in Word document

    Question

  • Hi Mike,

     

    Word 2003, VSTO 2005, C#, VS.NET 2005

     

    Is there a way to set the location of the cursor in a non-XML word 2003 doc using VSTO/C#?

     

    Our users want to automatically insert some text and hyperlinks several times through their document authoring effort.  I can insert the text and the hyperlinks but when I'm done the cursor is always at the top of the document.  I'd like to do this:

    1. User selects a commandbar button: Inserts standard text/hyperlink, I want to leave the cursor on a newline just below what was just inserted.

    2.  The user will then insert their text a few lines to several paragraphs.

    3. From a commandbar button the user will select the next set of standard text.  Again, I want to leave the insertion point on a newline below this text.

    etc etc...

     

    How do I leave the cursor at that new line position?

     

    Thanks in advance for any assistance,

    Paul

    Saturday, February 02, 2008 7:16 PM

Answers

  • When you force a new line in Word (whether by using ASCII 11 or ASCII 13) this does count as an additional character in the document, yes. Even though it's not as ".NET correct", for this reason you might want to use the C# escape codes instead of Environment.NewLine. \r is the equivalent of ASCII 13 = new paragraph. Right off-hand I can't remember what the equivalent of ASCII 11 is = new line (Word-specific).

     

    Or, you'd need to rebuild your procedure to use the other approach. Here's an untested example, off the top of my head, of how using a single range would work:

     

    String text1 = "The first text.";

    String text2 = "Some more text ";

    String text3 = "A third set of text.";

    Word.Range rng = theDoc.Content;

    //I want to start at the top of the document = start of the range

    object oCollapseStart = Word.WdCollapseDirection.wdCollapseStart;

    //I need to continue after a range

    object oCollapseEnd = Word.WdCollapseDirection.wdCollapseEnd;

     

    rng.Collapse(ref oCollapseStart);

    rng.Text = text1;

    rng.InsertParagraph();

    rng.Collapse(ref oCollapseEnd);

    rng.Text = text2;

    rng.Collapse(ref oCollapseEnd);

    Word.Field fld = rng.Fields.Add(rng //other args);

    rng = fld.Result;

    //Insert the rest of the text in a new line, after the field

    rng.InsertParagraph;

    rng.Collapse(ref oCollapseEnd);

    rng.Text = text3;

    Monday, February 04, 2008 8:07 AM

All replies

  • Hi Paul

     

    It would make it easier to show you if you supplied the code you're using to insert the content. But I'll assume you're using a Range object, in one way or another, to identify that location. Let's assume you have a range, and you've just put some text in it, like this:

    rng.Text = "The new text in the document";

     

    The next thing you need to do is to collapse the range to a single point, following the range. Then select the range.

    rng.Collapse(Word.WdCollapseDirection.wdCollapseEnd);

    rng.Select();

     

    If the text you inserted was at the end of a line, the cursor will be on the next line. If you want a new line as part of the range you're inserting, type the following at the end of the text, above: \r

     

    Saturday, February 02, 2008 7:32 PM
  • Hi Cindy,

     

    Thanks that got me most of the way there.  However, after doing the above the cursor, while no longer at the top of the doc is now in the middle of the last sentence.

     

    Here's the code:

     

     

    string theLink = "http://www.crs.gov/products/flooraction/subscribe-crs-alert.shtml";

    object oAddress = theLink;

    // for setting the range of the hyperlink

    object hypStart ;

    object hypEnd ;

     

    // we want to collapse the range to the insertion point for the next text

    object collapseEnd = Word.WdCollapseDirection.wdCollapseEnd;

     

    // standard text

    string startText = "See this week's Alert: Our items at ";  // theLink goes here

    string nextText = " for full text of the following reports." + Environment.NewLine + Environment.NewLine +

    "The following selected reports focus on key policy issues or some of the key issues involved  that may receive  action during the week of " + DateTime.Now.Date.ToString("dddd dd MMMM") + " " + DateTime.Now.Date.Year.ToString() + "." + Environment.NewLine;

    hypStart = startText.Length;

    hypEnd = startText.Length + theLink.Length;

     

    testVSTO.ThisDocument newAlert = testVSTO.Globals.ThisDocument;

     

    // set the insertion point to the top of the page

    Word.Range report = newAlert.Range(ref missing, ref missing);

    report.Text = startText + theLink + " " + nextText + "\r";

     

    // The point at which to insert the hyperlink

    report = newAlert.Range(ref randStart, ref randEnd);

    newAlert.Hyperlinks.Add(report, ref oAddress, ref missing, ref missing, ref missing, ref missing);

     

     

    report.Collapse(ref collapseEnd);

    report.Select();

    _______________________________

     

    That is, the last two line of code above leave the cursor at the end of the hyperlink or at hypEnd.

     

    If I use this code:

    report.SetRange(newAlert.Characters.Count, newAlert.Characters.Count);

    instead of the

    report.Collapse(ref collapseEnd);

    the cursor is in the middle of the last sentence (eg: nextText).

     

    Thanks again for any assistance,

    Paul

    Saturday, February 02, 2008 8:04 PM
  • Hi Paul

     

    Mmm. Working with the Start and End points of a range is only reliable if you can be absolutely sure you aren't dealing with hidden text of fields. Fields are what Word uses to manage any dynamic content; page numbers are an obvious example. A field consists of the field code (which you can see by using Alt+F9 to toggle field codes on/off) and the field result. When you start counting characters in a selection or range, if a field is involved you'll get "strange" results. I avoid defining a range by using the Start and End properties if any other alternative is possible.

     

    Inserting a Hyperlink inserts a Hyperlink field. It's not clear from your code snippet where randStart and randEnd come from; I'm assuming a typo in what you posted, but that doesn't seem to be an issue...

     

    What I'd do in your place is either to work with multiple ranges, or to insert text-field-text so that I can continue "forwards" using the same range. Building on your approach, I'd make this small change:

     

    // The point at which to insert the hyperlink

    Word.Range rngHyp = newAlert.Range(ref randStart, ref randEnd);

    newAlert.Hyperlinks.Add(rngHyp, ref oAddress, ref missing, ref missing, ref missing, ref missing);

    //Now the range "report" doesn't change

    report.Collapse(ref collapseEnd);

    report.Select();

     

    Sunday, February 03, 2008 4:26 PM
  • Hi Again Cathy,

     

    Working with multiple ranges worked like a charm!!  (Sorry about the typo). 

     

    When I try to add a similar block of text later in the creation process (after the user has added 2-3 pages of text), they insertion of the hyperlink is "off" by a few characters.  Does the inclusion the "Environment.NewLine" affect the calculation of a range?  It appears that the number of these affects the placement of the hyperlink by that many characters.

     

    Here's the code:

     

    string legEndText = Environment.NewLine + "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" + Environment.NewLine +

    "Join or leave the AGENDA mailing list via the Web page: " + Environment.NewLine;

    string newEndText1 = Environment.NewLine + Environment.NewLine + "For assistance with joining and leaving, All subscribers " + Environment.NewLine +

    "please call (555) 555-5500. CRS subscribers please call (555) 555-5500. " + Environment.NewLine + Environment.NewLine +

    Environment.NewLine + "For information on the action Agenda, to order Products or to provide " + Environment.NewLine +

    "feedback, please call John Doe at (555) 555-5500. " + Environment.NewLine + Environment.NewLine +

    "To order our Products, please call (555) 555-5500. ";

     

    // since we're at the end of the document we need to get the range for the text up to the start of "newEndText"

    // then, add the hypStart to set the starting point for the hyperlink

    object startDoc = 0;

    object endDoc;

    Word.Range fullRange = legAlert.Range(ref startDoc, ref missing);

    // leaving out the end of the range, will get the end of the document's range

    endDoc = fullRange.End;

    // the length of the doc up to where we enter the remaining standard text

     

    // programmatically set the range for the hyperlink

    // the above strings can also be established in an app.config file and

    // be obtained on the fly

    hypStart = legEndText.Length + fullRange.End - 4;

    hypEnd = legEndText.Length + fullRange.End - 3 + theLink.Length;

     

    //  Here's where it gets a little weird,  the hyperlink is set to the right "area", except for a few characters.

    //  So it appears that I have to subtract from the fullRange.End in order to set the hyperlink to the correct range.

    //  is this because of the Environment.NewLine ?

     

    (As you can tell I'm new to this.)  Is the issue the number of Environment.NewLine's?  

     

    Thanks again,

    Paul

     

    Sunday, February 03, 2008 8:29 PM
  • When you force a new line in Word (whether by using ASCII 11 or ASCII 13) this does count as an additional character in the document, yes. Even though it's not as ".NET correct", for this reason you might want to use the C# escape codes instead of Environment.NewLine. \r is the equivalent of ASCII 13 = new paragraph. Right off-hand I can't remember what the equivalent of ASCII 11 is = new line (Word-specific).

     

    Or, you'd need to rebuild your procedure to use the other approach. Here's an untested example, off the top of my head, of how using a single range would work:

     

    String text1 = "The first text.";

    String text2 = "Some more text ";

    String text3 = "A third set of text.";

    Word.Range rng = theDoc.Content;

    //I want to start at the top of the document = start of the range

    object oCollapseStart = Word.WdCollapseDirection.wdCollapseStart;

    //I need to continue after a range

    object oCollapseEnd = Word.WdCollapseDirection.wdCollapseEnd;

     

    rng.Collapse(ref oCollapseStart);

    rng.Text = text1;

    rng.InsertParagraph();

    rng.Collapse(ref oCollapseEnd);

    rng.Text = text2;

    rng.Collapse(ref oCollapseEnd);

    Word.Field fld = rng.Fields.Add(rng //other args);

    rng = fld.Result;

    //Insert the rest of the text in a new line, after the field

    rng.InsertParagraph;

    rng.Collapse(ref oCollapseEnd);

    rng.Text = text3;

    Monday, February 04, 2008 8:07 AM