hexx 2024-03-09 10:58 采纳率: 0%
浏览 90

c++builder 怎样用 CEF4Delphi 获得网页source code?

我获取网页源代码的 c++builder 语句,如下:

class TMyStringVisitor : public TCefBaseRefCountedOwn , public ICefStringVisitor
{
public:
   void __fastcall Visit(const Uceftypes::ustring str);
   void * __fastcall Wrap(void) {return TCefBaseRefCountedOwn::Wrap();}
   bool __fastcall SameAs(void * aData) {return TCefBaseRefCountedOwn::SameAs(aData);}
   bool __fastcall SameAs(const _di_ICefBaseRefCounted aBaseRefCounted) {return TCefBaseRefCountedOwn::SameAs(aBaseRefCounted);}
   bool __fastcall HasOneRef(void) {return TCefBaseRefCountedOwn::HasOneRef();}
   bool __fastcall HasAtLeastOneRef(void) {return TCefBaseRefCountedOwn::HasAtLeastOneRef();}
   void __fastcall DestroyOtherRefs(void) {TCefBaseRefCountedOwn::DestroyOtherRefs();}
   virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, __RPC__deref_out void __RPC_FAR *__RPC_FAR *ppvObject)
    {return TCefBaseRefCountedOwn::QueryInterface(riid, ppvObject);}
   virtual ULONG STDMETHODCALLTYPE AddRef( void) {return TCefBaseRefCountedOwn::_AddRef();}
   virtual ULONG STDMETHODCALLTYPE Release( void) {return TCefBaseRefCountedOwn::_Release();}
};
 
void __fastcall TMyStringVisitor::Visit(const Uceftypes::ustring str)
{
 ShowMessage(str);
}
 
void __fastcall TForm1::Button1Click(TObject *Sender)
{
 _di_ICefStringVisitor myStringVisitor = new TMyStringVisitor;
 Form1->Chromium1->Browser->MainFrame->GetSource(myStringVisitor);
}

但调试跟踪没有执行TMyStringVisitor::Visit()
后来,我用Delphi写了一个unit,如下:

procedure StringVisitor(const str: ustring);
begin
  ShowMessage(str);
end;

procedure GetSourceHtml(chromium : TChromium);
var
  CefStringVisitor : ICefStringVisitor;
begin
  CefStringVisitor := TCefFastStringVisitor.Create(StringVisitor);
  chromium.Browser.MainFrame.GetSource(CefStringVisitor);
end;

然后,在c++builder里执行:GetSourceHtml(Form1->Chromium1);
正常显示了网页源码
现在,我想把 Delphi 的改为 c++builder 来写,遇到的问题是:
TCefStringVisitorProc 在Delphi 里定义为:TCefStringVisitorProc = {$IFDEF DELPHI12_UP}reference to{$ENDIF} procedure(const str: ustring);
而在 c++builder 里定义为:

__interface TCefStringVisitorProc  : public System::IInterface 
{
    virtual void __fastcall Invoke(const Uceftypes::ustring str) = 0 ;
};

请教大家,应怎样弄?

  • 写回答

3条回答 默认 最新

  • 专家-赤兔[在线] 优质创作者: 编程框架技术领域 2024-03-09 10:59
    关注

    引自免费微信小程序:皆我百晓生

    在C++Builder中使用CEF4Delphi获取网页源代码,你需要创建一个继承自ICefStringVisitor的类,并实现其Visit()方法。你之前提供的C++代码片段中已经创建了TMyStringVisitor类并实现了Visit(),但似乎没有正确地实例化和调用该类。

    下面是一个针对C++Builder修改后的完整示例:

    // 首先确保包含了必要的头文件
    #include "Cef headers"
    
    class TMyStringVisitor : public virtual TCefBaseRefCounted, public ICefStringVisitor
    {
    public:
        IMPLEMENT_REFCOUNTING(TMyStringVisitor);
        STDMETHOD(QueryInterface)(REFIID riid, void **ppv) override {
            if (IsEqualIID(riid, IID_ICefStringVisitor)) {
                *ppv = static_cast<ICefStringVisitor*>(this);
                AddRef();
                return S_OK;
            }
            return E_NOINTERFACE;
        }
    
        STDMETHOD_(ULONG, AddRef)(void) override {
            return refcount_base::AddRefImpl();
        }
    
        STDMETHOD_(ULONG, Release)(void) override {
            return refcount_base::ReleaseImpl();
        }
    
        // 重写 Visit 方法以处理接收到的网页源码
        STDMETHOD(Visit)(const CefString& str) override {
            ShowMessage(str.c_str()); // 假设 ShowMessage 是你的消息框显示函数
            return S_OK;
        }
    };
    
    //---------------------------------------------------------------------------
    
    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
        _di_ICefStringVisitor myStringVisitor = new TMyStringVisitor;
        Chromium1->Browser->MainFrame->GetSource(myStringVisitor);
    }
    

    注意,C++Builder中的CEF接口通常需要手动实现COM接口的相关方法(如QueryInterface、AddRef和Release),以及通过IMPLEMENT_REFCOUNTING宏来管理引用计数。上述代码应该能解决你在C++Builder中无法执行TMyStringVisitor::Visit()的问题。

    评论 编辑记录

报告相同问题?

问题事件

  • 修改了问题 3月9日
  • 创建了问题 3月9日