C++Builder を Delphi として使う？

# はじめに
Delphi と C++Builder には Community Edition という無償版があるのですが、どちらか片方しかインストールできない (両方同時にインストールできない) という制限があります。[^1]

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/b5d1e5a4-c521-bafd-eba1-924262dfa609.png)

 - [Delphi Community Edition (Embarcadero)](https://www.embarcadero.com/jp/products/delphi/starter)
 - [C++Builder Community Edition (Embarcadero)](https://www.embarcadero.com/jp/products/cbuilder/starter/)

Delphi だけをやりたいって人は迷わず Delphi をインストールすればいいのですが、ポトリペタリで C++ の RAD 開発ができる C++Builder も魅力的です。

さて、どっちをインストールするべきなのでしょう？

# C++Builder と Delphi

VCL フレームワークも FireMonkey フレームワークも Object Pascal で書かれています。C++Builder では VCL や FireMonkey が使えます...という事は？

## C++Builder で Delphi のプロジェクトを読み込ませてみる
C++Builder でプロジェクトを開こうとすると気になる選択肢があります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/0b260728-2a24-9204-0bd0-03cbdafc2680.png)

**Delphi プロジェクト？**

え？C++Builder で Delphi のプロジェクト開けるの？試しに Delphi のプロジェクトを読み込ませてみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/a283f421-574f-9714-c033-c4ebad58ad95.png)

ぬか喜びじゃないですかヤダー！どうやらこれは RAD Studio の機能のようです。単体インストールされた C++Builder では使えません。

## C++Builder で Delphi のユニットを読み込ませてみる
では Delphi のユニットを読み込ませてみます。Delphi で作った空のフォームです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/aabc3ff2-a665-232b-0739-e3dd2833f8d7.png)

読み込みはしましたが〔F12〕を押してソースコードに切り替える事はできませんでした...がっかりです。

## C++Builder のプロジェクトに Delphi のユニットを読み込ませてみる
さて、この辺で**茶番は終わり**にしましょう。結論を先に言うと、限定的ではありますが **C++Builder で Object Pascal プログラミングをすることは可能**です。次に具体的な方法を示します。

### 1.C++Builder のプロジェクトを作成する
まず、普通に C++Builder のプロジェクトを作成します。今回は VCL アプリケーションにしてみます。[ファイル | 新規作成 | Windows VCL アプリケーション - C++Builder] です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/30eca9ce-0578-5b40-1720-f3111743536a.png)

### 2.C++Builder のユニットを削除する
プロジェクトマネージャにあるユニットをプロジェクトから削除します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/18a6f829-8a31-7064-f751-79ec617665b3.png)

こんな感じになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/c5c8f9f7-89b0-30cd-b843-56aedce43cf5.png)

### 3.Delphi で作ったユニットを追加する
[プロジェクト | プロジェクトに追加] であらかじめ用意しておいた Object Pascal (Delphi) ユニットを読み込ませます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/686c3e38-2a9d-82f9-62c0-e35dd6817c6a.png)

### 4.C++Builder プロジェクトを一旦保存する
[ファイル | プロジェクトに名前を付けて保存] でプロジェクトを一旦保存します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/d70d8bc0-792b-580b-d847-c2e154589ad4.png)

### 5.Delphi ユニットを開く
プロジェクトマネージャで Object Pascal のユニットをダブルクリックして開き、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/ca6be513-24ec-47b4-b2ec-f9c6dbd7e409.png)

[ファイル | 名前を付けて保存] で C++Builder プロジェクトと同じ場所に保存しておきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/45621091-0eb2-e9df-276a-83b857279bac.png)

これで、**C++Builder のプロジェクトに Object Pascal (Delphi) のユニット**という奇妙なプロジェクトができました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/87f5c00a-e7af-5b43-1caf-2b1b6eb2c655.png)

### 6.フォームにコンポーネントを貼る
フォームデザイナでフォームにラベルとボタンを貼ります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/b7e157a5-d6b0-c523-4dc5-32f713150a8c.png)

### 7.コードを記述する
コードを記述します。フォームデザイナでボタンをダブルクリックすると...

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/4ad35969-93e6-066e-1f88-be2817abb463.png)

イベントハンドラを記述できます...**Object Pascal のイベントハンドラを。**

```pascal
procedure TForm1.Button1Click(Sender: TObject);
begin
  Label1.Caption := 'Hello,world.';
end;
```
イベントハンドラにはボタンを押したらラベルに `Hello,world.` を表示するコードを記述しました。

### 8.コンパイル
とりあえず何も考えずに〔F9〕を押してデバッグ実行してみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/b157ba8a-f910-e683-9451-8d51a87b2ba7.png)

ボタンをクリックすると...

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/b035de88-3850-be38-2253-3791d80c4fa9.png)

