 |
BorlandTalk.com Borland discussion newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
garyc Guest
|
Posted: Tue Mar 20, 2007 5:33 pm Post subject: Custom property page for an activeform control |
|
|
Hello,
Has anyone successfully added a custom property page to an active form
control?
I have a very simple control that wraps a list control for displaying
information. The control has a couple of buttons that clears the list
content or looks up an error code entered into an edit box.
It works, I have added the component to a package and can successfully
embed it in VCL applications.
I then attempted to add a property to my control. The property is of
type VARIANT_BOOL and is called 'Extended'. The idea was to control
the runtime behavior of the control according to the value of
'Extended' set when the control was placed on the vcl form.
I added the property to the typelibrary for the control, the
'get_Extended' and 'set_Extended' skeleton methods were added to my
code which i fleshed out to return or set the value of the member
variable 'm_vtBoolExtended', nothing fancy:
STDMETHODIMP TComErrorCtrlXImpl::get_Extended(VARIANT_BOOL* Value)
{
try
{
*Value = m_vtBoolExtended;
}
catch(Exception &e)
{
return Error(e.Message.c_str(), IID_IComErrorCtrlX);
}
return S_OK;
};
STDMETHODIMP TComErrorCtrlXImpl::set_Extended(VARIANT_BOOL Value)
{
try
{
m_vtBoolExtended = Value;
}
catch(Exception &e)
{
return Error(e.Message.c_str(), IID_IComErrorCtrlX);
}
return S_OK;
};
Following the C++Builder 6 manual i used the 'new property page'
wizard to add a custom property page. On this page i placed a single
check box control.
In my control code i added the ATL macro entries for the new property
page and an entry for the
custom property that it would set:
BEGIN_PROPERTY_MAP(TComErrorCtrlXImpl)
PROP_PAGE(CLSID_PropertyPage1)
PROP_ENTRY("Extended", 231, CLSID_PropertyPage1) // 231 = DispID
from typelib editor
END_PROPERTY_MAP()
In my property page code I fleshed out the 'UpdatePropertyPage' and
'UpdateObject' methods:
void __fastcall TPropertyPage1::UpdatePropertyPage(void)
{
// Update your controls from OleObjects
Variant vtTemp;
vtTemp = OleObject.OlePropertyGet("Extended");
if (vtTemp == VARIANT_FALSE) {
chk_Extended->Checked = false;
}
else {
chk_Extended->Checked = true;
}
}
void __fastcall TPropertyPage1::UpdateObject(void)
{
// Update OleObjects from your controls
// n.b. this is not the code given in the manual, the manual code
// attempts to access template OlePropertySet method for each
// type of parameter, they are protected however and so we must
// use the TAutoArgsBase incarnation which is public
VARIANT_BOOL vtBool;
TAutoArgs<1> args;
if (chk_Extended->Checked) {
args[1] = VARIANT_TRUE;
}
else {
args[1] = VARIANT_FALSE;
}
OleObject.OlePropertySet("Extended",
static_cast<TAutoArgsBase&>(args));
}
I then unload the control package, unregister the control, rebuild and
re-register the control, recreate the package and load it.
Now when i add the control to a VCL form everything is fine until i
right click on the control and select 'properties'.
I get the error
Access violation at address 10F7821D in module 'COMERR~1.OCX'. Read of
address D8558B6D
The Details of the error are:
+ $5D[10F7821D]{COMERR~1.OCX} variant.cpp.GetIDsOfNames + $5D
+ $0[51F26B4B]{rtl100.bpl } System.System.@HandleAnyException (Line
9980, "system.pas" + 13) + $0
+ $41[7C903786]{ntdll.dll } RtlConvertUlongToLargeInteger + $41
+ $9[7C90EAF5]{ntdll.dll } KiUserExceptionDispatcher + $9
+ $7A[10F7829E]{COMERR~1.OCX} variant.cpp.Variant.OlePropertyGet +
$7A
As far as i can tell it looks like GetIDsOfNames, called from
OlePropertyGet, is raising an exception. If i remove the OleObject
call in my 'UpdatePropertyPage' implementation and just set a boolean
value the property page is display without error.
Is there some additional step I need to complete to initialise
OleObject somehow?
Has anyone encountered this before?
Has anyone successfully created an activex control with a custom
property page with C++Builder 2006?
Regards
Gary |
|
| Back to top |
|
 |
