Re: Ribbon and a checkbox (C++ ATL)

Tech-Archive recommends: Repair Windows Errors & Optimize Windows Performance



The only callback signature I'm familiar with for onAction is something like this C# signature:

public void Ribbon_onAction(Ribbon.IRibbonControl control)

{

}

For getPressed it looks like this:

public bool Ribbon_getPressed(IRibbonControl control)

{

}

To me that implies that for C++ it could be something like this:

CheckboxClicked([in]IDispatch* ribboncontrol, [out]VARIANT_BOOL state);

Are you sure about that [in] attribute on the state variable?

You can take a look at www.outlookcode.com, there are some C++ COM addin samples for Outlook there, if you haven't seen them already.

For my own coding I restrict managed code addins to those that only need to support Outlook 2003 or later. I could do 2000 or later but there are some problems with the PIA's for 2002 and the 2002-modified one for 2000 that I prefer to avoid. For addins that must support Outlook 2000 and later I use VB6, I don't really do any C++ programming, just some hacking from time to time.

When I need to do one of those addins I reference the Outlook and Office 2000 tlb's and add ribbon support by using a special XLIRibbonExtensibility tlb that has the ribbon interfaces. That way I fork my code based on Outlook version and use the CommandBars interface for versions before 2007 and the ribbon for 2007 and 2010 for Inspectors (and Explorers for 2010).

When I do a C# addin that has to support Outlook 2003 and later I use ribbon interface definitions based on a blog article by Andrew Whitechapel of the VSTO team in a RibbonInterop class and handle the callbacks in a RibbonX class. The RibbonInterop class has definitions like this (it's been modified to also support the new interfaces in IRibbonUI for Office 2010):

//internal namespace to facilitate "Office" alias

namespace 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

}

}


--
Ken Slovak
[MVP - Outlook]
http://www.slovaktech.com
Author: Professional Programming Outlook 2007.
Reminder Manager, Extended Reminders, Attachment Options.
http://www.slovaktech.com/products.htm


"Tom" <tom@xxxxxxxxxxxxxxxxxxxxxxx> wrote in message news:eODka%23SEKHA.1516@xxxxxxxxxxxxxxxxxxxxxxx
Hi Ken,

Yes I can successfully call get_id and it returns the correct ID of the check box and yes when I call get _context it does return the correct dispatch. But when I call get_tag it throws an exception. In addition when I look at the number of arguments passed to the invoke procedure their is only one argument when there should be two.

I also modified the VS2005 C++/ATL example to be a check box and I get the same result.

Yesterday after I sent this post, I started mucking around with this and forgot to mention one thing that was puzzling to me. My interface and the OnAction method (CheckboxClicked())could only be defined as:

HRESULT CheckboxClicked([in]IDispatch* ribboncontrol);

But the actual event is returning two parameters.

HRESULT CheckboxClicked([in]IDispatch* ribboncontrol, [in]VARIANT_BOOL state);

So I believe by including the callback interface we are circumventing the default events for the checkbox. Something just is not adding up.

Is there an event interface that we can setup an advise on?

BTW - I have tried several ideas on the web. There is not any unmanaged solutions/examples that I have seen that appear to work one hundred percent. Most of our outlook add-ins have to support all versions of Outlook from 2000 (and windows 2000 and above) and above and a managed solution is not an option.

BTW2 - we were trying to use the ribbon as an experiment for one of our own products that we are releasing in a couple months. So far I think we are going to have to use the same add-in toolbar that we have for 2002 and 2003.

Thanks,
Tom

.



Relevant Pages

  • Re: Ribbon and a checkbox (C++ ATL)
    ... BTW - we have created our own ribbon tlb also using the MIDL compiler. ... ribbon interface definitions based on a blog article by Andrew Whitechapel ... MethodCodeType = MethodCodeType.Runtime), DispId] get;} ... string Tag { ...
    (microsoft.public.outlook.program_addins)
  • Problem with ActiveX UserControl event mechanism
    ... Managed Server as the event source and for example write a COM Client ... sink interface and connects the interface to the SampleControl class. ... public delegate void SomeEventDelegate; ... AxRegisterClass(String key) ...
    (microsoft.public.dotnet.framework.interop)
  • Re: Help with finding entry point (
    ... > SetSchema Sets the bidi schema string. ... The interface description is taken from the bidispl.h header file. ... ComImport, ... void UnbindDevice(); ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: Calling Still Image API in C#
    ... also included the updated interface definition. ... void GetDeviceInfo([In, MarshalAs(UnmanagedType.LPWStr)] string ... pwszDeviceName, string pValueName, ...
    (microsoft.public.dotnet.framework.interop)
  • Re: ActiveX & IE interaction
    ... serviceProvider.QueryService(ref SID_STopLevelBrowser, ref ... public interface IServiceProvider ... void QueryService(ref Guid guidService, ref Guid riid, ... [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = ...
    (microsoft.public.dotnet.general)