
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からクローンしてきたりダウンロードする。
移動
適当な場所に移動。
今回はパブリックのドキュメント内に保存。
C:\Users\Public\Documents\CEF4Delphi-master
CEF
GitHubのreadme内に記載されている「32bit」のファイルをダウンロードして解凍し、
ReleaseとResourcesというフォルダの中身を全て
C:\Users\Public\Documents\Embarcadero\Studio\20.0\BPL\
に「cef」というフォルダを作成して
その中にコピーもしくは移動させる。
(これはデバッグ時と、コンパイル時後に使うため。)
C++Builderで作業
C++Builderを起動。
ツールオプション
ツール->オプション
言語->Delphiオプション->ライブラリ
内の、
ライブラリパスの横の「…」をクリックしてディレクトリ一覧を表示させたら、そこに先程移動させたフォルダ内のCEF4Delphi-master/sourceフォルダを追加します。
コンポーネントのインストール
コンポーネントのインストールを選択
ユニットファイル名項目の右にある「...」をクリックしてCEF4Delphi-master/packagesフォルダ内のCEF4Delphi_Register.pasを選択。(CEF4Delphi_FMX_Register.pasを選択するとFiremonkeyで使用可能になるそうですが、エラー回避が出来なかった)
新規パッケージにインストールにチェックを入れて次へ
パッケージ名の右の「...」をクリックしてCEF4Delphi-master/packages/CEF4Delphi.dpkを選択、
「C++Builderパッケージ」にチェックを入れて完了。
完了すると、エラーが表示されるが、気にせず次へ
保存する
ファイル->全てを保存で適当に保存。
インストール
プロジェクトウィンドウのプロジェクト名の部分を右クリックしてインストールを選択。
インストールを完了させる。
フォームを作る
C++Builderを開き直して、Windows VCLアプリケーションを作成する。
TChromiumを貼り付け
TChromiumとTCEFWindowParentを貼り付ける。
保存しようとすると、ヘッダが見つからない旨が表示されるので、sourceフォルダ内の同名のファイルを指定する。
TCEFWindowParentは表示場所なので、目一杯に広げておく。
さらに、TEditとTButtonを配置しておく。
コード
Project1.cpp
Project1.cppのコードを下記URLのように記述していく。ただし、TCefApplicationのコンストラクタの仕様が変わっているらしいので、trueと記述しているところを消す。
TChromium vs C++ Builder - BriskBard and CEF4Delphi
//---------------------------------------------------------------------------
# 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)"
以上。