Ribbon and a checkbox (C++ ATL)

Status
Not open for further replies.
T

Tom

Hi,

I have run into a problem using the a checkbox within a Ribbon control. I

have a C++ COM component which I have implemented a ribbon solution that

works fine for all of the buttons; but does not work 100 percent for a

checkbox.

I originally implemented the ribbon logic in accordance with an article by

Jensen Harris (Using RibbonX with C++ and ATL) and implementing buttons was

not an issue. However I have not been able to get the checkbox logic to work

correctly.

The only difference with his implementation and mine is that I am handling

the IDispatch::invoke directly (for many reasons other than the ribbon).

I am able to capture the onAction event without problem. But the issue I am

facing is the getPressed event is not acting the way I would think. I am

expecting two parameters, one being the dispatch for the ribbon control and

the other being the return value of the initial state of the checkbox.

However when I capture the event I only receive one parameter. So I do get

the event (id 2) and I can see that it is the proper ID for the checkbox by

calling GetId. However if I try to call GetTag is throws an unhandeled

exception.

Does anybody have any idea what is going on? I think I am missing something

in the design.

Thanks,

Tom -
 
The obvious and dumb question is whether your getPressed() signature is

correct.

Can you access the other Context and Id control properties passed to

getPressed() as part of the IRibbonControl object passed to you?

Does it work if you do what Eric mentioned in the blog post and not use your

own implementation? That's probably the first thing I'd look at.

"Tom" <tom@gigasoftdevelopment.com> wrote in message

news:eLuYM9IEKHA.1492@TK2MSFTNGP03.phx.gbl...
> Hi,

> I have run into a problem using the a checkbox within a Ribbon control. I
> have a C++ COM component which I have implemented a ribbon solution that
> works fine for all of the buttons; but does not work 100 percent for a
> checkbox.

> I originally implemented the ribbon logic in accordance with an article by
> Jensen Harris (Using RibbonX with C++ and ATL) and implementing buttons
> was not an issue. However I have not been able to get the checkbox logic
> to work correctly.

> The only difference with his implementation and mine is that I am handling
> the IDispatch::invoke directly (for many reasons other than the ribbon).

> I am able to capture the onAction event without problem. But the issue I
> am facing is the getPressed event is not acting the way I would think. I
> am expecting two parameters, one being the dispatch for the ribbon control
> and the other being the return value of the initial state of the checkbox.
> However when I capture the event I only receive one parameter. So I do get
> the event (id 2) and I can see that it is the proper ID for the checkbox
> by calling GetId. However if I try to call GetTag is throws an unhandeled
> exception.

> Does anybody have any idea what is going on? I think I am missing
> something in the design.

> Thanks,
> Tom -

>
 
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
<kenslovak@mvps.org> wrote in message

news:u4XzK2REKHA.1248@TK2MSFTNGP04.phx.gbl...
> The obvious and dumb question is whether your getPressed() signature is
> correct.

> Can you access the other Context and Id control properties passed to
> getPressed() as part of the IRibbonControl object passed to you?

> Does it work if you do what Eric mentioned in the blog post and not use
> your own implementation? That's probably the first thing I'd look at.

> >

>

> "Tom" <tom@gigasoftdevelopment.com> wrote in message
> news:eLuYM9IEKHA.1492@TK2MSFTNGP03.phx.gbl...
> > Hi,
>

>> I have run into a problem using the a checkbox within a Ribbon control. I
> > have a C++ COM component which I have implemented a ribbon solution that
> > works fine for all of the buttons; but does not work 100 percent for a
> > checkbox.
>

>> I originally implemented the ribbon logic in accordance with an article
> > by Jensen Harris (Using RibbonX with C++ and ATL) and implementing
> > buttons was not an issue. However I have not been able to get the
> > checkbox logic to work correctly.
>

>> The only difference with his implementation and mine is that I am
> > handling the IDispatch::invoke directly (for many reasons other than the
> > ribbon).
>

