Outlook 2007 & 2010

  • Thread starter Thread starter rakesh
  • Start date Start date
R

rakesh

Hi,

I've developed a plugin which works perfect with all Outlook versions up to
Outlook 2007.
Now, I am developing the same plugin for Outlook 2010.

Should I have two different COM dlls?
OR
Could I implement both interfaces (IRibbonExtensibility) in one DLL and
based on Outlook version could execute them?

Please guide me.

_
Best Regards
 
If you want to handle the ribbon, it must be in the same class that
implements extensibility. That's a requirement.

You need to tell us more about your setup. What language are you using for
your addin, what version of Visual Studio if you are using an MS language?
What is the earliest version of Outlook you are supporting? What version are
you referencing and if using managed code what version of the Outlook PIA?

Are you now handling the ribbon for Inspectors, something that you should be
doing anyway for support for Outlook 2007?

You can use one addin for everything, but how that's done depends on the
factors I asked about above.
 
Thanks Ken,

I am using MS VC6 with ATL to build this COM plugin. Upto Outlook 2007, my
plugin was looking great in Outlook's toolbar pane and in Outlook's menu.
But in Outlook 2010 with ribbon technology, this toolbar looks very awkward.
So I want to create a ribbon for my plugin in MS Outlook. And want to remove
old toolbar from it.

To create ribbon, I came to know that Windows 7 sdk is needed and mostly MS
VS 2005/2008 c++ is used to develop them.
I've created a sample ribbon button in Outlook with the help of other
articles. But now I am confused, about my previous code.
How can I merge both in one DLL?

If one user has Outlook 2000 - 2007 and another has Outlook 2010, I want to
support them using one DLL. Based on Outlook version I want to show the
apropriate Toolbar to the user. Internal processing works fine for all
versions. Difference is only in GUI.
Is it feasible?

Suggest me...

_
Best Regards
 
What you want to do is feasible. I don't do C++ addins, but here's how I'd
do it using C#. I'd set up one class that handles the extensibility
interface. I'd reference the Outlook 2000 object model. In my extensibility
class (or actually a partial instance of that class) I'd have the ribbon
declarations.

When I got OnConnection() I'd get the Outlook version. Based on that I'd
create user interface for Explorers and Inspectors using CommandBars where
appropriate, and just let the ribbon callbacks fire for that UI where it was
Outlook 2007 or 2010. For 2007 I'd create Explorer UI using CommandBars, for
2010 it would just be ribbon UI for Explorers.

For the ribbon declarations I'd have something like this:

//internal namespace to facilitate "Office" alias
space RibbonInterop

{

namespace Office

{

#region Ribbon

[ComImport(), Guid("000C0395-0000-0000-C000-000000000046"),
TypeLibType((short)0X1040)]

public interface IRibbonControl

{

[DispId(1)]

string Id { [return: MarshalAs(UnmanagedType.BStr)]

[MethodImpl(MethodImplOptions.InternalCall,

MethodCodeType = MethodCodeType.Runtime), DispId(1)] get; }


[DispId(2)]

object Context { [return: MarshalAs(UnmanagedType.IDispatch)]

[MethodImpl(MethodImplOptions.InternalCall,

MethodCodeType = MethodCodeType.Runtime), DispId(2)] get; }


[DispId(3)]

string Tag { [return: MarshalAs(UnmanagedType.BStr)]

[MethodImpl(MethodImplOptions.InternalCall,

MethodCodeType = MethodCodeType.Runtime), DispId(3)] get; }

}

[ComImport(), Guid("000C0396-0000-0000-C000-000000000046"),
TypeLibType((short)0X1040)]

public interface IRibbonExtensibility

{

[return: MarshalAs(UnmanagedType.BStr)]

[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType =
MethodCodeType.Runtime), DispId(1)]

string GetCustomUI([In(), MarshalAs(UnmanagedType.BStr)] string RibbonID);

}

[ComImport(), Guid("000C03A7-0000-0000-C000-000000000046"),
TypeLibType((short)0X1040)]

public interface IRibbonUI

{

// for both Office 2007 and 2010

[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType =
MethodCodeType.Runtime), DispId(1)]

void Invalidate();

[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType =
MethodCodeType.Runtime), DispId(2)]

void InvalidateControl([In(), MarshalAs(UnmanagedType.BStr)] string
ControlID);

// for Office 2010

