LoginSignup
8
2

More than 5 years have passed since last update.

C++BuilderでChromiumブラウザを作る

Last updated at Posted at 2019-01-05

スクリーンショット 2019-01-05 22.55.54.png

C++BuilderでChromiumを使うための方法。
Chromium Embedded Framework と、DEF4DelphiというライブラリをC++Builderで使う方法を記載。
iOSやMacなんかはTWebBrowserを使っても十分だが、WindowsだけIEがベースになっているのでCSSが崩れたりJavascriptがうまく動作しなかったりするためこの方法を探した。
なお、DelphiがなくてもC++Builderだけで可能だが、VCLの32bitのみでしか成功していない。
だれか64bitのFireMonkeyで成功した人は居ないかな?

環境

Windows10
C++Builder 10.3 Rio

ダウンロード

下記URLのGitHubからクローンしてきたりダウンロードする。

GitHub - salvadordf/CEF4Delphi: CEF4Delphi is an open source project to embed Chromium-based browsers in applications made with Delphi or Lazarus/FPC.

移動

適当な場所に移動。
今回はパブリックのドキュメント内に保存。
C:\Users\Public\Documents\CEF4Delphi-master

CEF

GitHubのreadme内に記載されている「32bit」のファイルをダウンロードして解凍し、

4f2434bc.png

ReleaseとResourcesというフォルダの中身を全て

C:\Users\Public\Documents\Embarcadero\Studio\20.0\BPL\

に「cef」というフォルダを作成して
その中にコピーもしくは移動させる。
(これはデバッグ時と、コンパイル時後に使うため。)

スクリーンショット 2019-01-05 18.20.47.png

C++Builderで作業

C++Builderを起動。

ツールオプション

ツール->オプション
言語->Delphiオプション->ライブラリ
内の、
ライブラリパスの横の「…」をクリックしてディレクトリ一覧を表示させたら、そこに先程移動させたフォルダ内のCEF4Delphi-master/sourceフォルダを追加します。

3cb40f4f.png

コンポーネントのインストール

コンポーネントのインストールを選択

3c9284ea.png

ユニットファイル名項目の右にある「...」をクリックしてCEF4Delphi-master/packagesフォルダ内のCEF4Delphi_Register.pasを選択。(CEF4Delphi_FMX_Register.pasを選択するとFiremonkeyで使用可能になるそうですが、エラー回避が出来なかった)
新規パッケージにインストールにチェックを入れて次へ

fb95d126.png

パッケージ名の右の「...」をクリックしてCEF4Delphi-master/packages/CEF4Delphi.dpkを選択、

「C++Builderパッケージ」にチェックを入れて完了。
完了すると、エラーが表示されるが、気にせず次へ

保存する

ファイル->全てを保存で適当に保存。

インストール

プロジェクトウィンドウのプロジェクト名の部分を右クリックしてインストールを選択。
インストールを完了させる。

12bed3c8.png

フォームを作る

C++Builderを開き直して、Windows VCLアプリケーションを作成する。

TChromiumを貼り付け

TChromiumとTCEFWindowParentを貼り付ける。
保存しようとすると、ヘッダが見つからない旨が表示されるので、sourceフォルダ内の同名のファイルを指定する。
TCEFWindowParentは表示場所なので、目一杯に広げておく。

さらに、TEditとTButtonを配置しておく。

f38e0ed1.png

コード

Project1.cpp

Project1.cppのコードを下記URLのように記述していく。ただし、TCefApplicationのコンストラクタの仕様が変わっているらしいので、trueと記述しているところを消す。

TChromium vs C++ Builder - BriskBard and CEF4Delphi

Project1.cpp
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop
#include <tchar.h>
//---------------------------------------------------------------------------
USEFORM("Unit1.cpp", Form1);
#include "uCEFApplication.hpp"
#define SetPEFlags IMAGE_FILE_LARGE_ADDRESS_AWARE //In mine I didn't used it and works fine, i recompiled with it and it works fine for me as well

//---------------------------------------------------------------------------
int WINAPI _tWinMain(HINSTANCE, HINSTANCE, LPTSTR, int)
{
    try
    {
        GlobalCEFApp = new TCefApplication();//<-- here you had false;
        GlobalCEFApp->CheckCEFFiles =true; //<- like this you are sure that all files are good
        GlobalCEFApp->FrameworkDirPath = "cef";
        GlobalCEFApp->ResourcesDirPath = "cef";
        GlobalCEFApp->LocalesDirPath = "cef\\locales";
        GlobalCEFApp->Cache = "cef\\cache";
        GlobalCEFApp->Cookies = "cef\\cookies";
        GlobalCEFApp->UserDataPath = "cef\\User Data";
        // Added some Misc info to disable possible "can broke things" extensions
        GlobalCEFApp->FlashEnabled=false;
        GlobalCEFApp->FastUnload=true;
        GlobalCEFApp->NoSandbox=false;
        GlobalCEFApp->SingleProcess=true; //<-C++ builder seems a little bit akward using multiprocess.

        if(GlobalCEFApp->StartMainProcess())
          {
            Application->Initialize();
            Application->MainFormOnTaskBar = true;
            Application->CreateForm(__classid(TForm1), &Form1);
            Application->Run();
          }
        // GlobalCEFApp->~TCefApplication(); // Here "GlobalCEFApp->Free();" crash the app at shutdown
    }
    catch (Exception &exception)
    {
        Application->ShowException(&exception);
    }
    catch (...)
    {
        try
        {
            throw Exception("");
        }
        catch (Exception &exception)
        {
            Application->ShowException(&exception);
        }
    }
    return 0;
}
//---------------------------------------------------------------------------

一度実行させると、エラーが表示されるので、該当する箇所(多分下記のような記述で41行目と42行目)をコメントアウトさせる。

extern "C" System::LongBool __fastcall ProcessUnderWow64(NativeUInt hProcess, System::LongBool &Wow64Process);
extern "C" System::LongBool __stdcall TzSpecificLocalTimeToSystemTime(Winapi::Windows::PTimeZoneInformation lpTimeZoneInformation, Winapi::Windows::PSystemTime lpLocalTime, Winapi::Windows::PSystemTime lpUniversalTime);

TFromのイベント

TFormの各イベントにコードを記述

TFromのコンストラクタ

コンストラクタ内でLoadURL()を実行しようとしても上手くいかない。

__fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) {
    Chromium1->CreateBrowser(CEFWindowParent1);
}
TFromを閉じるときのイベント(念の為)
void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action) {
    // クローズ
    Chromium1->CloseBrowser(true);
}
ボタンのイベント

ボタンを押したときにEditのURLを開くようにする。

void __fastcall TForm1::Button1Click(TObject *Sender) {
    Chromium1->LoadURL(Edit1->Text);
}

ビルド後イベント

DLL等をコンパイルした先にコピーするようにしておく。

xcopy /y /d /S /E "C:\Users\Public\Documents\Embarcadero\Studio\20.0\BPL\*" "$(OUTPUTDIR)"

以上。

8
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
2