3

I need to write a Windows application that uses browser component in it. I chose RAD Studio's C++ Builder because I have already used it in the past, however, I'm not so much experienced in C++ programming as I do in web-dev (I'm mainly a web-developer: JS, PHP, etc...), so, I encountered some problems with realization of my project. I hope, I'm missing something very basic that C++ professional specialist could solve as quick as thought.

Built-in TWebBroswer component has many disadvantages, so I made a decision to use Chromium (https://github.com/hgourvest/dcef3). It took time to install it and make it work not only in Delphi, but in C++ Builder as well, however, I've got a project with TChromium in form that compiles and works fine at the moment: I can navigate pages, execute JS and more.

Nevertheless, there is one problem I still cannot solve: accessing document's DOM. In Google search results I found nothing helpful: one topic with same problem and no answers (http://www.cyberforum.ru/cpp-builder/thread996496.html) and documentation.

In the documentation it has been said that I have to use VisitDom method for this purpose, but I have no idea how to do this in C++ Builder.

In this C++ demo: https://code.google.com/p/chromiumembedded/source/browse/trunk/cef3/tests/cefclient/dom_test.cpp?r=689 I see the following code:

class ClientDOMVisitor : public CefDOMVisitor {
 public:
  ClientDOMVisitor() {
  }

  virtual void Visit(CefRefPtr<CefDOMDocument> document) OVERRIDE {
    // Register a click listener for the button.
    CefRefPtr<CefDOMNode> button = document->GetElementById("button");
    ASSERT(button.get());
    button->AddEventListener("click", new ClientDOMEventListener(), false);
  }

  IMPLEMENT_REFCOUNTING(ClientDOMVisitor);
};

Then, in VisitDom method:

VisitDOM(new ClientDOMVisitor)

When I'm trying to compile this piece of code, errors occur (in C++ Builder), such as:

[BCC32 Error] Unit1.cpp(184): E2303 Type name expected

Later, I've tryied to use advice from this topic (not DOMVisitor - StringVisitor, but I think, if I could make one of them work I would have no problems with the second one): https://groups.google.com/forum/#!msg/delphichromiumembedded/DckdcKOCLzw/-zgUXOUTXa4J It is written in Delphi, so I'm not sure if I correctly translated the code to C++.

In Unit1.h, I've added ICefStringVisitor to TForm1 as discussed and added a Visit method into private declaration section:

    class TForm1 : public TForm, ICefStringVisitor
    {
    __published:    // IDE-managed Components
// ... I've hide a part of code, nothing useful here ...
        TChromium *Chromium1;
        void __fastcall Chromium1BeforeBrowse(TObject *Sender, const ICefBrowser *browser,
              const ICefFrame *frame, const ICefRequest *request, bool isRedirect,
              bool Result);
        void __fastcall Chromium1LoadEnd(TObject *Sender, const ICefBrowser *browser, const ICefFrame *frame,
              int httpStatusCode);
    private:    // User declarations
        void __fastcall Visit(const UnicodeString str);
    public:     // User declarations

        __fastcall TForm1(TComponent* Owner);
    };

In Unit1.cpp I've added:

void __fastcall TForm1::Visit(const UnicodeString str)
{
   ShowMessage(str);
}
void __fastcall TForm1::Chromium1LoadEnd(TObject *Sender, const ICefBrowser *browser, const ICefFrame *frame, int httpStatusCode)
{
   ICefFrame * ncFrame = const_cast<ICefFrame *>(frame);
   // doesn't compile without const_cast
   ncFrame->GetSource(this);    
}

This code compiles and runs, but I'm immediately getting this error and application terminates:

Pure virtual function called

I'm so tired struggling with this. Can anyone experienced advice me how to use all of these VisitDom, ViewSource and other methods in RAD Studio C++ Builder? In Delpi, as I see, it is rather easy.

P.S. If it would help somehow, in ceflib.hpp I found the following declaration:

__interface ICefDomVisitor;
typedef System::DelphiInterface<ICefDomVisitor> _di_ICefDomVisitor;
__interface  INTERFACE_UUID("{8FD3D3A6-EA3A-4A72-8501-0276BD5C3D1D}") ICefFrame  : public ICefBase 
{

public:
    virtual bool __fastcall IsValid(void) = 0 ;
    virtual void __fastcall Undo(void) = 0 ;
    virtual void __fastcall Redo(void) = 0 ;
    virtual void __fastcall Cut(void) = 0 ;
    virtual void __fastcall Copy(void) = 0 ;
    virtual void __fastcall Paste(void) = 0 ;
    virtual void __fastcall Del(void) = 0 ;
    virtual void __fastcall SelectAll(void) = 0 ;
    virtual void __fastcall ViewSource(void) = 0 ;
    virtual void __fastcall GetSource(const _di_ICefStringVisitor visitor) = 0 ;
    virtual void __fastcall GetSourceProc(const _di_TCefStringVisitorProc proc) = 0 ;
    virtual void __fastcall GetText(const _di_ICefStringVisitor visitor) = 0 ;
    virtual void __fastcall GetTextProc(const _di_TCefStringVisitorProc proc) = 0 ;
    virtual void __fastcall LoadRequest(const _di_ICefRequest request) = 0 ;
    virtual void __fastcall LoadUrl(const ustring url) = 0 ;
    virtual void __fastcall LoadString(const ustring str, const ustring url) = 0 ;
    virtual void __fastcall ExecuteJavaScript(const ustring code, const ustring scriptUrl, int startLine) = 0 ;
    virtual bool __fastcall IsMain(void) = 0 ;
    virtual bool __fastcall IsFocused(void) = 0 ;
    virtual ustring __fastcall GetName(void) = 0 ;
    virtual __int64 __fastcall GetIdentifier(void) = 0 ;
    virtual _di_ICefFrame __fastcall GetParent(void) = 0 ;
    virtual ustring __fastcall GetUrl(void) = 0 ;
    virtual _di_ICefBrowser __fastcall GetBrowser(void) = 0 ;
    virtual _di_ICefv8Context __fastcall GetV8Context(void) = 0 ;
    virtual void __fastcall VisitDom(const _di_ICefDomVisitor visitor) = 0 ;
    virtual void __fastcall VisitDomProc(const _di_TCefDomVisitorProc proc) = 0 ;
    __property ustring Name = {read=GetName};
    __property ustring Url = {read=GetUrl};
    __property _di_ICefBrowser Browser = {read=GetBrowser};
    __property _di_ICefFrame Parent = {read=GetParent};
};

0 Answers0