« April 2008 | Main | June 2008 »
Outlook Development Tip - Preventing Multiple Events with Toolbar Buttons
If you're hooking your toolbar to every Explorer that gets created in Outlook, you may run into an issue where the events that fire from your toolbar buttons will fire for every explorer that's open. So if I have a button that opens a new window, and I have three explorers open, clicking that button will open three windows.
Easy to fix - be sure to set the "Tag" property of the button to something unique. Using the buttons instance ID helps. Here's what I use in Inbox:
cmdBarButton.Tag = "cmdBarButton" + cmdBarButton.InstanceId.ToString();
Posted by Nick Harris on May 29, 2008 at 09:19 AM | Permalink | Comments (1)
Outlook Development Tip - Icons on Toolbar Buttons
Adding icons to your Outlook toolbar not only makes it look better, but it also helps with usability since training your mind to recognize an icon is easier than looking for a word. Picking the right icon than becomes very important.
Microsoft Office has hundreds of icons built in that you can use on your toolbar. When you create the button, you simply give it the Face ID of the icon you want to use:
(Microsoft.Office.Core.CommandBarButton)cmdBarButton.FaceId = 984;
Finding the correct icon is easy using FaceID Browser (http://skp.mvps.org/faceid.htm) - it's a must have for any Office Add-in developer.
Sometimes though you may want to add an icon that isn't built into Office. This is where it gets a little trickier. In Outlook 2003 and higher all you need to do is set the "Picture" and "Mask" properties of the button as outlined in this MSDN article. For Outlook XP or 2000, you'll need copy your image to the clip board, than use the PasteFace() function.
Here's all the functions I use in Inbox to create custom toolbar icons:
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Reflection;
using System.Windows.Forms;
using System.Drawing;
using Outlook = Microsoft.Office.Interop.Outlook;
using Office = Microsoft.Office.Core;
using stdole;
private void AddCustomIcon(string resourceName, Office.CommandBarButton btn)
{
try
{
Assembly ng = Assembly.GetAssembly(m_nginbox.GetType());
Stream str = ng.GetManifestResourceStream(resourceName);
Bitmap bm = new Bitmap(str);
if (IsOutlookXP())
{
btn.Picture = (IPictureDisp)AxHost2.GetIPictureDispFromPicture(bm);
btn.Mask = (IPictureDisp)AxHost2.GetIPictureDispFromPicture(CreateMask(bm));
}
else
{
MakeBitmapTransparent(bm);
SaveCurrentClipboard();
Clipboard.SetDataObject(bm);
btn.PasteFace();
RestoreClipboard();
}
}
catch (System.Exception ex)
{
}
private void SaveCurrentClipboard()
{
IDataObject clipboardCurrent = Clipboard.GetDataObject();
clipboardPreserve = new DataObject();
foreach (string format in clipboardCurrent.GetFormats(false))
clipboardPreserve.SetData(format, clipboardCurrent.GetData(format));
}
private void RestoreClipboard()
{
if (clipboardPreserve != null)
Clipboard.SetDataObject(clipboardPreserve, true);
}
private void MakeBitmapTransparent(Bitmap icon)
{
Color colorTransparent = icon.GetPixel(0, 0);
for (int x = icon.Width - 1; x >= 0; x--)
for (int y = icon.Height - 1; y >= 0; y--)
if (icon.GetPixel(x, y) == colorTransparent)
icon.SetPixel(x, y,
Color.FromKnownColor(System.Drawing.KnownColor.Control));
}
private Bitmap CreateMask(Bitmap original)
{
Bitmap mask = new Bitmap(16, 16);
Color colorTransparent = original.GetPixel(0, 0);
for (int x = original.Width - 1; x >= 0; x--)
{
for (int y = original.Height - 1; y >= 0; y--)
{
if (original.GetPixel(x, y) == colorTransparent)
mask.SetPixel(x, y, System.Drawing.Color.White);
else
mask.SetPixel(x, y, System.Drawing.Color.Black);
}
}
return mask;
}
public class AxHost2 : AxHost
{
public AxHost2() : base(null) { }
public new static IPictureDisp GetIPictureDispFromPicture(Image image)
{
return (IPictureDisp)AxHost.GetIPictureDispFromPicture(image);
}
}
Posted by Nick Harris on May 28, 2008 at 03:48 PM | Permalink | Comments (1)
Strongly Typed Languages
One thing that I've never liked about JavaScript is that it's not a strongly typed programming language. I get the arguments around dynamic typing but I've never found the benefits to be anything substantial. Strong typing is also why I preferred Delphi over Visual Basic when I first started Windows programming.
Dare's post about implicit type declarations in C# 3.0 and refactoring tools that suggest using "var" in place of using a static types is troublesome. Readability is one thing, but the biggest benefit to me of strongly typed languages is the amount of runtime errors that can be prevented at compile time. I'd rather know that the property I'm trying to access on an object doesn't exists before I run code.
Dare's point about variable naming is also something that I think about often when writing code. MyObject.Name is my preferred way of writing as opposed to MyObject.MyObjectName - even though it may be a little more readable when I come back to the code later, the extra time and space to include type information in a property name isn't worth it.
This reminds me of when I first heard that versions of .Net will allow you to mix C# or VB directly into your SQL stored procedures. Yes, it may give less experienced programmers the ability to manipulate SQL results with languages they already know, but it discourages learning the proper use of the programming tools they have. You can hit a nail with a wrench, but a hammer works much better.
I also see now why people say they blog less when they start using twitter - I'm making an effort to change that.
Posted by Nick Harris on May 21, 2008 at 10:28 AM | Permalink | Comments (0)
Nick Bradbury asks - "The Future of Feed Reading: What Do YOU Want?"
Nick Bradbury is asking his users an interesting question - "The Future of Feed Reading: What Do YOU Want?". Below is Nick's post. What kind of things do you want when it comes to RSS? Feel free to comment here or on Nick's post.
http://nick.typepad.com/blog/2008/05/the-future-of-f.html
Every now and then I'll see a blog post predicting the future of feed reading, and invariably it's written by someone who spends every waking moment reading their feeds. Which is fine, of course - we certainly want to know what power users expect from the future of RSS. But predictions from these folks are usually based on what they need from RSS, and their needs don't always match the needs of the majority.
Most people who use an RSS reader don't live in it. They use it to stay up-to-date with the latest news from the blogosphere, to keep tabs on what people they trust are talking about, or simply to kill some time between more important tasks.
This blog post is aimed towards these people - the ones who love their RSS reader, but don't feel withdrawal symptoms when they don't use it for a day.
What do you want from your RSS reader in the future? If you could change the future of feed reading to suit your needs, what would you want that future to look like?
Posted by Nick Harris on May 19, 2008 at 10:13 AM | Permalink | Comments (1)