views:

768

answers:

4

Many of the parameters for interacting with the Office Object model in VSTO require object parameters that are passed by reference, even when the notional type of the parameter is an int or string.

  1. I suppose that this mechanism is used so that code can modify the parameter, although I can't figure out why these need to be passed as generic object instead of as their more appropriate types. Can anyone enlighten me?
  2. The mechanism I've been using (cribbed from help and MSDN resources) essentially creates a generic object that contains the appropriate data and then passes that to the method, for example:

    object nextBookmarkName = "NextContent"; object nextBookmark = this.Bookmarks.get_Item( ref nextBookmarkName ).Range;

    Microsoft.Office.Interop.Word.Range newRng = this.Range( ref nextBookmark, ref nextBookmark );

This seems like a lot of extra code, but I can't see a better way to do it. I'm sure I'm missing something; what is it? Or is this really the best practice?

A: 

I'd be interested in this too. I'm coding several apps that uses automation in Word and I even have things like

object oFalse = false, oTrue = true, oOne = 1;

It's very nasty, but it's the only way I know so far.

The only thing I can think of is writing a wrapper class for the frequently used functions...

KTamas
A: 

I think it was just poor design of the original Word object model. I know that passing strings by reference can be slightly faster in the COM world because it avoids the need to make a copy, so perhaps that was part of the justification. But the downside is that the callee can modify the value, and in most cases with Word they are input parameters.

I think your technique is the best practice. For the millions of optional parameters that many of the Word object model methods require, you can create a single static field "missing" something like:

object missing = Type.Missing;

// Example object fileName = ... document.SaveAs(ref fileName, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing, ref missing);

Joe
That's what I was afraid of. And FWIW, C# VSTO (I don't know about VB.Net, since I've never used it) already includes a built-in missing object
cori
+2  A: 

I agree with Joe. I even developed helper structs and classes like this one:

internal struct Argument
{
    internal static object False = false;

    internal static object Missing = System.Type.Missing;

    internal static object True = true;
}

And this one:

/// <summary>
/// Defines the "special characters"
/// in Microsoft Word that VSTO 1.x
/// translates into C# strings.
/// </summary>
internal struct Characters
{
    /// <summary>
    /// Word Table end-of-cell marker.
    /// </summary>
    /// <remarks>
    /// Word Table end-of-row markers are also
    /// equal to this value.
    /// </remarks>
    internal static string CellBreak = "\r\a";

    /// <summary>
    /// Word line break (^l).
    /// </summary>
    internal static string LineBreak = "\v";

    /// <summary>
    /// Word Paragraph break (^p).
    /// </summary>
    internal static string ParagraphBreak = "\r";
}

And a few more...

rasx
A: 

I think, all of this is taken care of with VS.NET 2010 and new language constructs introduced in c# 4.0 (c# will have optional arguments).

See the video by Anders Hejlberg at PDC 2008 on channel9 for changes related to office development.

I cant find that link but this could also be helpful.
http://channel9.msdn.com/shows/Going+Deep/Inside-C-40-dynamic-type-optional-parameters-more-COM-friendly/

shahkalpesh