can't get AdxOutlookAppEvents1_ExplorerSelectionChange to behave

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

can't get AdxOutlookAppEvents1_ExplorerSelectionChange to behave
the same as AdxOutlookAppEvents1_InspectorActivate 
Gordon Prince


Guest


I can't figure out why the first procedure works and the second one doesn't. What I want to get is to have my Add-in respond to the ProcessBeforeAttachmentRead event.

If I open the item in an Inspector window everything behaves properly.
    Private Sub AdxOutlookAppEvents1_InspectorActivate(sender As Object, inspector As Object, folderName As String) Handles AdxOutlookAppEvents1.InspectorActivate
        Dim myInsp As Outlook.Inspector = Nothing
        Dim item As Object = Nothing
        Try
            myInsp = inspector
            item = myInsp.CurrentItem
            If itemEvents.IsConnected Then itemEvents.RemoveConnection()
            itemEvents.ConnectTo(item, True)
            Marshal.ReleaseComObject(item)
            Debug.Print("AdxOutlookAppEvents1_InspectorActivate itemEvents.ConnectTo(item, True) fired")
        Catch
        Finally
            If item IsNot Nothing Then Marshal.ReleaseComObject(item) : item = Nothing
            ' don't release myInsp
        End Try
    End Sub

But making it the active selection in an Explorer window doesn't fire the events -- most of the time. If I open the item in an Inspector window, close it and leave it the active selection, then the ProcessBeforeAttachmentRead fires and everything behaves. But most of the time it doesn't.
    Private Sub AdxOutlookAppEvents1_ExplorerSelectionChange(sender As System.Object, explorer As System.Object) Handles AdxOutlookAppEvents1.ExplorerSelectionChange
        Dim myExplorer As Outlook.Explorer = Nothing
        Dim sel As Outlook.Selection = Nothing
        Dim item As Object = Nothing
        Try
            myExplorer = CType(explorer, Outlook.Explorer)
            If myExplorer Is Nothing Then Return
            Try
                sel = myExplorer.Selection
            Catch ex As Exception
            End Try
            If sel Is Nothing Then Return
            If sel.Count = 1 Then
                item = sel.Item(1)
                If itemEvents.IsConnected Then itemEvents.RemoveConnection()
                itemEvents.ConnectTo(item, True)
                Marshal.ReleaseComObject(item)
                Debug.Print("AdxOutlookAppEvents1_ExplorerSelectionChange itemEvents.ConnectTo(item, True) fired")
            End If
        Finally
            If item IsNot Nothing Then Marshal.ReleaseComObject(item) : item = Nothing
            If sel IsNot Nothing Then Marshal.ReleaseComObject(sel) : sel = Nothing
            ' don't release myExplorer
        End Try
    End Sub

What makes the first one work and the second one not?
How can I get the second one to behave the same?
Posted 20 Nov, 2015 08:55:26 Top
Andrei Smolin


Add-in Express team


Posts: 18825
Joined: 2006-05-11
Hello Gordon,

Gordon Prince writes:
If I open the item in an Inspector window, close it and leave it the active selection, then the ProcessBeforeAttachmentRead fires and everything behaves


It looks like you don't handle the ExplorerActivate event; it should connect to the currently selected item.

I suppose BeforeAttachmentRead doesn't fire in this scenario; please check if BeforeAttachmentPreview fires.


Andrei Smolin
Add-in Express Team Leader
Posted 20 Nov, 2015 09:23:50 Top
Gordon Prince


Guest


I've had this (but didn't include it in the initial post):
    Private Sub AdxOutlookAppEvents1_ExplorerActivate(sender As Object, explorer As Object) Handles AdxOutlookAppEvents1.ExplorerActivate
        Dim theExplorer As Outlook.Explorer = Nothing
        Dim selection As Outlook.Selection = Nothing
        Try
            theExplorer = TryCast(explorer, Outlook.Explorer)
            If theExplorer IsNot Nothing Then
                Try
                    selection = theExplorer.Selection
                Catch
                End Try
                If selection IsNot Nothing Then
                    ConnectToSelectedItem(selection)
                    Debug.Print("AdxOutlookAppEvents1_ExplorerActivate called ConnectToSelectedItem(selection)")
                End If
            End If
        Finally
            If selection IsNot Nothing Then Marshal.ReleaseComObject(selection) : selection = Nothing
            ' don't release theExplorer
        End Try
    End Sub

It's using the ConnectToSelectedItem(selection) instead of itemEvents.ConnectTo(item, True), and I don't know why.
    Private Sub ConnectToSelectedItem(ByVal selection As Outlook.Selection)
        If selection IsNot Nothing Then
            If selection.Count = 1 Then
                Dim item As Object = selection.Item(1)
                If itemEvents.IsConnected Then itemEvents.RemoveConnection()
                itemEvents.ConnectTo(item, True)
                Marshal.ReleaseComObject(item) : item = Nothing
                ' Debug.Print("ConnectToSelectedItem() itemEvents.ConnectTo(item, True) fired")
            End If
        End If
    End Sub