>> I am able to capture the onAction event without problem. But the issue I
> > am facing is the getPressed event is not acting the way I would think. I
> > am expecting two parameters, one being the dispatch for the ribbon
> > control and the other being the return value of the initial state of the
> > checkbox. However when I capture the event I only receive one parameter.
> > So I do get the event (id 2) and I can see that it is the proper ID for
> > the checkbox by calling GetId. However if I try to call GetTag is throws
> > an unhandeled exception.
>

>> Does anybody have any idea what is going on? I think I am missing
> > something in the design.
>

>> Thanks,
> > Tom -
>

>
>>

>
 
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

}

}

"Tom" <tom@gigasoftdevelopment.com> wrote in message

news:eODka%23SEKHA.1516@TK2MSFTNGP05.phx.gbl...
> 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
 
Hi Ken,

Thanks Ken.

I have snipped my invoke code below.

Actually your C# function for getpressed is equivalent to

CheckboxClicked([in]IDispatch* ribboncontrol, [out,retval]VARIANT_BOOL

state);

But I am not getting that event.

However the OnAction is infact sending me two parameters for the checkbox.

BTW - we have created our own ribbon tlb also using the MIDL compiler.

STDMETHODIMP CGSDExt::Invoke(DISPID dispidMember,REFIID riid, LCID lcid,

WORD wFlags,

DISPPARAMS* pdispparams, VARIANT* pvarResult,

EXCEPINFO* pexcepinfo, UINT* puArgErr)

{

if(dispidMember == 0xf001)

{

// Handle the NewInpector event

OnNewInspector(pdispparams->rgvarg[0].pdispVal);

}

else if(dispidMember == 1) // OnAction

{

// STDMETHOD(CheckboxClicked)( IDispatch * RibbonControl)

ATLTRACE(_T("state = %i\n"), pdispparams->rgvarg[0].boolVal);

DWORD dwDisable = 0;

if(pdispparams->rgvarg[0].boolVal)

{

dwDisable = 1;

GenericRegistry::WriteDwordValue(REGISTRY_CONFIG_ENTRY_OUTLOOK,

REGISTRY_DISABLE_BCC, dwDisable);

}

else

{

GenericRegistry::WriteDwordValue(REGISTRY_CONFIG_ENTRY_OUTLOOK,

REGISTRY_DISABLE_BCC, dwDisable);

}

CComPtr<IRibbonControl> spRibbon;

HRESULT hr =

pdispparams->rgvarg[1].pdispVal->QueryInterface(IID_IRibbonControl,

(LPVOID*)&spRibbon);

if(SUCCEEDED(hr) && spRibbon)

{

}

}

else if(dispidMember == 2) //getPressed

{

// STDMETHOD(GetCheckboxState)( IDispatch * RibbonControl, VARIANT_BOOL *

state)

BSTR b;

CComPtr<IRibbonControl> spRibbon;

BSTR bstr = NULL;

if(pdispparams->rgvarg[0].vt == VT_DISPATCH)

{

HRESULT hr =

pdispparams->rgvarg[0].pdispVal->QueryInterface(IID_IRibbonControl,

(LPVOID*)&spRibbon);

if(SUCCEEDED(hr) && spRibbon)

{

//hr = spRibbon->get_Tag(&b); <<<< This blows up

hr = spRibbon->get_Id(&bstr);

if(SUCCEEDED(hr) && bstr)

{

TString str = (const TCHAR*)_bstr_t(bstr, true);

::SysFreeString(bstr);

if(str.find(_T("gsdcheckbox")) != TString::npos)

{

DWORD dwDisable = 0;

if(!GenericRegistry::ReadDwordValue(REGISTRY_CONFIG_ENTRY_OUTLOOK,

REGISTRY_DISABLE_BCC, dwDisable))

{

dwDisable = 0;

GenericRegistry::WriteDwordValue(REGISTRY_CONFIG_ENTRY_OUTLOOK,

REGISTRY_DISABLE_BCC, dwDisable);

}

/* >>> the first parameter is the dispatch - Ugh!

// This should be the first parameter

if(dwDisable)

{

*(pdispparams->rgvarg[0].pboolVal) = VARIANT_TRUE;

}

else

*(pdispparams->rgvarg[0].pboolVal) = VARIANT_FALSE;

*/

}

}

}

}

}