garyc Guest
|
Posted: Tue Mar 20, 2007 6:23 pm Post subject: Re: Custom property page for an activeform control |
|
|
On 20 Mar, 12:33, "garyc" <gary.cuthb...@codaoctopus.com> wrote:
| Quote: | Hello,
Has anyone successfully added a custom property page to an active form
control?
I have a very simple control that wraps a list control for displaying
information. The control has a couple of buttons that clears the list
content or looks up an error code entered into an edit box.
It works, I have added the component to a package and can successfully
embed it in VCL applications.
I then attempted to add a property to my control. The property is of
type VARIANT_BOOL and is called 'Extended'. The idea was to control
the runtime behavior of the control according to the value of
'Extended' set when the control was placed on the vcl form.
I added the property to the typelibrary for the control, the
'get_Extended' and 'set_Extended' skeleton methods were added to my
code which i fleshed out to return or set the value of the member
variable 'm_vtBoolExtended', nothing fancy:
STDMETHODIMP TComErrorCtrlXImpl::get_Extended(VARIANT_BOOL* Value)
{
try
{
*Value = m_vtBoolExtended;
}
catch(Exception &e)
{
return Error(e.Message.c_str(), IID_IComErrorCtrlX);
}
return S_OK;
};
STDMETHODIMP TComErrorCtrlXImpl::set_Extended(VARIANT_BOOL Value)
{
try
{
m_vtBoolExtended = Value;
}
catch(Exception &e)
{
return Error(e.Message.c_str(), IID_IComErrorCtrlX);
}
return S_OK;
};
Following the C++Builder 6 manual i used the 'new property page'
wizard to add a custom property page. On this page i placed a single
check box control.
In my control code i added the ATL macro entries for the new property
page and an entry for the
custom property that it would set:
BEGIN_PROPERTY_MAP(TComErrorCtrlXImpl)
PROP_PAGE(CLSID_PropertyPage1)
PROP_ENTRY("Extended", 231, CLSID_PropertyPage1) // 231 = DispID
from typelib editor
END_PROPERTY_MAP()
In my property page code I fleshed out the 'UpdatePropertyPage' and
'UpdateObject' methods:
void __fastcall TPropertyPage1::UpdatePropertyPage(void)
{
// Update your controls from OleObjects
Variant vtTemp;
vtTemp = OleObject.OlePropertyGet("Extended");
if (vtTemp == VARIANT_FALSE) {
chk_Extended->Checked = false;
}
else {
chk_Extended->Checked = true;
}
}
void __fastcall TPropertyPage1::UpdateObject(void)
{
// Update OleObjects from your controls
// n.b. this is not the code given in the manual, the manual code
// attempts to access template OlePropertySet method for each
// type of parameter, they are protected however and so we must
// use the TAutoArgsBase incarnation which is public
VARIANT_BOOL vtBool;
TAutoArgs<1> args;
if (chk_Extended->Checked) {
args[1] = VARIANT_TRUE;
}
else {
args[1] = VARIANT_FALSE;
}
OleObject.OlePropertySet("Extended",
static_cast<TAutoArgsBase&>(args));
}
I then unload the control package, unregister the control, rebuild and
re-register the control, recreate the package and load it.
Now when i add the control to a VCL form everything is fine until i
right click on the control and select 'properties'.
I get the error
Access violation at address 10F7821D in module 'COMERR~1.OCX'. Read of
address D8558B6D
The Details of the error are:
+ $5D[10F7821D]{COMERR~1.OCX} variant.cpp.GetIDsOfNames + $5D
+ $0[51F26B4B]{rtl100.bpl } System.System.@HandleAnyException (Line
9980, "system.pas" + 13) + $0
+ $41[7C903786]{ntdll.dll } RtlConvertUlongToLargeInteger + $41
+ $9[7C90EAF5]{ntdll.dll } KiUserExceptionDispatcher + $9
+ $7A[10F7829E]{COMERR~1.OCX} variant.cpp.Variant.OlePropertyGet +
$7A
As far as i can tell it looks like GetIDsOfNames, called from
OlePropertyGet, is raising an exception. If i remove the OleObject
call in my 'UpdatePropertyPage' implementation and just set a boolean
value the property page is display without error.
Is there some additional step I need to complete to initialise
OleObject somehow?
Has anyone encountered this before?
Has anyone successfully created an activex control with a custom
property page with C++Builder 2006?
Regards
Gary
|
Ok within minutes of posting this i finally found a lead in article
'How to update the property page with the values of the ActiveX
control properties?' on this group.
The trick is not to use the 'OleObject' member (which is there for
backwards compatiblity?? compatbile with what?, it doesn't work! from
what i have read 'OleObjects' was added in version 4 how come there is
no mention of it in version 6 documentation just the nonfunctional
redundant property).
If you include the 'XXX_TLB.h' file in the property page implementaion
and use the OleObjects container to get the iunknown and then query
for the control interface you can successfully call the get/set
methods so in the above code UpdateProeprtyPage becomes:
void __fastcall TPropertyPage1::UpdatePropertyPage(void)
{
// Update your controls from OleObjects
Variant vtTemp;
IUnknown* pUnk = OleObjects->First();
IComErrorCtrlX* pCtrl = 0;
// query for control interface
pUnk->QueryInterface(IID_IComErrorCtrlX, (void**)&pCtrl);
// now we can access the properties
vtTemp = pCtrl->get_Extended();
// tidy away interface
pCtrl->Release();
if (vtTemp == VARIANT_FALSE) {
chk_Extended->Checked = false;
}
else {
chk_Extended->Checked = true;
}
}
I have been trying out various COM/DCOM/COM+ technologies with C+
+Builder 2006 and on several occasions i have been mislead into time
consuming problems by following incorrect documentation or using
wizards that just don't work (COM+ events wizards anyone?!?). Very
frustrating. |
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|