[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType =
MethodCodeType.Runtime), DispId(3)]

void InvalidateControlMso([In(), MarshalAs(UnmanagedType.BStr)] string
ControlID);

[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType =
MethodCodeType.Runtime), DispId(4)]

void ActivateTab([In(), MarshalAs(UnmanagedType.BStr)] string ControlID);

[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType =
MethodCodeType.Runtime), DispId(5)]

void ActivateTabMso([In(), MarshalAs(UnmanagedType.BStr)] string ControlID);

[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType =
MethodCodeType.Runtime), DispId(6)]

void ActivateTabQ([In(), MarshalAs(UnmanagedType.BStr)] string ControlID,

[In(), MarshalAs(UnmanagedType.BStr)] string Namespace);

}

#endregion

}

}
 
Thanks again Ken,

I was out of station so today I've checked your reply.
I'll try this then will update you what is the output,
:-)

_
Best Regards


Ken Slovak - said:
What you want to do is feasible. I don't do C++ addins, but here's how I'd
do it using C#. I'd set up one class that handles the extensibility
interface. I'd reference the Outlook 2000 object model. In my
extensibility class (or actually a partial instance of that class) I'd
have the ribbon declarations.

When I got OnConnection() I'd get the Outlook version. Based on that I'd
create user interface for Explorers and Inspectors using CommandBars where
appropriate, and just let the ribbon callbacks fire for that UI where it
was Outlook 2007 or 2010. For 2007 I'd create Explorer UI using
CommandBars, for 2010 it would just be ribbon UI for Explorers.

For the ribbon declarations I'd have something like this:

//internal namespace to facilitate "Office" alias
space RibbonInterop

{

namespace Office

{

#region Ribbon

[ComImport(), Guid("000C0395-0000-0000-C000-000000000046"),
TypeLibType((short)0X1040)]

public interface IRibbonControl

{

[DispId(1)]

string Id { [return: MarshalAs(UnmanagedType.BStr)]

[MethodImpl(MethodImplOptions.InternalCall,

MethodCodeType = MethodCodeType.Runtime), DispId(1)] get; }


[DispId(2)]

object Context { [return: MarshalAs(UnmanagedType.IDispatch)]

[MethodImpl(MethodImplOptions.InternalCall,

MethodCodeType = MethodCodeType.Runtime), DispId(2)] get; }


[DispId(3)]

string Tag { [return: MarshalAs(UnmanagedType.BStr)]

[MethodImpl(MethodImplOptions.InternalCall,

MethodCodeType = MethodCodeType.Runtime), DispId(3)] get; }

}

[ComImport(), Guid("000C0396-0000-0000-C000-000000000046"),
TypeLibType((short)0X1040)]

public interface IRibbonExtensibility

{

[return: MarshalAs(UnmanagedType.BStr)]

[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType =
MethodCodeType.Runtime), DispId(1)]

string GetCustomUI([In(), MarshalAs(UnmanagedType.BStr)] string RibbonID);

}

[ComImport(), Guid("000C03A7-0000-0000-C000-000000000046"),
TypeLibType((short)0X1040)]

public interface IRibbonUI

{

// for both Office 2007 and 2010

[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType =
MethodCodeType.Runtime), DispId(1)]

void Invalidate();

[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType =
MethodCodeType.Runtime), DispId(2)]

void InvalidateControl([In(), MarshalAs(UnmanagedType.BStr)] string
ControlID);

// for Office 2010

[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType =
MethodCodeType.Runtime), DispId(3)]

void InvalidateControlMso([In(), MarshalAs(UnmanagedType.BStr)] string
ControlID);

[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType =
MethodCodeType.Runtime), DispId(4)]

void ActivateTab([In(), MarshalAs(UnmanagedType.BStr)] string ControlID);

[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType =
MethodCodeType.Runtime), DispId(5)]

void ActivateTabMso([In(), MarshalAs(UnmanagedType.BStr)] string
ControlID);

[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType =
MethodCodeType.Runtime), DispId(6)]

void ActivateTabQ([In(), MarshalAs(UnmanagedType.BStr)] string ControlID,

[In(), MarshalAs(UnmanagedType.BStr)] string Namespace);

}

#endregion

}

}





rakesh said:
Thanks Ken,

