言語の概要

提供: RAD Studio
移動先: 案内検索

Delphi 言語ガイド:インデックス への移動


Delphi は、厳密に型指定されるコンパイラ型の高レベル言語であり、構造化されたオブジェクト指向設計をサポートしています。Object Pascal をベースにしており、コードが読みやすい、コンパイルが高速、複数のユニット ファイルを使用したモジュラー プログラミングが可能などの利点があります。Delphi には、RAD Studio のコンポーネント フレームワークおよび環境をサポートするための特別な機能が備わっています。この言語ガイドの説明および例では、基本的に、Embarcadero 開発ツールを使用していることを前提としています。


Embarcadero ソフトウェア開発ツールを使って開発を行う場合には、通常、統合開発環境(IDE)内でコードを書いてコンパイルします。ユニット間の依存情報の管理など、プロジェクトやソース ファイルの詳細なセットアップの多くは、Embarcadero 開発ツールが処理してくれます。また、厳密には Object Pascal 言語仕様に含まれない、プログラム構成に対する制約も、この製品で設定できます。たとえば、IDE を使わずにプログラムを記述し、コマンド プロンプトからコンパイルした場合には、ファイルやプログラムの命名規則を無視することが可能ですが、Embarcadero 開発ツールを使用するとその規則を強制的に守らせることができます。

この言語ガイドでは、基本的に、IDE で作業をし、ビジュアル コンポーネント ライブラリ(VCL)を使ったアプリケーションを構築することを前提としています。時折 Delphi 固有の規則が出てくる場合がありますが、それは Object Pascal プログラミング全体に適用される規則とは区別して記載しています。

このセクションでは以下のトピックについて説明します。

  • プログラムの構成。アプリケーションをユニットや名前空間に分割するための基本の言語機能について説明します。
  • サンプル プログラム。コンソール アプリケーションおよび GUI アプリケーションの簡単なサンプルと、コマンドラインからコンパイラを実行する基本の命令を示します。

プログラムの構成

Delphi プログラムは、通常、ユニットと呼ばれるソース コード モジュールに分かれています。ほとんどのプログラムは program というヘッダーで始まり、ここでプログラム名が指定されます。program ヘッダーの後には、オプションの uses 句と、さらに宣言およびステートメントのブロックが続きます。uses 句には、プログラムにリンクされるユニットの一覧が含まれます。このユニットは、さまざまなプログラムで共有することができ、多くはそれ自体が uses 句を持っています。

この uses 句によって、モジュール間の依存関係についての情報がコンパイラに伝えられます。モジュール自体にこの情報が格納されているため、Delphi 言語のほとんどのプログラムでは、メイクファイルやヘッダー ファイルやプリプロセッサの "include" 指令が必要ありません。

Delphi ソース ファイル

コンパイラでは、次の 3 種類のファイルに Delphi のソース コードが含まれることを想定しています。

ユニット ソース ファイルには、通常、アプリケーションのほとんどのコードが含まれます。各アプリケーションには 1 つのプロジェクト ファイルと複数のユニット ファイルが含まれます。このプロジェクト ファイルは、従来の Pascal の program ファイルに対応するもので、ユニット ファイルをアプリケーションにまとめる働きをします。Embarcadero 開発ツールでは、アプリケーションごとに 1 つのプロジェクト ファイルを自動的に保守します。

コマンドラインからプログラムをコンパイルする場合には、すべてのソース コードをユニット(.pas)ファイルに記述することができます。IDE を使ってアプリケーションをビルドする場合には、プロジェクト(.dpr)ファイルが作成されます。

パッケージ ソース ファイルは、プロジェクト ファイルと似ていますが、パッケージと呼ばれる動的にリンク可能な特別なライブラリを作成するために使用します。

アプリケーションのビルドに使用するその他のファイル

Embarcadero 製品では、ソース コード モジュールのほかに、Pascal 以外のいくつかのファイルを使用してアプリケーションをビルドします。これらのファイルは IDE によって自動的に保守されます。具体的には次のようなものがあります。

  • VCL フォーム ファイル(Win32 の場合の拡張子は .dfm)
  • リソース ファイル(拡張子は .res)
  • プロジェクト オプション ファイル(拡張子は .dof)