ちゃんと実行されましたね。

**C++Builder では Object Pascal (Delphi) のユニットを混在させてコンパイルする事ができます。** 一つのソースコードの中でのミックスドランゲージはできないのですが、一つのプロジェクト内でのマルチランゲージは可能です。しかも C++ と Object Pascal 混在のプロジェクトであってもビルドはシームレスに行われます。

プロジェクトファイルだけ C++Builder で作って、Object Pascal (Delphi) のユニットを追加すると**なんちゃって Delphi** として使う事ができます。

## デメリット
C++Builder を Delphi 代わりに使う事のデメリットは次の通りです。

 - コンパイルが遅い
 - Delphi プロジェクトが使えない (Delphi コードでのコンソールアプリが書きにくい)
 - コンパイラが 1 対 1 で存在するとは限らない [^2]。
 - C++ と Object Pascal を混在させるとコードが複雑になる
 - Delphi のユニットを新規作成できない

**Delphi を使いたければ素直に Delphi インストールしときなさい**って事なのですが、最後の一つはどうにでもなります。Delphi で作られた空のユニットを用意しておけばいいのです。サンプルフォルダから適当なユニットを持ってきてもいいでしょう。

先にやったように、空の Object Pascal (Delphi) ユニットを [プロジェクト | プロジェクトに追加] で読み込ませて [ファイル | 名前を付けて保存] で保存すれば OK です。

### 空の VCL Pascal ユニット
空の VCL Pascal ユニットです。フォームファイル (\*.dfm) とユニットファイル (\*.pas) になります。

```pascal:Unit1.dfm
object Form1: TForm1
  Left = 0
  Top = 0
  Caption = 'Form1'
  ClientHeight = 299
  ClientWidth = 635
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'Tahoma'
  Font.Style = []
  OldCreateOrder = False
  PixelsPerInch = 96
  TextHeight = 13
end
```

```pascal:Unit1.pas
unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
  System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs;

type
  TForm1 = class(TForm)
  private
    { Private 宣言 }
  public
    { Public 宣言 }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

end.
```

### 空の FireMonkey Pascal ユニット
空の FireMonkey Pascal ユニットです。フォームファイル (\*.fmx) とユニットファイル (\*.pas) になります。[ファイル | 新規作成 | マルチデバイスアプリケーション - C++Builder] で FireMonkey プロジェクトを作成した時にはこちらのユニットが必要になります。

```pascal:Unit1.fmx
object Form1: TForm1
  Left = 0
  Top = 0
  Caption = 'Form1'
  ClientHeight = 480
  ClientWidth = 640
  FormFactor.Width = 320
  FormFactor.Height = 480
  FormFactor.Devices = [Desktop]
  DesignerMasterStyle = 0
end
```

```pascal:Unit1.pas
unit Unit1;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs;

type
  TForm1 = class(TForm)
  private
    { private 宣言 }
  public
    { public 宣言 }
  end;

var
  Form1: TForm1;

implementation

{$R *.fmx}

end.
```

### なお RAD Studio
なお、RAD Studio をお持ちの場合は、C++Builder ではなく **RAD Studio で起動して C++Builder プロジェクトを開く**と、C++Builder プロジェクトに対して簡単に Object Pascal (Delphi) ユニットを追加できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/06a16943-0f71-d37a-4293-f94166bc3d22.png)

便利ですね。

# おわりに
**「Delphi Community Edition をアンインストールしても C++ Community Edition をインストールできない！」** ってなる方がいらっしゃるといけないので言っておきますと、Delphi Community Edition をインストールしていて C++ Community Edition に入れ替えたい場合 (またはその逆) には、**アンインストールする前に** [ヘルプ | ライセンスマネージャ] か、インストールフォルダ内にある LicenseManager.exe を実行し、該当するライセンスを削除してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21785/e8613037-e612-131f-1685-88897951e29e.png)

なお、C++ と Object Pascal を混在させる方法は Embarcadero 公式のブログでも言及されていますのでご一読ください。

 - [Mixing Delphi and C++ (Embarcadero Blog)](https://community.idera.com/developer-tools/b/blog/posts/mixing-delphi-and-c)

Delphi には C++ コンパイラが付属しないため、Community Edition のようにどちらか片方しかインストールできないとしたら C++Builder を選ぶべきなのでしょうね...やれる事の幅が広がりますので。

C++Builder Community Edition をインストールして最初に書くアプリケーションは Delphi (Object Pascal) ユニットジェネレータですかね :smile:

[^1]: [Community Edition Q&A (Embarcadero)](https://www.embarcadero.com/jp/products/delphi/starter/faq)
[^2]: [Wikipedia](https://ja.wikipedia.org/wiki/C%2B%2B_Builder) 等で対応するコンパイラを確認してください。