When should I use which? Is this what's causing the problem?
Posted 20 Nov, 2015 10:32:48 Top
Gordon Prince


Guest


And is this legitimate?

    Private Sub AdxOutlookAppEvents1_ExplorerActivate(sender As Object, explorer As Object) Handles AdxOutlookAppEvents1.ExplorerActivate

        AdxOutlookAppEvents1_ExplorerSelectionChange(sender, explorer)
    End Sub

If I want them to behave the same, then this would make them, wouldn't it?
Posted 20 Nov, 2015 10:37:37 Top
Gordon Prince


Guest


I think maybe it's this pair of lines in the code that is causing the problem:
            itemEvents.ConnectTo(item, True)   
            Marshal.ReleaseComObject(item)  

If I comment out the
Marshal.ReleaseComObject(item)

everything seems to work properly.

Does that make sense to you?
Posted 21 Nov, 2015 10:58:31 Top
Gordon Prince


Guest


Also, what about this to insure both events behave the same:
    Private Sub AdxOutlookAppEvents1_ExplorerActivate(sender As Object, explorer As Object) Handles _
        AdxOutlookAppEvents1.ExplorerActivate, _
        AdxOutlookAppEvents1.ExplorerSelectionChange

Is it ok to have the same procedure handle two different events? My inclination is that it's reusable code, less maintenance, 0% chance the behaviors will get different (from having two copies of the code).

But I thought I should ask. Does this look ok to you? Or should I not do this?

Cheers.
Posted 21 Nov, 2015 11:00:27 Top
Gordon Prince


Guest


This is what I wound up with, and it seems to be working:
Private Sub AdxOutlookAppEvents1_InspectorActivate(sender As Object, inspector As Object, folderName As String) Handles AdxOutlookAppEvents1.InspectorActivate
        Dim myInsp As Outlook.Inspector = Nothing
        Dim item As Object = Nothing
        Try
            myInsp = inspector
            item = myInsp.CurrentItem
            If itemEvents.IsConnected Then itemEvents.RemoveConnection()
            itemEvents.ConnectTo(item, True)
        Catch ex As Exception
        Finally
        End Try
    End Sub

    Private Sub AdxOutlookAppEvents1_ExplorerActivate(sender As Object, explorer As Object) Handles _
                AdxOutlookAppEvents1.ExplorerActivate, _
                AdxOutlookAppEvents1.ExplorerSelectionChange
        Dim myExplorer As Outlook.Explorer = TryCast(explorer, Outlook.Explorer)
        If myExplorer Is Nothing Then Return
        Dim sel As Outlook.Selection = Nothing
        Dim item As Object = Nothing
        Try
            sel = myExplorer.Selection
        Catch
        End Try
        If sel Is Nothing Then Return
        Try
            If sel.Count = 1 Then
                item = sel.Item(1)
                If itemEvents.IsConnected Then itemEvents.RemoveConnection()
                itemEvents.ConnectTo(item, True)
            End If
        Catch ex As Exception
        Finally
            If sel IsNot Nothing Then Marshal.ReleaseComObject(sel) : sel = Nothing
        End Try
    End Sub

I got rid of completely the NewInspector event, since it is followed by the InspectorActivate event. So as you suggested, no point in having the logic fire twice, once via NewInspector then immediately again via InspectorActivate.

Also, in the first procedure I don't release any of the objects.
myInsp is passed into the procedure, so it shouldn't be released.
item gets connected to the events, so if it's released it won't be responding any more.
Am I thinking about this right?

Looking forward to any thoughts you have about this. As I said, it seems to be working.

Thanks.
Posted 22 Nov, 2015 19:03:00 Top
Andrei Smolin


Add-in Express team


Posts: 18825
Joined: 2006-05-11
Hello Gordon,

Gordon Prince writes:
It's using the ConnectToSelectedItem(selection) instead of itemEvents.ConnectTo(item, True), and I don't know why.


ConnectToSelectedItem connects to the item and immediately releases it; you don't get events from it any longer.

Gordon Prince writes:
If I comment out the Marshal.ReleaseComObject(item)
everything seems to work properly.
Does that make sense to you?


It does.

Gordon Prince writes:
If I want them to behave the same, then this would make them, wouldn't it?


You can use the Properties window to assign the same method as an event handler of several events.

Gordon Prince writes:
This is what I wound up with, and it seems to be working:


I don't see any problem in that code.


Andrei Smolin
Add-in Express Team Leader
Posted 23 Nov, 2015 03:47:13 Top
Gordon Prince


Guest


Thanks for your review and comments. Cheers.
Posted 23 Nov, 2015 04:08:58 Top
Andrei Smolin


Add-in Express team


Posts: 18825
Joined: 2006-05-11
You are welcome!


Andrei Smolin
Add-in Express Team Leader
Posted 23 Nov, 2015 04:33:05 Top