4

I found the brilliant Delphi Chromium project for embedding Chrome in a Delphi form. It works well in Delphi7 after a bit of hacking and I can get the demo app running.

However when I do my own app with the component, I can't load my own url. I get a access violation.

Chromium2.Browser.MainFrame.LoadUrl('http://www.example.com');

The TChromium component is working and I have all the DLLs in the right place, since if I set DefaultUrl it works fine.

I have Chromium2 in a TPageControl page and with the OnClick event of a button I call the above code. I get an AccessViolation. Mainframe is nil.

I can't find a way around this, has anyone got this to work?

ain
  • 21,481
  • 3
  • 47
  • 70
Toby Allen
  • 10,562
  • 10
  • 70
  • 120

5 Answers5

4

I still haven't found a resolution but I found the following work around

procedure TForm1.lblWebsiteClick(Sender: TObject);
var MainFrame : ICefFrame;
begin
  MainFrame := Chromium2.Browser.GetMainFrame;
  MainFrame.LoadUrl('http://www.cookingisfun.ie');
end;
Toby Allen
  • 10,562
  • 10
  • 70
  • 120
  • That does not look like a workaround. That looks like how it is meant to be used. Front page of documentation says "CefFrame represents a single frame in the browser window. Each browser window also has a top-level main frame that can be accessed via the CefBrowser::GetMainFrame() method." – David Heffernan Sep 17 '11 at 13:46
  • @David, the code in the Demo apps uses the code in the structure I origionally tried `Chromium2.Browser.MainFrame.LoadUrl('http://www.example.com');` so presumably the author felt this was the way it was meant to be used. – Toby Allen Sep 17 '11 at 13:48
  • You've got the source. I don't. It should be easy to see where MainFrame gets allocated (or not). – David Heffernan Sep 17 '11 at 13:49
  • I don't need this workaround in my own project. `Chromium2.Browser.MainFrame.LoadUrl('http://www.example.com');` works as expected with mine. I have no `DefaultUrl` defined.. that's maybe the difference. – Whiler Sep 17 '11 at 14:52
  • Its fairly odd alright. It may be something to do with running Delphi 7 on a Windows 7 machine. – Toby Allen Sep 19 '11 at 13:48
3

The problem is that mainframe only loads after the page has loaded.

For one thing, you need to do:

if Assigned(Chromium2.Browser.MainFrame)
    then  Chromium2.Browser.MainFrame...

However, that is not the preferred way to navigate, but instead you should do:

Chromium1.Load( theUrl );

If you still want to use MainFrame, do it in OnLoadEnd event.

Christian
  • 25,801
  • 14
  • 102
  • 151
2

Had similar problems and after quite a few hours located the problem:

  1. If TChromium is on the main form of the application then ok.

  2. If TChromium is not on main form (or on a frame) then:

    1. Open cef.inc and remove the dot to define:

      {.$DEFINE CEF_MULTI_THREADED_MESSAGE_LOOP} 
      
    2. Remove DefaultURL value so it is an empty string.

I googled CEF_MULTI_THREADED_MESSAGE_LOOP but it didn't come up with much at all.

Lastly, had resizing/refreshing problems (even with alignment set to alClient). Short term fix is within
crmLoadEnd event do something like:

     if crm.Height < panclient.Height then
        crm.Height := panclient.Height;
Tim Cooper
  • 144,163
  • 35
  • 302
  • 261
tomo7
  • 405
  • 7
  • 6
0

Had this problem as well. It seems the MainFrame is first created when the frame/window gets visible. But there is an easy way around it. Just call .Load('about:blank') directly on your TChromium object. This will initialize the missing frame earlier.

0

Do you have alll the required DLL in the folder where your application is built?

You need: libcef.dll, icudt.dll, ...

Check this thread on their support group.


When you build/run the demos, they are built in this subfolder (*DCC_ExeOutput*): DCEF\bin\ which is why it works with them...

Whiler
  • 7,757
  • 3
  • 28
  • 55
  • 1
    @David: if they are loaded dynamically and GetProcAddress returns nil, it could. – Rudy Velthuis Sep 17 '11 at 11:16
  • @Rudy `GetProcAddress` returning `nil` seems unlikely to lead to `MainFrame` being `nil`. `MainFrame` sounds like a component to me rather than a procedure address. What makes you think it is a procedure address? What am I missing? – David Heffernan Sep 17 '11 at 12:02
  • I use this component and if I remove the DLL from my executable folder, I have this behaviour... so, I think this is the reason why he gets this AV... – Whiler Sep 17 '11 at 12:02
  • MainFrame is set to `nil` when DLLs are missing, but is assigned if they are there? Really? – David Heffernan Sep 17 '11 at 12:06
  • I **think** that `MainFrame` is not instanciate when dll are missing... and if DLL are present, it is automatically instanciate... BTW, my code is always prefix with `if (chrm1.Browser <> nil) then` before each method calls... – Whiler Sep 17 '11 at 12:13
  • I'll take your word for it but it seems unusual. Binding errors usually result in bind time errors. – David Heffernan Sep 17 '11 at 12:42
  • 1
    All the dlls are in place, the exe is built to the bin directory with the dlls. If I set DefaultUrl it works and loads the url, but I cant set my own url. Browser isnt nil, mainframe is. – Toby Allen Sep 17 '11 at 13:35
  • @Toby: That's weird... See my other comment in your answer – Whiler Sep 17 '11 at 14:51