VCL フォーム ファイルには、フォームのプロパティとフォームが所有するコンポーネントの情報が含まれています。各フォーム ファイルは 1 つのフォームを表し、そのフォームは通常、アプリケーション内の 1 つのウィンドウまたはダイアログ ボックスに対応します。IDE を使用すると、フォーム ファイルをテキストとして表示および編集したり、フォーム ファイルをテキスト形式(バージョン管理に適した形式)またはバイナリ形式で保存することができます。デフォルトではフォーム ファイルはテキスト形式で保存されますが、通常はこれを手動で編集することはありません。編集は Embarcadero のビジュアル設計ツールを使って行う方が一般的です。各プロジェクトは少なくとも 1 つのフォームを持ち、各フォームにはデフォルトでフォーム ファイルと同じ名前を持つユニット(.pas)ファイルが関連付けられます。

各プロジェクトでは、VCL フォーム ファイルのほかに、アプリケーションのアイコンや文字列などのリソースを保持するリソース(.res)ファイルが使われます。このファイルの名前は、デフォルトではプロジェクト(.dpr)ファイルと同じです。

プロジェクト オプション(.dof)ファイルには、コンパイラおよびリンカの設定、検索パスの情報、バージョン情報などが含まれます。各プロジェクトには、プロジェクト(.dpr)ファイルと同じ名前のプロジェクト オプション ファイルが 1 つ関連付けられます。このファイルに格納されるオプションは、通常、[<プロジェクト名> のプロジェクト オプション]ダイアログで設定します。

IDE の各種ツールは、別の種類のファイルにデータを格納します。デスクトップ設定(.dsk)ファイルには、ウィンドウの配置などの構成オプションの情報が含まれます。デスクトップ設定は、プロジェクト単位で、または環境全体で設定できます。これらのファイルは、コンパイルには直接影響しません。

コンパイラによって生成されるファイル

アプリケーションまたはパッケージを初めてビルドすると、プロジェクトで使用する新しいユニットごとに、コンパイル済みのユニット ファイル(Win32 では .dcu)がコンパイラによって作成されます。その後、プロジェクト内のすべての .dcu ファイルがリンクされて、1 つの実行可能ファイルまたは共有パッケージが作成されます。パッケージを初めてビルドすると、パッケージに含まれる新しいユニットごとに 1 つのファイルがコンパイラによって作成され、その後 .dcp ファイルとパッケージ ファイルの両方が作成されます。コンパイラ スイッチ GD を指定した場合には、リンカによってマップ ファイルと .drc ファイルが作成されます。この .drc ファイルは文字列リソースを含むもので、これをコンパイルしてリソース ファイルを作成することができます。

プロジェクトをビルドしたときに個々のユニットが再コンパイルされるのは、前回のコンパイル以降にソース(.pas)ファイルが変更された場合、ユニットの .dcu/.dpu ファイルが見つからない場合、再コンパイルするようコンパイラに明示的に指示した場合、および、変更された別のユニットにユニットのインターフェイスが依存している場合だけです。実際には、コンパイラがコンパイル済みのユニット ファイルを見つけることができ、変更された別のユニットに対してそのユニットが依存していなければ、ユニットのソース ファイルが存在している必要はまったくありません。

サンプル プログラム

以下の例では、Delphi プログラミングの基本機能を説明します。これらの例は、通常は IDE でコンパイルされることがない単純なアプリケーションです。これはコマンドラインからコンパイルできます。

単純なコンソール アプリケーション

次のプログラムは、コマンド プロンプトからコンパイルして実行できる、単純なコンソール アプリケーションです。

 program Greeting;

 {$APPTYPE CONSOLE}

 var
   MyMessage: string;

 begin
   MyMessage := 'Hello world!';
   Writeln(MyMessage);
 end.

