What are differences between adxOutlookEvents_ItemSend and ProcessSend?

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

What are differences between adxOutlookEvents_ItemSend and ProcessSend?
 
Byung Kun Kim




Posts: 48
Joined: 2011-12-15
There are two different locations that I can handle outlook mail send event.
Which one is better? Just the same functionality? One thing I know is 'adxOutlookEvents_ItemSend' can be used without connectTo method.

1)
Private Sub adxOutlookEvents_ItemSend(sender As Object, e As ADXOlItemSendEventArgs) Handles adxOutlookEvents.ItemSend

2)
Public Class OlItemEvents
Inherits AddinExpress.MSO.ADXOutlookItemEvents

Public Overrides Sub ProcessSend(ByVal E As AddinExpress.MSO.ADXCancelEventArgs)

And another question.

In one of your example source code, 'outlookItemEvents.ConnectTo' is called when InspectorActivate. InspectorActivate(and ExploreActivate either) event occurs on every inspector window or outlook itself got focused. Is it safe to call connectTo method multiple times without removeConnection? (Though adxOutlookEvents_InspectorClose event occurs just one time when inpector window closed.)

Private Sub adxOutlookEvents_InspectorActivate(sender As Object, inspector As Object, folderName As String) Handles adxOutlookEvents.InspectorActivate
LF("The InspectorActivate event has occurred.")

If canConnect Then
Dim olInsp As Outlook._Inspector = DirectCast(inspector, Outlook._Inspector)
Dim item As Object = olInsp.CurrentItem

If TypeOf item Is Outlook._MailItem Then
outlookItemEvents.ConnectTo(item, True)
End If
End If
End Sub

Private Sub adxOutlookEvents_InspectorClose(sender As Object, inspector As Object, folderName As String) Handles adxOutlookEvents.InspectorClose
LF("The InspectorClose event has occurred.")

If outlookItemEvents IsNot Nothing Then
outlookItemEvents.RemoveConnection()
End If
End Sub
Posted 09 Nov, 2016 07:15:06 Top
Andrei Smolin


Add-in Express team


Posts: 14140
Joined: 2006-05-11
Hello Byung,

adxOutlookEvents_ItemSend is the Application.ItemSend event described at https://msdn.microsoft.com/en-us/library/office/ff865076.aspx.

ProcessSend is the MailItem.Send event described at https://msdn.microsoft.com/en-us/library/office/ff865379.aspx.

adxOutlookEvents_ItemSend is the last event which occurs during the process of sending an email. Note that MailItem.Send occurs on an early stage; the user may cancel the process "manually" after this event occurs.

Byung Kun Kim writes:
In one of your example source code, 'outlookItemEvents.ConnectTo' is called when InspectorActivate. InspectorActivate(and ExploreActivate either) event occurs on every inspector window or outlook itself got focused. Is it safe to call connectTo method multiple times without removeConnection?


In almost all examples I created, I implemented the approach requiring just one instance of the events class. This instance is reconnected to the selected Outlook item when you select an item or when you activate an explorer window. This events class instance is connected to the opened Outlook item when you activate an inspector window. When using this approach, you need to disconnect from the previously connected item before connecting the class to another item.

In other situations, you may need to manage an array (list, dictionary) of events class instances. The reconnection logic may be different but disconnecting from an item (it is a COM object!) is correct when reconnecting the events class to another item.

Regards from Belarus (GMT+3),

Andrei Smolin
Add-in Express Team Leader
Posted 09 Nov, 2016 09:25:39 Top
Byung Kun Kim




Posts: 48
Joined: 2011-12-15
the user may cancel the process "manually"


Thank you for your reply, could you please how user can cancel? some delayed mail you mean?
-> I tested, but using delayed mail option, both two events occurred when I click send button. (here, another question, how can I capture delayed mail send event? no event was captured)

Could you explain some usage scenarios? when to use Application.ItemSend and when to use MailItem.Send events?

---

When using only one itemEvents class instance, with connectTo on InspectorActivate, ProcessBeforeAttachmentAdd event was missed when I drop a file to no-focused window. or send button click on not-focused window. I'm not sure both of them or one was missed the events. (some old memory)