return S_OK;

}
<kenslovak@mvps.org> wrote in message

news:ety7GWUEKHA.1380@TK2MSFTNGP02.phx.gbl...
> 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

> }

> }

> >

>

> "Tom" <tom@gigasoftdevelopment.com> wrote in message
> news:eODka%23SEKHA.1516@TK2MSFTNGP05.phx.gbl...
> > 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

>
 
The signature for a button's onAction callback is just the control, for a

checkbox it has 2 parameters: the control and a bool for pressed. In that

case the bool tells you the state of the checkbox. True == checked, false ==

unchecked.

For a checkbox in VB the getPressed signature is supposed to have 2

parameters: control and pressed. You set the pressed parameter to check the

checkbox and clear that bool to uncheck it. In VB terms that is passed

ByRef. In C# the signature is as a function with a bool return and only 1

parameter.

I was able to get the Tag property from control without any problems in a C#

test addin I keep around. It was null when I didn't set Tag in the ribbon

XML, it had the string value I set when I modified the XML to set the tag

property.

I'm curious if you'd have the same problem getting Tag in getPressed() on a

toggleButton?

I guess I can't really help with this any further, except to say that since

things work in both C# and VB6 testing I just did here that there must be

something in your implementation.

This does look correct:

//hr = spRibbon->get_Tag(&b);

with the call and BSTR return as far as I can see.

As a non-C++ guy I can't be more specific, and offhand I can't think of

another group that would be better for answers on this. About all I can

think of otherwise is to open a support case with MS. If you have MSDN you

can use one of your support incidents for that.

"Tom" <tom@gigasoftdevelopment.com> wrote in message

news:OjX4ghUEKHA.1248@TK2MSFTNGP04.phx.gbl...
> Hi Ken,

> Thanks Ken.

> I have snipped my invoke code below.

> Actually your C# function for getpressed is equivalent to

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

> But I am not getting that event.

> However the OnAction is infact sending me two parameters for the checkbox.

> BTW - we have created our own ribbon tlb also using the MIDL compiler.

> STDMETHODIMP CGSDExt::Invoke(DISPID dispidMember,REFIID riid, LCID lcid,
> WORD wFlags,
> DISPPARAMS* pdispparams, VARIANT* pvarResult,
> EXCEPINFO* pexcepinfo, UINT* puArgErr)
> {
> if(dispidMember == 0xf001)
> {
> // Handle the NewInpector event
> OnNewInspector(pdispparams->rgvarg[0].pdispVal);
> }
> else if(dispidMember == 1) // OnAction
> {
> // STDMETHOD(CheckboxClicked)( IDispatch * RibbonControl)
> ATLTRACE(_T("state = %i\n"), pdispparams->rgvarg[0].boolVal);
> DWORD dwDisable = 0;
> if(pdispparams->rgvarg[0].boolVal)
> {
> dwDisable = 1;
> GenericRegistry::WriteDwordValue(REGISTRY_CONFIG_ENTRY_OUTLOOK,
> REGISTRY_DISABLE_BCC, dwDisable);
> }
> else
> {
> GenericRegistry::WriteDwordValue(REGISTRY_CONFIG_ENTRY_OUTLOOK,
> REGISTRY_DISABLE_BCC, dwDisable);
> }

> CComPtr<IRibbonControl> spRibbon;

> HRESULT hr =
> pdispparams->rgvarg[1].pdispVal->QueryInterface(IID_IRibbonControl,
> (LPVOID*)&spRibbon);
> if(SUCCEEDED(hr) && spRibbon)
> {
> }

> }
> else if(dispidMember == 2) //getPressed
> {
> // STDMETHOD(GetCheckboxState)( IDispatch * RibbonControl, VARIANT_BOOL
> * state)
> BSTR b;
> CComPtr<IRibbonControl> spRibbon;
> BSTR bstr = NULL;
> if(pdispparams->rgvarg[0].vt == VT_DISPATCH)
> {
> HRESULT hr =
> pdispparams->rgvarg[0].pdispVal->QueryInterface(IID_IRibbonControl,
> (LPVOID*)&spRibbon);
> if(SUCCEEDED(hr) && spRibbon)
> {

> //hr = spRibbon->get_Tag(&b); <<<< This blows up
> hr = spRibbon->get_Id(&bstr);
> if(SUCCEEDED(hr) && bstr)
> {
> TString str = (const TCHAR*)_bstr_t(bstr, true);
> ::SysFreeString(bstr);
> if(str.find(_T("gsdcheckbox")) != TString::npos)
> {
> DWORD dwDisable = 0;
> if(!GenericRegistry::ReadDwordValue(REGISTRY_CONFIG_ENTRY_OUTLOOK,
> REGISTRY_DISABLE_BCC, dwDisable))
> {
> dwDisable = 0;
> GenericRegistry::WriteDwordValue(REGISTRY_CONFIG_ENTRY_OUTLOOK,
> REGISTRY_DISABLE_BCC, dwDisable);
> }
> /* >>> the first parameter is the dispatch - Ugh!
> // This should be the first parameter
> if(dwDisable)
> {
> *(pdispparams->rgvarg[0].pboolVal) = VARIANT_TRUE;
> }
> else
> *(pdispparams->rgvarg[0].pboolVal) = VARIANT_FALSE;

> */
> }
> }
> }
> }
> }

