1
0
mirror of https://github.com/Kopano-dev/kopano-ol-extension.git synced 2023-10-10 13:37:40 +02:00

Further event hooking tests

This commit is contained in:
Patrick Simpson 2017-02-13 14:02:37 +01:00
parent a698c4e475
commit b3c0aae951
7 changed files with 307 additions and 84 deletions

View File

@ -285,12 +285,14 @@
<Compile Include="Stubs\ICommandBars.cs" /> <Compile Include="Stubs\ICommandBars.cs" />
<Compile Include="Stubs\IComWrapper.cs" /> <Compile Include="Stubs\IComWrapper.cs" />
<Compile Include="Stubs\IExplorer.cs" /> <Compile Include="Stubs\IExplorer.cs" />
<Compile Include="Stubs\IItemEvents.cs" />
<Compile Include="Stubs\IOutlookWindow.cs" /> <Compile Include="Stubs\IOutlookWindow.cs" />
<Compile Include="Stubs\IRecipient.cs" /> <Compile Include="Stubs\IRecipient.cs" />
<Compile Include="Stubs\OutlookWrappers\AddInWrapper.cs" /> <Compile Include="Stubs\OutlookWrappers\AddInWrapper.cs" />
<Compile Include="Stubs\OutlookWrappers\AddressEntryWrapper.cs" /> <Compile Include="Stubs\OutlookWrappers\AddressEntryWrapper.cs" />
<Compile Include="Stubs\OutlookWrappers\CommandBarsWrapper.cs" /> <Compile Include="Stubs\OutlookWrappers\CommandBarsWrapper.cs" />
<Compile Include="Stubs\OutlookWrappers\ExplorerWrapper.cs" /> <Compile Include="Stubs\OutlookWrappers\ExplorerWrapper.cs" />
<Compile Include="Stubs\OutlookWrappers\ItemEventsWrapper.cs" />
<Compile Include="Stubs\OutlookWrappers\OutlookItemWrapper.cs" /> <Compile Include="Stubs\OutlookWrappers\OutlookItemWrapper.cs" />
<Compile Include="Stubs\OutlookWrappers\RecipientWrapper.cs" /> <Compile Include="Stubs\OutlookWrappers\RecipientWrapper.cs" />
<Compile Include="Stubs\Wrappers.cs" /> <Compile Include="Stubs\Wrappers.cs" />

View File

@ -34,6 +34,14 @@ namespace Acacia.Stubs
string Body { get; set; } string Body { get; set; }
string Subject { get; set; } string Subject { get; set; }
/// <summary>
/// Returns the events for the item. The same object is returned, it does not need to be disposed.
/// </summary>
IItemEvents Events
{
get;
}
#endregion #endregion
#region User properties #region User properties

View File

@ -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
}
}

View File

@ -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
}
}

View File

@ -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<Type>(string name) public Type GetUserProperty<Type>(string name)
{ {
using (ComRelease com = new ComRelease()) using (ComRelease com = new ComRelease())

View File

@ -15,10 +15,16 @@ namespace Acacia.Stubs
return Mapping.WrapOrDefault<IFolder>(obj); return Mapping.WrapOrDefault<IFolder>(obj);
} }
public static WrapType Wrap<WrapType>(object o, bool mustRelease = true) public static WrapType Wrap<WrapType>(this object o, bool mustRelease = true)
where WrapType : IBase where WrapType : IBase
{ {
return Mapping.Wrap<WrapType>(o, mustRelease); return Mapping.Wrap<WrapType>(o, mustRelease);
} }
public static WrapType WrapOrDefault<WrapType>(this object o, bool mustRelease = true)
where WrapType : IBase
{
return Mapping.WrapOrDefault<WrapType>(o, mustRelease);
}
} }
} }

View File