1 行目では、Greeting というプログラムを宣言しています。{$APPTYPE CONSOLE} 指令は、これがコンソール アプリケーションであり、コマンドラインから実行されることをコンパイラに知らせています。次の行では、文字列を保持する MyMessage という変数を宣言しています (Delphi には純粋な文字列データ型があります)。プログラムでは、その後、"Hello world!" という文字列を変数 MyMessage に代入し、Writeln 手続きを使って MyMessage の内容を標準出力に送っています ((Writeln は、コンパイラによって自動的にすべてのアプリケーションに含められる System ユニットで暗黙的に定義されています)。

このプログラムを greeting.pas または greeting.dpr というファイルに入力し、次のコマンドを入力してコンパイルします。

dcc32 greeting

これによって Win32 実行可能ファイルが作成されます。

作成された実行可能ファイルは、Hello world! というメッセージを出力します。

このサンプル プログラムは、単純であるほかに、Embarcadero 開発ツールで通常作成するプログラムとはいくつかの重要な点が異なります。まず、これはコンソール アプリケーションです。Embarcadero 開発ツールで作成するアプリケーションの多くはグラフィカル インターフェイスを備えているため、通常は Writeln を呼び出すことがありません。また、サンプル プログラム全体(Writeln を除く)が 1 つのファイルに含まれています。標準的な GUI アプリケーションでは、サンプルの 1 行目にあるプログラム ヘッダーは、独立したプロジェクト ファイルに含められます。ユニット ファイルで定義されたルーチンをいくつか呼び出す以外に、このプロジェクト ファイルに実際のアプリケーション ロジックは含められません。

いくらか複雑な例

次の例は、プロジェクト ファイルとユニット ファイルの 2 ファイルに分割されたプログラムです。プロジェクト ファイルは次のような内容で、greeting.dpr という名前で保存します。

 program Greeting;

 {$APPTYPE CONSOLE}

 uses
   Unit1;

 begin
   PrintMessage('Hello World!');
 end.

1 行目では greeting というプログラムを宣言しています。先ほどの例と同じコンソール アプリケーションです。uses Unit1; 句では、プログラム greetingUnit1 というユニットに依存していることをコンパイラに知らせています。最後に、プログラムは PrintMessage 手続きを呼び出して、文字列 Hello World! を渡します。PrintMessage 手続きは Unit1 で定義されています。Unit1 のソース コードは次のとおりです。これは Unit1.pas というファイルに保存しなければなりません。

 unit Unit1;

 interface

 procedure PrintMessage(msg: string);

 implementation

 procedure PrintMessage(msg: string);
 begin
    Writeln(msg);
 end;

 end.

Unit1 では PrintMessage という手続きを定義しています。この手続きは 1 つの文字列を引数に取り、その文字列を標準出力に送ります (Delphi では、値を返さないルーチンを手続きと呼びます。値を返すルーチンは関数と呼びます)。

PrintMessage

Unit1 内で 2 度宣言されていることに注意してください。予約語 interface の下にある最初の宣言は、Unit1 を使用する他のモジュール(greeting など)から PrintMessage を使用できるようにするためのものです。予約語 implementation の下にある 2 番目の宣言では、実際に PrintMessage を定義します。

コマンドラインで次のように入力すると Greeting をコンパイルできます。

dcc32 greeting

これによって Win32 実行可能ファイルが作成されます。

コマンドライン引数として Unit1 を指定する必要はありません。コンパイラが greeting.dpr を処理するときに、greeting プログラムが依存しているユニット ファイルが自動的に検索されます。作成された実行可能ファイルは、最初のサンプル プログラムと同じ動作をします。つまり、Hello world! というメッセージを出力します。

VCL アプリケーション

次の例は、IDE でビジュアル コンポーネント ライブラリ(VCL)コンポーネントを使ってビルドするアプリケーションです。このプログラムでは自動生成のフォーム ファイルとリソース ファイルを使用するため、ソース コードだけからアプリケーションをコンパイルすることはできません。ただし、ここには Delphi 言語の重要な機能が示されています。このプログラムは、複数のユニットのほかに、クラスとオブジェクトを使用します。

このプログラムには、1 つのプロジェクト ファイルと 2 つの新しいユニット ファイルが含まれます。まず、次に示すのがプロジェクト ファイルです。

 program Greeting;

 uses
   Forms, Unit1, Unit2;

 {$R *.res} { この指令はプロジェクトのリソース ファイルをリンクする }

 begin
    { グローバル インスタンス Application の呼び出し }
    Application.Initialize;
    Application.CreateForm(TForm1, Form1);
    Application.CreateForm(TForm2, Form2);
    Application.Run;
 end.

このプログラムも greeting という名前です。ここでは 3 つのユニットを使用します。VCL の一部である Forms、アプリケーションのメイン フォーム(Form1)に関する Unit1、別のフォーム(Form2)に関する Unit2 です。

このプログラムでは、Forms ユニットで定義された Vcl.Forms.TApplication クラスのインスタンスである Application というオブジェクトに対して、一連の呼び出しを実行しています (どのプロジェクトにも Application オブジェクトが自動生成されます)。その中の 2 つでは、Vcl.Forms.TApplication クラスの CreateForm というメソッドを呼び出しています。最初の CreateForm の呼び出しでは Form1 が作成されます。これは Unit1 で定義された TForm1 クラスのインスタンスです。2 番目の CreateForm の呼び出しでは Form2 が作成されます。これは Unit2 で定義された TForm2 クラスのインスタンスです。

Unit1 は次のようになっています。

 unit Unit1;

 interface

 uses SysUtils, Types, Classes, Graphics, Controls, Forms, Dialogs;

 type
   TForm1 = class(TForm)
     Button1: TButton;
     procedure Button1Click(Sender: TObject);
   end;

 var
   Form1: TForm1;

 implementation

 uses Unit2;

 {$R *.dfm}

 procedure TForm1.Button1Click(Sender: TObject);
   begin
     Form2.ShowModal;
   end;

 end.

Unit1 では、Vcl.Forms.TForm から派生した TForm1 というクラスと、そのクラスのインスタンス Form1 を作成します。TForm1 クラスには、Vcl.StdCtrls.TButton クラスのインスタンスである Button1 というボタンと、ユーザーが Button1 を押したときに呼び出される Button1Click という手続きがあります。Button1Click では、Form1 を非表示にし、Form2 を表示します(Form2.ShowModal の呼び出し部分)。

メモ: 上記の例の Form2.ShowModal は、自動生成されたフォームを使うことを前提としています。このサンプル コードでは問題ありませんが、自動生成されたフォームを使うことは推奨されていません。

Form2Unit2 で次のように定義されています。

 unit Unit2;

 interface

 uses SysUtils, Types, Classes, Graphics, Controls, Forms, Dialogs;

 type
 TForm2 = class(TForm)
   Label1: TLabel;
   CancelButton: TButton;
   procedure CancelButtonClick(Sender: TObject);
 end;

 var
   Form2: TForm2;

 implementation

 uses Unit1;

 {$R *.dfm}

 procedure TForm2.CancelButtonClick(Sender: TObject);
   begin
     Form2.Close;
   end;

 end.

Unit2 では、TForm2 というクラスと、そのクラスのインスタンス Form2 を作成します。TForm2 クラスには、Vcl.StdCtrls.TButton のインスタンスである CancelButton というボタンと、Vcl.StdCtrls.TLabel のインスタンスである Label1 というラベルがあります。ソース コードからはわかりませんが、Label1 には Hello world! というキャプションが表示されます。このキャプションは、Form2 のフォーム ファイル Unit2.dfm で定義されています。

TForm2 では、CancelButtonClick というメソッドを宣言し、定義しています。これは実行時にユーザーが CancelButton を押すと呼び出されます。この手続き(および Unit1TForm1.Button1Click)は、プログラム実行中に発生するイベントに応答するため、イベント ハンドラと呼ばれます。イベント ハンドラは、Form1 および Form2 のフォーム ファイルによって具体的なイベントに割り当てられます。

greeting プログラムを起動すると、Form1 は表示されますが、Form2 は表示されません (デフォルトでは、プロジェクト ファイル内で最初に作成されたフォームだけが実行時に表示されます。これをプロジェクトのメイン フォームと呼びます)。ユーザーが Form1 上のボタンを押すと、Form2Hello world! という挨拶が表示されます。ユーザーが CancelButton またはタイトル バーの Close ボタンを押すと、Form2 は閉じます。

関連項目