> return S_OK;
> }
 
Thanks Ken.

Yes - I think I will open a support case.

BTW - I saw somebody else on a blog that had the exact same problem. But

nobody gave him an answer.
<kenslovak@mvps.org> wrote in message

news:uE$c5yVEKHA.1340@TK2MSFTNGP05.phx.gbl...
> The signature for a button's onAction callback is just the control, for a
> checkbox it has 2 parameters: the control and a bool for pressed. In that
> case the bool tells you the state of the checkbox. True == checked, false
> == unchecked.

> For a checkbox in VB the getPressed signature is supposed to have 2
> parameters: control and pressed. You set the pressed parameter to check
> the checkbox and clear that bool to uncheck it. In VB terms that is passed
> ByRef. In C# the signature is as a function with a bool return and only 1
> parameter.

> I was able to get the Tag property from control without any problems in a
> C# test addin I keep around. It was null when I didn't set Tag in the
> ribbon XML, it had the string value I set when I modified the XML to set
> the tag property.

> I'm curious if you'd have the same problem getting Tag in getPressed() on
> a toggleButton?

> I guess I can't really help with this any further, except to say that
> since things work in both C# and VB6 testing I just did here that there
> must be something in your implementation.

> This does look correct:

> //hr = spRibbon->get_Tag(&b);

> with the call and BSTR return as far as I can see.

> As a non-C++ guy I can't be more specific, and offhand I can't think of
> another group that would be better for answers on this. About all I can
> think of otherwise is to open a support case with MS. If you have MSDN you
> can use one of your support incidents for that.

> >

>

> "Tom" <tom@gigasoftdevelopment.com> wrote in message
> news:OjX4ghUEKHA.1248@TK2MSFTNGP04.phx.gbl...
> > Hi Ken,
>

>> Thanks Ken.
>

>> I have snipped my invoke code below.
>

>> Actually your C# function for getpressed is equivalent to
>

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

>> But I am not getting that event.
>

>> However the OnAction is infact sending me two parameters for the
> > checkbox.
>

>> BTW - we have created our own ribbon tlb also using the MIDL compiler.
>