@ -21,7 +21,6 @@ using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using Acacia.Stubs; using Acacia.Stubs;
using Acacia.Stubs.OutlookWrappers; using Acacia.Stubs.OutlookWrappers;
using NSOutlook = Microsoft.Office.Interop.Outlook;
namespace Acacia.Utils namespace Acacia.Utils
{ {
@ -47,22 +46,18 @@ namespace Acacia.Utils
public event MailResponseEventHandler Respond; public event MailResponseEventHandler Respond;
public event MailResponseEventHandler Reply; 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: check release of first item
// TODO: release if not sending event // TODO: release if not sending event
try try
{ {
if ((Reply != null || Respond != null) && mail != null) if ((Reply != null || Respond != null) && mail != null && response != null)
{ {
using (IMailItem mailWrapped = Mapping.Wrap<IMailItem>(mail, false), if (Reply != null)
responseWrapped = Mapping.Wrap<IMailItem>(response)) Reply(mail, response);
{ if (Respond != null)
if (Reply != null) Respond(mail, response);
Reply(mailWrapped, responseWrapped);
if (Respond != null)
Respond(mailWrapped, responseWrapped);
}
} }
} }
catch (System.Exception e) catch (System.Exception e)
@ -72,22 +67,18 @@ namespace Acacia.Utils
} }
public event MailResponseEventHandler ReplyAll; 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: check release of first item
// TODO: release if not sending event // TODO: release if not sending event
try try
{ {
if ((ReplyAll != null || Respond != null) && mail != null) if ((ReplyAll != null || Respond != null) && mail != null && response != null)
{ {
using (IMailItem mailWrapped = Mapping.Wrap<IMailItem>(mail, false), if (ReplyAll != null)
responseWrapped = Mapping.Wrap<IMailItem>(response)) ReplyAll(mail, response);
{ if (Respond != null)
if (ReplyAll != null) Respond(mail, response);
ReplyAll(mailWrapped, responseWrapped);
if (Respond != null)
Respond(mailWrapped, responseWrapped);
}
} }
} }
catch (System.Exception e) catch (System.Exception e)
@ -97,22 +88,18 @@ namespace Acacia.Utils
} }
public event MailResponseEventHandler Forward; 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: check release of first item
// TODO: release if not sending event // TODO: release if not sending event
try try
{ {
if ((Forward != null || Respond != null) && mail != null) if ((Forward != null || Respond != null) && mail != null && response != null)
{ {
using (IMailItem mailWrapped = Mapping.Wrap<IMailItem>(mail, false), if (Forward != null)
responseWrapped = Mapping.Wrap<IMailItem>(response)) Forward(mail, response);
{ if (Respond != null)
if (Forward != null) Respond(mail, response);
Forward(mailWrapped, responseWrapped);
if (Respond != null)
Respond(mailWrapped, responseWrapped);
}
} }
} }
catch (System.Exception e) catch (System.Exception e)
@ -122,18 +109,13 @@ namespace Acacia.Utils
} }
public event MailEventHandler Read; 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 try
{ {
if (Read != null && mail != null) if (Read != null && mail != null)
{ {
using (IMailItem wrapped = Mapping.Wrap<IMailItem>(mail, false)) Read(mail);
{
Read(wrapped);
}
} }
} }
catch (System.Exception e) catch (System.Exception e)
@ -143,17 +125,13 @@ namespace Acacia.Utils
} }
public event CancellableItemEventHandler BeforeDelete; public event CancellableItemEventHandler BeforeDelete;
private void OnBeforeDelete(object item, ref bool cancel) private void OnBeforeDelete(IItem item, ref bool cancel)
{ {
try try
{ {
if (BeforeDelete != null && item != null) if (BeforeDelete != null && item != null)
{ {
using (IItem wrapped = Mapping.Wrap<IItem>(item, false)) BeforeDelete(item, ref cancel);
{
if (wrapped != null)
BeforeDelete(wrapped, ref cancel);
}
} }
} }
catch(System.Exception e) catch(System.Exception e)
@ -164,17 +142,13 @@ namespace Acacia.Utils
// TODO: should this be CancellableMailItemEventHandler? // TODO: should this be CancellableMailItemEventHandler?
public event CancellableItemEventHandler Write; public event CancellableItemEventHandler Write;
private void OnWrite(object item, ref bool cancel) private void OnWrite(IItem item, ref bool cancel)
{ {
try try
{ {
if (Write != null && item != null) if (Write != null && item != null)
{ {
using (IItem wrapped = Mapping.Wrap<IItem>(item, false)) Write(item, ref cancel);
{
if (wrapped != null)
Write(wrapped, ref cancel);
}
} }
} }
catch (System.Exception e) catch (System.Exception e)
@ -216,104 +190,103 @@ namespace Acacia.Utils
private void OnItemLoad(object item) private void OnItemLoad(object item)
{ {
using (IItem wrapped = Wrappers.Wrap<IItem>(item)) IItem wrapped = Wrappers.Wrap<IItem>(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<NSOutlook.ItemEvents_10_Event> private class MailEventHooker : DisposableWrapper
{ {
private IItem _item;
private readonly MailEvents _events; private readonly MailEvents _events;
// TODO: remove id and debug logging // TODO: remove id and debug logging
private int _id; private int _id;
private static int nextId; 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._id = ++nextId;
this._events = events; this._events = events;
HookEvents(true); HookEvents(true);
} }
~MailEventHooker() /*~MailEventHooker()
{ {
} }
*/
protected override void DoRelease() protected override void DoRelease()
{ {
Logger.Instance.Debug(this, "DoRelease: {0}", _id); Logger.Instance.Debug(this, "DoRelease: {0}", _id);
// TODO: It looks like release _itemEvents is not only not needed, but causes exceptions. // 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 // If that is really the case, this doesn't need to be a ComWrapper
_item.Dispose();
} }
private void HookEvents(bool add) private void HookEvents(bool add)
{ {
if (add) if (add)
{ {
_item.BeforeDelete += HandleBeforeDelete; _item.Events.BeforeDelete += HandleBeforeDelete;
_item.Forward += HandleForward; _item.Events.Forward += HandleForward;
_item.Read += HandleRead; _item.Events.Read += HandleRead;
_item.Reply += HandleReply; _item.Events.Reply += HandleReply;
_item.ReplyAll += HandleReplyAll; _item.Events.ReplyAll += HandleReplyAll;
_item.Unload += HandleUnload; _item.Events.Unload += HandleUnload;
_item.Write += HandleWrite; _item.Events.Write += HandleWrite;
} }
else else
{ {
_item.BeforeDelete -= HandleBeforeDelete; _item.Events.BeforeDelete -= HandleBeforeDelete;
_item.Forward -= HandleForward; _item.Events.Forward -= HandleForward;
_item.Read -= HandleRead; _item.Events.Read -= HandleRead;
_item.Reply -= HandleReply; _item.Events.Reply -= HandleReply;
_item.ReplyAll -= HandleReplyAll; _item.Events.ReplyAll -= HandleReplyAll;
_item.Unload -= HandleUnload; _item.Events.Unload -= HandleUnload;
_item.Write -= HandleWrite; _item.Events.Write -= HandleWrite;
} }
} }
private void HandleBeforeDelete(object item, ref bool cancel) private void HandleBeforeDelete(object item, ref bool cancel)
{ {
Logger.Instance.Debug(this, "HandleBeforeDelete: {0}", _id); Logger.Instance.Debug(this, "HandleBeforeDelete: {0}", _id);
_events.OnBeforeDelete(item, ref cancel); _events.OnBeforeDelete(item.WrapOrDefault<IItem>(), ref cancel);
} }
private void HandleForward(object response, ref bool cancel) private void HandleForward(object response, ref bool cancel)
{ {
Logger.Instance.Debug(this, "HandleForward: {0}", _id); Logger.Instance.Debug(this, "HandleForward: {0}", _id);
_events.OnForward(_item as NSOutlook.MailItem, response as NSOutlook.MailItem); _events.OnForward(_item as IMailItem, response.WrapOrDefault<IMailItem>());
} }
private void HandleRead() private void HandleRead()
{ {
Logger.Instance.Debug(this, "HandleRead: {0}", _id); 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) private void HandleReply(object response, ref bool cancel)
{ {
Logger.Instance.Debug(this, "HandleReply: {0}", _id); Logger.Instance.Debug(this, "HandleReply: {0}", _id);
_events.OnReply(_item as NSOutlook.MailItem, response as NSOutlook.MailItem); _events.OnReply(_item as IMailItem, response.WrapOrDefault<IMailItem>());
} }
private void HandleReplyAll(object response, ref bool cancel) private void HandleReplyAll(object response, ref bool cancel)
{ {
Logger.Instance.Debug(this, "HandleReplyAll: {0}", _id); Logger.Instance.Debug(this, "HandleReplyAll: {0}", _id);
_events.OnReplyAll(_item as NSOutlook.MailItem, response as NSOutlook.MailItem); _events.OnReplyAll(_item as IMailItem, response.WrapOrDefault<IMailItem>());
} }
private void HandleUnload() private void HandleUnload()
{ {
Logger.Instance.Debug(this, "HandleUnload: {0}", _id); Logger.Instance.Debug(this, "HandleUnload: {0}", _id);
// All events must be unhooked on unload, otherwise a resource leak is created. // All events must be unhooked on unload, otherwise a resource leak is created.
//HookEvents(false); HookEvents(false);
//Dispose(); Dispose();
} }
private void HandleWrite(ref bool cancel) private void HandleWrite(ref bool cancel)