Few days back I worked on an issue where a Word 2007 VSTO document solution, developed using VSTO 3.0, was behaving erratically when VSTO 4.0 was installed on the same machine. The Word document was very simple, it just had a Rich Text content control on it and the customer was using the following code to manipulate it:
1: Private Sub ThisDocument_Open() Handles Me.Open
2: Me.TrackFormatting = False
3: Me.TrackRevisions = False
4: rt1.LockContentControl = False
5: rt1.LockContents = False
6: rt1.Text = "TEST COMPLETED"
7: Me.TrackFormatting = True
8: Me.TrackRevisions = True
9: rt1.LockContentControl = True
10: rt1.LockContents = True
11: End Sub
He was getting the following error on the line where he was accessing the rich text control in the code (Line number 4 in the above code snippet):
Surprisingly, on uninstalling the VSTO 4.0 from the machine the solution worked perfectly fine. Also, the solution worked without any problem if I remove the content control and add it again to the document.
After spending hours on troubleshooting the problem, we discovered that the problem was due to a bug in Word 2007. The bug was, if a content control’s id is greater than 2^31 (2 to the power 31) and you try to access it like the following (VBA code):
Word will throw the following error:
However, if you try to access the same content control using the following:
It works, as shown below:
The VSTO 3.0 uses the second method to access the content controls on the document. It loops through the content controls collection and matches the ID of the control it is looking for.
In case of VSTO 4.0, the content control is retrieved using “ContentControls.Item (ID)”, where ID is the ID of the content control it is looking for and hence we see the problem.
The problem with the VSTO document was that the ID of the content control it had was 3678349844, which is greater than 2^31 (2147483648).
While the Content Control is being added to the document, the ID is being generated as unsigned DWORD, that is it can have any value up to 2^32, however, while trying to get/retrieve the control, the passed in ID is being converted to signed DWORD which results in an overflow and hence the error.
This bug is fixed in Word 2010 but it still exists with Word 2007.
One of the workaround to the problem is to delete the content controls (which have ID more than 2^31) and add them again (making sure that the ID is less than 2^31). Another workaround could be to access the underlying inner object (Word RichTextControl) rather than using the VSTO wrapped one. For example:
Imports Word = Microsoft.Office.Interop.Word
Dim cc As Word.ContentControl
For Each cc In Me.ContentControls
If (cc.Tag.Equals("MyContentControl")) Then
cc.LockContentControl = False
cc.LockContents = False
cc.Range.Text = "Hello World!!!"