>
>> STDMETHODIMP CGSDExt::Invoke(DISPID dispidMember,REFIID riid, LCID lcid,
> > WORD wFlags,
> > DISPPARAMS* pdispparams, VARIANT* pvarResult,
> > EXCEPINFO* pexcepinfo, UINT* puArgErr)
> > {
> > if(dispidMember == 0xf001)
> > {
> > // Handle the NewInpector event
> > OnNewInspector(pdispparams->rgvarg[0].pdispVal);
> > }
> > else if(dispidMember == 1) // OnAction
> > {
> > // STDMETHOD(CheckboxClicked)( IDispatch * RibbonControl)
> > ATLTRACE(_T("state = %i\n"), pdispparams->rgvarg[0].boolVal);
> > DWORD dwDisable = 0;
> > if(pdispparams->rgvarg[0].boolVal)
> > {
> > dwDisable = 1;
> > GenericRegistry::WriteDwordValue(REGISTRY_CONFIG_ENTRY_OUTLOOK,
> > REGISTRY_DISABLE_BCC, dwDisable);
> > }
> > else
> > {
> > GenericRegistry::WriteDwordValue(REGISTRY_CONFIG_ENTRY_OUTLOOK,
> > REGISTRY_DISABLE_BCC, dwDisable);
> > }
>

>> CComPtr<IRibbonControl> spRibbon;
>

>> HRESULT hr =
> > pdispparams->rgvarg[1].pdispVal->QueryInterface(IID_IRibbonControl,
> > (LPVOID*)&spRibbon);
> > if(SUCCEEDED(hr) && spRibbon)
> > {
> > }
>

>> }
> > else if(dispidMember == 2) //getPressed
> > {
> > // STDMETHOD(GetCheckboxState)( IDispatch * RibbonControl, VARIANT_BOOL
> > * state)
> > BSTR b;
> > CComPtr<IRibbonControl> spRibbon;
> > BSTR bstr = NULL;
> > if(pdispparams->rgvarg[0].vt == VT_DISPATCH)
> > {
> > HRESULT hr =
> > pdispparams->rgvarg[0].pdispVal->QueryInterface(IID_IRibbonControl,
> > (LPVOID*)&spRibbon);
> > if(SUCCEEDED(hr) && spRibbon)
> > {
>

>> //hr = spRibbon->get_Tag(&b); <<<< This blows up
> > hr = spRibbon->get_Id(&bstr);
> > if(SUCCEEDED(hr) && bstr)
> > {
> > TString str = (const TCHAR*)_bstr_t(bstr, true);
> > ::SysFreeString(bstr);
> > if(str.find(_T("gsdcheckbox")) != TString::npos)
> > {
> > DWORD dwDisable = 0;
> > if(!GenericRegistry::ReadDwordValue(REGISTRY_CONFIG_ENTRY_OUTLOOK,
> > REGISTRY_DISABLE_BCC, dwDisable))
> > {
> > dwDisable = 0;
> > GenericRegistry::WriteDwordValue(REGISTRY_CONFIG_ENTRY_OUTLOOK,
> > REGISTRY_DISABLE_BCC, dwDisable);
> > }
> > /* >>> the first parameter is the dispatch - Ugh!
> > // This should be the first parameter
> > if(dwDisable)
> > {
> > *(pdispparams->rgvarg[0].pboolVal) = VARIANT_TRUE;
> > }
> > else
> > *(pdispparams->rgvarg[0].pboolVal) = VARIANT_FALSE;
>

>> */
> > }
> > }
> > }
> > }
> > }
>

>> return S_OK;
> > }

>
 
We attribute some Outlook things to the phases of the moon, they're just

unsolvable <g

"Tom" <tom@gigasoftdevelopment.com> wrote in message

news:O6h25$VEKHA.1516@TK2MSFTNGP05.phx.gbl...
> Thanks Ken.

> Yes - I think I will open a support case.

> BTW - I saw somebody else on a blog that had the exact same problem. But
> nobody gave him an answer.
 
Yes - we'll have to share a beer over that. I could tell you some good ones.

I am begining to see (unfortunately) the death of C++ in the Microsoft

world. This will make things extremely difficult designing any kind of low

level component.

Thanks agian for your thoughts on this!
<kenslovak@mvps.org> wrote in message

news:OYQ1UFWEKHA.4608@TK2MSFTNGP02.phx.gbl...
> We attribute some Outlook things to the phases of the moon, they're just
> unsolvable <g
> >

>

> "Tom" <tom@gigasoftdevelopment.com> wrote in message
> news:O6h25$VEKHA.1516@TK2MSFTNGP05.phx.gbl...
> > Thanks Ken.
>

>> Yes - I think I will open a support case.
>

>> BTW - I saw somebody else on a blog that had the exact same problem. But
> > nobody gave him an answer.

>
 