Does reconnecting needed when creating each itemEvents for inspector? Can I approach below way? connect on NewInspector and removeConnection on InspectorClose. This time what can be the key for dictionary, 'inspector As Object' can be a key?


    Dim itemEventsList2 As New Dictionary(Of Outlook.Inspector, ItemEvents)

    Private Sub adxOutlookEvents_NewInspector(sender As Object, inspector As Object, folderName As String) Handles adxOutlookEvents.NewInspector
        Dim olInsp As Outlook._Inspector = DirectCast(inspector, Outlook._Inspector)
        Dim item As Object = olInsp.CurrentItem

        If TypeOf item Is Outlook._MailItem Then
            Dim itemEvents2 As New ItemEvents(Me)
            itemEventsList2.Add(inspector, itemEvents2)
            itemEvents2.ConnectTo(item, True)
        End If
    End Sub

    Private Sub adxOutlookEvents_InspectorClose(sender As Object, inspector As Object, folderName As String) Handles adxOutlookEvents.InspectorClose
        itemEventsList2(inspector).RemoveConnection()
        itemEventsList2(inspector).Dispose()
        itemEventsList2.Remove(inspector)
    End Sub
Posted 09 Nov, 2016 12:11:06 Top
Andrei Smolin


Add-in Express team


Posts: 14140
Joined: 2006-05-11
Hello Byung,

Byung Kun Kim writes:
Thank you for your reply, could you please how user can cancel? some delayed mail you mean?


Imagine entering an incorrect email address which isn't recognized when the recipient is being resolved. In this case, Outlook shows a message box which allows the user to cancel the send operation.

Byung Kun Kim writes:
When using only one itemEvents class instance, with connectTo on InspectorActivate, ProcessBeforeAttachmentAdd event was missed when I drop a file to no-focused window. or send button click on not-focused window. I'm not sure both of them or one was missed the events. (some old memory)


I'm afraid, I don't follow. Whatever you do with a non-focused window, it becomes focused as soon as you touch it in any way. Accordingly, this fires the InspectorActivate event. In the event handler you need to disconnect from the currently connected Outlook item and connect to the item from the inspector just activated.

Byung Kun Kim writes:
Does reconnecting needed when creating each itemEvents for inspector?


If you *create* an Item Events class, then you don't need to *re*-connect it.

Byung Kun Kim writes:
Can I approach below way? connect on NewInspector and removeConnection on InspectorClose. This time what can be the key for dictionary, 'inspector As Object' can be a key?


I wouldn't call RemoveConnection on InspectorClose. This is because immediately after closing an inspector you get one of the following events:
- ExplorerActivate
- InspectorActivate (e.g. there was two inspectors, you close one of them, the other one becomes active)
- the add-in unloads

That is, you can use InspectorActivate, ExplorerActivate, and ExplorerSelectionChange to disconnect from the currently connected item and connect to another one. Inspector can't be used as a key. This is because the inspector parameter passed to your event handlers is released as soon as your event handler finishes. This occurs with all COM objects that Add-in Express passes to your code.

You could bypass this restriction by getting an inspector object yourself but I wouldn't recommend this because the Inspector object (actually, each object that the Outlook object model returns) is a COM object. And Outlook is specifically sensitive to COM objects that your add-in doesn't release: many, many problems occur due to a COM object(s) left unreleased.

Could you please describe what you need to achieve? Probably, there are some other ways.

Regards from Belarus (GMT+3),

Andrei Smolin
Add-in Express Team Leader
Posted 10 Nov, 2016 03:02:41 Top
Byung Kun Kim




Posts: 48
Joined: 2011-12-15
I'm afraid, I don't follow. Whatever you do with a non-focused window, it becomes focused as soon as you touch it in any way. Accordingly, this fires the InspectorActivate event. In the event handler you need to disconnect from the currently connected Outlook item and connect to the item from the inspector just activated.


Nope, plz see my screen cam. screen cam

This is OutlookItemEventsDemo running cam, got from ADX blog. I dropped a file to non-focused inspector window. ProcessBeforeAttachmentAdd not occured because of not first activated inspector window.

One itemEvents instance and on InspectorActivate approach have problem, I think.

That's why I'm looking for another way to connecting itemEvents.

I'm using Office 2016.



It seems working well using inspector key dictionary though (just now?), what would you recommend for my approach? for the key! I'm afraid of using inspector as key, too.
Posted 10 Nov, 2016 04:22:05 Top
Byung Kun Kim




