We interupt this blog’s coverage of OOPSLA with a quick observation &
question related to development…
I’m hacking around writing a Word 2003 SmartTag in C# (more on the why
later). I wanted my
recognizer
to be document-dependent – i.e. depending on some custom document
properties, I wanted to change what gets recognized. A little digging
reveils that there is no way (that I could find) to access the Word
object model from the recognizer! The
Recognize
(and
Recognize2)
method receives strings as parameters, but it doesn’t receive an
app-specific target object. This is unlike the Smart Tag
Action‘s
InvokeVerb
(and
InvokeVerb2)
method which receives a Range
object (from
which you can navigate to the containing document, application and
window) when running inside of Word. Bummer.
I think the reason for this is that the recognizer appears to run on a
background thread while the action appears to run on the main app
thread. Furthermore, both threads are STA apartment threaded, so if I
can access the COM-based object model from the action thread, I can’t
access it directly from the recognizer thread. I actually hacked up an
add-in to provide the
ActiveDocument
to the recognizer thru a backchannel and it hangs Word on shutdown. I
thought there might be an issue releasing the COM reference, but
explicitly releasing it crashes the recognizer the next time it accesses
the ActiveDocument.
So I’ve come to the conclusion that I somehow need to marshal this call
from the background thread to the main app thread the action and addin
are runing on (I did verify that both of those run on the same thread).
The question is, what’s the best way to do that given that I’m writing
this in C#? I thought I might use a system similar to Windows Form’s
Control.Invoke(…),
but it turns out that works by sending windows messages which isn’t
particularly feasible for my problem. So now I’m thinking I have pass
the ActiveDocument reference to the background thread using
CoMarshalInterface.
Or I might be able to use
RemotingServices.Marshal()
instead.
Anyone have any ideas? If so, leave a comment or drop me a
line.