From b3c0aae95129d80f7b6f8983a27c73adcb7b9c19 Mon Sep 17 00:00:00 2001
From: Patrick Simpson
Date: Mon, 13 Feb 2017 14:02:37 +0100
Subject: [PATCH] Further event hooking tests
---
.../AcaciaZPushPlugin.csproj | 2 +
.../AcaciaZPushPlugin/Stubs/IItem.cs | 8 +
.../AcaciaZPushPlugin/Stubs/IItemEvents.cs | 44 +++++
.../OutlookWrappers/ItemEventsWrapper.cs | 179 ++++++++++++++++++
.../OutlookWrappers/OutlookItemWrapper.cs | 11 ++
.../AcaciaZPushPlugin/Stubs/Wrappers.cs | 8 +-
.../AcaciaZPushPlugin/Utils/MailEvents.cs | 139 ++++++--------
7 files changed, 307 insertions(+), 84 deletions(-)
create mode 100644 src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/IItemEvents.cs
create mode 100644 src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/ItemEventsWrapper.cs
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/AcaciaZPushPlugin.csproj b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/AcaciaZPushPlugin.csproj
index 1a546d4..746e59c 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/AcaciaZPushPlugin.csproj
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/AcaciaZPushPlugin.csproj
@@ -285,12 +285,14 @@
+
+
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/IItem.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/IItem.cs
index 30ed2a0..5846ab6 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/IItem.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/IItem.cs
@@ -34,6 +34,14 @@ namespace Acacia.Stubs
string Body { get; set; }
string Subject { get; set; }
+ ///
+ /// Returns the events for the item. The same object is returned, it does not need to be disposed.
+ ///
+ IItemEvents Events
+ {
+ get;
+ }
+
#endregion
#region User properties
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/IItemEvents.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/IItemEvents.cs
new file mode 100644
index 0000000..7628d9c
--- /dev/null
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/IItemEvents.cs
@@ -0,0 +1,44 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using NSOutlook = Microsoft.Office.Interop.Outlook;
+
+namespace Acacia.Stubs
+{
+ public interface IItemEvents
+ {
+ #region Event handlers
+
+ // TODO: custom delegates
+ event NSOutlook.ItemEvents_10_AfterWriteEventHandler AfterWrite;
+ event NSOutlook.ItemEvents_10_AttachmentAddEventHandler AttachmentAdd;
+ event NSOutlook.ItemEvents_10_AttachmentReadEventHandler AttachmentRead;
+ event NSOutlook.ItemEvents_10_AttachmentRemoveEventHandler AttachmentRemove;
+ event NSOutlook.ItemEvents_10_BeforeAttachmentAddEventHandler BeforeAttachmentAdd;
+ event NSOutlook.ItemEvents_10_BeforeAttachmentPreviewEventHandler BeforeAttachmentPreview;
+ event NSOutlook.ItemEvents_10_BeforeAttachmentReadEventHandler BeforeAttachmentRead;
+ event NSOutlook.ItemEvents_10_BeforeAttachmentSaveEventHandler BeforeAttachmentSave;
+ event NSOutlook.ItemEvents_10_BeforeAttachmentWriteToTempFileEventHandler BeforeAttachmentWriteToTempFile;
+ event NSOutlook.ItemEvents_10_BeforeAutoSaveEventHandler BeforeAutoSave;
+ event NSOutlook.ItemEvents_10_BeforeCheckNamesEventHandler BeforeCheckNames;
+ event NSOutlook.ItemEvents_10_BeforeDeleteEventHandler BeforeDelete;
+ event NSOutlook.ItemEvents_10_BeforeReadEventHandler BeforeRead;
+ event NSOutlook.ItemEvents_10_CloseEventHandler Close;
+ event NSOutlook.ItemEvents_10_CustomActionEventHandler CustomAction;
+ event NSOutlook.ItemEvents_10_CustomPropertyChangeEventHandler CustomPropertyChange;
+ event NSOutlook.ItemEvents_10_ForwardEventHandler Forward;
+ event NSOutlook.ItemEvents_10_OpenEventHandler Open;
+ event NSOutlook.ItemEvents_10_PropertyChangeEventHandler PropertyChange;
+ event NSOutlook.ItemEvents_10_ReadEventHandler Read;
+ event NSOutlook.ItemEvents_10_ReadCompleteEventHandler ReadComplete;
+ event NSOutlook.ItemEvents_10_ReplyEventHandler Reply;
+ event NSOutlook.ItemEvents_10_ReplyAllEventHandler ReplyAll;
+ event NSOutlook.ItemEvents_10_SendEventHandler Send;
+ event NSOutlook.ItemEvents_10_UnloadEventHandler Unload;
+ event NSOutlook.ItemEvents_10_WriteEventHandler Write;
+
+ #endregion
+ }
+}
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/ItemEventsWrapper.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/ItemEventsWrapper.cs
new file mode 100644
index 0000000..378f125
--- /dev/null
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/ItemEventsWrapper.cs
@@ -0,0 +1,179 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using NSOutlook = Microsoft.Office.Interop.Outlook;
+
+namespace Acacia.Stubs.OutlookWrappers
+{
+ class ItemEventsWrapper : IItemEvents
+ {
+ private readonly NSOutlook.ItemEvents_10_Event _item;
+
+ internal ItemEventsWrapper(object item)
+ {
+ this._item = (NSOutlook.ItemEvents_10_Event)item;
+ }
+
+ #region Events
+
+ public event NSOutlook.ItemEvents_10_AfterWriteEventHandler AfterWrite
+ {
+ add { _item.AfterWrite += value; }
+ remove { _item.AfterWrite -= value; }
+ }
+
+ public event NSOutlook.ItemEvents_10_AttachmentAddEventHandler AttachmentAdd
+ {
+ add { _item.AttachmentAdd += value; }
+ remove { _item.AttachmentAdd -= value; }
+ }
+
+ public event NSOutlook.ItemEvents_10_AttachmentReadEventHandler AttachmentRead
+ {
+ add { _item.AttachmentRead += value; }
+ remove { _item.AttachmentRead -= value; }
+ }
+
+ public event NSOutlook.ItemEvents_10_AttachmentRemoveEventHandler AttachmentRemove
+ {
+ add { _item.AttachmentRemove += value; }
+ remove { _item.AttachmentRemove -= value; }
+ }
+
+ public event NSOutlook.ItemEvents_10_BeforeAttachmentAddEventHandler BeforeAttachmentAdd
+ {
+ add { _item.BeforeAttachmentAdd += value; }
+ remove { _item.BeforeAttachmentAdd -= value; }
+ }
+
+ public event NSOutlook.ItemEvents_10_BeforeAttachmentPreviewEventHandler BeforeAttachmentPreview
+ {
+ add { _item.BeforeAttachmentPreview += value; }
+ remove { _item.BeforeAttachmentPreview -= value; }
+ }
+
+ public event NSOutlook.ItemEvents_10_BeforeAttachmentReadEventHandler BeforeAttachmentRead
+ {
+ add { _item.BeforeAttachmentRead += value; }
+ remove { _item.BeforeAttachmentRead -= value; }
+ }
+
+ public event NSOutlook.ItemEvents_10_BeforeAttachmentSaveEventHandler BeforeAttachmentSave
+ {
+ add { _item.BeforeAttachmentSave += value; }
+ remove { _item.BeforeAttachmentSave -= value; }
+ }
+
+ public event NSOutlook.ItemEvents_10_BeforeAttachmentWriteToTempFileEventHandler BeforeAttachmentWriteToTempFile
+ {
+ add { _item.BeforeAttachmentWriteToTempFile += value; }
+ remove { _item.BeforeAttachmentWriteToTempFile -= value; }
+ }
+
+ public event NSOutlook.ItemEvents_10_BeforeAutoSaveEventHandler BeforeAutoSave
+ {
+ add { _item.BeforeAutoSave += value; }
+ remove { _item.BeforeAutoSave -= value; }
+ }
+
+ public event NSOutlook.ItemEvents_10_BeforeCheckNamesEventHandler BeforeCheckNames
+ {
+ add { _item.BeforeCheckNames += value; }
+ remove { _item.BeforeCheckNames -= value; }
+ }
+
+ public event NSOutlook.ItemEvents_10_BeforeDeleteEventHandler BeforeDelete
+ {
+ add { _item.BeforeDelete += value; }
+ remove { _item.BeforeDelete -= value; }
+ }
+
+ public event NSOutlook.ItemEvents_10_BeforeReadEventHandler BeforeRead
+ {
+ add { _item.BeforeRead += value; }
+ remove { _item.BeforeRead -= value; }
+ }
+
+ public event NSOutlook.ItemEvents_10_CloseEventHandler Close
+ {
+ add { _item.Close += value; }
+ remove { _item.Close -= value; }
+ }
+
+ public event NSOutlook.ItemEvents_10_CustomActionEventHandler CustomAction
+ {
+ add { _item.CustomAction += value; }
+ remove { _item.CustomAction -= value; }
+ }
+
+ public event NSOutlook.ItemEvents_10_CustomPropertyChangeEventHandler CustomPropertyChange
+ {
+ add { _item.CustomPropertyChange += value; }
+ remove { _item.CustomPropertyChange -= value; }
+ }
+
+ public event NSOutlook.ItemEvents_10_ForwardEventHandler Forward
+ {
+ add { _item.Forward += value; }
+ remove { _item.Forward -= value; }
+ }
+
+ public event NSOutlook.ItemEvents_10_OpenEventHandler Open
+ {
+ add { _item.Open += value; }
+ remove { _item.Open -= value; }
+ }
+
+ public event NSOutlook.ItemEvents_10_PropertyChangeEventHandler PropertyChange
+ {
+ add { _item.PropertyChange += value; }
+ remove { _item.PropertyChange -= value; }
+ }
+
+ public event NSOutlook.ItemEvents_10_ReadEventHandler Read
+ {
+ add { _item.Read += value; }
+ remove { _item.Read -= value; }
+ }
+
+ public event NSOutlook.ItemEvents_10_ReadCompleteEventHandler ReadComplete
+ {
+ add { _item.ReadComplete += value; }
+ remove { _item.ReadComplete -= value; }
+ }
+
+ public event NSOutlook.ItemEvents_10_ReplyEventHandler Reply
+ {
+ add { _item.Reply += value; }
+ remove { _item.Reply -= value; }
+ }
+
+ public event NSOutlook.ItemEvents_10_ReplyAllEventHandler ReplyAll
+ {
+ add { _item.ReplyAll += value; }
+ remove { _item.ReplyAll -= value; }
+ }
+
+ public event NSOutlook.ItemEvents_10_SendEventHandler Send
+ {
+ add { _item.Send += value; }
+ remove { _item.Send -= value; }
+ }
+
+ public event NSOutlook.ItemEvents_10_UnloadEventHandler Unload
+ {
+ add { _item.Unload += value; }
+ remove { _item.Unload -= value; }
+ }
+
+ public event NSOutlook.ItemEvents_10_WriteEventHandler Write
+ {
+ add { _item.Write += value; }
+ remove { _item.Write -= value; }
+ }
+
+ #endregion
+ }
+}
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/OutlookItemWrapper.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/OutlookItemWrapper.cs
index eb95a3b..61a352a 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/OutlookItemWrapper.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/OutlookItemWrapper.cs
@@ -16,6 +16,17 @@ namespace Acacia.Stubs.OutlookWrappers
{
}
+ private ItemEventsWrapper _events;
+ public IItemEvents Events
+ {
+ get
+ {
+ if (_events == null)
+ _events = new ItemEventsWrapper(_item);
+ return _events;
+ }
+ }
+
public Type GetUserProperty(string name)
{
using (ComRelease com = new ComRelease())
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/Wrappers.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/Wrappers.cs
index cae4834..a30c9a7 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/Wrappers.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/Wrappers.cs
@@ -15,10 +15,16 @@ namespace Acacia.Stubs
return Mapping.WrapOrDefault(obj);
}
- public static WrapType Wrap(object o, bool mustRelease = true)
+ public static WrapType Wrap(this object o, bool mustRelease = true)
where WrapType : IBase
{
return Mapping.Wrap(o, mustRelease);
}
+
+ public static WrapType WrapOrDefault(this object o, bool mustRelease = true)
+ where WrapType : IBase
+ {
+ return Mapping.WrapOrDefault(o, mustRelease);
+ }
}
}
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Utils/MailEvents.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Utils/MailEvents.cs
index 0a9442f..044562d 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Utils/MailEvents.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Utils/MailEvents.cs
@@ -21,7 +21,6 @@ using System.Text;
using System.Threading.Tasks;
using Acacia.Stubs;
using Acacia.Stubs.OutlookWrappers;
-using NSOutlook = Microsoft.Office.Interop.Outlook;
namespace Acacia.Utils
{
@@ -47,22 +46,18 @@ namespace Acacia.Utils
public event MailResponseEventHandler Respond;
public event MailResponseEventHandler Reply;
- private void OnReply(NSOutlook.MailItem mail, NSOutlook.MailItem response)
+ private void OnReply(IMailItem mail, IMailItem response)
{
// TODO: check release of first item
// TODO: release if not sending event
try
{
- if ((Reply != null || Respond != null) && mail != null)
+ if ((Reply != null || Respond != null) && mail != null && response != null)
{
- using (IMailItem mailWrapped = Mapping.Wrap(mail, false),
- responseWrapped = Mapping.Wrap(response))
- {
- if (Reply != null)
- Reply(mailWrapped, responseWrapped);
- if (Respond != null)
- Respond(mailWrapped, responseWrapped);
- }
+ if (Reply != null)
+ Reply(mail, response);
+ if (Respond != null)
+ Respond(mail, response);
}
}
catch (System.Exception e)
@@ -72,22 +67,18 @@ namespace Acacia.Utils
}
public event MailResponseEventHandler ReplyAll;
- private void OnReplyAll(NSOutlook.MailItem mail, NSOutlook.MailItem response)
+ private void OnReplyAll(IMailItem mail, IMailItem response)
{
// TODO: check release of first item
// TODO: release if not sending event
try
{
- if ((ReplyAll != null || Respond != null) && mail != null)
+ if ((ReplyAll != null || Respond != null) && mail != null && response != null)
{
- using (IMailItem mailWrapped = Mapping.Wrap(mail, false),
- responseWrapped = Mapping.Wrap(response))
- {
- if (ReplyAll != null)
- ReplyAll(mailWrapped, responseWrapped);
- if (Respond != null)
- Respond(mailWrapped, responseWrapped);
- }
+ if (ReplyAll != null)
+ ReplyAll(mail, response);
+ if (Respond != null)
+ Respond(mail, response);
}
}
catch (System.Exception e)
@@ -97,22 +88,18 @@ namespace Acacia.Utils
}
public event MailResponseEventHandler Forward;
- private void OnForward(NSOutlook.MailItem mail, NSOutlook.MailItem response)
+ private void OnForward(IMailItem mail, IMailItem response)
{
// TODO: check release of first item
// TODO: release if not sending event
try
{
- if ((Forward != null || Respond != null) && mail != null)
+ if ((Forward != null || Respond != null) && mail != null && response != null)
{
- using (IMailItem mailWrapped = Mapping.Wrap(mail, false),
- responseWrapped = Mapping.Wrap(response))
- {
- if (Forward != null)
- Forward(mailWrapped, responseWrapped);
- if (Respond != null)
- Respond(mailWrapped, responseWrapped);
- }
+ if (Forward != null)
+ Forward(mail, response);
+ if (Respond != null)
+ Respond(mail, response);
}
}
catch (System.Exception e)
@@ -122,18 +109,13 @@ namespace Acacia.Utils
}
public event MailEventHandler Read;
- private void OnRead(NSOutlook.MailItem mail)
+ private void OnRead(IMailItem mail)
{
- // TODO: check release of first item
- // TODO: release if not sending event
try
{
if (Read != null && mail != null)
{
- using (IMailItem wrapped = Mapping.Wrap(mail, false))
- {
- Read(wrapped);
- }
+ Read(mail);
}
}
catch (System.Exception e)
@@ -143,17 +125,13 @@ namespace Acacia.Utils
}
public event CancellableItemEventHandler BeforeDelete;
- private void OnBeforeDelete(object item, ref bool cancel)
+ private void OnBeforeDelete(IItem item, ref bool cancel)
{
try
{
if (BeforeDelete != null && item != null)
{
- using (IItem wrapped = Mapping.Wrap(item, false))
- {
- if (wrapped != null)
- BeforeDelete(wrapped, ref cancel);
- }
+ BeforeDelete(item, ref cancel);
}
}
catch(System.Exception e)
@@ -164,17 +142,13 @@ namespace Acacia.Utils
// TODO: should this be CancellableMailItemEventHandler?
public event CancellableItemEventHandler Write;
- private void OnWrite(object item, ref bool cancel)
+ private void OnWrite(IItem item, ref bool cancel)
{
try
{
if (Write != null && item != null)
{
- using (IItem wrapped = Mapping.Wrap(item, false))
- {
- if (wrapped != null)
- Write(wrapped, ref cancel);
- }
+ Write(item, ref cancel);
}
}
catch (System.Exception e)
@@ -216,104 +190,103 @@ namespace Acacia.Utils
private void OnItemLoad(object item)
{
- using (IItem wrapped = Wrappers.Wrap(item))
+ IItem wrapped = Wrappers.Wrap(item);
+ // TODO: check type
+ if (wrapped != null)
{
+ new MailEventHooker(wrapped, this);
}
-
- /*
- NSOutlook.ItemEvents_10_Event hasEvents = item as NSOutlook.ItemEvents_10_Event;
- if (hasEvents != null)
- {
- new MailEventHooker(hasEvents, this);
- }*/
}
- private class MailEventHooker : ComWrapper
+ private class MailEventHooker : DisposableWrapper
{
+ private IItem _item;
private readonly MailEvents _events;
// TODO: remove id and debug logging
private int _id;
private static int nextId;
- public MailEventHooker(NSOutlook.ItemEvents_10_Event itemEvents, MailEvents events) : base(itemEvents)
+ public MailEventHooker(IItem item, MailEvents events)
{
+ this._item = item;
this._id = ++nextId;
this._events = events;
HookEvents(true);
}
- ~MailEventHooker()
+ /*~MailEventHooker()
{
-
}
+ */
protected override void DoRelease()
{
Logger.Instance.Debug(this, "DoRelease: {0}", _id);
// TODO: It looks like release _itemEvents is not only not needed, but causes exceptions.
// If that is really the case, this doesn't need to be a ComWrapper
+ _item.Dispose();
}
private void HookEvents(bool add)
{
if (add)
{
- _item.BeforeDelete += HandleBeforeDelete;
- _item.Forward += HandleForward;
- _item.Read += HandleRead;
- _item.Reply += HandleReply;
- _item.ReplyAll += HandleReplyAll;
- _item.Unload += HandleUnload;
- _item.Write += HandleWrite;
+ _item.Events.BeforeDelete += HandleBeforeDelete;
+ _item.Events.Forward += HandleForward;
+ _item.Events.Read += HandleRead;
+ _item.Events.Reply += HandleReply;
+ _item.Events.ReplyAll += HandleReplyAll;
+ _item.Events.Unload += HandleUnload;
+ _item.Events.Write += HandleWrite;
}
else
{
- _item.BeforeDelete -= HandleBeforeDelete;
- _item.Forward -= HandleForward;
- _item.Read -= HandleRead;
- _item.Reply -= HandleReply;
- _item.ReplyAll -= HandleReplyAll;
- _item.Unload -= HandleUnload;
- _item.Write -= HandleWrite;
+ _item.Events.BeforeDelete -= HandleBeforeDelete;
+ _item.Events.Forward -= HandleForward;
+ _item.Events.Read -= HandleRead;
+ _item.Events.Reply -= HandleReply;
+ _item.Events.ReplyAll -= HandleReplyAll;
+ _item.Events.Unload -= HandleUnload;
+ _item.Events.Write -= HandleWrite;
}
}
private void HandleBeforeDelete(object item, ref bool cancel)
{
Logger.Instance.Debug(this, "HandleBeforeDelete: {0}", _id);
- _events.OnBeforeDelete(item, ref cancel);
+ _events.OnBeforeDelete(item.WrapOrDefault(), ref cancel);
}
private void HandleForward(object response, ref bool cancel)
{
Logger.Instance.Debug(this, "HandleForward: {0}", _id);
- _events.OnForward(_item as NSOutlook.MailItem, response as NSOutlook.MailItem);
+ _events.OnForward(_item as IMailItem, response.WrapOrDefault());
}
private void HandleRead()
{
Logger.Instance.Debug(this, "HandleRead: {0}", _id);
- _events.OnRead(_item as NSOutlook.MailItem);
+ _events.OnRead(_item as IMailItem);
}
private void HandleReply(object response, ref bool cancel)
{
Logger.Instance.Debug(this, "HandleReply: {0}", _id);
- _events.OnReply(_item as NSOutlook.MailItem, response as NSOutlook.MailItem);
+ _events.OnReply(_item as IMailItem, response.WrapOrDefault());
}
private void HandleReplyAll(object response, ref bool cancel)
{
Logger.Instance.Debug(this, "HandleReplyAll: {0}", _id);
- _events.OnReplyAll(_item as NSOutlook.MailItem, response as NSOutlook.MailItem);
+ _events.OnReplyAll(_item as IMailItem, response.WrapOrDefault());
}
private void HandleUnload()
{
Logger.Instance.Debug(this, "HandleUnload: {0}", _id);
// All events must be unhooked on unload, otherwise a resource leak is created.
- //HookEvents(false);
- //Dispose();
+ HookEvents(false);
+ Dispose();
}
private void HandleWrite(ref bool cancel)