c++delphic++builderc++builder-2010c++builder-10.2-tokyo

C++Builder 12 error in dynamic OnDocumentComplete event assignment for TCppWebBrowser


I'm using C++Builder since version 1.0 (1994). I used it until version 2010. Lately, we got the latest version of the IDE "Embarcadero® C++Builder 12 Version 29.0.50491.5718".

I have created tons of objects dynamically in the past without any problems, but now I want to upgrade an old project and I'm getting an error that I'm not able to fix.

I'm trying to create a TCppWebBrowser dynamically (using the IDE works perfectly).

My code is basically this:

void __fastcall TFormAdmin::CppWebBrowser1DocumentComplete(TObject *Sender, LPDISPATCH pDisp,
    Variant *URL)
{
    //Here the event code
}

And in other part of code, the dynamic creation of the object:

TCppWebBrowser *CppWebBrowser1;
CppWebBrowser1=new TCppWebBrowser(this);
CppWebBrowser1->TOleControl::Parent = this;
CppWebBrowser1->OnDocumentComplete = CppWebBrowser1DocumentComplete;

I get an error on this line:

CppWebBrowser1->OnDocumentComplete = CppWebBrowser1DocumentComplete;

[bcc32 Error] admin.cpp(78): E2034 Cannot convert 'void (_fastcall * (_closure )(TObject *,IDispatch *,Variant *))(TObject *,IDispatch *,Variant *)' to 'TCppWebBrowserDocumentComplete'

When I use this code using the IDE (creating and assigning the object and event in designing time), it works perfectly.

Function prototype is:

typedef void __fastcall (__closure * TCppWebBrowserDocumentComplete)(System::TObject * Sender,LPDISPATCH pDisp,VARIANT* URL);

The parameters are the same, the type is the same.

I'm not sure about what to do. I don't understand why it works at design-time but not programmatically.


Solution

  • There seems to be a discrepancy between the closure type and the generated function. The closure type is defined as:

    typedef void __fastcall (__closure * TCppWebBrowserDocumentComplete)(
        System::TObject * Sender, 
        LPDISPATCH pDisp /*[in]*/, 
        VARIANT* URL /*[in]*/);
    

    but the generated function uses Variant instead of VARIANT. This works for the components you drop in the IDE for some reason, but not when you do it manually. The solution is to change the function signature in both the header file and .cpp file to match:

    class TForm1 : public TForm
    {
        void __fastcall CppWebBrowser1DocumentComplete(
            TObject *Sender, LPDISPATCH pDisp, VARIANT *URL);
    //                                         ^^^^^^^
    
    void __fastcall TForm1::CppWebBrowser1DocumentComplete(
        TObject *Sender, LPDISPATCH pDisp, VARIANT *URL) {
    //                                     ^^^^^^^
    

    I wrote bug report RSS-1314 regarding this.