Answered by:
Outlook 2007 Web Browsing Add-in

Question
-
I am trying to develop an add-in for Outlook 2007 which is essentially a web browsing add-in. The basic workflow is:
1. Select a folder listed under Inbox\Mail Folders
2. A list of websites appear as mail items would
3. Select one of the mail items to pull up the site in the right frame
The purpose of this is to be able to navigate a portal system from within Outlook. It seems pretty straightforward to me but so far I've ran into a couple roadblocks. First, it seems that the WebViewURL property only exists on Folders, not on MailItems. Secondly, the only method I can find to open an HTML page from a MailItem seems to only work with HTML files saved locally, not with URLs.
As an alternative, I would be happy with having the "websites" be represented by additional folders and just using the WebViewURL property, but I don't think I can change the icon to something that doesn't resemble a folder in some way. Also, I don't think you can change the way the folders are sorted -- they are always alphabetical.
I assume that it's possible to do what I need to do, but my experience with VSTO is limited to just this project. I am hoping that someone here can lead me in the right direction... I'm not looking for a complete solution... just any suggestions that may help me get there.
Thanks,
Ryan
Thursday, April 19, 2007 6:20 PM
Answers
-
Hello Ryan,
here is a sample codesnippet.
There you can see a FolderSwitch event of the explorer.
Also there is a samlpe how to manage multiple Explorers and Inspectors.
Hope this will give you a start.
greets, Helmut.
P.S. sometimes VB is better - sometimes C#
my personal favourite is C#
Code Snippetusing
System;using
System.Windows.Forms;using
Microsoft.VisualStudio.Tools.Applications.Runtime;using
Outlook = Microsoft.Office.Interop.Outlook;using
Office = Microsoft.Office.Core;using
System.Collections;using
System.Diagnostics;using
System.Reflection;namespace
ExplorerTest{
public partial class ThisAddIn{
/// <summary> /// This generic collection holds a reference to our open explorers. /// </summary> Hashtable _WrappedExplorers; /// <summary> /// This variable must be used to keep a reference to the Application Explorers collection. /// Required to get informed about new Explorers. /// </summary>Outlook.
Explorers _Explorers; Hashtable _WrappedInspectors;Outlook.
Inspectors _Inspectors; private void ThisAddIn_Startup(object sender, System.EventArgs e){
// initialize the List that will keep an eye on our active Outlook Explorers._WrappedExplorers =
new Hashtable(10); // Do we have already some explorers after startup ?_Explorers = Application.Explorers;
for (int i = _Explorers.Count; i >= 1; i--){
// Wrap the Explorer and do some usefull with itWrapExplorer(_Explorers[i]);
}
// remember the Outlook.Explorers (GC)_Explorers =
this.Application.Explorers; // register for new Explorer event._Explorers.NewExplorer +=
new Outlook.ExplorersEvents_NewExplorerEventHandler(Explorers_NewExplorer); // remember the Outlook.Inspectors object (GC)_Inspectors =
this.Application.Inspectors; // Create a Hashtable that holds a reference to the wrapped Inspectors_WrappedInspectors =
new Hashtable(); // register for the new inspector event_Inspectors.NewInspector +=
new Outlook.InspectorsEvents_NewInspectorEventHandler(_Inspectors_NewInspector);}
private void ThisAddIn_Shutdown(object sender, System.EventArgs e){
// remove all references to the wrapped Inspectors._WrappedInspectors.Clear();
_Inspectors =
null; // remove all references to the wrapped Explorers._WrappedExplorers.Clear();
_Explorers =
null;}
/// <summary> /// The new Inspector event occures whenever an outlook inspector was opened. /// </summary> /// <param name="Inspector">The outlook inspector object.</param> void _Inspectors_NewInspector(Outlook.Inspector Inspector){
try{
Outlook.
Inspector inspector = Inspector;WrapInspector(inspector);
}
catch (System.Exception ex){
// log the error always Trace.TraceError("{0}: [class]:{1} [method]:{2}\n[message]:{3}\n[Stack]:\n{4}", DateTime.Now, // when was the error happened MethodInfo.GetCurrentMethod().DeclaringType.Name, // the class name MethodInfo.GetCurrentMethod().Name, // the method nameex.Message,
// the error messageex.StackTrace
// the stack trace information);
}
}
{
// Wrap the Explorer and do some usefull with it InspectorWrapper wrappedInspector = new InspectorWrapper(Inspector); // register for the closed event, so we can releas it from memorywrappedInspector.InspectorClosed +=
new InspectorClosedDelegate(UnwrapInspector);_WrappedInspectors.Add(wrappedInspector.ID, wrappedInspector);
}
/// <summary> /// This method should be called when a wrapped Outlook Inspector has been closed. /// </summary> /// <param name="explorerId">The unique ID of the closed explorer.</param> void UnwrapInspector(Guid explorerId){
// if we have a reference to this explorer we can release it now if (_WrappedInspectors.ContainsKey(explorerId)){
_WrappedInspectors.Remove(explorerId);
GC.Collect(); GC.WaitForPendingFinalizers();}
}
{
// Wrap the Explorer and do some usefull with itOutlook.
Explorer activeExplorer = Application.ActiveExplorer();WrapExplorer(activeExplorer);
}
/// <summary> /// This method wraps an Outlook Explorer object and registers for the ExplorerClosed event. /// </summary> /// <param name="Explorer">The Outlook Explorer Object.</param> void WrapExplorer(Outlook.Explorer Explorer){
// Wrap the Explorer and do some usefull with it ExplorerWrapper wrappedExplorer = new ExplorerWrapper(Explorer); // register for the closed event, so we can releas it from memorywrappedExplorer.ExplorerClosed +=
new ExplorerClosedDelegate(UnwrapExplorer);_WrappedExplorers.Add(wrappedExplorer.ID, wrappedExplorer);
}
/// <summary> /// This method should be called when a wrapped Outlook Explorer has been closed. /// </summary> /// <param name="explorerId">The unique ID of the closed explorer.</param> void UnwrapExplorer(Guid explorerId){
// if we have a reference to this explorer we can release it now if (_WrappedExplorers.ContainsKey(explorerId)){
_WrappedExplorers.Remove(explorerId);
}
}
#region
VSTO generated code /// <summary> /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// </summary> private void InternalStartup(){
this.Startup += new System.EventHandler(ThisAddIn_Startup); this.Shutdown += new System.EventHandler(ThisAddIn_Shutdown);}
#endregion
}
#region
delegates used handling explorers /// <summary> /// A delegate used to inform the application that an explorer has been closed. /// </summary> /// <param name="explorerId">The unique ID of the Explorer that has been closed.</param> internal delegate void ExplorerClosedDelegate(Guid explorerId);#endregion
#region
ExplorerWrapper /// <summary> /// The ExplorerWrapper is used to wrap around an Outlook Explorer. /// It keeps a reference to the Explorer in memory and registers for the Explorer events. /// </summary> internal class ExplorerWrapper{
#region
explorer wrapper events /// <summary> /// This event is fired from out wrapper when the wrapped Outlook Explorer has been closed. /// </summary> public event ExplorerClosedDelegate ExplorerClosed;#endregion
#region
explorer wrapper variables & properties /// <summary> /// An unique ID that can used to identify this explorer (commandbars, buttons, etc...) /// </summary> Guid _Id; /// <summary> /// An unique ID that can used to identify this explorer (commandbars, buttons, etc...) /// </summary> public Guid ID{
get { return _Id; }}
/// <summary> /// The Outlook Explorer object used to keep a reference in memory and register for the explorer events. /// </summary>Outlook.
ExplorerClass _Explorer; /// <summary> /// The Outlook Explorer object used to keep a reference in memory and register for the explorer events. /// </summary> public Outlook.Explorer Explorer{
get { return _Explorer; }}
/// <summary> /// A Missing.Value used for COM interoperability. /// </summary> object _Missing = System.Reflection.Missing.Value;#endregion
#region
explorer wrapper construction and cleanup /// <summary> /// The construction code. /// </summary> /// <param name="explorer">The outlook explorer that should be wrapped.</param> public ExplorerWrapper(Outlook.Explorer explorer){
try{
_Id =
Guid.NewGuid();_Explorer = explorer
as Outlook.ExplorerClass; if (_Explorer != null){
_Explorer.FolderSwitch +=
new Microsoft.Office.Interop.Outlook.ExplorerEvents_10_FolderSwitchEventHandler(_Explorer_FolderSwitch);_Explorer.ExplorerEvents_Event_Close +=
new Microsoft.Office.Interop.Outlook.ExplorerEvents_CloseEventHandler(_Explorer_ExplorerEvents_Event_Close);}
}
catch (System.Exception ex){
// log the error always Trace.TraceError("{0}: [class]:{1} [method]:{2}\n[message]:{3}\n[Stack]:\n{4}", DateTime.Now, // when was the error happened MethodInfo.GetCurrentMethod().DeclaringType.Name, // the class name MethodInfo.GetCurrentMethod().Name, // the method nameex.Message,
// the error messageex.StackTrace
// the stack trace information);
// throw the Exception to the calling class throw ex;}
}
#endregion
/// <summary> /// This event occures when this explorer has been closed. /// </summary> void _Explorer_ExplorerEvents_Event_Close(){
// here we release all references to the explorer from memory._Explorer.FolderSwitch -=
new Microsoft.Office.Interop.Outlook.ExplorerEvents_10_FolderSwitchEventHandler(_Explorer_FolderSwitch);_Explorer.ExplorerEvents_Event_Close -=
new Microsoft.Office.Interop.Outlook.ExplorerEvents_CloseEventHandler(_Explorer_ExplorerEvents_Event_Close);_Explorer =
null; // fire an event to inform the application that this explorer has been closed. if (ExplorerClosed != null){
ExplorerClosed(
this._Id);}
}
/// <summary> /// This event occures when another folder has been selected in this explorer. /// </summary> void _Explorer_FolderSwitch(){
try{
// We change the application menu depending on what folder we have selected // ModifyMenu();}
catch (System.Exception ex){
// log the error always Trace.TraceError("{0}: [class]:{1} [method]:{2}\n[message]:{3}\n[Stack]:\n{4}", DateTime.Now, // when was the error happened MethodInfo.GetCurrentMethod().DeclaringType.Name, // the class name MethodInfo.GetCurrentMethod().Name, // the method nameex.Message,
// the error messageex.StackTrace
// the stack trace information);
// now display a friendly error to the user MessageBox.Show(null, "There was an application error, you should save your work and restart Outlook.", "OutlookAdminTools", MessageBoxButtons.OK, MessageBoxIcon.Error);}
}
#endregion
}
#region
delegates used handling inspectors /// <summary> /// A delegate used to inform the application that an inspector has been closed. /// </summary> /// <param name="inspectorId">The unique ID of the Explorer that has been closed.</param> internal delegate void InspectorClosedDelegate(Guid inspectorId);#endregion
{
/// <summary> /// This event informs our application that an "wrapped" inspector has been closed and should be released from memory. /// </summary> public event InspectorClosedDelegate InspectorClosed;#region
explorer wrapper variables & properties /// <summary> /// An unique ID that can used to identify this explorer (commandbars, buttons, etc...) /// </summary> Guid _Id; /// <summary> /// An unique ID that can used to identify this explorer (commandbars, buttons, etc...) /// </summary> public Guid ID{
get { return _Id; }}
/// <summary> /// This variable holds a reference to the outlook iitem behind the inspector. /// Used to handle to item.open event. /// Only when the item has been displayed, it's save to manipulate the inspector - or close the inspector. /// </summary> object _Item; /// <summary> /// The outlook inspector object that is wrapped by this class. /// </summary>Outlook.
InspectorClass _Inspector;#endregion
/// <summary> /// Initialisation code. /// Remembers the inspector in memory and registers for the close event and the item.open event /// </summary> /// <param name="inspector">The outlook inspector object that should be handled.</param> public InspectorWrapper(Outlook.Inspector inspector){
try{
// each inspector gets a unique id._Id =
Guid.NewGuid(); // remember the inspector object in memory_Inspector = inspector
as Outlook.InspectorClass; // register for the close event - used to release ourself from memory_Inspector.InspectorEvents_Event_Close +=
new Outlook.InspectorEvents_CloseEventHandler(_Inspector_InspectorEvents_Event_Close); // remember the item behind the inspector in memory_Item = _Inspector.CurrentItem;
// register for the item_open event if (_Item is Outlook.ContactItem){
// we have no latebinding - so we have to cast explicitly to get eventsOutlook.
ContactItem item = _Item as Outlook.ContactItem;item.Open +=
new Outlook.ItemEvents_10_OpenEventHandler(item_Open); // remember the object in memory_Item = item;
}
else if (_Item is Outlook.TaskItem){
Outlook.
TaskItem item = _Item as Outlook.TaskItem;item.Open +=
new Outlook.ItemEvents_10_OpenEventHandler(item_Open);_Item = item;
}
else if (_Item is Outlook.JournalItem){
Outlook.
JournalItem item = _Item as Outlook.JournalItem;item.Open +=
new Outlook.ItemEvents_10_OpenEventHandler(item_Open);_Item = item;
}
else if (_Item is Outlook.MailItem){
Outlook.
MailItem item = _Item as Outlook.MailItem;item.Open +=
new Outlook.ItemEvents_10_OpenEventHandler(item_Open);_Item = item;
}
else{
// we don't handle this inspector and release it from memory_Item =
null;}
}
catch (System.Exception ex){
// log the error always Trace.TraceError("{0}: [class]:{1} [method]:{2}\n[message]:{3}\n[Stack]:\n{4}", DateTime.Now, // when was the error happened MethodInfo.GetCurrentMethod().DeclaringType.Name, // the class name MethodInfo.GetCurrentMethod().Name, // the method nameex.Message,
// the error messageex.StackTrace
// the stack trace information);
// the wrapper is called only from application - throw the message to it. throw new Exception("There was an application error, the new Window could not be handled.\nyou should save your work and restart Outlook.", ex);}
}
/// <summary> /// Handles the item open event and checks if this item a OutlooAdminTools item. /// When we have a new item - and we are in an OAT folder - we close this item and create a new OAT item. /// </summary> /// <param name="Cancel"></param> void item_Open(ref bool Cancel){
try{
Type itemType = _Item.GetType(); // check the messageclass of the new opened inspector. string messageclass = (string)itemType.InvokeMember("MessageClass", BindingFlags.GetProperty, null, _Item, null); // access the entryId - so we can get the parent folder object string entryId = (string)itemType.InvokeMember("EntryID", BindingFlags.GetProperty, null, _Item, null); // after we have accessed the entryID - we can access the parentfolder propertyOutlook.
MAPIFolder parent = itemType.InvokeMember("Parent", BindingFlags.GetProperty, null, _Item, null) as Outlook.MAPIFolder; string folderName = parent.Description; int itemSize = (int)itemType.InvokeMember("Size", BindingFlags.GetProperty, null, _Item, null);}
catch (System.Exception ex){
// log the error always Trace.TraceError("{0}: [class]:{1} [method]:{2}\n[message]:{3}\n[Stack]:\n{4}", DateTime.Now, // when was the error happened MethodInfo.GetCurrentMethod().DeclaringType.Name, // the class name MethodInfo.GetCurrentMethod().Name, // the method nameex.Message,
// the error messageex.StackTrace
// the stack trace information);
// the wrapper is called anytime from application. // display a messagebox directly to the user MessageBox.Show("There was an application error, a new Window could not be handled,\nyou should save your work and restart Outlook.", "OutlookAdminTools", MessageBoxButtons.OK, MessageBoxIcon.Error);}
}
/// <summary> /// This event occures when the user has closed the open inspector. /// Used to release ourself from memory and avoid memory leaks. /// </summary> void _Inspector_InspectorEvents_Event_Close(){
try{
_Item =
null;_Inspector.InspectorEvents_Event_Close -=
new Outlook.InspectorEvents_CloseEventHandler(_Inspector_InspectorEvents_Event_Close);_Inspector =
null; GC.Collect(); GC.WaitForPendingFinalizers(); if (InspectorClosed != null){
InspectorClosed(_Id);
}
}
catch (System.Exception ex){
// log the error always Trace.TraceError("{0}: [class]:{1} [method]:{2}\n[message]:{3}\n[Stack]:\n{4}", DateTime.Now, // when was the error happened MethodInfo.GetCurrentMethod().DeclaringType.Name, // the class name MethodInfo.GetCurrentMethod().Name, // the method nameex.Message,
// the error messageex.StackTrace
// the stack trace information);
// the wrapper is called anytime from application. // display a messagebox directly to the user MessageBox.Show("There was an application error, a Window close could not be handled,\nyou should save your work and restart Outlook.", "OutlookAdminTools", MessageBoxButtons.OK, MessageBoxIcon.Error);}
}
}
Monday, April 23, 2007 6:50 PMAnswerer
All replies
-
Hello Ryan,
Navigating to a Website within Outlook:
When you go to the Menu / View / Toolbars - make sure that the "Web" Toolbar is visible.
Here you can paste a Url and the Right View navigates to the Url.
How can you do this programmatically ?
Find the ID for this Address-Textbox, create your own CommandBar, add a textbox and give it the same ID.
Here you can paste the Url and it should work.
Select a Folder -> use the Explorer.FolderChanged event, Check the Folder and Update a Pane with the specific infromation.
Hope this helps,
greets Helmut
Thursday, April 19, 2007 10:31 PMAnswerer -
I don't see an Explorer.FolderChanged event... I am using C#, is there an equivalent event?
On the other hand, am I better off writing this in VB?
Monday, April 23, 2007 5:48 PM -
Hello Ryan,
here is a sample codesnippet.
There you can see a FolderSwitch event of the explorer.
Also there is a samlpe how to manage multiple Explorers and Inspectors.
Hope this will give you a start.
greets, Helmut.
P.S. sometimes VB is better - sometimes C#
my personal favourite is C#
Code Snippetusing
System;using
System.Windows.Forms;using
Microsoft.VisualStudio.Tools.Applications.Runtime;using
Outlook = Microsoft.Office.Interop.Outlook;using
Office = Microsoft.Office.Core;using
System.Collections;using
System.Diagnostics;using
System.Reflection;namespace
ExplorerTest{
public partial class ThisAddIn{
/// <summary> /// This generic collection holds a reference to our open explorers. /// </summary> Hashtable _WrappedExplorers; /// <summary> /// This variable must be used to keep a reference to the Application Explorers collection. /// Required to get informed about new Explorers. /// </summary>Outlook.
Explorers _Explorers; Hashtable _WrappedInspectors;Outlook.
Inspectors _Inspectors; private void ThisAddIn_Startup(object sender, System.EventArgs e){
// initialize the List that will keep an eye on our active Outlook Explorers._WrappedExplorers =
new Hashtable(10); // Do we have already some explorers after startup ?_Explorers = Application.Explorers;
for (int i = _Explorers.Count; i >= 1; i--){
// Wrap the Explorer and do some usefull with itWrapExplorer(_Explorers[i]);
}
// remember the Outlook.Explorers (GC)_Explorers =
this.Application.Explorers; // register for new Explorer event._Explorers.NewExplorer +=
new Outlook.ExplorersEvents_NewExplorerEventHandler(Explorers_NewExplorer); // remember the Outlook.Inspectors object (GC)_Inspectors =
this.Application.Inspectors; // Create a Hashtable that holds a reference to the wrapped Inspectors_WrappedInspectors =
new Hashtable(); // register for the new inspector event_Inspectors.NewInspector +=
new Outlook.InspectorsEvents_NewInspectorEventHandler(_Inspectors_NewInspector);}
private void ThisAddIn_Shutdown(object sender, System.EventArgs e){
// remove all references to the wrapped Inspectors._WrappedInspectors.Clear();
_Inspectors =
null; // remove all references to the wrapped Explorers._WrappedExplorers.Clear();
_Explorers =
null;}
/// <summary> /// The new Inspector event occures whenever an outlook inspector was opened. /// </summary> /// <param name="Inspector">The outlook inspector object.</param> void _Inspectors_NewInspector(Outlook.Inspector Inspector){
try{
Outlook.
Inspector inspector = Inspector;WrapInspector(inspector);
}
catch (System.Exception ex){
// log the error always Trace.TraceError("{0}: [class]:{1} [method]:{2}\n[message]:{3}\n[Stack]:\n{4}", DateTime.Now, // when was the error happened MethodInfo.GetCurrentMethod().DeclaringType.Name, // the class name MethodInfo.GetCurrentMethod().Name, // the method nameex.Message,
// the error messageex.StackTrace
// the stack trace information);
}
}
{
// Wrap the Explorer and do some usefull with it InspectorWrapper wrappedInspector = new InspectorWrapper(Inspector); // register for the closed event, so we can releas it from memorywrappedInspector.InspectorClosed +=
new InspectorClosedDelegate(UnwrapInspector);_WrappedInspectors.Add(wrappedInspector.ID, wrappedInspector);
}
/// <summary> /// This method should be called when a wrapped Outlook Inspector has been closed. /// </summary> /// <param name="explorerId">The unique ID of the closed explorer.</param> void UnwrapInspector(Guid explorerId){
// if we have a reference to this explorer we can release it now if (_WrappedInspectors.ContainsKey(explorerId)){
_WrappedInspectors.Remove(explorerId);
GC.Collect(); GC.WaitForPendingFinalizers();}
}
{
// Wrap the Explorer and do some usefull with itOutlook.
Explorer activeExplorer = Application.ActiveExplorer();WrapExplorer(activeExplorer);
}
/// <summary> /// This method wraps an Outlook Explorer object and registers for the ExplorerClosed event. /// </summary> /// <param name="Explorer">The Outlook Explorer Object.</param> void WrapExplorer(Outlook.Explorer Explorer){
// Wrap the Explorer and do some usefull with it ExplorerWrapper wrappedExplorer = new ExplorerWrapper(Explorer); // register for the closed event, so we can releas it from memorywrappedExplorer.ExplorerClosed +=
new ExplorerClosedDelegate(UnwrapExplorer);_WrappedExplorers.Add(wrappedExplorer.ID, wrappedExplorer);
}
/// <summary> /// This method should be called when a wrapped Outlook Explorer has been closed. /// </summary> /// <param name="explorerId">The unique ID of the closed explorer.</param> void UnwrapExplorer(Guid explorerId){
// if we have a reference to this explorer we can release it now if (_WrappedExplorers.ContainsKey(explorerId)){
_WrappedExplorers.Remove(explorerId);
}
}
#region
VSTO generated code /// <summary> /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// </summary> private void InternalStartup(){
this.Startup += new System.EventHandler(ThisAddIn_Startup); this.Shutdown += new System.EventHandler(ThisAddIn_Shutdown);}
#endregion
}
#region
delegates used handling explorers /// <summary> /// A delegate used to inform the application that an explorer has been closed. /// </summary> /// <param name="explorerId">The unique ID of the Explorer that has been closed.</param> internal delegate void ExplorerClosedDelegate(Guid explorerId);#endregion
#region
ExplorerWrapper /// <summary> /// The ExplorerWrapper is used to wrap around an Outlook Explorer. /// It keeps a reference to the Explorer in memory and registers for the Explorer events. /// </summary> internal class ExplorerWrapper{
#region
explorer wrapper events /// <summary> /// This event is fired from out wrapper when the wrapped Outlook Explorer has been closed. /// </summary> public event ExplorerClosedDelegate ExplorerClosed;#endregion
#region
explorer wrapper variables & properties /// <summary> /// An unique ID that can used to identify this explorer (commandbars, buttons, etc...) /// </summary> Guid _Id; /// <summary> /// An unique ID that can used to identify this explorer (commandbars, buttons, etc...) /// </summary> public Guid ID{
get { return _Id; }}
/// <summary> /// The Outlook Explorer object used to keep a reference in memory and register for the explorer events. /// </summary>Outlook.
ExplorerClass _Explorer; /// <summary> /// The Outlook Explorer object used to keep a reference in memory and register for the explorer events. /// </summary> public Outlook.Explorer Explorer{
get { return _Explorer; }}
/// <summary> /// A Missing.Value used for COM interoperability. /// </summary> object _Missing = System.Reflection.Missing.Value;#endregion
#region
explorer wrapper construction and cleanup /// <summary> /// The construction code. /// </summary> /// <param name="explorer">The outlook explorer that should be wrapped.</param> public ExplorerWrapper(Outlook.Explorer explorer){
try{
_Id =
Guid.NewGuid();_Explorer = explorer
as Outlook.ExplorerClass; if (_Explorer != null){
_Explorer.FolderSwitch +=
new Microsoft.Office.Interop.Outlook.ExplorerEvents_10_FolderSwitchEventHandler(_Explorer_FolderSwitch);_Explorer.ExplorerEvents_Event_Close +=
new Microsoft.Office.Interop.Outlook.ExplorerEvents_CloseEventHandler(_Explorer_ExplorerEvents_Event_Close);}
}
catch (System.Exception ex){
// log the error always Trace.TraceError("{0}: [class]:{1} [method]:{2}\n[message]:{3}\n[Stack]:\n{4}", DateTime.Now, // when was the error happened MethodInfo.GetCurrentMethod().DeclaringType.Name, // the class name MethodInfo.GetCurrentMethod().Name, // the method nameex.Message,
// the error messageex.StackTrace
// the stack trace information);
// throw the Exception to the calling class throw ex;}
}
#endregion
/// <summary> /// This event occures when this explorer has been closed. /// </summary> void _Explorer_ExplorerEvents_Event_Close(){
// here we release all references to the explorer from memory._Explorer.FolderSwitch -=
new Microsoft.Office.Interop.Outlook.ExplorerEvents_10_FolderSwitchEventHandler(_Explorer_FolderSwitch);_Explorer.ExplorerEvents_Event_Close -=
new Microsoft.Office.Interop.Outlook.ExplorerEvents_CloseEventHandler(_Explorer_ExplorerEvents_Event_Close);_Explorer =
null; // fire an event to inform the application that this explorer has been closed. if (ExplorerClosed != null){
ExplorerClosed(
this._Id);}
}
/// <summary> /// This event occures when another folder has been selected in this explorer. /// </summary> void _Explorer_FolderSwitch(){
try{
// We change the application menu depending on what folder we have selected // ModifyMenu();}
catch (System.Exception ex){
// log the error always Trace.TraceError("{0}: [class]:{1} [method]:{2}\n[message]:{3}\n[Stack]:\n{4}", DateTime.Now, // when was the error happened MethodInfo.GetCurrentMethod().DeclaringType.Name, // the class name MethodInfo.GetCurrentMethod().Name, // the method nameex.Message,
// the error messageex.StackTrace
// the stack trace information);
// now display a friendly error to the user MessageBox.Show(null, "There was an application error, you should save your work and restart Outlook.", "OutlookAdminTools", MessageBoxButtons.OK, MessageBoxIcon.Error);}
}
#endregion
}
#region
delegates used handling inspectors /// <summary> /// A delegate used to inform the application that an inspector has been closed. /// </summary> /// <param name="inspectorId">The unique ID of the Explorer that has been closed.</param> internal delegate void InspectorClosedDelegate(Guid inspectorId);#endregion
{
/// <summary> /// This event informs our application that an "wrapped" inspector has been closed and should be released from memory. /// </summary> public event InspectorClosedDelegate InspectorClosed;#region
explorer wrapper variables & properties /// <summary> /// An unique ID that can used to identify this explorer (commandbars, buttons, etc...) /// </summary> Guid _Id; /// <summary> /// An unique ID that can used to identify this explorer (commandbars, buttons, etc...) /// </summary> public Guid ID{
get { return _Id; }}
/// <summary> /// This variable holds a reference to the outlook iitem behind the inspector. /// Used to handle to item.open event. /// Only when the item has been displayed, it's save to manipulate the inspector - or close the inspector. /// </summary> object _Item; /// <summary> /// The outlook inspector object that is wrapped by this class. /// </summary>Outlook.
InspectorClass _Inspector;#endregion
/// <summary> /// Initialisation code. /// Remembers the inspector in memory and registers for the close event and the item.open event /// </summary> /// <param name="inspector">The outlook inspector object that should be handled.</param> public InspectorWrapper(Outlook.Inspector inspector){
try{
// each inspector gets a unique id._Id =
Guid.NewGuid(); // remember the inspector object in memory_Inspector = inspector
as Outlook.InspectorClass; // register for the close event - used to release ourself from memory_Inspector.InspectorEvents_Event_Close +=
new Outlook.InspectorEvents_CloseEventHandler(_Inspector_InspectorEvents_Event_Close); // remember the item behind the inspector in memory_Item = _Inspector.CurrentItem;
// register for the item_open event if (_Item is Outlook.ContactItem){
// we have no latebinding - so we have to cast explicitly to get eventsOutlook.
ContactItem item = _Item as Outlook.ContactItem;item.Open +=
new Outlook.ItemEvents_10_OpenEventHandler(item_Open); // remember the object in memory_Item = item;
}
else if (_Item is Outlook.TaskItem){
Outlook.
TaskItem item = _Item as Outlook.TaskItem;item.Open +=
new Outlook.ItemEvents_10_OpenEventHandler(item_Open);_Item = item;
}
else if (_Item is Outlook.JournalItem){
Outlook.
JournalItem item = _Item as Outlook.JournalItem;item.Open +=
new Outlook.ItemEvents_10_OpenEventHandler(item_Open);_Item = item;
}
else if (_Item is Outlook.MailItem){
Outlook.
MailItem item = _Item as Outlook.MailItem;item.Open +=
new Outlook.ItemEvents_10_OpenEventHandler(item_Open);_Item = item;
}
else{
// we don't handle this inspector and release it from memory_Item =
null;}
}
catch (System.Exception ex){
// log the error always Trace.TraceError("{0}: [class]:{1} [method]:{2}\n[message]:{3}\n[Stack]:\n{4}", DateTime.Now, // when was the error happened MethodInfo.GetCurrentMethod().DeclaringType.Name, // the class name MethodInfo.GetCurrentMethod().Name, // the method nameex.Message,
// the error messageex.StackTrace
// the stack trace information);
// the wrapper is called only from application - throw the message to it. throw new Exception("There was an application error, the new Window could not be handled.\nyou should save your work and restart Outlook.", ex);}
}
/// <summary> /// Handles the item open event and checks if this item a OutlooAdminTools item. /// When we have a new item - and we are in an OAT folder - we close this item and create a new OAT item. /// </summary> /// <param name="Cancel"></param> void item_Open(ref bool Cancel){
try{
Type itemType = _Item.GetType(); // check the messageclass of the new opened inspector. string messageclass = (string)itemType.InvokeMember("MessageClass", BindingFlags.GetProperty, null, _Item, null); // access the entryId - so we can get the parent folder object string entryId = (string)itemType.InvokeMember("EntryID", BindingFlags.GetProperty, null, _Item, null); // after we have accessed the entryID - we can access the parentfolder propertyOutlook.
MAPIFolder parent = itemType.InvokeMember("Parent", BindingFlags.GetProperty, null, _Item, null) as Outlook.MAPIFolder; string folderName = parent.Description; int itemSize = (int)itemType.InvokeMember("Size", BindingFlags.GetProperty, null, _Item, null);}
catch (System.Exception ex){
// log the error always Trace.TraceError("{0}: [class]:{1} [method]:{2}\n[message]:{3}\n[Stack]:\n{4}", DateTime.Now, // when was the error happened MethodInfo.GetCurrentMethod().DeclaringType.Name, // the class name MethodInfo.GetCurrentMethod().Name, // the method nameex.Message,
// the error messageex.StackTrace
// the stack trace information);
// the wrapper is called anytime from application. // display a messagebox directly to the user MessageBox.Show("There was an application error, a new Window could not be handled,\nyou should save your work and restart Outlook.", "OutlookAdminTools", MessageBoxButtons.OK, MessageBoxIcon.Error);}
}
/// <summary> /// This event occures when the user has closed the open inspector. /// Used to release ourself from memory and avoid memory leaks. /// </summary> void _Inspector_InspectorEvents_Event_Close(){
try{
_Item =
null;_Inspector.InspectorEvents_Event_Close -=
new Outlook.InspectorEvents_CloseEventHandler(_Inspector_InspectorEvents_Event_Close);_Inspector =
null; GC.Collect(); GC.WaitForPendingFinalizers(); if (InspectorClosed != null){
InspectorClosed(_Id);
}
}
catch (System.Exception ex){
// log the error always Trace.TraceError("{0}: [class]:{1} [method]:{2}\n[message]:{3}\n[Stack]:\n{4}", DateTime.Now, // when was the error happened MethodInfo.GetCurrentMethod().DeclaringType.Name, // the class name MethodInfo.GetCurrentMethod().Name, // the method nameex.Message,
// the error messageex.StackTrace
// the stack trace information);
// the wrapper is called anytime from application. // display a messagebox directly to the user MessageBox.Show("There was an application error, a Window close could not be handled,\nyou should save your work and restart Outlook.", "OutlookAdminTools", MessageBoxButtons.OK, MessageBoxIcon.Error);}
}
}
Monday, April 23, 2007 6:50 PMAnswerer