J
JRomeo
Hi.
It's my first time ever writing an add-in. It's for Outlook 2003 using VSTO
SE. It works well. However, we're about to deploy this to about 1000 users,
and before we do, I'd like to see if anyone can catch any gaping holes in my
code. It's a single C# class called ThisAddin.cs. It does the following:
- Adds a control to the standard toolbar of each Appointment Inspector
- Clicking the control grabs the values of some of the inspectors
ItemProperties, opens a IE window, and passes them in a URL
- Closing the inspector removes the control and releases the objects and
related events
Warnings, gotchas, best practices: all comments welcome. Here it is. Thanks
in advance.
-----------
using System;
using System.Windows.Forms;
using Diagnostics = System.Diagnostics;
using Microsoft.VisualStudio.Tools.Applications.Runtime;
using Outlook = Microsoft.Office.Interop.Outlook;
using Office = Microsoft.Office.Core;
using SHDocVw;
namespace OutlookConfCallerBtn
{
public partial class ThisAddIn
{
Diagnostics.Process newIE;
Office.CommandBars cmdBars;
Office.CommandBar stdBar;
Office.CommandBarButton Btn_ConfRoomSchdlr;
Outlook.Inspectors openInspectors;
Outlook.AppointmentItem item;
/// <summary>
/// Do the setup on add-in startup
/// </summary>
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
openInspectors = this.Application.Inspectors;
openInspectors.NewInspector += new
Outlook.InspectorsEvents_NewInspectorEventHandler(newInspector_Event);
}
/// <summary>
/// Release the objects on shutdown
/// </summary>
private void ThisAddIn_Shutdown(object sender, System.EventArgs e)
{
// Drop the NewInspector and Btn_ConfRoomSchdlr event handlers
openInspectors.NewInspector -= new
Microsoft.Office.Interop.Outlook.InspectorsEvents_NewInspectorEventHandler(newInspector_Event);
// Kill the class-level objects in play
openInspectors = null;
cmdBars = null;
stdBar = null;
Btn_ConfRoomSchdlr = null;
item = null;
newIE = null;
}
/// <summary>
/// Handle the Inspector.NewInspector event
/// This adds the command bar control to all Appointment inspectors
/// </summary>
private void newInspector_Event(Outlook.Inspector new_Inspector)
{
// Check what type of inspector we have
Outlook.AppointmentItem item = new_Inspector.CurrentItem as
Outlook.AppointmentItem;
// For appointment items, add a custom control
if (item != null)
{
try
{
// Get the standard toolbar for this inspector
cmdBars = new_Inspector.CommandBars;
stdBar = cmdBars["standard"];
// Add the control
Btn_ConfRoomSchdlr =
(Office.CommandBarButton)stdBar.Controls.Add(1, missing, missing, 12, true);
Btn_ConfRoomSchdlr.Style =
Office.MsoButtonStyle.msoButtonIconAndCaption;
Btn_ConfRoomSchdlr.Caption = "Reserve Room(s)";
Btn_ConfRoomSchdlr.Tag = "Reserve Room(s)";
Btn_ConfRoomSchdlr.BeginGroup = true;
Btn_ConfRoomSchdlr.Picture = getImage();
// Set the event handlers for the button click and
Inspector.Close
((Outlook.InspectorEvents_Event)new_Inspector).Close +=
new Outlook.InspectorEvents_CloseEventHandler(closeInspector_Event);
Btn_ConfRoomSchdlr.Click += new
Office._CommandBarButtonEvents_ClickEventHandler(clickButton_Event);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
/// <summary>
/// Handle the Button.Click event. This opens the conference room
scheduler
/// </summary>
private void clickButton_Event(Office.CommandBarButton ctrl, ref
bool cancel)
{
// Set up the reference time data
System.Collections.Hashtable timeHash = new
System.Collections.Hashtable();
int hr = 5;
String min = "00";
String mdn = "am";
// Build the times on the fly, from 5:00 am - 9:30 pm
for (int i = 1; i <= 34; i++)
{
String tKey = "_" + hr.ToString() + min + mdn;
timeHash.Add(tKey, i.ToString());
if (i % 2 != 0) { min = "30"; }
else
{
min = "00";
if (hr == 12) { hr = 1; }
else
{
hr++;
if (hr == 11)
{
mdn = "pm";
}
}
}
}
// Assemble the Start Time and End Time values and open a URL
item =
this.Application.ActiveInspector().CurrentItem as Outlook.AppointmentItem;
String [] StartGroup =
item.ItemProperties["Start"].Value.ToString().Split(new Char[] {' '});
String [] EndGroup =
item.ItemProperties["End"].Value.ToString().Split(new Char[] { ' ' });
String [] StartTime = StartGroup[1].Split(new Char[] { ':' });
String [] EndTime = EndGroup[1].Split(new Char[] { ':' });
String selDate = StartGroup[0];
String sTimeKey = ("_" + StartTime[0] + StartTime[1] +
StartGroup[2]).ToLower();
String eTimeKey = ("_" + EndTime[0] + EndTime[1] +
EndGroup[2]).ToLower();
// Get the time values from timeHash, otherwise use -1
String sTimeID = (timeHash.ContainsKey(sTimeKey) ?
timeHash[sTimeKey].ToString() : "-1");
String eTimeID = (timeHash.ContainsKey(eTimeKey) ?
timeHash[eTimeKey].ToString() : "-1");
String ConfSchdURL =
"http://devapps/confroom/index.cfm?event=wizard";
ConfSchdURL += "&StartTime=" + sTimeID + "&EndTime=" +
eTimeID + "&SelDate=" + selDate;
// MessageBox.Show(sTimeKey + ":" + sTimeID + " " + eTimeKey
+ ":" + eTimeID);
newIE = System.Diagnostics.Process.Start("IExplore.exe",
ConfSchdURL);
}
/// <summary>
/// Handle the Inspector.Close event
/// </summary>
void closeInspector_Event()
{
// Drop the Btn_ConfRoomSchdlr event handler
Btn_ConfRoomSchdlr.Click -= new
Office._CommandBarButtonEvents_ClickEventHandler(clickButton_Event);
}
/// <summary>
/// Add the converted image to an ImageList
/// </summary>
private stdole.IPictureDisp getImage()
{
stdole.IPictureDisp tempImage = null;
try
{
System.Drawing.Icon newIcon = Properties.Resources.confchair;
ImageList newImageList = new ImageList();
newImageList.Images.Add(newIcon);
tempImage = ConvertImage.Convert(newImageList.Images[0]);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
return tempImage;
}
#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
}
// Convert the icon file to an Image object
sealed public class ConvertImage : System.Windows.Forms.AxHost
{
private ConvertImage()
: base(null)
{
}
public static stdole.IPictureDisp Convert(System.Drawing.Image image)
{
return
(stdole.IPictureDisp)System.Windows.Forms.AxHost.GetIPictureDispFromPicture(image);
}
}
}
It's my first time ever writing an add-in. It's for Outlook 2003 using VSTO
SE. It works well. However, we're about to deploy this to about 1000 users,
and before we do, I'd like to see if anyone can catch any gaping holes in my
code. It's a single C# class called ThisAddin.cs. It does the following:
- Adds a control to the standard toolbar of each Appointment Inspector
- Clicking the control grabs the values of some of the inspectors
ItemProperties, opens a IE window, and passes them in a URL
- Closing the inspector removes the control and releases the objects and
related events
Warnings, gotchas, best practices: all comments welcome. Here it is. Thanks
in advance.
-----------
using System;
using System.Windows.Forms;
using Diagnostics = System.Diagnostics;
using Microsoft.VisualStudio.Tools.Applications.Runtime;
using Outlook = Microsoft.Office.Interop.Outlook;
using Office = Microsoft.Office.Core;
using SHDocVw;
namespace OutlookConfCallerBtn
{
public partial class ThisAddIn
{
Diagnostics.Process newIE;
Office.CommandBars cmdBars;
Office.CommandBar stdBar;
Office.CommandBarButton Btn_ConfRoomSchdlr;
Outlook.Inspectors openInspectors;
Outlook.AppointmentItem item;
/// <summary>
/// Do the setup on add-in startup
/// </summary>
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
openInspectors = this.Application.Inspectors;
openInspectors.NewInspector += new
Outlook.InspectorsEvents_NewInspectorEventHandler(newInspector_Event);
}
/// <summary>
/// Release the objects on shutdown
/// </summary>
private void ThisAddIn_Shutdown(object sender, System.EventArgs e)
{
// Drop the NewInspector and Btn_ConfRoomSchdlr event handlers
openInspectors.NewInspector -= new
Microsoft.Office.Interop.Outlook.InspectorsEvents_NewInspectorEventHandler(newInspector_Event);
// Kill the class-level objects in play
openInspectors = null;
cmdBars = null;
stdBar = null;
Btn_ConfRoomSchdlr = null;
item = null;
newIE = null;
}
/// <summary>
/// Handle the Inspector.NewInspector event
/// This adds the command bar control to all Appointment inspectors
/// </summary>
private void newInspector_Event(Outlook.Inspector new_Inspector)
{
// Check what type of inspector we have
Outlook.AppointmentItem item = new_Inspector.CurrentItem as
Outlook.AppointmentItem;
// For appointment items, add a custom control
if (item != null)
{
try
{
// Get the standard toolbar for this inspector
cmdBars = new_Inspector.CommandBars;
stdBar = cmdBars["standard"];
// Add the control
Btn_ConfRoomSchdlr =
(Office.CommandBarButton)stdBar.Controls.Add(1, missing, missing, 12, true);
Btn_ConfRoomSchdlr.Style =
Office.MsoButtonStyle.msoButtonIconAndCaption;
Btn_ConfRoomSchdlr.Caption = "Reserve Room(s)";
Btn_ConfRoomSchdlr.Tag = "Reserve Room(s)";
Btn_ConfRoomSchdlr.BeginGroup = true;
Btn_ConfRoomSchdlr.Picture = getImage();
// Set the event handlers for the button click and
Inspector.Close
((Outlook.InspectorEvents_Event)new_Inspector).Close +=
new Outlook.InspectorEvents_CloseEventHandler(closeInspector_Event);
Btn_ConfRoomSchdlr.Click += new
Office._CommandBarButtonEvents_ClickEventHandler(clickButton_Event);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
/// <summary>
/// Handle the Button.Click event. This opens the conference room
scheduler
/// </summary>
private void clickButton_Event(Office.CommandBarButton ctrl, ref
bool cancel)
{
// Set up the reference time data
System.Collections.Hashtable timeHash = new
System.Collections.Hashtable();
int hr = 5;
String min = "00";
String mdn = "am";
// Build the times on the fly, from 5:00 am - 9:30 pm
for (int i = 1; i <= 34; i++)
{
String tKey = "_" + hr.ToString() + min + mdn;
timeHash.Add(tKey, i.ToString());
if (i % 2 != 0) { min = "30"; }
else
{
min = "00";
if (hr == 12) { hr = 1; }
else
{
hr++;
if (hr == 11)
{
mdn = "pm";
}
}
}
}
// Assemble the Start Time and End Time values and open a URL
item =
this.Application.ActiveInspector().CurrentItem as Outlook.AppointmentItem;
String [] StartGroup =
item.ItemProperties["Start"].Value.ToString().Split(new Char[] {' '});
String [] EndGroup =
item.ItemProperties["End"].Value.ToString().Split(new Char[] { ' ' });
String [] StartTime = StartGroup[1].Split(new Char[] { ':' });
String [] EndTime = EndGroup[1].Split(new Char[] { ':' });
String selDate = StartGroup[0];
String sTimeKey = ("_" + StartTime[0] + StartTime[1] +
StartGroup[2]).ToLower();
String eTimeKey = ("_" + EndTime[0] + EndTime[1] +
EndGroup[2]).ToLower();
// Get the time values from timeHash, otherwise use -1
String sTimeID = (timeHash.ContainsKey(sTimeKey) ?
timeHash[sTimeKey].ToString() : "-1");
String eTimeID = (timeHash.ContainsKey(eTimeKey) ?
timeHash[eTimeKey].ToString() : "-1");
String ConfSchdURL =
"http://devapps/confroom/index.cfm?event=wizard";
ConfSchdURL += "&StartTime=" + sTimeID + "&EndTime=" +
eTimeID + "&SelDate=" + selDate;
// MessageBox.Show(sTimeKey + ":" + sTimeID + " " + eTimeKey
+ ":" + eTimeID);
newIE = System.Diagnostics.Process.Start("IExplore.exe",
ConfSchdURL);
}
/// <summary>
/// Handle the Inspector.Close event
/// </summary>
void closeInspector_Event()
{
// Drop the Btn_ConfRoomSchdlr event handler
Btn_ConfRoomSchdlr.Click -= new
Office._CommandBarButtonEvents_ClickEventHandler(clickButton_Event);
}
/// <summary>
/// Add the converted image to an ImageList
/// </summary>
private stdole.IPictureDisp getImage()
{
stdole.IPictureDisp tempImage = null;
try
{
System.Drawing.Icon newIcon = Properties.Resources.confchair;
ImageList newImageList = new ImageList();
newImageList.Images.Add(newIcon);
tempImage = ConvertImage.Convert(newImageList.Images[0]);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
return tempImage;
}
#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
}
// Convert the icon file to an Image object
sealed public class ConvertImage : System.Windows.Forms.AxHost
{
private ConvertImage()
: base(null)
{
}
public static stdole.IPictureDisp Convert(System.Drawing.Image image)
{
return
(stdole.IPictureDisp)System.Windows.Forms.AxHost.GetIPictureDispFromPicture(image);
}
}
}