Saturday, February 02, 2008 7:16 PM
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.
How do I leave the cursor at that new line position?
Thanks in advance for any assistance,
Saturday, February 02, 2008 7:32 PMModerator
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.
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 8:04 PM
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:
stringtheLink = "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 textobject 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);
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:
instead of the
the cursor is in the middle of the last sentence (eg: nextText).
Thanks again for any assistance,
Sunday, February 03, 2008 4:26 PMModerator
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);
Sunday, February 03, 2008 8:29 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:
stringlegEndText = 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 rangefor 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?
Monday, February 04, 2008 8:07 AMModeratorWhen 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.Text = text1;
rng.Text = text2;
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.Text = text3;