I am using MS VC6 with ATL to build this COM plugin. Upto Outlook 2007,
my plugin was looking great in Outlook's toolbar pane and in Outlook's
menu.
But in Outlook 2010 with ribbon technology, this toolbar looks very
awkward. So I want to create a ribbon for my plugin in MS Outlook. And
want to remove old toolbar from it.

To create ribbon, I came to know that Windows 7 sdk is needed and mostly
MS VS 2005/2008 c++ is used to develop them.
I've created a sample ribbon button in Outlook with the help of other
articles. But now I am confused, about my previous code.
How can I merge both in one DLL?

If one user has Outlook 2000 - 2007 and another has Outlook 2010, I want
to support them using one DLL. Based on Outlook version I want to show
the apropriate Toolbar to the user. Internal processing works fine for
all versions. Difference is only in GUI.
Is it feasible?

Suggest me...

_
Best Regards
 
Hi Ken,

I hope you are doing well and preparing for Christmas.

- I've tried your code to put into .idl file of my code.
And derived my COM plug in class from IRibbonExtensibility. But it does
not work.
class ATL_NO_VTABLE OAddin :
public ISupportErrorInfo,
public CComObjectRootEx <CComSingleThreadModel>,
public CComCoClass <OAddin, &CLSID_OAddin>,
public IDispatchImpl <IOAddin, &IID_IOAddin, &LIBID_OALib>,
public IDispatchImpl <_IDTExtensibility2, &IID__IDTExtensibility2,
&LIBID_AddInDesignerObjects>,
public IDispatchImpl<IRibbonExtensibility, &IID_IRibbonExtensibility,
&LIBID_Office>,

- Then, I placed the mso.dll in my project directory and Implement the
interface (IRibbonExtensibility) from it.
Almost same code as above. But it again gives some errors. I am a bit
confused again. How to implement this interface in my existing class?

- I am also trying to do late binding using IUnkown and IDispatch
interface. But it is also getting failed.
m_spApp->QueryInterface (IID_IRibbonExtensibility, (void**)&pInterface);

Please suggest me which way I should go and which one has better scalablity.

_
Best Regards




rakesh said:
Thanks again Ken,

I was out of station so today I've checked your reply.
I'll try this then will update you what is the output,
:-)

_
Best Regards


Ken Slovak - said:
What you want to do is feasible. I don't do C++ addins, but here's how
I'd do it using C#. I'd set up one class that handles the extensibility
interface. I'd reference the Outlook 2000 object model. In my
extensibility class (or actually a partial instance of that class) I'd
have the ribbon declarations.

When I got OnConnection() I'd get the Outlook version. Based on that I'd
create user interface for Explorers and Inspectors using CommandBars
where appropriate, and just let the ribbon callbacks fire for that UI
where it was Outlook 2007 or 2010. For 2007 I'd create Explorer UI using
CommandBars, for 2010 it would just be ribbon UI for Explorers.

For the ribbon declarations I'd have something like this:

//internal namespace to facilitate "Office" alias
space RibbonInterop

{

namespace Office

{

#region Ribbon

[ComImport(), Guid("000C0395-0000-0000-C000-000000000046"),
TypeLibType((short)0X1040)]

public interface IRibbonControl

{

[DispId(1)]

string Id { [return: MarshalAs(UnmanagedType.BStr)]

[MethodImpl(MethodImplOptions.InternalCall,

MethodCodeType = MethodCodeType.Runtime), DispId(1)] get; }


[DispId(2)]

object Context { [return: MarshalAs(UnmanagedType.IDispatch)]

[MethodImpl(MethodImplOptions.InternalCall,

MethodCodeType = MethodCodeType.Runtime), DispId(2)] get; }


[DispId(3)]

string Tag { [return: MarshalAs(UnmanagedType.BStr)]

[MethodImpl(MethodImplOptions.InternalCall,

MethodCodeType = MethodCodeType.Runtime), DispId(3)] get; }

}

[ComImport(), Guid("000C0396-0000-0000-C000-000000000046"),
TypeLibType((short)0X1040)]

public interface IRibbonExtensibility

{

[return: MarshalAs(UnmanagedType.BStr)]

[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType =
MethodCodeType.Runtime), DispId(1)]

string GetCustomUI([In(), MarshalAs(UnmanagedType.BStr)] string
RibbonID);

}

[ComImport(), Guid("000C03A7-0000-0000-C000-000000000046"),
TypeLibType((short)0X1040)]

public interface IRibbonUI

{

// for both Office 2007 and 2010

[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType =
MethodCodeType.Runtime), DispId(1)]

void Invalidate();

[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType =
MethodCodeType.Runtime), DispId(2)]