Posts: 48
Joined: 2011-12-15
I think that I managed to improve my codes using inspector's hashcode. Any comment plz?


    Dim itemEventsList2 As New Hashtable 'for inspectors

    Private Sub adxOutlookEvents_NewInspector(sender As Object, inspector As Object, folderName As String) Handles adxOutlookEvents.NewInspector
        Dim olInsp As Outlook._Inspector = DirectCast(inspector, Outlook._Inspector)
        Dim item As Object = olInsp.CurrentItem

        If TypeOf item Is Outlook._MailItem Then
            Dim itemEvents2 As New ItemEvents(Me)
            itemEventsList2.Add(inspector.GetHashCode(), itemEvents2)
            LF("inspector reference key added. itemEventsList2.Count: {0}, GetHashCode: {1}", AA(itemEventsList2.Count, inspector.GetHashCode()))
            itemEvents2.ConnectTo(item, True)
        End If
    End Sub

    Private Sub adxOutlookEvents_InspectorClose(sender As Object, inspector As Object, folderName As String) Handles adxOutlookEvents.InspectorClose
        Dim hash As Integer = inspector.GetHashCode()
        itemEventsList2(hash).RemoveConnection()
        itemEventsList2(hash).Dispose()
        itemEventsList2.Remove(hash)
        LF("inspector reference key removed. itemEventsList2.Count: {0}, GetHashCode: {1}", AA(itemEventsList2.Count, hash))
    End Sub


Below is log of ItemsCount and HashCodes. I opened three new compose windows, and closed in reverse order.


2016-11-10 19:41:39,602 [1] DEBUG - [adxOutlookEvents_NewInspector] inspector reference key added. itemEventsList2.Count: 1, GetHashCode: 20031746
2016-11-10 19:41:44,400 [1] DEBUG - [adxOutlookEvents_NewInspector] inspector reference key added. itemEventsList2.Count: 2, GetHashCode: 52493967
2016-11-10 19:41:47,581 [1] DEBUG - [adxOutlookEvents_NewInspector] inspector reference key added. itemEventsList2.Count: 3, GetHashCode: 53182860
2016-11-10 19:42:01,002 [1] DEBUG - [adxOutlookEvents_InspectorClose] inspector reference key removed. itemEventsList2.Count: 2, GetHashCode: 53182860
2016-11-10 19:42:05,469 [1] DEBUG - [adxOutlookEvents_InspectorClose] inspector reference key removed. itemEventsList2.Count: 1, GetHashCode: 52493967
2016-11-10 19:42:09,903 [1] DEBUG - [adxOutlookEvents_InspectorClose] inspector reference key removed. itemEventsList2.Count: 0, GetHashCode: 20031746
Posted 10 Nov, 2016 06:03:00 Top
Andrei Smolin


Add-in Express team


Posts: 14140
Joined: 2006-05-11
Thank you. Now I see. That is, although the event does occur, it isn't handled just because the events class is connected to the events of the Outlook item in the active inspector window.

In this case, you need to connect (re-connect) to items opened in *all* Outlook inspector windows. This means, you need to manage a dictionary of events class instances. The best place to add an instance to that list is the NewInspector event (see the Outlook Events component). To remove such an instance, you need to use the InspectorClose event. And using an Inspector object as the key is rational.

Byung Kun Kim writes:
It seems working well using inspector key dictionary though (just now?), what would you recommend for my approach? for the key! I'm afraid of using inspector key, too.


I suppose this works because Add-in Express maintains a list of inspectors and it releases an Inspector object only when the corresponding inspector closes, right after Add-in Express generates the InspectorClose event. So, it looks like you can use an Inspector object as a key.

Regards from Belarus (GMT+3),

Andrei Smolin
Add-in Express Team Leader
Posted 10 Nov, 2016 06:21:03 Top
Byung Kun Kim




Posts: 48
Joined: 2011-12-15
So, my first question, if I want to validate some user inputs and cancel send, the best place is item level send event(in OlItemEvents) handler .

And if I want to append some text to body (disclaimer or something else) the best place to handle the event is application level ItemSend event handler.

Right?
Posted 10 Nov, 2016 21:27:55 Top
Andrei Smolin


Add-in Express team


Posts: 14140
Joined: 2006-05-11
Ah, I've made a mistake: I posted my response to another topic: please check https://www.add-in-express.com/forum/read.php?FID=5&TID=14226&MID=72836#message72836.

Regards from Belarus (GMT+3),

Andrei Smolin
Add-in Express Team Leader
Posted 11 Nov, 2016 04:28:21 Top