Threading issue with Outlook 2003 + Word editor?

Add-in Express™ Support Service
That's what is more important than anything else

Threading issue with Outlook 2003 + Word editor?
 
Daniel Garcia




Posts: 9
Joined: 2010-10-14
I'm having trouble displaying a WPF form when clicking a mail inspector button, but only when running in Outlook 2003 + MS Word as the email editor.

We have a ADXOlInspectorCommandBar with a button. Here is the "Click" handler:

Private Sub Button_Settings4_Click(ByVal sender As Object) Handles Button_Settings4.Click
  Dim theDialog As MyDll.MyWPFDialog = New MyDll.MyWPFDialog()
  theDialog.ShowDialog()
End Sub


This causes the exception listed below. However, if I change the settings to NOT use MS Word as the email editor, everything works prefectly. Also, the same code seems to work perfectly fine for Outlook 2007/2010, although in this case we use an ADXRibbonTab. Here is the handler:

Private Sub Button_Settings3_OnClick(ByVal sender As System.Object, ByVal control As AddinExpress.MSO.IRibbonControl, ByVal pressed As System.Boolean) Handles Button_Settings3.OnClick
  Dim theDialog As MyDll.MyWPFDialog = New MyDll.MyWPFDialog()
  theDialog.ShowDialog()
End Sub 


Also, I am not (knowingly) doing anything with threads in MyWPFDialog. In fact, it seems the exception is thrown by the default constructor of MyWPFDialog before any of my code has a chance to run.

Am I missing something obvious? I've found these 2 posts, which seem somewhat related to my issue, but I seem to be unable to put the pieces together:

http://social.msdn.microsoft.com/forums/en-US/vsto/thread/506920bb-fd5f-43e5-9ae7-9fbfdfb6a9b0

http://social.msdn.microsoft.com/forums/en-US/vsto/thread/ef297b3c-806c-4f95-8f49-f4f97370e0a1/


Here are the exception details:

Exception Type: System.InvalidOperationException
Message: The calling thread must be STA, because many UI components require this.
Dat a: System.Collections.ListDictionaryInternal
TargetSite: Void .ctor()
HelpLink: NULL
Source: PresentationCore

StackTrace Information:

   at System.Windows.Input.InputManager..ctor()
   at System.Windows.Input.InputManager.GetCurrentInputManagerImpl()
   at System.Windows.Input.InputManager.get_Current()
   at System.Windows.Input.KeyboardNavigation..ctor()
   at System.Windows.FrameworkElement.FrameworkServices..ctor()
   at System.Windows.FrameworkElement.EnsureFrameworkServices()
   at System.Windows.FrameworkElement..ctor()
   at System.Windows.Controls.Control..ctor()
   at System.Windows.Window..ctor()
   at MyDll.MyWPFDialog..ctor()
Posted 09 Feb, 2011 09:55:44 Top
Eugene Astafiev


Guest


Hi Daniel,

Please take a look at the http://www.add-in-express.com/files/projects_pub/winformoverwordinoutlook.zip. Does it help?
Posted 09 Feb, 2011 13:36:45 Top
Daniel Garcia




Posts: 9
Joined: 2010-10-14
Hi Eugene,

Thanks, your suggestion may help (we are testing and will report back ASAP) but I hope there is a cleaner way to fix this issue because of a couple of practical requirements that I did not mention in my original post:

1) [MyDll] is being used in different contexts outside of our add-in-express plugin, so ideally we'd like to keep [MyDll] intact. Your suggestion seems to require modifying every form in [MyDll] to handle the "Closed" event to send the WM_MYMESSAGES2 message. Not fun, but we can do this if we must.

2) [MyDll] contains not only forms, but also methods like [MyDll.MyHandler.RunWizard()] which takes the user through a bunch of forms. All of that workflow is encapsulated inside [MyDll], including the creation and displaying of the necessary forms, so I'm not sure how we would apply your suggestion here?

So, basically what we need is a way to "set things up" in the add-in in a way that let's [MyDll] do whatever it wants in terms of opening/closing WPF forms internally. Do you think there is any hope of achieving this?
Posted 09 Feb, 2011 20:28:27 Top
Eugene Astafiev


Guest


Hi Daniel,

Note, in case of Word editor a button event handler of the inspector window is executed in another thread. Please try to use the approach implemented in the sample add-in project I posted above. Does it work for you? If not, could you please send a sample (newly created, not your complex one) add-in project which can reproduce the issue to the support e-mail address (see readme.txt for details)?
Posted 10 Feb, 2011 12:13:52 Top
Daniel Garcia




Posts: 9
Joined: 2010-10-14
Hi Eugene,

Thanks, your sample avoids the STA error during form creation, and I'm showing the pseudo-code below in case it helps someone else (it is based on the sample you sent).

But before that, a couple of questions about your last post:

1) Is this "event-handler-in-another-thread" something that affects all versions of Outlook? (we have only encountered it in 2003)

2) So, if I understand your last post correctly, all we need to do is to "forward" the event (via SendMessage) to the main thread and then do whatever we want from there, like calling MyDll.MyHandler.RunWizard()?


And here is the pseudo-code. Note that since we are using wpf we are dealing with the parent/owner window issue in a different manner than in your sample:

Private Const WM_USER As Integer = &H400
Private Const WM_MYMESSAGES1 As Integer = WM_USER + 1001
Private Const WM_MYMESSAGES2 As Integer = WM_USER + 1002

Private mySettingsForm As MyDll.MyWpfDialog = Nothing

Private Sub Button_Settings4_Click(ByVal sender As Object) Handles Button_Settings4.Click
   Me.SendMessage(WM_MYMESSAGES1, IntPtr.Zero, IntPtr.Zero)
End Sub

Private Sub AddinModule_OnSendMessage(ByVal sender As Object, ByVal e As AddinExpress.MSO.ADXSendMessageEventArgs) Handles Me.OnSendMessage
   Select Case e.Message
       Case WM_MYMESSAGES1
           SyncLock Me
               Try
                   If (mySettingsForm Is Nothing) Then
                       mySettingsForm = New MyDll.MyWpfDialog() 
                       Dim theInteropHelper As Windows.Interop.WindowInteropHelper = New Windows.Interop.WindowInteropHelper(mySettingsForm)
                       theInteropHelper.Owner = Me.NativeWindowHandle
                       AddHandler mySettingsForm.Closed, AddressOf mySettingsForm_Closed
                   End If
                   mySettingsForm.ShowDialog()
                Catch
                End Try
            End SyncLock
            Exit Select
        Case WM_MYMESSAGES2
            SyncLock Me
                mySettingsForm = Nothing
            End SyncLock
            Exit Select
    End Select
End Sub

Private Sub mySettingsForm_Closed(ByVal sender As Object, ByVal e As System.EventArgs)
    Me.SendMessage(WM_MYMESSAGES2, IntPtr.Zero, IntPtr.Zero)
End Sub
Posted 10 Feb, 2011 14:19:21 Top
Eugene Astafiev


Guest


Hi Daniel,

1. Nope. As far as I know only Outlook 2003 uses Word as an e-mail editor.
2. Exactly! You are on the right avenue.

Good luck with your add-in project!
Posted 11 Feb, 2011 06:32:27 Top