void InvalidateControl([In(), MarshalAs(UnmanagedType.BStr)] string
ControlID);

// for Office 2010

[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType =
MethodCodeType.Runtime), DispId(3)]

void InvalidateControlMso([In(), MarshalAs(UnmanagedType.BStr)] string
ControlID);

[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType =
MethodCodeType.Runtime), DispId(4)]

void ActivateTab([In(), MarshalAs(UnmanagedType.BStr)] string ControlID);

[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType =
MethodCodeType.Runtime), DispId(5)]

void ActivateTabMso([In(), MarshalAs(UnmanagedType.BStr)] string
ControlID);

[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType =
MethodCodeType.Runtime), DispId(6)]

void ActivateTabQ([In(), MarshalAs(UnmanagedType.BStr)] string ControlID,

[In(), MarshalAs(UnmanagedType.BStr)] string Namespace);

}

#endregion

}

}





rakesh said:
Thanks Ken,

I am using MS VC6 with ATL to build this COM plugin. Upto Outlook 2007,
my plugin was looking great in Outlook's toolbar pane and in Outlook's
menu.
But in Outlook 2010 with ribbon technology, this toolbar looks very
awkward. So I want to create a ribbon for my plugin in MS Outlook. And
want to remove old toolbar from it.

To create ribbon, I came to know that Windows 7 sdk is needed and mostly
MS VS 2005/2008 c++ is used to develop them.
I've created a sample ribbon button in Outlook with the help of other
articles. But now I am confused, about my previous code.
How can I merge both in one DLL?

If one user has Outlook 2000 - 2007 and another has Outlook 2010, I want
to support them using one DLL. Based on Outlook version I want to show
the apropriate Toolbar to the user. Internal processing works fine for
all versions. Difference is only in GUI.
Is it feasible?

Suggest me...

_
Best Regards
 
I'm sorry, as I mentioned before I don't do C++ addins so I have no idea how
to correct any problems you might have. What I showed you does work in C#
addins for handling the ribbon, what would need to be done to make that work
in a C++ addin I haven't a clue.
 
It's OK Ken,

Your suggestion helps a lot.
I've resolved that issue. Now I have another issues....
1) How to disable the individual button of toolbar on Outlook event e.g. on
folder selection change?
2) How to set the custom image of the toolbar?
3) How to add a command in context menu of Outlook?

I've all these features in my plug in for older version of Outlook but did
not get any hint on internet for these points.
Please share your knowledge here.
:-)

_
Best Regards
 
You use the Enabled Boolean property of a button or toolbar to enable or
disable that object. You obviously need a handle to whatever you are
disabling or enabling of course.

A toolbar (CommandBar) cannot have an image. Only a CommandBarButton has an
image. If the button is in-process to Outlook you pass IPictureDisp images
to the Picture and Mask properties of the button. IPictureDisp objects
cannot be passed across process boundaries.

Look at the Outlook.Application object in the Object Browser and review the
various context menu events that are available in Outlook 2007 and later.

If you plan to do any sort of Outlook development you really should become
familiar with using the Object Browser on the Outlook object model. There
are also many sample applications and code samples available that your
searches aren't finding, if you are searching at all. The Office Developer
area of MSDN has a lot of sample addins in C# and some in VB.NET and there
are many, many samples at www.outlookcode.com. If you aren't finding
anything about the 3 topics you just asked about you just aren't searching
very well.
 
Thanks again Ken for your long reply.

This is my mistake in the last line of the last post. I have not mentioned
that I am facing these problems only in Outlook 2010.
In previous versions of Outlook, till 2007 all functionalities are working
fine.
Due to ribbon buttons, I am not finding the solution to disable button on
Outlook events.

Thanks for the suggestions.

_
Best Regards
 
For Outlook 2010 you need to work with the ribbon for both Inspectors and
Explorers. In that case you would probably want to set up getEnabled
handlers in your ribbon control XML. You can then call Ribbon.Invalidate()
or .InvalidateControl(controlID) to force that callback (among others) to
fire. In that callback you can then decide whether or not the controls are
enabled or disabled.

It's the same principle as handling disabling/enabling on Inspector ribbon
controls in Outlook 2007.
 
Back
Top