Status
Not open for further replies.
Similar threads
Thread starter Title Forum Replies Date
TomHuckstep Remove Send/Receive All Folders (IMAP/POP) button from Outlook 365 Ribbon Using Outlook 2
L Getting Index from dropdown inserted on ribbon Outlook VBA and Custom Forms 3
kburrows Outlook 365 - Ribbon Customizations Disappear Using Outlook 0
e_a_g_l_e_p_i Trying to customize the ribbon but can't figure this one out Using Outlook 3
Witzker Customized Ribbon lost every now and then Using Outlook 3
M Disable Contact Card Results when using "Search People" in Outlook Ribbon Using Outlook 7
Witzker Customized ribbon and entries disappeared Using Outlook 0
M In Outlook Calendar remove the buttons: 'Today' and '<' (Back a day) and '>' (Forward a day) that are below the Ribbon and above the calendar display. Using Outlook 0
W Ribbon XML customization Using Outlook 4
M Simplified ribbon missing Using Outlook 3
L Outlook Office 365 client: won't remember my setting File, not to collapse ribbon Using Outlook 2
S How to set up button in ribbon for individual Quick Steps Using Outlook 1
A Possible to hide ribbon with custom appointment form? Outlook VBA and Custom Forms 3
I Retention policies on outlook 2016 ribbon Using Outlook 2
V not able to change name in customize Ribbon Outlook VBA and Custom Forms 1
Wayne Dardis Calling Ribbon Button in Outlook 2016 Outlook VBA and Custom Forms 6
W Adding A Macro To Message Ribbon Outlook VBA and Custom Forms 2
Diane Poremsky Customize the Outlook Toolbar, Ribbon or QAT Using Outlook 0
M No Show Group on ribbon Using Outlook 8
I Ribbon buttons grayed-out in Outlook 2013 Using Outlook 2
B How can I adjust the ribbon width? I want to see all of my Quick Steps. Using Outlook 1
piusg 2013: Place custom view on the ribbon Using Outlook 3
P Outlook 2007 Calendar Ribbon has changed and I can't fix it Using Outlook 10
R Can I create custom subgroups on the ribbon? Using Outlook 5
M missing iCloud tab on ribbon bar Using Outlook 0
G Adding 3rd-Party Add-In to Home Ribbon in Outlook 2010 Using Outlook 1
E Outlook Ribbon Customization and Deployment Using Outlook 1
C Outlook Calendar Ribbon with iCloud Using Outlook 2
S ADD-IN Ribbon Missing Using Outlook 2
S ADD-IN Ribbon Missing Using Outlook 5
S Outlook 2010 Ribbon - Creating Links To Websites or EXE Files Using Outlook 4
M Move 'Reply All' on Ribbon in Outlook 2010 Using Outlook 2
L Email button on ribbon defaulting to exchange when POP is default Using Outlook 7
K call a help file when click on a button xml ribbon Outlook VBA and Custom Forms 1
J Executing Ribbon Command from Code Outlook 2010 Outlook VBA and Custom Forms 3
T Word 2007 add-in ribbon icons greyed out Outlook VBA and Custom Forms 1
K add a designed group into a existing inspector ribbon Outlook VBA and Custom Forms 7
C Create a Ribbon for the OL2010 Explorer Outlook VBA and Custom Forms 1
T Ribbon Control questions Outlook VBA and Custom Forms 7
S What's the appointment ribbon called? Outlook VBA and Custom Forms 1
H Program "Click on Ribbon Button" Using VBA Outlook VBA and Custom Forms 1
M Can I embed ribbon item into form region? Outlook VBA and Custom Forms 2
R Build custom ribbon in Outlook 2007 Outlook VBA and Custom Forms 3
C Ribbon problem Outlook VBA and Custom Forms 3
J Ribbon question Outlook VBA and Custom Forms 6
R Could i do this with ribbon(outlook2007)? Outlook VBA and Custom Forms 1
M Stop ribbon item tool tip text from wrapping? Outlook VBA and Custom Forms 2
H access appointmentItem from ribbon menu Outlook VBA and Custom Forms 1
D Application.ActiveInspector() is Null on Ribbon Load Outlook VBA and Custom Forms 1
T Using Ribbon in Inspector window Outlook VBA and Custom Forms 2

Similar threads

Back
Top