Outlook custom property page 'Apply' button

A

AShe

I write my own add-in for Outlook 2007 with С++ and ATL, and create property
page for it. All works fine (property page shown), but when I change some
textbox's text on property page 'Apply' button is not enabled.
MSDN says for 'PropertyPage.Dirty': "The ActiveX control that implements the
PropertyPage object sets the value of this property, and Microsoft Outlook
queries this in response to the OnStatusChange method of a PropertyPageSite
object."
When I change some text on property page, my function 'SetPageDirty' launch.
It's code:

void CMyPropPage::SetPageDirty(void)
{
m_bIsDirty = true;
IOleClientSite* ppClientSite;
HRESULT hr = this->GetClientSite(&ppClientSite);
if (FAILED(hr))
{
ATLTRACE2(L"Failed GetClientSite\r\n");
return;
}
CComQIPtr<Outlook::propertyPageSite> spPropPageSite(ppClientSite);
if (spPropPageSite != NULL)
{
hr = spPropPageSite->OnStatusChange();
if (FAILED(hr))
{
ATLTRACE2(L"Failed OnStatusChange\r\n");
}
}
}

This function works fine (no trace outputs), but Outlook not try to query
'Dirty' property. It's code:

STDMETHODIMP CMyPropPage::get_Dirty(VARIANT_BOOL * Dirty)
{
*Dirty = (m_bIsDirty) ? VARIANT_TRUE : VARIANT_FALSE;
return S_OK;
}

I have breakpoint on first line of 'get_Dirty' and it's not hitting. And
'Apply' button still disabled. What I'm doing wrong?
 
K

Ken Slovak - [MVP - Outlook]

Are you positive that the code after this line is actually being executed?

if (spPropPageSite != NULL)
{
}

Try either setting up a trace on the site being null or step the code there
and see.

If OnStatusChange() is actually being called that should cause Outlook to
query the dirty property, so my assumption is that block of code isn't being
executed.
 
A

AShe

Yes, I'm sure that this code is executed. I debug it by steps. And when I
debug this code I'm write:

if (spPropPageSite != NULL)
{
Outlook::OlObjectClass Class;
spPropPageSite->get_Class(&Class);
....
}

and 'Class == olPropertyPageSite'. Also in my class I have method like
'IOleObject_GetClientSite' and 'InternalGetSite', I try theirs instead
'GetClientSite', but same effect.
In this example
'http://msdn.microsoft.com/en-us/library/aa140126(office.10).aspx' used
'Parent' property as PropertyPageSite, but in my class I haven't this
property. Maybe I'm not implement some intarface?
 
K

Ken Slovak - [MVP - Outlook]

The Parent property in that code sample is the parent of the ActiveX
UserControl object. That equates to the Outlook.Application object. Of
course that code sample is VB6 code.

Note also that the PropertyPageSite interface isn't instantiated yet in the
Initialize() event of the UserControl, you have to wait for the
InitProperties() event to fire.

I don't do C++ addins at all, but in C# the way I get a handle for the
PropertyPageSite object is much more obscure, due to the nature of managed
code and the Interop. I don't know if this will help you at all, but here's
how I do it in C# code, in the UserControl constructor:

// at class module level
private Outlook.PropertyPageSite m_site;



// in constructor

// HACK: uses reflection to call a private unsafe method!

Type userControlType = typeof(System.Object);

string assembly = userControlType.Assembly.CodeBase.Replace("mscorlib.dll",
"System.Windows.Forms.dll");

assembly = assembly.Replace("file:///", "");

string assemblyName =
System.Reflection.AssemblyName.GetAssemblyName(assembly).FullName;

Type unsafeMethods =
Type.GetType(System.Reflection.Assembly.CreateQualifiedName(assemblyName,
"System.Windows.Forms.UnsafeNativeMethods"));

Type oleObjectType = unsafeMethods.GetNestedType("IOleObject");

System.Reflection.MethodInfo method =
oleObjectType.GetMethod("GetClientSite");

try

{

m_site = (Outlook.PropertyPageSite)method.Invoke(this, null);

}

catch

{

m_site = null;

}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top